答:
You can never know an exact or nearly exact price, since it depends on many factors. Example:

Case study

You got a request for a small website based on WordPress. The only thing you have to do: work with your designer to create attractive graphics, then create the website itself (nothing highly technical, just a set of plugins to add to WordPress), and then deploy it. The work being really easy, you quoted it $600.

Your designer created the first draft. The customer explained that he finds it not attractive at all. The same went with the second, third and fourth draft. Finally, after two weeks of hard work, the designer finally got the draft which was accepted by the customer.

But sadly the designer was hit by a bus and the only thing you got was the JPEGs he sent you, but not the original PSDs, so you had to start over with a new designer. Finally, you got the graphics and started your job.

Surprise: you've discovered that the plugin A is incompatible with the plugin B, that the plugin C is not working as expected, and that the plugin D cannot be installed on the newest version of WordPress, while the plugin A can be installed only on this newest version. Now you have to do a lot of PHP coding by hand, and since you're a Python developer and never wrote a single line of code in PHP, it's not the easiest task.

Meanwhile, the customer starts to send you scary e-mails, asking why the work is not already done, while the deadline was a week ago. You finally finish the PHP coding, and everything works perfectly well on your machine. The customer is happy.

Then you start deploying the website to the hosting server to discover that not only the website fails with some cryptic error, but also the hosting company doesn't support a feature of PHP you've used a lot in your code.

Finally, after spending more than $3,000 on this project, you have the website up and running. The customer is angry because of the deadlines and because "nothing works as expected with you". Would you ask $600? $3,000?

Why does it happen?

What I illustrated in this example happens much more often than you may believe. Why? Because there are too many variables that you can't predict and which increase the risk. Here, the risk was increased by:

The unclear specifications related to visual design,

The death of the designer,

The incompatibility of the plugins you've selected,

The bad support of the plugins you've selected,

The fact that you haven't used PHP before,

The difference between the development environment and the production environment and the absence of staging.

One could solve those issues with specific approaches:

Clear and precise functional and non-functional requirements,

Hit-by-a-bus scenario management (i.e. the designer had to share every document with you so that he could be dead at any moment without compromising the project),

Prior knowledge of tools and languages you have to use (which requires a lot of work),

Staging, intensive testing, etc.

The only problem is that with this approach, you have to tell your customer that he would pay at least $5,000 in the first place, since it is actually the price of requirements, specification, design, testing, etc. Chances for this customer to accept your quote are extremely low.

So there is nothing to do?

If you can't give a very precise price, you can still give an approximation, which takes in account every part of the work to do separately, with a risk index being affected to every part. Higher is the predictable risk, higher is the price.

You have two ways to do that:

1. Watefally way

If you work on projects which fit Waterfall/V-Model, this may work:

List the functional and non-functional requirements of a project. Get the document signed by the customer, the same way he signs the contract.

Once you got this document, you already have:

The price you already spent gathering the requirements and creating this document. This may represent an important amount of money, since those documents may vary from twenty to a hundred of pages for an ordinary project, and be hundreds or thousands of pages for large projects.

The clear, precise and complete understanding of the product you're requested to do.

Go with your team step by step, analyzing each requirement and evaluating:

An average price of this part of the project,

A maximum price without taking in account the risk,

A risk index.

All three will be taken in account to determine the price you will give to the customer.

Asset the risk which doesn't depend on a specific requirement, but rather on the compatibility between the requirements or on the system in general.

Pros of waterfally approach: the customer gets a price which is quite precise, considering that you have a very clear vision of the work to do and the risks which may arise.

Cons of waterfally approach: you have to write a 200 pages document before giving the price. What if the customer cancels the project meanwhile, or goes to your concurrent? The whole process is also extremely heavy and the requirements cannot change later.

2. Agile way

If you work on projects which fit Scrum or other agile models:

either don't give the overall price of the project, but rather the prices of every component,

or you may indicate a very approximate overall price at the beginning, and then give the more and more precise one.

In both cases, you should have either a strong trust between you and the customer, or have excellent people in sales department. Otherwise,

in the first case, the person would believe that you're just stealing her money asking for small amounts again and again, and this will never end,

in the second case, the person would not understand why you're changing your price all the time, especially if the price is rising most of the time.

Pros of Agile approach: the customer can cancel at any moment. Also, if she cancels at early stages, she still has some source code which works.

Cons of Agile approach: the price is too imprecise or not even given. Most customers would be unwilling to do business with you if you don't tell them how much they will have to pay.

Title: Quantifying the price for source code and software product

Body:
I'm about to undertake a project. This requires me to write code, and tons of it. The client's requirement is to hand in all source code at the end of the project.

My question is: How do I quantify the price for source code and the software product? Is there any metric that one follows to determine pricing? How would I quantify the software product?

Extra info: The application must run anywhere, in any OS, including tablets (iPad, Galaxy tabs, etc.), Smartphones (iPhone, Android phones, etc.) and also on the web.
(Now, imagine how much code this will be).


问:
Plagued by multithreaded bugs
On my new team that I manage, the majority of our code is platform, TCP socket, and http networking code. All C++.  Most of it originated from other developers that have left the team. The current developers on the team are very smart, but mostly junior in terms of experience.

Our biggest problem: multi-threaded concurrency bugs. Most of our class libraries are written to be asynchronous by use of some thread pool classes. Methods on the class libraries often enqueue long running taks onto the thread pool from one thread and then the callback methods of that class get invoked on a different thread. As a result, we have a lot of edge case bugs involving incorrect threading assumptions.  This results in subtle bugs that go beyond just having critical sections and locks to guard against concurrency issues.

What makes these problems even harder is that the attempts to fix are often incorrect. Some mistakes I've observed the team attempting (or within the legacy code itself) includes something like the following:

Common mistake #1 - Fixing concurrency issue by just put a lock around the shared data, but forgetting about what happens when methods don't get called in an expected order.  Here's a very simple example:

```<code>void Foo::OnHttpRequestComplete(statuscode status)
{
    m_pBar->DoSomethingImportant(status);
}

void Foo::Shutdown()
{
    m_pBar->Cleanup();
    delete m_pBar;
    m_pBar=nullptr;
}
</code>```

So now we have a bug in which Shutdown could get called while OnHttpNetworkRequestComplete is occuring on. A tester finds the bug, captures the crash dump, and assigns the bug to a developer. He in turn fixes the bug like this.

```<code>void Foo::OnHttpRequestComplete(statuscode status)
{
    AutoLock lock(m_cs);
    m_pBar->DoSomethingImportant(status);
}

void Foo::Shutdown()
{
    AutoLock lock(m_cs);
    m_pBar->Cleanup();
    delete m_pBar;
    m_pBar=nullptr;
}
</code>```

The above fix looks good until you realize there's an even more subtle edge case. What happens if Shutdown gets called before OnHttpRequestComplete gets called back? The real world examples my team has are even more complex, and the edge cases are even harder to spot during the code review process.

Common Mistake #2 - fixing deadlock issues by blindly exiting the lock, wait for the other thread to finish, then re-enter the lock - but without handling the case that the object just got updated by the other thread!

Common Mistake #3 - Even though the objects are reference counted, the shutdown sequence "releases" it's pointer. But forgets to wait for the thread that is still running to release it's instance. As such, components are shutdown cleanly, then spurious or late callbacks are invoked on an object in an state not expecting any more calls.

There are other edge cases, but the bottom line is this:

Multithreaded programming is just plain hard, even for smart people.

As I catch these mistakes, I spend time discussing the errors with each developer on developing a more appropriate fix. But I suspect they are often confused on how to solve each issue because of the enormous amount of legacy code that the "right" fix will involve touching.

We're going to be shipping soon, and I'm sure the patches we're applying will hold for the upcoming release. Afterwards, we're going to have some time to improve the code base and refactor where needed. We won't have time to just re-write everything. And the majority of the code isn't all that bad. But I'm looking to refactor code such that threading issues can be avoided altogether.

One approach I am considering is this. For each significant platform feature, have a dedicated single thread where all events and network callbacks get marshalled onto. Similar to COM apartment threading in Windows with use of a message loop. Long blocking operations could still get dispatched to a work pool thread, but the completion callback is invoked on on the component's thread. Components could possibly even share the same thread. Then all the class libraries running inside the thread can be written under the assumption of a single threaded world.

Before I go down that path, I am also very interested if there are other standard techniques or design patterns for dealing with multithreaded issues.  And I have to emphasize - something beyond a book that describes the basics of mutexes and semaphores. What do you think?

I am also interested in any other approaches to take towards a refactoring process.  Including any of the following:

Literature or papers on design patterns around threads. Something beyond an introduction to mutexes and semaphores. We don't need massive parallelism either, just ways to design an object model so as to handle asynchronous events from other threads correctly.

Ways to diagram the threading of various components, so that it will be easy to study and evolve solutions for. (That is, a UML equivalent for discussing threads across objects and classes)

Educating your development team on the issues with multithreaded code.

What would you do?

答:
Based on the code shown, you have a pile of WTF.  It is extremely difficult if not impossible to incrementally fix a poorly written multi-threaded application.  Tell the owners that the application will never be reliable without significant rework. Give them an estimate based on inspecting and reworking every bit of the code that is interacting with shared objects.  First give them an estimate for the inspection.  Then you can give an estimate for the rework.

When you do rework the code, you should plan to write the code so that it provably correct.  If you don't know how to do that, find someone who does, or you will end up in the same place.

ContentLicense: CC BY-SA 3.0

Title: Plagued by multithreaded bugs


问:
Fear of releasing a hobby project - how to overcome?
I don't know if this question is strictly related to software development, but still I'll give it a try:

Like a lot of programmers, I love to work on hobby projects. Sometimes, seemingly good ideas turn out to be not so good, so I drop the project. But sometimes, something useful comes out of the project. So, I could release it, present it to the world, right?

Wrong. Somehow, I don't seem to be able to make this step. I fear that my code is not good enough, I can always think of things which are suboptimal, of features which could be added. So, I don't release anything, I lose interest, and at one point abandon the project.

Is this normal? How do you overcome such a situation?

答:
What do you have to lose ?

You can also take comfort in knowing that it probably won't be noticed anyways, unless it's really good or fills a new niche.

And, if you get a negative feedback - it's a chance to learn.. Don't waste it.


问:
What does Jamie Zawinski's Law mean?
I need a proper explaination of Jamie Zawinski's Law of Software Envelopment:

Every program attempts to expand until it can read mail. Those programs which cannot so expand are replaced by ones which can.

答:
It is a comment on how some software projects seem to keep expanding and adding more and more features.

Many projects can't seem to be able to resist adding features, whether needed or not.

A logical conclusion is that every piece of software will end up sending mail.

Also see Scope Creep.

Title: What does Jamie Zawinski's Law mean?


答: It's not a real law, it's a satirical comment on how software projects (if not properly managed) can grow so large and complicated, they somehow eventually include an email reader (even if it has nothing to do with the original purpose of the project). A manager I once had was fond of a similar phrase "Any sufficiently complicated system contains a half-assed LISP implementation within it".

Title: What does Jamie Zawinski's Law mean?

Body:
I need a proper explaination of Jamie Zawinski's Law of Software Envelopment:

Every program attempts to expand until it can read mail. Those programs which cannot so expand are replaced by ones which can.


问:
Trac/SVN to DVCS Migration
The project I'm currently working on is using Trac, with SVN integration. It's worked great until now. Now, however, we've taken on some additional developers and we're running into issues with branching and merging. Because of this, I think a move to a distributed version control system is in order.

The problem is that Trac is very closely integrated with the SVN repository. We have tight integration between the tickets and the revision numbers of code changes corresponding to those tickets. In addition we have a support wiki that has a lot of data that helps the tech. support team. Is there a way we can migrate to git or mercurial without losing the benefits of Trac? I've looked at the git plugin for Trac, and I'm unsure of how well it works. Has anyone here used it with a project that's been migrated from SVN?

EDIT: I should note that the most important priority for us is maintaining the links between Trac tickets and the corresponding changesets in SVN. That's a tool that we use every day, and it provides an easy way to jump to code changes when reviewing tickets. Wiki migration would be nice to have, but if it's not possible, we can continue to run the old system whilst we write some kind of a one-off script to migrate the content.

答:
I used Trac + SVN for a long time and really liked it. I think that it is a  highly competitive solution, and (although I currently use Hg) would think twice about changing.

It might be worthwhile taking a little time to examine what other factors might be causing problems. Look beyond the purely technical and consider team structure and organization, personalities, processes and communications structures.

For example, is it feasible for everybody (as much as is possible) to commit to /trunk instead of branching? Integration problems will be found and fixed much faster if you do this. It also makes it much easier to configure Development Automation tools like Continuous Integration; Automated Test servers etc...

Title: Trac/SVN to DVCS Migration


答:
As everyone else already mentioned the "law" is a humorous observation on software bloat and score creep, and it's very similar to Greenspun's tenth rule:

Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.

The law reflects Zawinski's work with the Netscape browser and later with Netscape
Mail & News, as described here by, well, himself:

Next, I designed, and Terry Weissman and I implemented, the Netscape Mail and News clients, versions 2.0 through 3.0. This was our contribution to the proof of the Law of Software Envelopment:

"Every program attempts to expand until it can read mail. Those programs which cannot so expand are replaced by ones which can."

Netscape browser, at the time the most popular browser, has often been criticised as having too many features for its own good, if I'm not horribly mistaken it was the last (popular) browser that supported two rendering engines, Gecko and Trident. For example, Ben Goodger identifies Netscape's bloat as one of the (many) reasons that lead to the creation of Firefox1:

Mozilla's UI Dysfunction

Since most of the user interface design for the Netscape products was done by Netscape staff working to Netcenter requirements, the Mozilla user interface suffered. Instead of being a clean core upon which Netscape could build a product to suit its needs, the Mozilla suite never felt quite right; it was replete with awkward UI constructs that existed only to be filled in by overlays in the Netscape's private source repository — the “commercial tree.”

Compounding this dysfunction, at the time the project was being developed by over a hundred engineers in different, sometimes poorly connected departments within CPD. Netscape had grown rapidly in previous years, and with an uneven hiring bar engineers with abilities that would suggest they needed more assistance from others had far too much autonomy in feature design and implementation. User experience assistance was sparse, and as a result the application quickly bloated.

1 From an archived version of Ben Goodger's now defunct blog.

Title: What does Jamie Zawinski's Law mean?


答:
You have to understand that this happened a long while back, and at that time it was not yet mainstream for computers to be able to run more than one program at a time for a given user.  DOS for Personal Computers (and possibly Windows 3 on top) and character based terminals for Unix-users (only a few had X11).

This mean that in order to check whether you had gotten an email you had to exit what you were currently doing, start the mail program, read mail, exit the mail program and restart your old program.  I guess you can see that if your current program could let you read your email, you could avoid all that.

Hence if your current program could not read your email, you were inclined to either make it do so (remember this was MIT students) or switch to another which could.

These days that is hard to imagine, but you can get an inkling of how it was by limiting yourself to a single browser window - no tabs, no extra windows - and perhaps even not use bookmarks.

Title: What does Jamie Zawinski's Law mean?


答:
I'm sorry but you are doing the exact opposite of what you should be doing!

Release it as soon as possible, listen to people's feedback, and then implement new functionality based on that. Not the other way around!

Title: Fear of releasing a hobby project - how to overcome?

Body:
I don't know if this question is strictly related to software development, but still I'll give it a try:

Like a lot of programmers, I love to work on hobby projects. Sometimes, seemingly good ideas turn out to be not so good, so I drop the project. But sometimes, something useful comes out of the project. So, I could release it, present it to the world, right?

Wrong. Somehow, I don't seem to be able to make this step. I fear that my code is not good enough, I can always think of things which are suboptimal, of features which could be added. So, I don't release anything, I lose interest, and at one point abandon the project.

Is this normal? How do you overcome such a situation?


问:
When to do code reviews when doing continuous integration?
We are trying to switch to a continuous integration environment but are not sure when to do code reviews. From what I've read of continuous integration, we should be attempting to check in code as often as multiple times a day.  I assume, this even means for features that are not yet complete.

So the question is, when do we do the code reviews?

We can't do it before we check in the code, because that would slow down the process where we will not be able to do daily checkins, let alone multiple checkins per day.

Also, if the code we are checking in merely compiles but is not feature complete, doing a code review then is pointless, as most code reviews are best done as the feature is finalized.  Does this mean we should do code reviews when a feature is completed, but that unreviewed code will get into the repository?

答:
Why not have more than one repository? One for "daily" work, driving a continuous integration server, running all the unit tests & integration tests to get the nice tight feedback loop, and another for "stable" work, where commits are less frequent, but have to go through review.

Depending on the path that changes take as they move through the system, this can end up being a bit of a complex solution, and might work best when using tools like Git, or Mercurial Queues, (caveat: I have used neither in anger) but lots of organizations do something similar.

OwnerDisplayName: SpecialEd


答:
All the answers (and comments) so far seem to focus entirely on the first half of the statement, making it into a comment about "bloat," when the important half is the second half: Those programs which cannot so expand are replaced by ones which can.

This is not about software bloat, it's about the realities of the market.  People may say they want a simple product, but when you look at actual usage, the things that get used are the things that allow users to do more, and they end up replacing less-capable tools.

Part of the problem is that "simple" is a confusing word.  Like "cleave," it can mean two almost completely opposite things.  What people want is something that simplifies complex tasks.  That's "the good simple," and it requires a great deal of complexity to do right.  What some people interpret it as, though, is that people want something simplistic, or minimalist.  This concept may have some niche appeal, but on the whole it's the wrong kind of "simple" to focus on when designing a product.  No matter how good your work is, the new feature requests keep coming in.

To give an example, there's the program I work on at work.  You've probably never heard of it, but we're the market leader in a specialized industry: media control.  Our program most likely runs your favorite TV and/or radio station.  The customers love it, they say it's so much better than anything else they've worked with.

It's also enormous.  The EXE is over 65 MB in size, with around 4 million lines of code, backed by a database with over 150 tables, built up over the course of more than a decade of work.  And yet it seems like every time we try to get it installed at some new station or network, there's one or two things that are absolutely essential to their workflow, that we don't have any support for.  So we end up adding the new features because otherwise the customers wouldn't want to switch from the system they're already used to.  And let me repeat, the customers love it.

Title: What does Jamie Zawinski's Law mean?


问:
Is there a faster way to work out this logic?
The purpose of this assignment was the find the smallest and largest of the integer(User inputs 5 entries)

I am a beginner Java programmer with no prior experience. Is there an easier way to do this without a ton of if/else statements?

Forgive for the dirty code.

```<code>    //Scanner Object
    Scanner input = new Scanner(System.in);

    int num1, num2, num3, num4, num5;
    int large;
    int small;

    System.out.print("Enter Num1: ");
    num1 = input.nextInt();

    System.out.print("Enter Num2: ");
    num2 = input.nextInt();

    System.out.print("Enter Num3: ");
    num3 = input.nextInt();

    System.out.print("Enter Num4: ");
    num4 = input.nextInt();

    System.out.print("Enter Num5: ");
    num5 = input.nextInt();

    //If/Else statements (SMALL)
    if (num1<num2 && num1<num3 && num1<num4 && num1<num5) {
        small = num1;

        }

    else if (num2<num1 && num2<num3 && num2<num4 && num2<num5) {
                small = num2;

                        }

    else if (num3<num1 && num3<num2 && num3<num4 && num3<num5) {
                small = num3;

    }

    else if (num4<num1 && num4<num2 && num4<num3 && num4<num5) {
                small = num4;

    }

    else {
        small = num5;

    }

    //Large

    if (num1>num2 && num1>num3 && num1>num4 && num1>num5) {
        large = num1;
    }

    else if (num2>num1 && num2>num3 && num2>num4 && num2>num5) {
                                        large = num2;
    }

    else if (num3>num1 && num3>num2 && num3>num4 && num3>num5) {
                large = num3;
    }

    else if (num4>num1 && num4>num2 && num4>num3 && num4>num5) {
                    large = num4;
    }

    else {
                large = num5;

            }

    //Display: Use printf when using a format limiter (%)

    System.out.printf("The smallest integer: %d\n", small);
    System.out.printf("The largest integer: %d\n", large);

    }// end of main

}
</code>```

答:
Others have provided good, generalized solutions. I would offer a variant of this which avoids sorting:

```<code>int largest = Integer.MIN_VALUE;
System.out.print("Enter Num1: ");
num1 = input.nextInt();
largest = Math.max(num1, largest)

System.out.print("Enter Num2: ");
num2 = input.nextInt();
largest = Math.max(num2, largest)

System.out.print("Enter Num3: ");
num3 = input.nextInt();
largest = Math.max(num3, largest)

System.out.print("Enter Num4: ");
num4 = input.nextInt();
largest = Math.max(num4, largest)

System.out.print("Enter Num5: ");
num5 = input.nextInt();
largest = Math.max(num5, largest)
</code>```

This is basically the same as Caleb's suggestion, but without the enumeration and done along the way.

Body:
Others have provided good, generalized solutions. I would offer a variant of this which avoids sorting:

int largest = Integer.MIN_VALUE;
System.out.print("Enter Num1: ");
num1 = input.nextInt();
largest = Math.max(num1, largest)

System.out.print("Enter Num2: ");
num2 = input.nextInt();
largest = Math.max(num2, largest)

System.out.print("Enter Num3: ");
num3 = input.nextInt();
largest = Math.max(num3, largest)

System.out.print("Enter Num4: ");
num4 = input.nextInt();
largest = Math.max(num4, largest)

System.out.print("Enter Num5: ");
num5 = input.nextInt();
largest = Math.max(num5, largest)

This is basically the same as Caleb's suggestion, but without the enumeration and done along the way.


答:
I think the main concept that will help is that of a "Staging" area.

Yes, you don't want to check in code that's broken.  But you also should be checking in code frequently.  Does this imply perfection? ;) No.  Just use multiple areas and a DVCS like git.

This way you make changes (locally) and commit them frequently as you test and develop until the tests pass.  Then you push to a staging area for code review.

You should then be pushing from Staging to other QA efforts such as browser tests and user tests.  Finally you may go to a volume testing area, then finally production.

There are also workflows within this such as everyone working on the main branch or using individual branches for all efforts.

Continuous integration itself can also happen at multiple levels.  It can be local to a developers machine 'until the tests pass' and it can also be in staging and qa areas for when code goes to them.

Title: When to do code reviews when doing continuous integration?

Body:
We are trying to switch to a continuous integration environment but are not sure when to do code reviews. From what I've read of continuous integration, we should be attempting to check in code as often as multiple times a day.  I assume, this even means for features that are not yet complete.

So the question is, when do we do the code reviews?

We can't do it before we check in the code, because that would slow down the process where we will not be able to do daily checkins, let alone multiple checkins per day.

Also, if the code we are checking in merely compiles but is not feature complete, doing a code review then is pointless, as most code reviews are best done as the feature is finalized.  Does this mean we should do code reviews when a feature is completed, but that unreviewed code will get into the repository?


问:
Beginning development of a C++ project
I study in software engineering and this year a new association at my university is opening a robotic submarine club. It's a new club and they needed software guys for micro-controllers manipulation, gui output and other software oriented requirements.

I've been accepted to the club and there is nothing established right now. Although the language might not matter on a higher level we are working in C++ under a UNIX system. Since I have to set up the base I'd like to have input from people with experience on starting up big projects with collaboration in mind. Obviously we want this to scale nicely over the years and have a solid API for the future students who will replace the older ones.

So to make my question more precise, I'm looking for tips on setting this up and perhaps books that could help me. I'm comfortable on implementation in C++ and I've done some analysis and conceptual OO courses too. It's really just that I've never had the chance to start up on something bigger than a 2-3 man group with SVN. I don't know either if there is a similar JUnit system and perhaps maintenance system that works well for C++ that I could set up for the team(I've used maven with trac in Java).

This is an opportunity for me and the others because we have a green flag on using any of the latest technology and best practices, so I would like to exploit that and learn a thing or two about software management that I wouldn't normally learn in a company with a system already in place.

答:
Language doesn't matter.  You want:

Source revision control

Automated integration server

Automated unit, integration and acceptance tests

A reasonably easy to manage build system

Bug/task repository

For unit testing I like BOOST.Test or CppUnit.

For building I think CMake is pretty far above the rest but maven might work as well.

For bugs and tasks you can use Jira or Bugzilla.  The former is quite a bit better but costs money after 10 users.  You can get a scrummy backlog too called "Greenhopper".

Title: Beginning development of a C++ project


问:
How might a Windows 8 Metro app handle back end database access?
While researching Metro and WinRT I haven't been able to find anything regarding enterprise apps and database access. All I hear about is the front end development.

Does anyone have any idea of how a Metro app will access a database server? Will this still be done through ASP.Net and ADO.Net? If not, then does anyone have any idea or guess as to how?

答: WinRT has NO system.data and that has been confirmed by Microsoft.  System.data has ADO and SQLclient.   No direct connect to SQL from WinRT.   Need to get data from a service.</p>


问:
Is it bad etiquette to ask a potential employer how they score on the Joel Test?
Developer interviews are different than most other places, because not only do you worry about the people you work with, benefits, job description, etc., you also have EXTRA to worry about after getting the job.  Writing two application with exact requirements can be vastly different if you're working in a loud vs quiet environment, using VS2003/.NET 2.0 vs VS210/.NET 4.0., using SVN vs VSS.

Is it ok to give the potential employer the straight-up Joel Test?  I try to ask as many questions to get the type of environment I will be working in, which is extremely important from my perspective, but what's the best way to cut to the chase and just ask the tough questions (like they ask you during the same interview).

NOTE: By the "Joel Test" I mean a specific list of things that are deal breakers that are important to you (not necessarily Joel), but you may not have time to get out using the traditional casual "conversational" way of asking them, so you decide to either email or schedule another meeting, or ask other people, etc.

答:
The Joel Test inspired me to ask questions 'like that'. What version control, bug tracking, testing, ...

I usually ask a ton of questions at the end of (or during) the interview.
If anything, it shows you're interested in best practices/quality assurance/.... If they don't do those things already, maybe they will be interested in you implementing eg: unit testing.

Best case scenario: they haven't thought about those things already, but they're amazed at what you can improve in their development process.

Worst case scenario: they dislike the fact you're asking so many questions, thus have no interest in improving their process, in which case you probably don't want to work there.

PS: just make sure you know what you're talking about, not just mindlessly walking over some list.

ContentLicense: CC BY-SA 2.5


答:
I see at least three ways to view it.

One is to ignore mail reading per se, and view it as a statement that people seem to like products with the flexibility to be turned to almost any task, regardless of how little it might have to do with the tool's original intent. If we look at it this way, a product like Photoshop that doesn't support mail reading isn't an anomaly because its plug-in architecture is flexible enough that it could support mail reading, even though (as far as I know) no such plug-in exists. This viewpoint could be summarize more cleanly, but less originally, as "flexibility beats specialization".

The second way to view it would be that Jamie Zawinski has such a narrow focus that he simply ignores the products like Photoshop, PowerPoint, most games, etc., that have been around for years, don't support mail reading, and don't seem to be getting replaced by anything else that does either.

The third would be a bit of a counterpoint to the second, saying that, in essence, integration between products has happened to such a degree that effectively mail reading is integrated into everything because most people now have a mail reader running in the background, all the time and can switch to it quickly/easily enough, cut and paste with anything else, etc., that the minor detail that the mail reader is packaged as a separate application has become irrelevant.

Title: What does Jamie Zawinski's Law mean?


问:
Checking for emptiness of collections with (in)equalities - what's the best practice?
For a long time now I've been in the habit of checking whether a collection (array, dictionary, whatever) is non-empty with a nonequality. Like this:

```<code>if ( MyArray.Length < 1 )
{
    // Do something if the array is empty
}
</code>```

Sometimes I do this for strings too, and other kinds of collections. In practice, this should be the same as

```<code>if ( MyArray.Length == 0 )
{
    // Do something if the array is empty
}
</code>```

Because the length of collection should never be less than 0 anyway, right? So I always thought - what the heck, I'll include the inequality and be double-safe even in the case the sky falls down.

But today a though struck me that the second version might be more readable than the first. It expresses more clearly that the case I'm looking for is the empty array, which is not immediately apparent from the first version. So maybe I should use that instead? Since, you know, if a collection length is less than 0, then I'm screwed anyway.

Which version do you use, and which would you suggest others to use (and why)?

Clarification: This was meant as a question about simple collections, where obtaining .Length is O(1) or otherwise inexpensive. If .Length itself is a nontrivial operation (such as necessitating the iteration through a linked list, or contacting the DB), then this is the wrong approach altogether.

The question was about x < 1 vs x == 0 where x is a nonnegative integer (although it might not be typed as such).

答:
Considering just "==" and "<", the question, it seems to me, is what are you going to do if the length is negative?  The most intelligent thing to do is ignore the question, because it's not going to happen.  Having failed at that, the proper thing to do is stop the program and set off alarms because something is very wrong indeed.  But no one is going to do that either.  So lastly, you need to consider the best course of action with a negative value.  I'd say most of the time treating it as zero (using "< 1") is the safest route.  But I would try to psychoanalyze whoever wrote the collection and base my final decision on that.

Note that "< 1" is the easiest route.  If -5 does not mean the collection is empty, does it mean there is an element 4?  Or does it mean there is an element -4?  If you want to be consistent, if you use "== 0" you need to code to handle negative lengths when the length doesn't equal zero.  So, in general, I'll vote for "< 1".


问:
how to handle / architect soa when service becomes unavailable?
Say I've got a third-party service called Cool.io that provides a RESTful API but often goes down. My applications consume that API, but when Cool.io goes down, my app really can't do much... but it should!

Say I create a proxy to the Cool.io and this proxy stores a copy of Cool.io's data and provides RESTful endpoints for my application. Let's assume that my proxy has 100% reliability, or, at least more than Cool.io's. Let's also assume that my proxy has no problem propagating PUTs/POSTs to Cool.io, and no problems receiving the same from Cool.io (in other words, there are no data sync issues between my proxy and Cool.io).

This decouples my application's dependency on Cool.io, which goes down all the time... but it doesn't decouple the proxy from the Cool.io service. As such, when my application modifies something on the proxy, the proxy's data changes and tries to send that change to Cool.io.

But, if Cool.io is down, that request just results in an unavailability error (or a failed connection).

What's the proper way to architect something like this? How do guys like Amazon or Netflix decouple their services such that an outage doesn't affect the consumer, or if it does, it does so gracefully?

Is a message queue in order here?

Is there a simpler solution than creating a proxy to the unreliable service?

答: I think you answered it yourself: Message Queue.  You need your proxy to be able to wait for the service to come back and then resubmit your requests.  So, push the requests into a queue.  Have the queue manager regularly ping the service to check its status, and send the messages from the queue when its up.  Don't remove the message from the queue until you get a positive response that the service processed it.</p>


问:
Backbone/JQuery, ExtJs 4.... is there something else worth looking?
Im currently evaluating a front-end architecture for a big app that will be developed by a team of about 6 developers + 1 web designer so that said, having a robust SVN friendly architecture is a must. So far I'm evaluating this two options:

A mixture of JQuery/UI/Mobile + Backbone/Underscore + Require JS + Twitter-Bootstrap

ExtJS 4

This are the requirements the architecture needs to meet:

SVN Fiendly (or Friendly depending on you previous experiences)

Active community and extensive documentation

Extensible

Easy to learn and to maintain (nice to have)

Cross-browser support (most of the time at least)

Support for Mobile devices

Easy to maintain (MVC, MVVM)

OpenSource (nice to have)

The previously mentioned ones meet most of the requirements in different levels and so far they are the only ones I've found about, am I missing any others?

答:
I'm confused by your SVN requirement. I've never heard of a JS framework, tool or library causing problems for version control. It's all just static files typically.

The most important tool in any front end arsenal is a tool to eliminate crossbrowser woes and DOM API cruft at the source. jQuery is an excellent choice on that front.

jQ, runs on a design philosophy that everything on the front end should follow, IMO. It stays out of your way when you want it out of your way and it plays nicely with others.

I tend to be less impressed with JQ's libraries and plug-ins but I would leave those choices to your devs.

EXTJS, is the exact, diametric opposite. It is a heavy-handed framework that is very difficult to reverse engineer owing to an obtuse anti-pattern cascading inheritance scheme, it does awful things to the DOM and throws CSS at absolutely everything, right down to redefining the box-sizing CSS for EVERYTHING on the page and adding IDs to just about everything that doesn't already have one. I do not recommend EXT. We've been wanting to strip the last vestige of it out of our app for a year now but it's been too much of a pain to give it the proper time commitment. It cracks me up that the guys who wanted to create a JS library that is less than open source wrote the worst one to ever enjoy any popularity of the lot.

My impression of bootstrap is that it's a designer tool. Let your devs and designer decide if they want it. The JS components it provides are nothing special and it's written by people who handle decidedly lower levels of complexity than it sounds like you plan on dealing with. What I dislike about it is that it relies overly much on non-standard HTML attributes (now considered okay in HTML5, but still making HTML harder to read in my book) and hooks into pre-defined classes that describe styles rather than component types or content hierarchy. It's okay to have hooks in the HTML but I find it's best when the framework or library lets you set them.

I have not used backbone, but it's very popular. The turnoff for me was seeing it described as a lock-in framework by which the article's author meant that if you ever decide you want to move on and use something different, it's going to be hard to port your existing functionality out of it. I've had too many headaches of that nature with dismantling EXT to see that as an acceptable tradeoff for any benefit.

What I would seriously recommend is that you get your client-side team assembled first, then decide on tools in context to what you're using on the back-end and what your own front end experts consider a good idea for creating an easily extended app with code written for the long rather than short-term. In spite of the plethora of JS architecture frameworks, UI widget and pre-styled HTML libraries out there nowadays, my personal choice, when I  have the choice, is to write my own UI, and wrap the jQuery soup in DIY architectural object schemes with ease of implementation and debug in mind. I also find I like the MVC pattern more for its general principles than exact implementation in a strictly client-side context.

In a complex front end app scenario,  any tool that produces components that aren't easy to modify, sets restrictions on or otherwise pollutes the client-side environment as a whole, or poses the prospect of making it really hard to ditch the framework in the future is big no-no in my book. But take that with a barrel of salt. I'm a bit of a curmudgeon and hard to please when it comes to my tools, partially because I've had to put up with some really bad ones (CMSes in particular).

At the end of the day though, nothing I'm aware of has the same flexibility as DIY (except jQuery which really just eliminates UI boilerplate) but make sure you have a dev team that can get behind some sort of consistent architecture or they may indeed be better off with backbone or knockout, or JS MVC.


问:
When using method chaining, do I reuse the object or create one?
When using method chaining like:

var car = new Car().OfBrand(Brand.Ford).OfModel(12345).PaintedIn(Color.Silver).Create();
```

<p>there may be two approaches:</p>

<ul>
<li><p>Reuse the same object, like this:</p>

<pre class="lang-cs prettyprint-override"><code>public Car PaintedIn(Color color)
{
    this.Color = color;
    return this;
}
</code>```

Create a new object of type Car at every step, like this:

public Car PaintedIn(Color color)
{
    var car = new Car(this); // Clone the current object.
    car.Color = color; // Assign the values to the clone, not the original object.
    return car;
}
```</li>
</ul>

<p>Is the first one <em>wrong</em> or it's rather a personal choice of the developer?</p>

<hr>

<p>I believe that he first approach may quickly cause the intuitive/misleading code. Example:</p>

<pre class="lang-cs prettyprint-override"><code>// Create a car with neither color, nor model.
var mercedes = new Car().OfBrand(Brand.MercedesBenz).PaintedIn(NeutralColor);

// Create several cars based on the neutral car.
var yellowCar = mercedes.PaintedIn(Color.Yellow).Create();
var specificModel = mercedes.OfModel(99).Create();

// Would `specificModel` car be yellow or of neutral color? How would you guess that if
// `yellowCar` were in a separate method called somewhere else in code?
</code>```

Any thoughts?

答:
I'd rather think just like the "Extension Methods" mechanism.</p>

```<code>public Car PaintedIn(this Car car, Color color)
{
    car.Color = color;
    return car;
}
</code>```

Body:
I'd rather think just like the "Extension Methods" mechanism.

public Car PaintedIn(this Car car, Color color)
{
    car.Color = color;
    return car;
}


问:
Productivity enhancing development strategies for small teams
I think one of the best ways to learn and become a better programmer is to share knowledge gained from working on personal or work projects with others. One way to do this at the workplace is to set aside an hour or so a week and let one or several team members present their progress on the part of the code base they have been working on. This is especially helpful when each team member has a specialized skill set. What are some other useful practices that managers can institute to increase team cohesion and improve productivity?</p>

答:
I've used "Training Tuesdays", though you could move it to a Thursday and keep the "TT" title, as an opportunity for the team to share what they know. I borrowed a few katas from Code Kata and worked through them as a team, they provide nice little programming scenarios that allow everyone a chance to think about a problem then propose a solution; one person might suggest LINQ another a for loop... then you've got a good ground for a discussion about the various benefits of each approach. It's not "mission critical" so the pressure is off and it's ok whatever you suggest. So if you've got good database skills you might see the problem in a particular light, explaining that to someone who's a good OO programmer means you both need to understand the other language to some extent.

I also used the excellent Summer of NHibernate / Autumn of Agile screencasts by Steve Bohlen in the sessions to bring in an understanding of ORMs and Agile processes, the Autumn of Agile shows advantages of agile over waterfall approach and it was good having that visualised for us.

We also gave mini-presentations on subjects we each were strong on; so there was a guy strong on UX and accessibility in the team and he showed what that involved and worked through some forms we had and highlighted good and bad aspects.

Then if someone has an interest in learning something new it can be a good opportunity there, for example finding out about javascript patterns or unit testing javascript so you can present back to the team on how they can be adopted. I'm currently spending a bit of free time learning Red Gate's SQL Test and in a week will be having an hour session with the team in which I hope to show them why we should start writing unit tests in the database. What I've found is that when you have to teach something it lifts your game; I teach martial arts and when I learned a technique for a grading I thought I understood it, but when I had to teach it to someone I had to see it from their perspective and think of ways they could understand it. The same has been true when I've mentored developers too; they ask different questions than I did when learning that feature so I had to really understand it.

Pair-programming could also help here; over time everyone works with everyone else on something, whether it's your core business or on a fun Friday afternoon project or even just on "hey lets have a look at that crazy rail's thing everyone's on about", when we've done this not only is the code we write better (you don't tend to cheat when you know someone is watching) but you have discussions about how to do xy or z (which is what happened with the code kata in the team, only here it's just 2 of you). So if you try to pair seniors with juniors the juniors get to work with someone who can help guide them and prevent them making mistakes. The seniors get someone asking "why, why why" and that makes them have to explain / teach and therefore question their understanding and deepen what they know, or pick up new ideas from people who aren't already set in their ways (I'm guilty of this, thought I knew all I needed to and stopped learning, new approaches came in and I was behind the times)


问:
Objective-C message passing related queries
I am learning objective-C after having good knowledge of C/C++. I have 2 questions:

Are Obj-C message passing and C++ vtable, two different ways of implementing polymorphism or Are they two very different concepts which I have misinterpreted into different implementations of same concept?

I read following line from this pdf http://www.gnustep.org/resources/documentation/ObjectivCBook.pdf

Polymorphism takes a pluralistic point of view and notes that several classes can each have a method with the same name. Argument overloading takes the point of the view of the method name and notes that it can have different effects depending on what kind of object it applies to

In essence both do what we want from them i.e. calling method according to the object. What is the difference then?

答:
Are they two very different concepts which I have misinterpreted into
  different implementations of same concept?

They do serve essentially the same purpose. It's like the difference between nails and screws: either can fasten two boards together, but they work differently.

What is the difference then?

One difference lies in which objects you can send a given message to. In C++, the compiler will complain if you try to call a method that the target object doesn't implement. In Objective-C, the compiler doesn't care -- the method that gets called when you send a message to some object isn't determined until the program is running and the message is actually sent.


问:
When should I start the server side coding?
I am creating a website, where users can upload their own videos. So far I am just building the main structure with HTML and CSS. Is it a better practice to write server-side code before the site layout is finished? Does it not make a difference?

答:
Designing the client side first with mocking can give you a strong advantage in knowing your website's functionality.  You can keep redesigning with minimal waste until you reach a good workflow for your product.  However, you should keep a rough sketch of server side requirements for each bit of functionality you'll need from the design so that you don't create a cool concept that is really hard or impossible to implement.

Also, I would keep small details in the website design flexible so that they can be adjusted to make the backend easier, more scalable or the whole website more testable.

In practice as a sole developer, I tend towards simultaneous implementation, working on the project feature by feature.  I'll design a feature in the backend and then tie it into the front end UI.  I then receive feedback on the work thus far before rolling onto the next feature, although there tends to be way more focus on various UI concerns over functionality.


问:
Atomic Memcache Operations in PHP
This post is a follow up to this question: PHP Atomic Memcache on StackOverflow.

Considering I am using Memcache (no d at the end) on PHP 5.3.10, I implemented a custom locking system where a client will wait until a lock key is destroyed before it begins to modify a key on memcache.

So:

Client 1 connects, checks for an active lock on key 1, finds none, and gets the data
Client 2 connects a few microsecond after Client 1, requests the same data from key 1,
   but finds a lock
Client 2 enters a retry loop until Client 1 releases the lock
Client 1 saves new data to key 1, releases the lock
Client 2 gets the fresh data, sets a lock on key 1, and continues
```

<p>This works 90% of the time. It would work 100% of the time if two requests are made far apart from each other (say 500ms). But lets say two requests are made at almost the same time (10 to 100 microseconds apart) the above solution fails, and both clients write to the same key, resulting in incorrect data. </p>

<p>I have tried many things, including a loop that varies in wait time every iteration:</p>

```while(/*lock key exists*/)
{
    usleep(mt_rand(1000,100000);
}
```

This helps only a little.

What would be the solution to this particular issue? These mecache processes must be atomic. I am willing to tolerate a 1% failure rate (since it means I just need to work a little harder to make it 0), but anything more is just too risky.

I've broken my head trying to figure this out. There is no possibility to upgrade to Memcached, and the value changes are not simple (they are not increments)

答:
Client 1 connects, checks for an active lock on key 1, finds none, and
  gets the data

You should not test for lock then create it, but rather attempt to create it with Memcache::add, which will either create lock or fail. It does so atomically, so you'll no longer have TOCTTOU race condition.

```<code>$mc= new Memcache;
$mc->connect('localhost', 11211);

while(!$mc->add('your_lock_key', 1))
{
    usleep(mt_rand(1000,100000);
}

manipulate_data(...)

$mc->delete('your_lock_key')
</code>```

Upon further inspection, according to PHP's documentation add is atomic. But digging deeper, it results that it may be not atomic on memcache clusters with multiple memcache servers. There is however a solution to this:

```<code>$mc= new Memcache;
$mc->connect('localhost', 11211);

$locked = false;

$lock_key = $mc->get('your_lock_key');
if (!$lock_key) {
   $lock_key = uniqid();
   $mc->add('your_lock_key', $lock_key);
}

while(!$locked) {
   if($mc->cas($cas_token, 'your_lock_key', $lock_key) &&
      $mc->getResultCode() == Memcached::RES_SUCCESS) {
        $locked = true;
        break;
   } else {
     $other_key = $mc->get('your_lock_key');  //this is only to reset last access for CAS
   }
   usleep(mt_rand(1000,100000);
}

manipulate_data(...)

$mc->delete('your_lock_key')
</code>```

Title: Atomic Memcache Operations in PHP

Body:
Client 1 connects, checks for an active lock on key 1, finds none, and
  gets the data

You should not test for lock then create it, but rather attempt to create it with Memcache::add, which will either create lock or fail. It does so atomically, so you'll no longer have TOCTTOU race condition.

$mc= new Memcache;
$mc->connect('localhost', 11211);

while(!$mc->add('your_lock_key', 1))
{
    usleep(mt_rand(1000,100000);
}

manipulate_data(...)

$mc->delete('your_lock_key')

Upon further inspection, according to PHP's documentation add is atomic. But digging deeper, it results that it may be not atomic on memcache clusters with multiple memcache servers. There is however a solution to this:

$mc= new Memcache;
$mc->connect('localhost', 11211);

$locked = false;

$lock_key = $mc->get('your_lock_key');
if (!$lock_key) {
   $lock_key = uniqid();
   $mc->add('your_lock_key', $lock_key);
}

while(!$locked) {
   if($mc->cas($cas_token, 'your_lock_key', $lock_key) &&
      $mc->getResultCode() == Memcached::RES_SUCCESS) {
        $locked = true;
        break;
   } else {
     $other_key = $mc->get('your_lock_key');  //this is only to reset last access for CAS
   }
   usleep(mt_rand(1000,100000);
}

manipulate_data(...)

$mc->delete('your_lock_key')


答:
This is where working with a Web designer can come in really handy. With a good design, you can start working on the server-side code without having any client side code written. Having a visual aid -- the design -- can give you a strong idea of what the server-side code will need to do, and most importantly, it can help you implement the server-side code in a manner that doesn't tightly couple it to the front-end.

There is a technique that is gaining popularity where developers use JSON and RESTful Web services as a way to separate the front-end and back-end code in a manner where one could develop a completely separate user interface that uses the same exact stable, tried and tested back-end.

However, I don't think it makes a difference whether you start with a top down approach where you build all of the HTML/CSS first and then work on the server-side code or whether you start with the server-side code and then work on the client-side, as long as you have a clear vision for what the application will look like and what it will need to do.

Having a clear vision will help you make sure to code out the server-side in a manner that makes it easier to maintain the code and easier to build something that's extensible.

Title: When should I start the server side coding?

Body: I am creating a website, where users can upload their own videos. So far I am just building the main structure with HTML and CSS. Is it a better practice to write server-side code before the site layout is finished? Does it not make a difference?


问:
random generator not good enough?
During an interview I was asked to implement a random generator in java without using any existing random number libraries that takes as an argument int n, and returns a random number between 0 and n. This was the implementation I provided:

```<code>public static int random(int n) {
    int r = 0;
    for (int i =0; i <n;i++) {
        r+=helper();
    }
    return r;
}

// helper that returns 0 or 1
private static int helper() {
    long t = System.nanoTime();
    if (t%2 == 0) {
        return 1;
    } else {
        return 0;
    }
}
</code>```

He said it's not right but he wouldn't tell me what he was expecting. Why did he say it's wrong? How would you have done it differently?

答:
He probably expected you to use Java's Random class.

Your current implementation takes a sum of "coin toss" results to determine a random number. While your results will be somewhat random, they won't be evenly distributed. If you roll two dice, you'll end up with a total of 7 roughly half the time. This approach to random number generation is subject to the same math.

The people who implement Java's libraries have gone out of their way to solve a lot of the issues around random number generation, and it's usually best to use them when they offer a solution to your problem. No need to reinvent the wheel.

If you want to know how to produce a good Random number generator, you can always read up on how Java implements theirs!

Title: random generator not good enough?


答:
first you have a binomial distribution (values towards n/2 are more likely to occur than 0 or n-1)

a better way would have been to generate ceil(log2(n)) bits and returning the value when the value is less than n and restarting otherwise

```<code>public static int random(int n) {
    while(true){
        int r = 0;
        for (int i =1; i<n;i<<=1) {
            r=(r<<1)|helper();
        }
        if(r<n)return r;
    }
}
</code>```

also nanoTime() is only as accurate as the system can provide, which means that t%2 might be biased 1 or 0. Calling it in such a tight loop gives a very high likelihood of the returned values being the same on a machine with a low accuracy

a much better solution would be implementing a proper RNG like a Linear congruential generator and using that for the generation of the random bits

Title: random generator not good enough?

Body:
During an interview I was asked to implement a random generator in java without using any existing random number libraries that takes as an argument int n, and returns a random number between 0 and n. This was the implementation I provided:

```<code>public static int random(int n) {
    int r = 0;
    for (int i =0; i <n;i++) {
        r+=helper();
    }
    return r;
}

// helper that returns 0 or 1
private static int helper() {
    long t = System.nanoTime();
    if (t%2 == 0) {
        return 1;
    } else {
        return 0;
    }
}
</code>```

He said it's not right but he wouldn't tell me what he was expecting. Why did he say it's wrong? How would you have done it differently?

Body:
first you have a binomial distribution (values towards n/2 are more likely to occur than 0 or n-1)

a better way would have been to generate ceil(log2(n)) bits and returning the value when the value is less than n and restarting otherwise

public static int random(int n) {
    while(true){
        int r = 0;
        for (int i =1; i<n;i<<=1) {
            r=(r<<1)|helper();
        }
        if(r<n)return r;
    }
}

also nanoTime() is only as accurate as the system can provide, which means that t%2 might be biased 1 or 0. Calling it in such a tight loop gives a very high likelihood of the returned values being the same on a machine with a low accuracy

a much better solution would be implementing a proper RNG like a Linear congruential generator and using that for the generation of the random bits


答:
To ratchet freak's answer I  would add that the interviewer probably considered your use of System.nanoTime() as cheating since, in a way, it's an external random number generator, though not a very good one by itself.

He probably wanted you to implement a clearly deterministic generator from scratch, as the one from Wikipedia pointed out by ratchet freak.

Title: random generator not good enough?


答:
Main issues with your approach:

System.nanoTime() isn't (on its own) a useful source of random bits - it's highly likely to produce the same value multiple times in a row if you call it in quick succession because many systems don't actually have a sufficiently accurate timer. Even if it was nano-second-accurate, you are likely to get predictable patterns from the lowest bits if you sample it in a tight loop. Valid uses of System.nanoTime in random number generation might be: a) one-off initialisation of a seed value or b) occasionally adding some extra randomness into an entropy pool (not guaranteed to be beneficial, but it can't hurt)

Even if the bits were truly random, by adding the 0/1 values n times you would be creating a binomial-style distribution with a mean of n/2, i.e. not a uniform distribution which is presumably what the interviewer was expecting.

Your algorithm is O(n) - not good for generating random numbers with a large value of n!

You ideally want a PRNG that produces new pseudo-random bits from an internal state. Here's the one I use:

```<code>private static volatile long state = 0xCAFEBABE; // initial non-zero value

public static final long nextLong() {
  long a=state;
  state = xorShift64(a);
  return a;
}

public static final long xorShift64(long a) {
  a ^= (a << 21);
  a ^= (a >>> 35);
  a ^= (a << 4);
  return a;
}

public static final int random(int n) {
  if (n<0) throw new IllegalArgumentException();
  long result=((nextLong()>>>32)*n)>>32;
  return (int) result;
}
</code>```

This is based on George Marsaglia's XORShift algorithm. It produces good pseudorandom numbers and is very fast (typically even faster than a Linear Congruential Generator since the xors and shifts are cheaper than multiplies and divides on most hardware).

Having said that, I wouldn't expect people to memorise this kind of algorithm for an interview unless you are specifically applying for a role as a crypto programmer!

Title: random generator not good enough?

Body:
Main issues with your approach:

System.nanoTime() isn't (on its own) a useful source of random bits - it's highly likely to produce the same value multiple times in a row if you call it in quick succession because many systems don't actually have a sufficiently accurate timer. Even if it was nano-second-accurate, you are likely to get predictable patterns from the lowest bits if you sample it in a tight loop. Valid uses of System.nanoTime in random number generation might be: a) one-off initialisation of a seed value or b) occasionally adding some extra randomness into an entropy pool (not guaranteed to be beneficial, but it can't hurt)

Even if the bits were truly random, by adding the 0/1 values n times you would be creating a binomial-style distribution with a mean of n/2, i.e. not a uniform distribution which is presumably what the interviewer was expecting.

Your algorithm is O(n) - not good for generating random numbers with a large value of n!

You ideally want a PRNG that produces new pseudo-random bits from an internal state. Here's the one I use:

private static volatile long state = 0xCAFEBABE; // initial non-zero value

public static final long nextLong() {
  long a=state;
  state = xorShift64(a);
  return a;
}

public static final long xorShift64(long a) {
  a ^= (a << 21);
  a ^= (a >>> 35);
  a ^= (a << 4);
  return a;
}

public static final int random(int n) {
  if (n<0) throw new IllegalArgumentException();
  long result=((nextLong()>>>32)*n)>>32;
  return (int) result;
}

This is based on George Marsaglia's XORShift algorithm. It produces good pseudorandom numbers and is very fast (typically even faster than a Linear Congruential Generator since the xors and shifts are cheaper than multiplies and divides on most hardware).

Having said that, I wouldn't expect people to memorise this kind of algorithm for an interview unless you are specifically applying for a role as a crypto programmer!


问:
How do the algorithms to solve problems encountered in interviews translate into real world solutions?
I have recently finished an undergraduate course in computer science and I am looking for a job. During the search I encountered several interesting (and tough) problems that needed clever algorithms to solve. I also use google code jam as a practice set.

I cannot understand how those solutions translate in solving real world problems. Many problems appear (to me) not only contrived and fantastical but also highly specific to be a general purpose solution (although it isn't impossible to extend them using ingenuity).

Are these problems there only to test the problem solving skills or are these some aspect of real world problem camouflaged?

答: It all depends on the software you're working on.  CRUD solutions typically aren't very clever unless you're attempting to replace various analytical\clerical professionals with software.  If you get into data mining with statistical analysis, it might help to know various ways of structuring data.  You're going to need to know your geometry operations if you're going to work with graphics.  Understanding various numerical algorithms is extremely important if you go into engineering or financial areas where accuracy and speed are crucial.  Algorithms are among the skills that will allow you to explore and work in an area that pushes the envelope in some domain as opposed to working on another reporting solution.</p>


问:
Ways to version user generated documents
I have an online document which essentially gets stored to the database as XML string.

I'm thinking about a way to implement versioning of the document for the user.  So that user can go back to previous versions of the document.

update In my case it's a web application with hundreds of thousands of users.  A user can store unlimited amount of documents. The XML for document is stored in MySQL blob field so it's not small.  Eventually I need to cap the limits somehow but that is a different topic all together.

Is there a standard way to approach this? Should I store only the differences between versions? What are other things that I need to consider?

答:
A relatively simple way is to increment a revision id upon each save, and save the new xml document under that new revision id.

table: docs

```<code>doc_id | name          | current_revision
   1   | Shopping List |       5
</code>```

table: doc_revisions

```<code>doc_id | revision | timestamp | xml_blob
  1    |    1     | 2012...   |
  1    |    2     | 2012...   |
  1    |    3     | 2012...   |
  1    |    4     | 2012...   |
  1    |    5     | 2012...   |
</code>```

You might also consider storing the xml files separately in the file system.  You can alter the doc_revisions table with a URL/path to the file rather than a blob.  That will allow your db to handle far higher volumes on a single server because the database wont physically be as big (you could move the docs to a different server) and you'd be taking the document retrieval load off the db server.

Personally, I wouldnt store the file differences.  Rather, I'd store the full new revision of the file each time.  Storage is cheap, and no need to complicate things.  'diff' functionality could be inplemented later if eventually turned out you really need it.  If you store diffs, be aware it could introduce a bunch of unexpected complexities, for example if you need to search the text of the documents.

Body:
A relatively simple way is to increment a revision id upon each save, and save the new xml document under that new revision id.

table: docs

doc_id | name          | current_revision
   1   | Shopping List |       5

table: doc_revisions

doc_id | revision | timestamp | xml_blob
  1    |    1     | 2012...   |
  1    |    2     | 2012...   |
  1    |    3     | 2012...   |
  1    |    4     | 2012...   |
  1    |    5     | 2012...   |

You might also consider storing the xml files separately in the file system.  You can alter the doc_revisions table with a URL/path to the file rather than a blob.  That will allow your db to handle far higher volumes on a single server because the database wont physically be as big (you could move the docs to a different server) and you'd be taking the document retrieval load off the db server.

Personally, I wouldnt store the file differences.  Rather, I'd store the full new revision of the file each time.  Storage is cheap, and no need to complicate things.  'diff' functionality could be inplemented later if eventually turned out you really need it.  If you store diffs, be aware it could introduce a bunch of unexpected complexities, for example if you need to search the text of the documents.


答: Usually,  interview problems are simpler than the actual problems that arise on the job.  The interview problems are designed to see if you are familiar with fundamental algorithms and data structures: hashing, tree traversal, graph search, dynamic programming, etc.  Every CS graduate should know these, but many don't.

Title: How do the algorithms to solve problems encountered in interviews translate into real world solutions?

Body:
I have recently finished an undergraduate course in computer science and I am looking for a job. During the search I encountered several interesting (and tough) problems that needed clever algorithms to solve. I also use google code jam as a practice set.

I cannot understand how those solutions translate in solving real world problems. Many problems appear (to me) not only contrived and fantastical but also highly specific to be a general purpose solution (although it isn't impossible to extend them using ingenuity).

Are these problems there only to test the problem solving skills or are these some aspect of real world problem camouflaged?


问:
Why C++ to write a compiler?
I was wondering why C++ is a good choice to write a compiler. Of course C is good for this purpose too, because many compilers are written either in C or C++ but I am more interested in C++ this time. Any good reasons ? I was looking for that in the Internet, but I cannot find any good reasons.</p>

答:
I suspect that the prime motivator for their use is that Lex/Yacc/Bison output is (primarily) in C. Since that's been the standard for so long, it has momentum.

Not that those are particularly good reasons...

Title: Why C++ to write a compiler?


问:
Do people in non-English-speaking countries code in English?
I've heard it said (by coworkers) that everyone "codes in English" regardless of where they're from. I find that difficult to believe, however I wouldn't be surprised if, for most programming languages, the supported character set is relatively narrow.

Have you ever worked in a country where English is not the primary language?

If so, what did their code look like?

答: I have never seen anyone use non-English names in code here in Israel, but my experience is limited to university projects. At any rate, I personally only code in English, and I actually also type all my emails and homework assignment in English. This is mainly because Hebrew is written right to left, and it can be very annoying incorporating English terms into the text.</p>


答:
Sometimes they don't translate to the company's core business at all. That's a fact.

However, at least some of the time, they are associated with a core business problem that the team, or the company, you're interviewing with, faces.

At one company I interviewed with, mostly known for helping users find a cost-effective flight, I was asked a couple of problems with roots in combinatorial complexity and in routing. One of them was an n choose k problem, which certainly can come up when you have a large number of sets and you need to enumerate all subsets of say, 1, 2 or 3 elements; there's at least a plausible case that finding all nonstop, one-stop and 2-stop flights might benefit from knowing how to solve the abstract problem. Separately, I was asked a 2D convex hull problem, which is closely related to a bunch of problems used in say, collision detection in computer graphics, some classes of image recognition and graphics-to-text transformation problems, and, in fact, certain classes of routing problems; they might as well have asked me about the minimum spanning tree problem, which has previously been used by, say, telephone companies to figure out where to nearly-optimally place telephone poles and switches and the like, and comes up in transportation problems as well.

In this particular team, I wouldn't have had any involvement in solving routing problems; I would have been mostly focused on internationalization work. But perhaps because of the culture of the organization, and their core business problems, these types of problems now pervade their software developer interview process, regardless of what you might end up actually working on.

Although I didn't do particularly well solving these problems, given my very non-algorithmic, non-academic background in software, I somehow was offered a job; I'm guessing that in some organizations, they just want to see you sweat, and see how you approach problems out of your comfort zone under pressure. In some teams, it might have actually been important to also solve the problem well, rather than just demonstrate your thought process.

While I don't think this is the best possible strategy to identify good developers, Google, Amazon, Microsoft, and dozens of other well-known companies have adopted the algorithm-heavy ritualized hazing interview process, so it may be unavoidable depending on where you want to work. You can prepare for them by reading Skiena's Algorithm Design Manual, which will help you pattern match concrete problems to abstract ones, and lead you to propose appropriate solutions, even if you can't implement them in an hour long coding interview.

If I were interviewing a candidate for a role that involved deep algorithmic knowledge, I would be inclined to probe by proposing problems that require them to pull from their algorithm toolkit. However, in most of my work, I focus mostly on finding candidates that realize why doing three layers of nested loops to issue separate queries to an external source one ID at a time is a bad idea, and try to find proof that they know how to do better than that. I focus on seeking evidence that they've figured out some sensible strategies for writing maintainable code, that they have intellectual curiosity, and that they have basic social skills. I try to verify that they've worked deeply enough through some problem that they've learned enough to be the local expert on it.

If you end up interviewing at a company whose business is built around solving some tough problem with the help of smart algorithms, there's a good chance they'll try to find evidence that you, too, can solve problems with the help of smart algorithms. I also think that, even if you end up writing "boring" enterprisey software, having a firm grasp on the landscape of algorithms is worthwhile, because you'll recognize insanely bad approaches when you see them and you'll step back and try to come up with better solutions. I've now seen a ton of crappy production code that basic computer science applied to the problem would have prevented.

Because of that, even though I don't find the algorithm-heavy interview as useful as some companies appear to, I am convinced that, if you can't see the connection between abstract algorithms and real business problems, the problem is, at least in part, you. You can get practice on pattern matching with the help of Skiena's book and by thinking about real world problems that you'd like to solve and implementing defensible solutions, so do that.


问:
When to do code reviews when doing continuous integration?
We are trying to switch to a continuous integration environment but are not sure when to do code reviews. From what I've read of continuous integration, we should be attempting to check in code as often as multiple times a day.  I assume, this even means for features that are not yet complete.

So the question is, when do we do the code reviews?

We can't do it before we check in the code, because that would slow down the process where we will not be able to do daily checkins, let alone multiple checkins per day.

Also, if the code we are checking in merely compiles but is not feature complete, doing a code review then is pointless, as most code reviews are best done as the feature is finalized.  Does this mean we should do code reviews when a feature is completed, but that unreviewed code will get into the repository?

答:
We use git flow for our repositories, and we do our code reviews when it comes to merging into the develop branch.

Anything in develop is complete, deployable and code reviewed.

We also have CI set up for our develop and master branches.


问:
Where could Distributed Version Control Systems currently be in Gartner's hype cycle?
Edit: Given the recent downvoting (+8/-6 at this point) it was made clear to me that Gartner's lifecycle is a biased metric from a programmer's perspective. This is something that is part of a paper I'm going to present to management, and management types are part of Gartner's audience.

Giving DVCS exposure & enthusiasm (that "could" be deemed as hype, or at least attacked as such), think about the following question when reading this one: "how could I use Gartner's hype cycle to convince management that DVCSs are ready (or ready-enough) for us, and that it is not just hype"

Just asking if DVCSs is hype wouldn't be constructive, Gartner's hype cycle is a more objective instrument than just asking that (even if this instrument is regarded as biased). If you know any other instrument please, by all means, mention it.

Edit #2: I agree that Gartner's Life Cycle is not for every technology, but I consider it may have generated enough buzz to be considered hype by some, so it maybe deserves to be at least evaluated/pondered as such by using this instrument in order to prove/disprove it to whatever degree. I'm an advocate of DVCS, BTW.

Edit #3: Thanks for your answers. Bounty goes to Caleb for answering my question with detail and practical advise. Accepted answer goes to philosodad for providing another useful instrument and answering beyond my question.

I'm doing research for a whitepaper I'm writing in favor of DVCS adoption at company and I stumbled upon the concept of social proof. I want to prove that the social proof of DVCS adoption is not necessarily cargo cult and doing further research I now stumbled upon Gartner's hype cycle which describes technology maturity in 5 phases.

My question is: what could be an indicator of the current location of Distributed Version Control Systems (I mean git, mercurial, bazaar, etc. in general) at a particular phase in the hype cycle?... in other (less convoluted) words, would you say that currently expectations of DVCSs are a) starting, b)inflated, c)decreasing (disillusionment), d)increasing (enlightenment) or e)stabilizing (mature) and (more importantly) why?

I know it is a hard question and there is subjectivity involved, but I'll grant the answer (and the traditional cookie) to the clearest argument/evidence for a particular phase.

答:
argument/evidence of a particular phase

Whatever phase could that be, it has to be one that matches the fact that technology is in professional use for "more than 10 years", since distributed VCS TeamWare has been there for more than that: pdf User's Guide referred below is dated July 2001.

Per Wikipedia, TeamWare's largest deployment was inside Sun itself, where (bar a few exceptions) at one point it was the only VCS used - that makes thousands developers using the tool. TeamWare has been used to manage Sun's largest source trees, including those for the Solaris operating system and the Java system.

Wikipedia article refers to a Usenix message from Evan Adams, who was the architectural lead for TeamWare, which states in particular:

In the spring of 1991 we decided to implement the TeamWare project...

TeamWare is a set of command line and GUI tools built from several common libraries. The libraries are provided by the TeamWare group for use by the TeamWare applications; they are not provided for more general use.

TeamWare is a code management product that encourages parallel development and is built on top of SCCS. A user makes a copy (bringover) of an SCCS hierarchy thus creating a personal hierarchy. In this hierarchy the user makes and tests changes. These changes are then integrated (putback) into the original hierarchy. If the integration hierarchy contains
  changes which are not in the user's hierarchy, then TeamWare detects that there have been parallel changes and refuses the integration. Therefore, users must incorporate changes in the integration hierarchy into their own hierarchy before integrating. TeamWare also includes the filemerge utility, a graphical three-way differences program allowing users to merge parallel changes. TeamWare tracks both source file changes (SCCS deltas) and file renames...

If you're interested, find more details here:

"The Old Man and the C" by Evan Adams

"Sun WorkShop TeamWare User’s Guide" at Oracle/Sun site - pdf July 2001, html

Per my recollection, centralized CVS / SVN back then had an advantage of being capable to run on Windows and Linux, while TeamWare (SCCS) has been locked in Solaris filesystem (at Linux it run more or less, if one knew how to hack over spurious "zero checksum" bugs).


答:
Compilers may be implemented in any modern language. However, one of the most important requirements from a compiler is to be fast.

C++ has a clear advantage here. Optimization in C++ does not come cheap. However, due the the low-level nature of this language, it is possible to manually optimize C++ code more than in any other language (except Assembly which is not portable).

Title: Why C++ to write a compiler?

Body: I was wondering why C++ is a good choice to write a compiler. Of course C is good for this purpose too, because many compilers are written either in C or C++ but I am more interested in C++ this time. Any good reasons ? I was looking for that in the Internet, but I cannot find any good reasons.</p>


答:
To compile what to what? A compiler transforms a source code from one language (source language) to another (destination language), which doesn't indicate anything about the low-levelness of the destination language.

CoffeeScript compiles to JavaScript, the compiler being written in CoffeeScript.

Script# compiles C# into JavaScript, the compiler being written in, if I remember well, C#.

etc.

The language you pick to write a compiler depends on the context. For example, working on a project which compiles a language derived from PHP to a native PHP code, I used a mix of PHP and C# to write the compiler, because it made the most sense for me given my skills. Another person would pick Python, or Java and PHP, or C++ with a bit of JavaScript, or whatsoever.

C or C++ is a popular choice because of the support of compiler related tools (see the answer by Telastyn), and because those two languages allow you to go really native. But there is nothing wrong in choosing another language.

Note that in order to be more geeky, you may pick the source language to write the compiler itself. It's what happened for CoffeeScript compiler and many other compilers. It is also popular with the IDEs: one of the first Visual Studio was built using the same Visual Studio.

Title: Why C++ to write a compiler?


答:
I don't claim to be an expert on the subject of hype cycles, but I'll offer a few observations:

The hype cycle seems to be more a product of expectations and media coverage than a characteristic of technology itself. My dictionary says that hype is "extravagant or intensive publicity or promotion." It defines publicity as "the notice or attention given to someone or something by the media." Media is a collective term for the various channels of mass communication.

If you accept the previous point, it follows that the hype cycle applies only when the media covers a given technology.

It's not at all clear that the hype cycle applies to all technologies. Scientific journals are filled with reports of advances which are never noticed by the mainstream media. Without media coverage, expectations are less likely to be inflated and the trough of disillusionment can be avoided.

Distributed version control systems aren't so much a new idea as a refinement of an old one. It's a stretch to call them an "emerging technology" of the sort that the hype cycle is supposed to predict.

Before you start to build a case for where DVCS's fit on a hype cycle graph, you need to build a case that distributed version control is subject to the hype cycle at all. Does distributed version control as a "technology" get media coverage? Are there now, or have there ever been, inflated expectations for distributed version control? Is it likely that DVCS users will become disillusioned when DVCS products don't live up to expectations?

It seems more likely to me that distributed version control is just an improvement on an existing category of products, just as SVN was an improvement on CVS. If you were to chart the adoption rate of SVN, I don't think you'd get a plot that looks like the hype cycle; instead, you'd get a plot that increases steadily up to the plateau of market dominance, followed by a long slow decline as distributed systems like 'git' gain popularity.

If you really need a hype-cycle answer, I'd suggest that DVCS joined the game at the bottom of a period of disillusionment/frustration with non-distributed version control systems and has been climbing the slope of enlightenment as the adoption rate increases.

Instead of relying on the hype cycle for your argument, I'd suggest focusing on the adoption rate of distributed version control and the reasons for it. There's plenty of anecdotal evidence that people are switching to DVCS because it works; on the other hand, I haven't heard of anyone switching back to a non-distributed system because they were disappointed. To get some hard data, you might try talking to a hosting company such as Beanstalk. Also, pay attention to interoperability between centralized systems and distributed systems. I hear that 'git' plays very nicely with SVN. Centralized systems continue to work pretty well in the corporate realm, so emphasizing the "plays nicely with" aspect could make a DVCS less risky and therefore more attractive to decision makers.

Update in response to OP's edit:

how could I use Gartner's hype cycle to convince management that DVCSs
  are ready (or ready-enough)[?]

I think that there are a few approaches that could help here, and all rely on hard data:

Google Trends. Google obviously collects a ton of data about what's on the net and what people search for. A few days ago, I looked for (but couldn't find) evidence of the hype cycle w.r.t. distributed version control. http://trends.google.com/ says that there's not enough data for the terms dvcs or distributed version control when I limit the region to the US (and the dvcs results for the world don't seem very relevant or helpful). Searching for more specific terms was somewhat better, but complicated by the fact that product names like git and mercurial have other meanings (who knew?). The result for git shows a trend that might be due in part to the version control system:

Trying to make that more specific to version control, I tried git repository:

One more... figuring that if people are adopting git there ought to be an increasing trend in searching for help with git commands, I tried git pull (blue), git commit (red), and git rebase (gold):

That last graph seems to provide the best evidence that people are adopting and using git.

Google search.

Try simply searching for terms like distributed version control and note the dates on, say, the top 25 articles you find. Plot the results. Most of top hits I found had dates in the 2007-2009 range. If the hype cycle applies, and if you can show that most of the media coverage happened 3-5 years ago, that seems like pretty good evidence that we've moved beyond the peak of inflated expectations.

Collect examples of projects that use DVCS.

There are plenty of examples in the open source world, including some big ones like Linux. (Linus Torvalds created git to help manage Linux development.) More useful to you will be examples of corporations that use a DVCS. (If there's anything managers hate more than adopting a technology too early, it's being behind the times.) Hype is just that -- buzz about a technology or product. If you can find evidence of corporate adoption of DVCS, that'll help counter the "it's just a lot of hype" argument perhaps better than anything else.

Last tips:

Be specific. Your company isn't going to adopt an entire technology -- you'll adopt a specific product. Some products are always going to be less mature than others. Pick two or three well-known DVCS products and show how each would fit into your development process. Managers like concrete ideas better than vague promises, so analyzing the tech in specific terms will make them feel more comfortable.

It's not all-or-nothing. Any real project using a DVCS is still going to have a central repository, so fears about losing control of the crown jewels can be easily assuaged.

No need to give up your current system. Some tools, like git, can play well with existing version control systems, like svn. So you can easily add DVCS to your development process without giving anything up.

Start small. Unless you're at a small company that has just one project, it ought to be easy to incorporate DVCS into the process for just one or two of your projects. You don't have to jump in head first -- just dip a toe.

In short, identify the points of resistance and address them as clearly as you can.

Title: Where could Distributed Version Control Systems currently be in Gartner's hype cycle?

Body:
Edit: Given the recent downvoting (+8/-6 at this point) it was made clear to me that Gartner's lifecycle is a biased metric from a programmer's perspective. This is something that is part of a paper I'm going to present to management, and management types are part of Gartner's audience.

Giving DVCS exposure & enthusiasm (that "could" be deemed as hype, or at least attacked as such), think about the following question when reading this one: "how could I use Gartner's hype cycle to convince management that DVCSs are ready (or ready-enough) for us, and that it is not just hype"

Just asking if DVCSs is hype wouldn't be constructive, Gartner's hype cycle is a more objective instrument than just asking that (even if this instrument is regarded as biased). If you know any other instrument please, by all means, mention it.

Edit #2: I agree that Gartner's Life Cycle is not for every technology, but I consider it may have generated enough buzz to be considered hype by some, so it maybe deserves to be at least evaluated/pondered as such by using this instrument in order to prove/disprove it to whatever degree. I'm an advocate of DVCS, BTW.

Edit #3: Thanks for your answers. Bounty goes to Caleb for answering my question with detail and practical advise. Accepted answer goes to philosodad for providing another useful instrument and answering beyond my question.

I'm doing research for a whitepaper I'm writing in favor of DVCS adoption at company and I stumbled upon the concept of social proof. I want to prove that the social proof of DVCS adoption is not necessarily cargo cult and doing further research I now stumbled upon Gartner's hype cycle which describes technology maturity in 5 phases.

My question is: what could be an indicator of the current location of Distributed Version Control Systems (I mean git, mercurial, bazaar, etc. in general) at a particular phase in the hype cycle?... in other (less convoluted) words, would you say that currently expectations of DVCSs are a) starting, b)inflated, c)decreasing (disillusionment), d)increasing (enlightenment) or e)stabilizing (mature) and (more importantly) why?

I know it is a hard question and there is subjectivity involved, but I'll grant the answer (and the traditional cookie) to the clearest argument/evidence for a particular phase.


答: C++ has two sides to it. It has a low-level development side which makes it seem like a natural language for doing low level thing like code generation. It also has a high-level side (which C does not) that lets you structure a complex application (like a compiler) in a logical, object oriented way, while still maintaining performance. Because it has both the low and high level aspects to it, it's a good choice for large application which require low-level features or performance.</p>

Title: Why C++ to write a compiler?


答:
I tend to question the basic premise here. While C and C++ work perfectly well for writing compilers, quite a few other languages seem to work perfectly well for the task as well.

A bit depends on the language you're compiling though. For small, simple languages, C and Pascal work quite nicely. If you're going to compile something big and complex, your compiler gets big and complex too -- in which case, C++'s extra features for organizing and working with larger programs obviously come in handy. That isn't really very specific to compiling though, just features useful for larger programs in general.

I think it's also worth mentioning one other point. Beginners (seem to) think of compilers as mostly doing text manipulation, so they think something like Perl will be a massive help in writing compilers. In reality, most of the interesting parts of compilation don't really start until after you've built your AST. While I'm sure Perl can do the job  perfectly well, its text manipulation capability doesn't really give it a huge advantage either (text manipulation is mostly in the lexer, and lexer generators for things like C all support REs anyway).

Title: Why C++ to write a compiler?