答: The underlying legal basis for open source software licenses is copyright.  They allow you to distribute copies as long as you meet certain restrictions (such as also releasing your own modifications).  If you don't want to allow them to redistribute copies then such licenses aren't helpful, as they are already prevented from doing so simply by virtue of you holding the copyright.  What you really want is a non-disclosure agreement or end user license agreement.


问:
Is having multiple CDN locations for a product self defeating?
I was double checking the URL for the CDN version of jQuery this morning, and noticed that there are three different locations now.

Is having multiple networks hosting a product bad, or even self-defeating?  I thought a primary advantage is that as more and more sites use a CDN version, that the odds the library being cached in the browser keep going up.  If the CDN is set up properly, and a user is using a decent browser, then the network doesn't even get accessed for a cached file.  In the case with jQuery, does't having having three CDNs lower the cache hit rate by 1/3?

Am I missing something here?

答: One of the primary purposes of a CDN is to distribute files globally and to serve clients from a location closest to them. This also provides redundancy. Cache hits across applications is not a primary purpose for an application using a CDN, although it is a side benefit for common libraries such as jQuery.</p>

ContentLicense: CC BY-SA 3.0


问:
How can I charge money for open source targeted at individuals?
Most questions like this only seem to apply for big pieces of software for companies with money. I'm developing a small application targeted at individuals.

Informally speaking, I want to sell the application to users, but allow them to fix and modify it(but not redistribute).

Practically and legally speaking, how would I do this?

答:
This is the same arrangement where Microsoft releases the source code for some of it's libraries - such as MFC. This way every user gets to fix bugs in MFC in their own way, none of the fixes are shared or make it back to Microsoft. The result id every major Windows package shipped with it's own modified (but same version) MFC dlls'

If you want to copy MSFT's license text it's here http://referencesource.microsoft.com/Default.aspx


问:
A simple ways to improve the release quality in RAD environment
A bit of a background here - we are a small team (of 5) of RAD developers responsible for internal software development in a big non-software company. "Internal software" varies from a desktop .NET application using MSSQL server as a backend to Python scripts running on the background  to MS Word documents and templates - a zoo of technologies.

The whole team consist of all-arounders able to get the requirements from users, code it up, test it and deploy into production. Once the software in the production it is being looked after by another team but it usually easy for us to intervene if something goes wrong.

All sounds good so far, but there is a problem - being a RAD team we have to release often, and there is no day going by without us releasing new versions of one or two applications(or it could be a script, updated word document, C++ console app, etc) into the production. We do a development testing and also do involve end-users by letting them run the software in UAT environment ...

... but the bugs are creeping in to production anyway. Users do understand that these bugs and the occasional instability is the price they are paying for getting what they want really quickly, but at the same time it got us thinking - perhaps we could improve our development or a release practices to improve the stability of the software and reduce the number of bugs we introduce when adding a new functionality.

The good thing - we don't really have much of the processes in the first place, so it should be easy to start improving, the bad thing - being a small RAD team we don't really have the much time and resources to implement something big, but we have been thinking about the following initiatives and would welcome any feedback, tips, hints and suggestions.

Currently some of the applications are being released into the production straight after the developer testing, bypassing the user acceptance testing. That practice should be discontinued and even a small change has to be tested by a end-user. Each application will have a dedicated beta-tester selected from the end-users. Only after a beta-tester has ok-ed the new release it is promoted from test to production environment.

We don't conduct code reviews - but we'll start doing code reviews before one of us checkin the changeset. I was also thinking about a "rollout review" - basically one of the developers has to sit next with the other watch him/her doing the software rollout (copy binaries, update configs, add new table to database, etc) - it usually only takes a 5-10 minutes so it won't take much of a "rollout review" time.

How to miminise the rollback time when a new release is proven to be buggy enough to be pullout from production and to be replaced by a good previous version. We do store a history of all releases (as a binaries) to make it easy to go one version back - and though it is quick "overwrite a newly released binaries with a previous versions binaries" it is still a manual process which is error prone and demanding at times "what if the rollback will fail and will render the system unusable instead of buggy".

This is where we ran out of our ideas and we'd like to get your feedback on these and if you could share some simple release / dev process improvement advices - that would be awesome.

答:
+1 for touching upon a great subject. When we do "Release early release often" line of development, things pick up real pace and as the momentum builds many such issues arise (as you described) which we are otherwise not very prepared to cope up with. Worst fear is when people see speed as an enemy of good work.

I have seen very limited literature on this however, this is what we practice that definitely helps:

1. Effective Bug tracking

Make bug tracking more effective - what we do is not only keep a list of bugs and tick mark, but when closed, we must define certain things like "was the problems reproducible?", "is this a permanent solution or work fix?", "what is the root cause" of trouble? This allows knowledge of what happened, when this bug was visible last time. This is key to ensure that bugs do not repeat often.

2. Define key fall back points

We all know that bugs will arrive, so we will need to provide effective fall-back which works most often. Time and again we finalize (with a ratio of about 1 of every 10 in our case) a most common release that works everywhere in most reliable manner. The total number of releases can be many but if anything goes wrong, the fall backs are select few and you don't have to fall back any further. One of the simplest way to know the best fall-back is to see which earliest release which has been running longest in production without much issues.

3. Distinguish risky and stable or small bug fix releases

When we know we have a major algorithm changes, more likely that bugs might creep in on scenarios that are not all foreseen. Where as there are times when issues are very small (or well understood) as well as little risk. Do NOT club such functionality and simple bugs in same releases. Always have a smaller bug fixed first, which must go wherever required. Make dedicated releases for special feature sets at best you can deprecate that feature but but all other important bugs are still available fixed in prior release.

4. Branch for significant feature development

Anything which associate changes which has design affect must be done separately on a branch. Larger development doesn't get completed quickly as compared to smaller bugs. If we introduce intermediate commits where 'partial' work related to feature which is still not in use - is a potential bug introduction region; the bugs which wouldn't have arise if full work for the feature would have completed atomically - hence these are bugs which we would n;t have to solve if there were branches.

5. Always plan release which are theme based

Many a times many different bugs arrive of different releases -but it is best to organize bugs (and features) which affect similar modules eases the repeat work and minimize the number of bugs originated from that work.
Always prepare release road-map well in advance; bugs keep pouring in - and that falls into different target releases to optimally have a good group of bugs to be shot together in a good release. When similar bugs are combined together, it always gives better insight about contradicting scenarios.

6. Extend any new release first to a few customers

In our case, we see test it in couple of sites first and all other sites are applied a release only when there is a demand for it. Many a times some (or most) users would jump only from stable release to another stable releases only.

7. Regression Testing

Along the lines of bugs being collected - build regression suit. Also if possible mark critical bugs and test to be most important that become minimum qualifying criteria to be tested before a release candidate becomes a release indeed.

8. Pause and reflect

When many things go in full speed, there should be time to put some breaks - take a pause and have releases that are functionally no better. In fact have holiday of releases for some time. (the duration is inversely proportional to frequency). For example, many a times we have these so called "clean-up" releases which achieves nothing new from functionality point of view - but that helps great in keeping code maintainable. Most such releases are great fall back points that you almost never recall the history prior to that.

9. Perhaps the most strange

I find this one difficult to implement often but is a sure shot good trick. Swap the owner of certain modules. When people are asked code-reviews to be done, not much comes out of this practice. But when you have to seriously deal with that new code, when you swap authors, potential "bad" ailments gets noticed quickly much before they start polluting the code. Of course, this reduces the speed - but if you do this often, chances are that people master various parts of the code and learn about whole product which is other wise very difficult to teach.

10. Last but not the least

Learn to go back to white board often. The more you re-think as if this feature would have been part of our most initial design, how would we have thought of the design at that time? Sometimes, the biggest challenge with incremental work is just that we are too constrained by order of functionality we built first and quite often can't go back to basics. The trick is to keep seeing how would we generalize rather than accommodate this new feature or scenario. This requires that design remains current, and that happens only if we go back go drawing board often. Also, as new generation programmers join in, they become part of the thinking tank rather than just putting patches around.

EDIT

11. Keep track of work-around and design gaps.

Quite often we are under pressure of timelines to fix the bug and release in production. However, when the bug is at design level quite a few things needs to change but often people will fix by some short-cuts to meet the deadline. This is OK. However, as multiple such work around solutions increases, the code becomes fragile. Keep a special track on how many design gaps are already gone in. Typically, when you negotiate the timelines with project manager it is best to make him/her commit that we shall deliver this in short-cut to save production but we shall also have timeline and resources to get permanent solution.


问:
Should I get a Math bachelors and then go into Computer Science?
This is my first question. I love Mathematics; I love the logic and the problem solving. At the same time, I enjoy Computer Science and hope to go into Artificial Intelligence research after I get my Bachelors degree, i.e pursue a PhD in Computer Science. Are there any advantages of having a firm grasp of Mathematics to studying Computer Science? Also, would I be at a disadvantage in getting a Bachelors in Mathematics instead of Computer Science when applying for graduate school to study Computer Science, particularly at institutions with high quality research infrastructure, like MIT and Stanford? Also, in reference to the first question, could you please tell me the advantages of a solid grasp of Mathematics, if there are any?

Thank you.

答:
If you really want to study advanced math, do it now.  The undergraduate years are critical for mathematical development.  Your ability to learn serious math will peak soon, then start to decline.  Learn as much math as you can now, and you will be able to apply it later.  Take CS courses that interest you and have high mathematical content (e.g. algorithms, cryptography).  Skip courses oriented to current technology (e.g. Database, OO programming, computer graphics).  You can pick up that sort of knowledge easily enough on your own.  If you are finding your undergraduate math classes too easy, then talk to profs about enrolling in graduate classes as soon as you can, or find a sponsor for some independent work on some problem that interests you.

Be sure to prepare for and take the Putnam Examination each year.  There should be a Putnam study group at your school.  Your results on the Putnam will give you a good idea of your relative mathematical talent.

If you can do math and have decent grades, I don't think you will have much trouble getting into graduate programs in CS, regardless of how much CS you did as an undergraduate.  Any showing on the Putnam, even an honorable mention, will be quite impressive to selection committees.  People switch fields all the time between undergraduate and graduate school.  A degree in mathematics is great preparation for graduate school in Math, CS, Physics, or Economics.


问:
Starting a coherent architecture in a legacy application
I have responsibility for a large Asp.Net based website. It is currently a website (not web application), some windows services and a number of class libraries.

The data layer uses a mixture of LLBLGEN  and Linq To LLBGen, as well as a number of instances of legacy inline SQL which have not been refactored.

There are some manager type implementations, but in many cases the application exhibits the Smart UI anti-pattern (i.e. too much business logic in code behind classes)

The site is reasonably high traffic, and performance is fine, but we are growing our development capability to a team of around 10, and increasingly it is clear we need an overarching layered design on top of the existing middleware.

My question is where to start? We have 10 years of code (some of it still really just migrated ASP Classic stuff), many different approaches, and styles.

Refactoring the entire code base is not realistic and, probably not desirable

I know this is not a novel situation, are there any useful ideas or concepts as to how to approach this problem?

答:
There is a really nice free book/pdf on reengineering legacy software:
http://scg.unibe.ch/download/oorp/

It says OO in the title but most of the ideas apply to any software. It discusses where to start, how to deal with different parts of a system during the restructuring and a lot more of those topics.


答: The fact that it is hosted by the 3 biggest players in the game means the library will be available and supported, I'm more comfortable having options and public shows of support and some extra cache misses. </p>

Title: Is having multiple CDN locations for a product self defeating?

Body:
I was double checking the URL for the CDN version of jQuery this morning, and noticed that there are three different locations now.

Is having multiple networks hosting a product bad, or even self-defeating?  I thought a primary advantage is that as more and more sites use a CDN version, that the odds the library being cached in the browser keep going up.  If the CDN is set up properly, and a user is using a decent browser, then the network doesn't even get accessed for a cached file.  In the case with jQuery, does't having having three CDNs lower the cache hit rate by 1/3?

Am I missing something here?


问:
Did the developers of Java consciously abandon RAII?
As a long-time C# programmer, I have recently come to learn more about the advantages of Resource Acquisition Is Initialization (RAII).  In particular, I have discovered that the C# idiom:

```<code>using (var dbConn = new DbConnection(connStr)) {
    // do stuff with dbConn
}
</code>```

has the C++ equivalent:

```<code>{
    DbConnection dbConn(connStr);
    // do stuff with dbConn
}
</code>```

meaning that remembering to enclose the use of resources like DbConnection in a using block is unnecessary in C++ !  This seems to a major advantage of C++.  This is even more convincing when you consider a class that has an instance member of type DbConnection, for example

```<code>class Foo {
    DbConnection dbConn;

    // ...
}
</code>```

In C# I would need to have Foo implement IDisposable as such:

```<code>class Foo : IDisposable {
    DbConnection dbConn;

    public void Dispose()
    {
        dbConn.Dispose();
    }
}
</code>```

and what's worse, every user of Foo would need to remember to enclose Foo in a using block, like:

```<code>   using (var foo = new Foo()) {
       // do stuff with "foo"
   }
</code>```

Now looking at C# and its Java roots I am wondering... did the developers of Java fully appreciate what they were giving up when they abandoned the stack in favor of the heap, thus abandoning RAII?

(Similarly, did Stroustrup fully appreciate the significance of RAII?)

答:
Yes, the designers of C# (and, I'm sure, Java) specifically decided against deterministic finalization. I asked Anders Hejlsberg about this multiple times circa 1999-2002.

First, the idea of different semantics for an object based on whether its stack- or heap-based is certainly counter to the unifying design goal of both languages, which was to relieve programmers of exactly such issues.

Second, even if you acknowledge that there are advantages, there are significant implementation complexities and inefficiencies involved in the book-keeping. You can't really put stack-like objects on the stack in a managed language. You are left with saying "stack-like semantics," and committing to significant work (value types are already hard enough, think about an object that is an instance of a complex class, with references coming in and going back into managed memory).

Because of that, you don't want deterministic finalization on every object in a programming system where "(almost) everything is an object." So you do have to introduce some kind of programmer-controlled syntax to separate a normally-tracked object from one that has deterministic finalization.

In C#, you have the using keyword, which came in fairly late in the design of what became C# 1.0. The whole IDisposable thing is pretty wretched, and one wonders if it would be more elegant to have using work with the C++ destructor syntax ~ marking those classes to which the boiler-plate IDisposable pattern could be automatically applied?


问:
What non-programming books should a programmer read to help develop programming/thinking skills?
There are a lot of questions about what programming books should be on the programmer's bookshelf. How about non-programming related books that can help you become a better programmer or developer? It would also be interesting to know why they would help.

My first choice would be Sun Tzu's "Art of War" (however cliché), because it made it obvious that the success of any project depends on the strength of its weakest link (and warfare is a big project).

答: While Strategy of the Dolphin is geared more towards adjusting one's mindset to solving problems arising from dealing with others, applying the adaptive skills in dealing with the absolute world of developer tools will help intuit new ways of addressing problems.

ContentLicense: CC BY-SA 2.5


答:
Bruce Eckel, author of "Thinking in Java" and "Thinking in C++" and a member of the C++ Standards Committee, is of the opinion that, in many areas (not just RAII), Gosling and the Java team didn't do their homework.

...To understand how the language can be both unpleasant and complicated, and well designed at the same time, you must keep in mind the primary design decision upon which everything in C++ hung: compatibility with C. Stroustrup decided -- and correctly so, it would appear -- that the way to get the masses of C programmers to move to objects was to make the move transparent: to allow them to compile their C code unchanged under C++. This was a huge constraint, and has always been C++'s greatest strength ... and its bane. It's what made C++ as successful as it was, and as complex as it is.

It also fooled the Java designers who didn't understand C++ well enough. For example, they thought operator overloading was too hard for programmers to use properly. Which is basically true in C++, because C++ has both stack allocation and heap allocation and you must overload your operators to handle all situations and not cause memory leaks. Difficult indeed. Java, however, has a single storage allocation mechanism and a garbage collector, which makes operator overloading trivial -- as was shown in C# (but had already been shown in Python, which predated Java). But for many years, the partly line from the Java team was "Operator overloading is too complicated." This and many other decisions where someone clearly didn't do their homework is why I have a reputation for disdaining many of the choices made by Gosling and the Java team.

There are plenty of other examples. Primitives "had to be included for efficiency." The right answer is to stay true to "everything is an object" and provide a trap door to do lower-level activities when efficiency was required (this would also have allowed for the hotspot technologies to transparently make things more efficient, as they eventually would have). Oh, and the fact that you can't use the floating point processor directly to calculate transcendental functions (it's done in software instead). I've written about issues like this as much as I can stand, and the answer I hear has always been some tautological reply to the effect that "this is the Java way."

When I wrote about how badly generics were designed, I got the same response, along with "we must be backwards compatible with previous (bad) decisions made in Java." Lately more and more people have gained enough experience with Generics to see that they really are very hard to use -- indeed, C++ templates are much more powerful and consistent (and much easier to use now that compiler error messages are tolerable). People have even been taking reification seriously -- something that would be helpful but won't put that much of a dent in a design that is crippled by self-imposed constraints.

The list goes on to the point where it's just tedious...

Title: Did the developers of Java consciously abandon RAII?

Body:
As a long-time C# programmer, I have recently come to learn more about the advantages of Resource Acquisition Is Initialization (RAII).  In particular, I have discovered that the C# idiom:

```<code>using (var dbConn = new DbConnection(connStr)) {
    // do stuff with dbConn
}
</code>```

has the C++ equivalent:

```<code>{
    DbConnection dbConn(connStr);
    // do stuff with dbConn
}
</code>```

meaning that remembering to enclose the use of resources like DbConnection in a using block is unnecessary in C++ !  This seems to a major advantage of C++.  This is even more convincing when you consider a class that has an instance member of type DbConnection, for example

```<code>class Foo {
    DbConnection dbConn;

    // ...
}
</code>```

In C# I would need to have Foo implement IDisposable as such:

```<code>class Foo : IDisposable {
    DbConnection dbConn;

    public void Dispose()
    {
        dbConn.Dispose();
    }
}
</code>```

and what's worse, every user of Foo would need to remember to enclose Foo in a using block, like:

```<code>   using (var foo = new Foo()) {
       // do stuff with "foo"
   }
</code>```

Now looking at C# and its Java roots I am wondering... did the developers of Java fully appreciate what they were giving up when they abandoned the stack in favor of the heap, thus abandoning RAII?

(Similarly, did Stroustrup fully appreciate the significance of RAII?)


答:
If it doesn't have a coherent architecture, it is because management doesn't understand/care about the problem.  Just code away.  You should introduce new good architecture as you write new code.

You should re-architect things only if they start having really serious bugs, you need to extend it and just can't, or it just doesn't match its requirements.

I'm basically saying only care about issues that your managers actually care about, not issues they would care about if they had your knowledge.

If you can sell re-architecture to management, start with testing.  If they don't want to invest in testing, your efforts will only get you trouble.

Title: Starting a coherent architecture in a legacy application

Body:
I have responsibility for a large Asp.Net based website. It is currently a website (not web application), some windows services and a number of class libraries.

The data layer uses a mixture of LLBLGEN  and Linq To LLBGen, as well as a number of instances of legacy inline SQL which have not been refactored.

There are some manager type implementations, but in many cases the application exhibits the Smart UI anti-pattern (i.e. too much business logic in code behind classes)

The site is reasonably high traffic, and performance is fine, but we are growing our development capability to a team of around 10, and increasingly it is clear we need an overarching layered design on top of the existing middleware.

My question is where to start? We have 10 years of code (some of it still really just migrated ASP Classic stuff), many different approaches, and styles.

Refactoring the entire code base is not realistic and, probably not desirable

I know this is not a novel situation, are there any useful ideas or concepts as to how to approach this problem?


问:
How to measure when a software project is complete?
I have very limited experience in software project management roles, and I was asked this question by another engineer and I was sort of stumped.

How do I measure when a software project is complete?

The part I'm struggling with is the "measure" part. I know there are measurements such as EVM, but they are more focused on overall project performance. For instance, having a low SPI or low CPI can indicate performance/allocation issues, but it doesn't really indicate how complete a project is.

Is there a rule of thumb here to say my project is XX% complete or am I overthinking this?

答:
Sounds like you might be over thinking it a bit, but we programmers do have a habit of doing that.

Track a list of requirements. When you can mark of each requirement as tested and implemented, begin system testing the project.


答:
In a plan-driven methodology, where you have the complete requirements up-front, a complete project would satisfy all of the requirements and pass the specified unit, integration, system, and acceptance tests. In a perfect world, the project would end at the end of the plan. However, the health of the project should be tracked as part of the plan, allowing for insight into health and status so that a project that is exceeding cost/time allowed can be cancelled early.

In an iterative and incremental methodology, you often end every iteration with a potentially shippable product, which includes all of the software and associated documentation that is required. The project could end under a number of circumstances - you run out of requirements to ship, you run out of money, the customer ends the project if the cost of a future iteration is less than the earned value, or so on.

You don't want to estimate a percentage of completion, as you can only measure against known requirements, as it doesn't account for unknown requirements or defective requirements. Instead, you want to measure project completion against measurements such as completed requirements, percentage of passing tests (especially acceptance tests), and earned value - these will give a general health/status of the project, regardless of the methodology used.

Depending on your specific methodology, there are a number of measurements and metrics that you might be interested in. A few examples include earned value, velocity, requirements churn (changed requirements/unit of time), defect reports, cost (compare actual to budgeted at each phase of the project), effort, and progress (actual completed tasks vs scheduled completed tasks).

Title: How to measure when a software project is complete?

Body:
I have very limited experience in software project management roles, and I was asked this question by another engineer and I was sort of stumped.

How do I measure when a software project is complete?

The part I'm struggling with is the "measure" part. I know there are measurements such as EVM, but they are more focused on overall project performance. For instance, having a low SPI or low CPI can indicate performance/allocation issues, but it doesn't really indicate how complete a project is.

Is there a rule of thumb here to say my project is XX% complete or am I overthinking this?


问:
I keep failing hands on part of the interview, suggestions?
So I have a couple of software/site in my portfolio. They make money but not a whole lot.

So I decided to get some job experience, mainly applying to Java/PHP junior development positions.

The problem is that I answer all the technical questions correctly and we schedule to do a coding "test", the final phase of the interview. I can never relax and over think things and end up doing the test very slowly. OR sometimes I just hit a block and find it very difficult to think on my feet.

I don't understand this because other stuff I had written were solving far more complex problems while the "Test" is actually brutally simple such as writing and testing palindrome.

Other times, they will give me a logic test with flows to math operations and again I won't be able to do it in the time they assign.

I know I can write sellable software/websites that can generate small revenues and find ways to solve problems but I have great difficulty with simple coding tests in interviews.

Any suggestions?

答:
As many people have already said I practice is one of the most important things.  If you have already done a similar problem you will be able to come up with the solution quickly.

If you are having a hard time coming up with problems to try and solve on your own try using Google search for programming interview questions for your language or choice.

Also you can pick up books that are designed for teaching lower level CS courses. Most of these books are filled with programming assignments that are small and can be done quickly at home.  They can be used for practice.


问:
Becoming a polyglot programmer
I know a few programming languages.  The most marketable ones being Java, Javascript, as well as non-trival stored procedures.  I also know some Python, Actionscript and a few dinosaurs language.  I am starting up a toy project with Scala/lift.  I enjoy each language for its own features and the paradigms they encourage.

I am interested in the concept of a polyglot programmer and becoming one.  What are the steps to being a true polyglot programmer?  (I.E. I don't just know different languages, I know them well, and know good design patterns for them.)  Is this something that can be made marketable?

答: The most important thing I would say is not to think in terms of programming languages, but in programming concepts. OOP is still OOP in Java, C#, C++, and Python. Every language has it's own quirks with how it handles it, but OOP concepts are the same no matter what language you are writing it.</p>

Title: Becoming a polyglot programmer


答:
There is a simple rule of thumb.  Define the goal of your project, express it in a number of units, see how many units you have completed so far, and compute the completion percentage.

For example, the goal of your project is to spend 400 hours writing some code.  You've already spent 280 hours.  Your completion percentage is 280/400 = 70%.  (This paragraph is 100% sarcasm, but unfortunately this is how most project managers see progress.)

To give another example, the goal of your project is to develop some product features and deploy them to users.  Let's say, you've got 10 features and you haven't deployed any of them yet.  Your completion percentage is 0/10 = 0%.  (This is where a typical project manager will say: "But we've coded and tested five of them; 50% or them are done!")

Moments when one of these metrics is close to zero while the other one is close to 100% are illuminating.  You know what your goal is, right?


问:
How can I convince my colleague to unit test his code?

Possible Duplicate:

  Colleague unwilling to use unit tests “as it's more to code”

I've been trying in the last couple of months to convince one of my colleagues to start unit testing his code and drop the old "print, run, debug" way of doing things. I need clear and elaborated proofs that unit testing increases your productivity - this guy has a decent amount of experience and can give a counter-argument for all of the arguments I gave him until now.

Unit testing is not a policy that's being enforced in the team, but is something that most of us do and it definitely worked for us, and we can see how print, run and debug isn't working for him - it's taking way too long to implement something and it's taking even longer to manually test his code.

答: Unit testing only takes you so far in the grand scheme of things, and TDD is harmful to large projects.  I find that using a sys out to see what is going on is far more beneficial than a unit test.  The issue you have is that there is not a policy in place to force a developer to do "the norm", if it continues to be a problem you should bring it up to management and have a meeting about the benefits.  The thing to realize here is that you need to write unit tests against his code and prove that this actually will make it easier for the team to progress.  However, if you fail to do so and you wasted time writing unit tests your management team will be less than pleased.</p>

OwnerDisplayName: hyperboreean


答:
I do NOT consider myself a polyglot programmer, but the few languages I do know span very different styles of coding. I would suggest the following to start:

Know how to program well in a lot of languages. Duh.

Be aware of the benefits and drawbacks of different language fundamentals. Some languages are by nature object-oriented, some string-oriented, some data-oriented. Be able to appropriately assess when a given style should be used.

Be familiar with many different coding styles. As many languages have their own idiosyncrasies, be familiar with these; it will make your code much more readable to the developers of that language.

Title: Becoming a polyglot programmer

Body:
I know a few programming languages.  The most marketable ones being Java, Javascript, as well as non-trival stored procedures.  I also know some Python, Actionscript and a few dinosaurs language.  I am starting up a toy project with Scala/lift.  I enjoy each language for its own features and the paradigms they encourage.

I am interested in the concept of a polyglot programmer and becoming one.  What are the steps to being a true polyglot programmer?  (I.E. I don't just know different languages, I know them well, and know good design patterns for them.)  Is this something that can be made marketable?


答:
Even the most versatile polyglot programmers have strong and weak languages; the point of being polyglot, IMO, is not so much having in-depth knowledge of a lot of any particular language, but rather being able to switch between languages and paradigms at ease, and being quick at picking up new ones. I don't think being a guru in 12 radically different languages is a realistic goal, but being fluent in four to six languages (including the core libraries they come with, and the customs and cultures of their respective communities), plus basic knowledge in another six to ten languages is certainly doable.

As far as marketability goes; there is certainly potential for a flexible programmer, especially in smaller shops, where being able to assign any programmer to any project is more important than having a bunch of specialists who won't function well outside their area of expertise. Most companies focus on a single technology stack (e.g. .NET, Java, LAMPP), but there are certainly others that use different platforms per project.

Title: Becoming a polyglot programmer


答: If you really want to put your diverse programming languages knowledge into a good use, consider adopting the language-oriented programming model. This way you'll be routinely inventing and implementing new languages, and knowing as many language concepts as possible is highly beneficial there.</p>

Title: Becoming a polyglot programmer


答:
It sounds to me that in your case the best way to convince your co-worker is to write unit tests for his code, or to write tests for the implementation he is doing, and just show him how it's so much faster than his method.

For some people, any theoretical argument can be refuted by some other theoretical statement, however few people will outright reject "cold hard facts."

Title: How can I convince my colleague to unit test his code?

Body:
Possible Duplicate:

  Colleague unwilling to use unit tests “as it's more to code”

I've been trying in the last couple of months to convince one of my colleagues to start unit testing his code and drop the old "print, run, debug" way of doing things. I need clear and elaborated proofs that unit testing increases your productivity - this guy has a decent amount of experience and can give a counter-argument for all of the arguments I gave him until now.

Unit testing is not a policy that's being enforced in the team, but is something that most of us do and it definitely worked for us, and we can see how print, run and debug isn't working for him - it's taking way too long to implement something and it's taking even longer to manually test his code.


答:
It seems like the proof you need, you already have. Your own performance improvement should be prove enough that in your environment, unit testing is more efficient.

If you have the time and oportunity, you might try something I did with a collegue of mine on a similar matter. We were trying to figure out which language/framework combo was more efficient in small projects (We are both similarly proficient programmers). A project came along which needed to be done really fast, so we argued about which one to use to develop the product. Since we couldn't come to an agreement, we decided each one would do it the way they though (we both were available) and see who finished first (delivered a verified and validate product first). I am not going to say who won (guess why) but trust me that the non-winner (looser) admitted to the affeciency of the competing selected combo.

No counter-argument can be given in that situation.


答:
This situation is very strange. I have never heard of anyone skipping unit testing.
Unless you make it a policy, there is no way to 'convince' some one to do that.
You project manager must establish a policy and a process for this to take place, otherwise, frankly, you should not consider your job done at all. If a programmer can't understand the value of unit testing, he/she probably get some education. The practice of throwing code into systems is harmful, unprofessional and can't be justified as a common practice in a team.

Edit:

Due to the comments below, I need to clarify that what the 'unit tests' I am referring to is 'any type of unit test', that is it is not necessarily automated unit tests, it may be manually performed.


问:
Good techniques to speed up database execution
I have an ASP.Net application that is using a MySQL database. My queries are not executing as fast as I would like them too. Are there some standard ways to increase the speed of a MySQL database short of putting it on a faster PC.

For example, (I'm not sure if these are true or not) using prepared statements over transactional SQL. Using foreign keys if applicable? Things along those lines.

EDIT:
The database is on a remote machine

答:
What you want to do is learn how to profile your queries using the MySQL EXPLAIN command (doc).  That will tell you how the query is pulling data out of the database - whether its scanning rows one by one or using indexes.  Using that, you can often dramatically speed up queries.  Of course, if you're not now using indexes, that would be the first place to start...

The effect of prepared vs non-prepared statements... thats generally minimal.  You'll want to profile that too in your code, but only after you've optimized indexes based on what you learned from running EXPLAIN.


答:
I am also very bad at tests and always have been.  I could not for the life of me figure out why a programming class was given me tests to take with pencil and paper.  I never got good at it.  However, what I did do was explain to interviewers that I had this problem and knew about it.  I also managed to interview for companies that did not give me silly tests.

My suggestion is to tell the company before you go into the interview that you don't do will with those sorts of tests, however you are happy to X instead. (Figure out an alternative that makes sense and you feel comfortable doing.)  For myself, I offered to send them code, and one time I suggested that they give me a simple program to write, and I'll bring it with me to the interview in 3 days time.

Depending on where you are looking to get jobs this may or may not work for you.

Title: I keep failing hands on part of the interview, suggestions?

Body:
So I have a couple of software/site in my portfolio. They make money but not a whole lot.

So I decided to get some job experience, mainly applying to Java/PHP junior development positions.

The problem is that I answer all the technical questions correctly and we schedule to do a coding "test", the final phase of the interview. I can never relax and over think things and end up doing the test very slowly. OR sometimes I just hit a block and find it very difficult to think on my feet.

I don't understand this because other stuff I had written were solving far more complex problems while the "Test" is actually brutally simple such as writing and testing palindrome.

Other times, they will give me a logic test with flows to math operations and again I won't be able to do it in the time they assign.

I know I can write sellable software/websites that can generate small revenues and find ways to solve problems but I have great difficulty with simple coding tests in interviews.

Any suggestions?


答:
I'm a very advanced programmer in several languages. I don't know if that make of me a polyglot programmer, but I'm at least on the path.

Here are the thing I consider important to get this qualifier and some tips on how to get them.

First of all, you need to master several programming paradigms :

Procedural

Object oriented

Functionnal

Event driven

Metaprogramming

To get to this point I suggest two things :

Try programming languages that promote paradigms.

Try paradigms in languages that do not promote them (it will show you what a given paradigm is about, what problems it does solve, and what the computer is actually doing when you use them). Good exercices are OOP in C (build the vtables manually, that's what real men do !) or non types languages in a strongly typed one (see std.variant for an exemple of that in D).

Then you'll have to know good practice and why they are good practice (remember, you have to know the WHY of a rule, so you know when to break it).

DRY

Separation of concerns

Naming (actually this is one of the most important because the code will tell you things throw names - for exemple, if you can't find a short and accurate name for a variable, then the variable isn't in the right place or its purpose isn't clear).

Many other, so many actually that I can't do a list here, but I think I have already given some of the most important ones.

To progress on that point, I suggest books. The pragmatic programmer is a good one, clean code too. Code complete is excellent too, but quite hard to read, because it's big and very dense in informations (but that is also its strength !).

You need also to fail badly at applying thoses concept and ends up with code that looks like jungle. Hard to travel, hard to adapt, with unfriendly inhabitants. This last point is the key because it will teach you how to use the tools to get quality code. What is the matter if you know what is quality but can't master tools to create it or vice versa ?

If you master the given point, you can consider yourself as a polyglot programmer IMO. By the way, this isn't all you need to be the greatest programmer. Computer science, knowledge on current technologies, management of yourself (sometime of others :D), understanding of the requirement, and so many other are required.

As a final tips, I suggest you to get involved in a recent language under active devellopement. This will teach you how language are created and why. This will teach you the limitation of actual languages, the difficulties you face to get better alternative (if that was easy, I would have been done in a first place !). Mine is D. It is also a multiparadigm language, so it is a good candidate. Choose yours !

Good luck. This require work, but it worth it !

Title: Becoming a polyglot programmer


答:
Java intentionally does not have stack-based objects (aka value-objects).  These are necessary to have the object automatically destructed at the end of the method like that.

Because of this and the fact that Java is garbage-collected, deterministic finalization is more-or-less impossible (ex. What if my "local" object became referenced somewhere else? Then when the method ends, we don't want it destructed).

However, this is fine with most of us, because there's almost never a need for deterministic finalization, except when interacting with native (C++) resources!

Why does Java not have stack-based objects?

(Other than primitives..)

Because stack-based objects have different semantics than heap-based references.  Imagine the following code in C++; what does it do?

```<code>return myObject;
</code>```

If myObject is a local stack-based object, the copy-constructor is called (if the result is assigned to something).

If myObject is a local stack-based object and we're returning a reference, the result is undefined.

If myObject is a member/global object, the copy-constructor is called (if the result is assigned to something).

If myObject is a member/global object and we're returning a reference, the reference is returned.

If myObject is a pointer to a local stack-based object, the result is undefined.

If myObject is a pointer to a member/global object, that pointer is returned.

If myObject is a pointer to a heap-based object, that pointer is returned.

Now what does the same code do in Java?

```<code>return myObject;
</code>```

The reference to myObject is returned.  It doesn't matter if the variable is local, member, or global; and there are no stack-based objects or pointer cases to worry about.

The above shows why stack-based objects are a very common cause of programming errors in C++.  Because of that, the Java designers took them out; and without them, there is no point in using RAII in Java.

Body:
Java intentionally does not have stack-based objects (aka value-objects).  These are necessary to have the object automatically destructed at the end of the method like that.

Because of this and the fact that Java is garbage-collected, deterministic finalization is more-or-less impossible (ex. What if my "local" object became referenced somewhere else? Then when the method ends, we don't want it destructed).

However, this is fine with most of us, because there's almost never a need for deterministic finalization, except when interacting with native (C++) resources!

Why does Java not have stack-based objects?

(Other than primitives..)

Because stack-based objects have different semantics than heap-based references.  Imagine the following code in C++; what does it do?

return myObject;

If myObject is a local stack-based object, the copy-constructor is called (if the result is assigned to something).

If myObject is a local stack-based object and we're returning a reference, the result is undefined.

If myObject is a member/global object, the copy-constructor is called (if the result is assigned to something).

If myObject is a member/global object and we're returning a reference, the reference is returned.

If myObject is a pointer to a local stack-based object, the result is undefined.

If myObject is a pointer to a member/global object, that pointer is returned.

If myObject is a pointer to a heap-based object, that pointer is returned.

Now what does the same code do in Java?

return myObject;

The reference to myObject is returned.  It doesn't matter if the variable is local, member, or global; and there are no stack-based objects or pointer cases to worry about.

The above shows why stack-based objects are a very common cause of programming errors in C++.  Because of that, the Java designers took them out; and without them, there is no point in using RAII in Java.


答:
Is the database write the only place you can speed up your program. Without more information on your use case, is it possible to use a topology of a write-behind cache?

A write-behind cache will allow you to put elements into a cache to be written to a database at a later date. For database entries that do not have further dependencies (such as being read from the database within a set time period) this would be ideal as once an element is in the cache, it will be in the database as far as your application is concerned.

This is the ehcache on how to implement a write-behind cache and I have also linked to a decent video presenting how a write-behind cache can remove a database bottleneck from an application. http://vimeo.com/21193026

Title: Good techniques to speed up database execution

Body:
I have an ASP.Net application that is using a MySQL database. My queries are not executing as fast as I would like them too. Are there some standard ways to increase the speed of a MySQL database short of putting it on a faster PC.

For example, (I'm not sure if these are true or not) using prepared statements over transactional SQL. Using foreign keys if applicable? Things along those lines.

EDIT:
The database is on a remote machine


答:
The best reason is much simpler than most of the answers here.

You can't pass stack allocated objects to other threads.

Stop and think about that. Keep thinking.... Now C++ didn't have threads when everyone got so keen in RAII. Even Erlang ( separate heaps per thread) gets icky when you pass too many objects around. C++ only got a memory model in C++2011; now you can almost reason about concurrency in C++ without having to refer to your compiler's "documentation".

Java was designed from (almost) day one for multiple threads.

I've still got my old copy of "The C++ Programming language" where Stroustrup assures me I won't need threads.

The second painful reason is to avoid slicing.


问:
What is better for coding - desktop or laptop?
Use of desktops are decreasing day by day in daily life but for coding purpose are there any reasons for using desktop over laptop? </p>

答:
Laptop, easily.

I do not like being stuck in the house all day. I actually try to stay out most of the time. I live in a city so I can go to a few diff coffee shops or wherever and code. If I am actually at the house, much easier to lay on the couch or something.

Just make sure you get one with high resolution. Preferably an apple macbook pro or dell studio with 1920x1200 res. Just use virtual desktops. I literally hate sitting at a desk all day, that was the main reason I quit my 9-5 job in the first place! Plus you can sell your desk/chair/speakers or whatever else you probably have and create more space.

Just go sit at your kitchen counter/table/couch/chair/coffee shops. I could never go back to working at a desk all day. It's also much easier for meeting clients somewhere and showing them things, or of course traveling. I live a lifestyle somewhat similar to the lady going to SF or Argentina.


问:
Tailoring your resume for a career switch within programming
I am currently interested in job prospects outside of my own area of programming. Specifically, I'm a web developer but want to make the transition to desktop application programming. How should I tailor my resume to show that I am capable of this type of software development when I have had no prior experience with it? This question can also be generalized for any other programmer making a leap to a different area (for example a programmer mostly experienced in finance software that wants to go into embedded systems programming).

In short, I've used HTML, CSS, PHP, MySQL and Javascript at work. For a short while I also used ColdFusion. I'm very familiar with OOP concepts and frameworks. In the meantime I've moonlighted for over 3 years on my personal hobby projects in C# and C++.

I know it's bad focusing too much on the tools than their application as a metric to measure your abilities, but for making a transition in my career, would emphasizing knowledge in these tools be good idea to put on your resume? Problem is that a lot of jobs put programming languages as strict job requirements (see here). My resume currently shows 5 years of web development experience. I know general programming concepts well enough, and at this point my experience counts much more than my degree.

I want to know how I can make a potential employer of a software company look at my resume with cautious optimism, and not instantly reject it when it shows I have 5 years web experience with PHP and zero desktop software experience.

答:
The advice I've been given for these sort of things before is to generalize your previous jobs.

Instead of writing:

I used JavaScript to create the website for company X

you could write:

I was instrumental in developing company x's product.

The general idea here is that you present responsibilities and achievements that you made in a way that shows they can be adapted to the new environment.  Your experiences at your previous companies are then seen as assets instead of irrelevant footnotes to your history.


答:
Some things that could be generally happening here:

The queries are slow.  Run the query directly on the MySql instance.  Host fast?  If it takes a few seconds tuning the query is necessary with additional indexes, etc.

There is too much data coming across the network.  The query could be running instantaneously, but the amount of the data coming over the wire is too much.  Return less data or page the data back to the client would be some suggestion(s).

The server is real busy.  What's the CPU and memory look like on the server?  Is it close to 100%?

Prepared statements don't make that much difference until the server has a high volume of queries coming through.  Speed wise prepared versus unprepared are just about the same, but with prepared statements the server doesn't have to work as hard, so it can use more resources to do other things.


答:
If you have to ask the question, you don't have a project, as a project needs to be defined (think SMART Goals - Specific, Measurable, Achievable, Realistic, Time framed.).

You either have a list of requirements and/or deliverable items that must be achieved, in which case it's complete when these are done. If you don't have these, you don't know what you are building, and really don't have a project. Given your probably going to fail in this case, when the money runs out is as good a point as any to call it complete.


答:
Project Euler

It seems to me that you're failing the fizzbuz test.  Mind numbing simple algorithms that don't generally serve any practical purpose except to identify if you understand the core concepts of programming.

Brush up on your basics

What I would recommend is that you brush up on your basics.

http://projecteuler.net/

Sign up and start practicing, you'll find that by going through those examples you'll get a deeper understanding of the core programming concepts.  I think you'll find a palindrome question in there along with fibonacci sequences and other mathematical concepts (sound familiar).


答:
First thing to consider is if your indexing is correct. Are your queries sargable (ie can they use the index if it exists)? Are your foreign key fields indexed?

Next are you doing things in a set-based manner or looping through records which is often slower in a database.

Are you using known performance killing techniques (in sql server this would include the use of correlated subqueries, cursors, scalar UDFs, functions in joins etc., not sure what the known killers are in MySQL but there are books available I'm sure on the topic.

Are you using select * and returning more data than you need especially in joins where at least the joins fields are repeated.


问:
What type of problem is this?
Business Analyst creates a requirement. Requirement implemented by developer.  BA performs QA.  Bug report includes various bugs that were never requirements.

E.G.

A requirement is made to display a report.  The report is displayed.  In QA, the analyst see's that a user can enter invalid data.  The invalid data makes the report invalid.  Per the requirements, an error message is displayed.

The analyst decides that they want the previously run report to have its data cleared.  Currently, when entering into an invalid state the system displays results from the previous report along with an error message.

In this case, the problem is that we are in an error state.  The error state requires an error message, but is otherwise undefined.

Is this "bug" scope creep, poorly defined requirements, lack of an overall business process for error management, lack of technical foresight on part of the BA/Dev, a valid request or other?  How can you minimize these types of problems?

Other details (specific to this app)

Web app.  Persistent State is an overall part of the design (thus the reason you see the report still displayed).  There are little to no HTTP POST/GET operations performed outside of AJAX.  Navigation menu changes pages without full postbacks.  Instead, perform HTTP GET to load HTML/JSON into portions of the web page on click.

答:
Most likely it is poorly defined requirements. The best way to minimize stuiff like this, in my opinion, is to push the Ba from the start to make the requirements more descriptive. When you first get them. Ask him how you want the system to handle bad data entry or other things that you think from previous experince have not been adequately covered. In my expereience most BAs don't know what to put into the requirements once you get away from the fields on the User interface. You need to push back virtually all requirements and ask for what you need to handle errors correctly, to handle what needs to go on behind the scenes, etc. If you see a decision place in the requirement, make sure to ask what happens if the less common decision is made (for instance suppose there is amanger approval, many BAs won't tell you without asking what should happen if the manager disapproves the request). The sooner you push back for more answers the less rework is needed.

To help you with this, keep a running list somewhere of what requirements changes you had for things that should have been defined but were not. Then you will know what things to ask about the next time you get a requirement. Fixing a poor requirement is the single best way I know to save time and money on a project.

Title: What type of problem is this?


答:
The problem is called human nature.  It's very difficult to anticipate these sorts of problems without seeing a working implementation, both for developers and requirements writers, although with experience on similar work you get better at it.

Most modern software processes acknowledge this fundamental difficulty and focus instead on tightening the feedback cycle.  Instead of working for 3 months and shipping something you deem complete off to QA, you let him see it in whatever state it's in every 2 weeks, or even sooner.  If a developer has a choice of how to act in an error condition, he asks the BA right then instead of just guessing or doing whatever is easier.  If your feedback cycle is already tight, but the changes annoy you because they seem "unplanned," then plan for them.  Schedule in some time for fixing requirements issues found in QA.

Title: What type of problem is this?

Body:
Business Analyst creates a requirement. Requirement implemented by developer.  BA performs QA.  Bug report includes various bugs that were never requirements.

E.G.

A requirement is made to display a report.  The report is displayed.  In QA, the analyst see's that a user can enter invalid data.  The invalid data makes the report invalid.  Per the requirements, an error message is displayed.

The analyst decides that they want the previously run report to have its data cleared.  Currently, when entering into an invalid state the system displays results from the previous report along with an error message.

In this case, the problem is that we are in an error state.  The error state requires an error message, but is otherwise undefined.

Is this "bug" scope creep, poorly defined requirements, lack of an overall business process for error management, lack of technical foresight on part of the BA/Dev, a valid request or other?  How can you minimize these types of problems?

Other details (specific to this app)

Web app.  Persistent State is an overall part of the design (thus the reason you see the report still displayed).  There are little to no HTTP POST/GET operations performed outside of AJAX.  Navigation menu changes pages without full postbacks.  Instead, perform HTTP GET to load HTML/JSON into portions of the web page on click.


答:
scope creep, poorly defined requirements, lack of an overall business process for error management, lack of technical foresight on part of the BA/Dev, a valid request

All of the above...  Seriously... EVEN a valid request.

It is scope creep because a new feature made its way into the release requiring more development and threatening the success of the project.

It is poorly defined requirements because this requirement that the BA wanted was missed in the formal specification.

It is lack of overall process in that you are lacking Change Control in your project management.  Let's face it, requirements get missed, but change control helps prevent missed and new requirements from creeping in and threatening the deadline of the project.

Lack of technical foresight because the requirements must have been reviewed by a tech lead or developer before the sprint/iteration and the developer didn't anticipate the technical issues that the poorly defined requirements COULD lead to.

It is a valid request because after all is said and done, the BA's and stakeholders are going to want the software to behave a certain way eventually.  It is unfortunate that it was missed but the problem should be owned by the BA or application manager and added to the backlog for the next sprint pending priority.

Title: What type of problem is this?


问:
Functional or non-functional requirement?
I'm wondering about functional or non-functional requirements. I have found lot of different definitions for those terms and I can't assign some of my requirement to proper category.

I'm wondering about requirements that aren't connected with some action or have some additional conditions, for example:

On the list of selected devices, device can be repeated.

Database must contain at least 100 items

Currency of some value must be in USD dollar.

Device must have a name and power consumption value in Watts.

are those requirements functional or non-functional ?

答:
A functional requirement is typically something the system can or will do. It can be expressed as a result of an action (Of a negative result).
A non fucntional requirement is something that the customer / end user does not care about, and does not affect the outcome - e.g

 - Windows will have a blue border with pink dots.
 - The program will be written in Java

 - Anything to do with coding standards, methods and process.

Be warned though that a non-functional requirements can be turned into functional requirements by customers. examples might be
 - The program will be written in Erlang because the customer read a magazine article on it and wants it written in Erlang.
 - The program must use DB 2. because the customer is going to run it on his existing DB 2 systems, has years of experience and an IT team familiar with that platform.

 - The source code must pass all MISRA recommendations.

In summary - if the customer cares about it, it's a functional requirement, otherwise it's a non functional requirement or possibly not even a requirement.


问:
Backtrack My "Education"
A while ago, I decided to start programming. I really, just jumped into a language (Perl) and went from there. What I regret is that I just jumped in:

I didn't learn the basics (if you would call them basics).

I didn't learn about Computer Science.

This issue, I believe, is holding me back from my true potential. Where should I "restart"? Are there any books, articles, etc. that I should read? Are there any topics an experienced programmer should know? What's your advice?

答:
I'd do this:

Path A: The Semi-Typical Method

Learn a language with a more regularized syntax like Java, C#, or Python. Perl is an insanely useful tool but it's also very very freeform in terms of how it lets you do things. The other languages I listed are much, much less so.

Get a book about Data Structures in said language.

Get a book on Algorithms in said language.

Get Code Complete and Effective Java/C#/Whatever Python's version is.

Path B: Joel Spolsky's Path of Enlightenment(or Death, take your pick)

Get the book "Code"

Get K&R's "The C Programming Language"

Get the Structure and Interpretation of Computer Programming

As far as the method's go, method 1 will teach you programming in a more regularized way. Computer Science concepts to an extent (no complexity theory yet, trust me) and provide you with a language that's better for working in projects with other people and for making bigger applications.

Method 2 is more hardcore, it's much more of a fundamentals approach with "Code" explaining the basics, K&R introducing the machine level stuff and the SICP introducing the higher level concepts. It's a much harder but more focused path.

In either case, give yourself time. Rome wasn't built in a day and neither are programming skills, even if you are a genius at it. Peter Norvig's Programming in 10 years is the usual essay I point people to.

Addendum:

As far as available free stuff: Python the Hard Way as listed below is a good start, from there, How to think like a Computer Scientist is a reasonable continuation.

There are a number of resources on Algorithms out there and honestly you probably could switch steps 3 and 4 without issue. Keep in mind, this is where the math really starts to show up so never be afraid to ask for help when you get to this stage. This seems to be a reasonable free guide.

There really isn't a cohesive free equivalent to Code Complete per say though Code like a Pythonista seems pretty solid. The big thing is to concentrate on making your code readable once you've got the fundamentals down pat. It's not "necessary" in the same way that having all your code syntax correct is but it makes live a lot easier once you get beyond small programs or work on something over a long period.

You might find that I've focused mostly on Python, that's because it is the easiest of the three to find well written free stuff. I think Java's tutorials by Oracle are fine but they are a little dry and not great for beginners. C# is in a similar situation though neither suffers from lack of documentation.

Also, your first CS joke/pun: you want to "Refactor" your education, not Backtrack.

Title: Backtrack My "Education"


答:
I'd say aim at Learn Python the Hard Way; it's a good approach. Go from there; it'll take long enough to give you time to find other resources.

In my opinion, "path B" mentioned in another answer isn't appropriate at this stage.

Title: Backtrack My "Education"

Body:
A while ago, I decided to start programming. I really, just jumped into a language (Perl) and went from there. What I regret is that I just jumped in:

I didn't learn the basics (if you would call them basics).

I didn't learn about Computer Science.

This issue, I believe, is holding me back from my true potential. Where should I "restart"? Are there any books, articles, etc. that I should read? Are there any topics an experienced programmer should know? What's your advice?


问:
How can I make sure I'm writing C++ like it's meant to be written?

Possible Duplicate:

  How can I learn to write idiomatic C++?

Besides the obvious answers of "use g++ instead of gcc, and cout instead of printf", how can I ensure that my toy project is teaching me proper C++ paradigms and patterns?

Backstory: I've never written a line of C++ beyond Hello World, and I've chosen what should be a straightforward (albeit somewhat complicated) sample project to help me learn the language.  I've decided that the goal I want to end at is a CLI Huffman encoder.  It doesn't have to  compete with modern compressors in speed or efficiency, it just seemed like a project that would help me touch many aspects of the language at once.

So, before I dive into this project, what are some things I should keep in mind?  A lot of what I'm going to be doing is research online, and I have a fear that a lot of tutorials are C-in-C++.  I'm looking for answers like: "if you're using malloc, you're probably doing something wrong" or "you should probably be using boost or something similar".  I'm also looking for suggestions like "if I were writing this, I'd use a template around x".

答:
Learn to use the standard library.  There are tons of containers and algorithms to choose from that are efficient and powerful.

I write large programs without worrying about memory management at all.  I use vector for container, I store by value.  If I must use new to create an object I wrap it in a smart pointer like unique_ptr or maybe shared_ptr.  These will clean up pointers automatically.  Never use delete.

If you have access to a recent g++ use the C++11 standard.  It's got a lot of nice features.  "g++ -std=c++0x" will use the new standard.

Have fun :o)


答:
Functional requirements define what the system or application will do - specifically in the context of an external interaction (with a user, or with another system).

When placing a new order, the system shall display the total cost and require confirmation from the user. That is a functional requirement; it describes a function of the system.

Refer to Wikipedia: Functional Requirement for more details.

Non-functional requirements are any requirements that don't describe the system's input/output behaviour. Note that we are still talking about requirements, not implementation details, so just because we're using the phrase "non-functional" doesn't mean that anything is fair game to put in that section.

The most common types of non-functional requirements you'll see relate to system operation (availability, continuity, DR), performance (throughput, latency, storage capacity), and security (authentication, authorization, auditing, privacy).

These are all cross-cutting concerns that impact every "feature" yet aren't really features themselves; they're more like feature metadata, helping describe not just whether the system does what it's supposed to but also how well it does it. Don't take that analogy too far, though - it's just an analogy.

Non-functional requirements are not subjective or hand-wavey, contrary to what some people here seem to be suggesting. In fact, they should actually have a hard metric attached to them (i.e. response time of no more than 100 ms).  NF requirements are also not implementation details or tasks like "upgrade the ORM framework" - no clue where anyone would get that idea.

More details at Wikipedia: Non-Functional Requirement.

To specifically address the examples in the question:

On the list of selected devices, device can be repeated.

Clearly a functional requirement. Describes what the system's output looks like.

Database must contain at least 100 items

Sounds like a business rule, so also a functional requirement. However, it seems incomplete. What is the reason for this rule? What will happen/should happen if the database contains fewer than 100 items?

Currency of some value must be in USD dollar.

Functional requirement, but not really a properly-stated one. A more useful wording would be: The system shall support one currency (USD).  Obviously this would be amended if more than one currency needed to be supported, and then the requirement would have to include information about currency conversions and so on.

Device must have a name and power consumption value in Watts.

Not really any kind of requirement, this is more like a technical specification. A functional requirement would be stated as the power rating is assumed to be in Watts. If there's more than one UOM, then as with the currency, the functional requirements should have sections about unit conversions, where/how they are configured, etc. (if applicable).

Title: Functional or non-functional requirement?

Body:
I'm wondering about functional or non-functional requirements. I have found lot of different definitions for those terms and I can't assign some of my requirement to proper category.

I'm wondering about requirements that aren't connected with some action or have some additional conditions, for example:

On the list of selected devices, device can be repeated.

Database must contain at least 100 items

Currency of some value must be in USD dollar.

Device must have a name and power consumption value in Watts.

are those requirements functional or non-functional ?


答:
I wouldn't recommend Huffman encoding as a C++ project- it'll mostly take place at the bit level, where C++ is really going to look the same as C. Nobody templates a binary operation, nor RAIIs it.

I'd implement an interpreter for a small language, maybe Brainfuck or Lua, for example, or your own small or esoteric language. This will involve quite some memory management and Standard algorithms and should generally be more instructive.

Title: How can I make sure I'm writing C++ like it's meant to be written?

Body:
Possible Duplicate:

  How can I learn to write idiomatic C++?

Besides the obvious answers of "use g++ instead of gcc, and cout instead of printf", how can I ensure that my toy project is teaching me proper C++ paradigms and patterns?

Backstory: I've never written a line of C++ beyond Hello World, and I've chosen what should be a straightforward (albeit somewhat complicated) sample project to help me learn the language.  I've decided that the goal I want to end at is a CLI Huffman encoder.  It doesn't have to  compete with modern compressors in speed or efficiency, it just seemed like a project that would help me touch many aspects of the language at once.

So, before I dive into this project, what are some things I should keep in mind?  A lot of what I'm going to be doing is research online, and I have a fear that a lot of tutorials are C-in-C++.  I'm looking for answers like: "if you're using malloc, you're probably doing something wrong" or "you should probably be using boost or something similar".  I'm also looking for suggestions like "if I were writing this, I'd use a template around x".


答:
Use new / delete instead of malloc/free. -

Use references whenever possible over plain pointers.

Use iostream over stdio.

Use string class over char *

Do NOT use uint8_ etc type of hard-coded data types.

Do not overuse/abuse templates unless there is genuine use.

Uses objects as opposed to static methods.

Use const instead of #defines where possible.

Use exceptions effectively with try-throw-catch.

There are many tips you can get from "Effective C++" from Scott Meyers which is return exclusively for the purpose to explain exactly why many C constructs are BAD to be used in C++ as it is even if compiler accepts it.


问:
Best Practices for Handing over Legacy Code
In a couple of months a colleague will be moving on to a new project and I will be inheriting one of his projects. To prepare, I have already ordered Michael Feathers' Working Effectively with Legacy Code.

But this books as well as most questions on legacy code I found so far are concerned with the case of inheriting code as-is. But in this case I actually have access to the original developer and we do have some time for an orderly hand-over.

Some background on the piece of code I will be inheriting:

It's functioning: There are no known bugs, but as performance requirements keep going up, some optimizations will become necessary in the not too distant future.

Undocumented: There is pretty much zero documentation at the method and class level. What the code is supposed to do at a higher level, though, is well-understood, because I have been writing against its API (as a black-box) for years.

Only higher-level integration tests: There are only integration tests testing proper interaction with other components via the API (again, black-box).

Very low-level, optimized for speed: Because this code is central to an entire system of applications, a lot of it has been optimized several times over the years and is extremely low-level (one part has its own memory manager for certain structs/records).

Concurrent and lock-free: While I am very familiar with concurrent and lock-free programming and have actually contributed a few pieces to this code, this adds another layer of complexity.

Large codebase: This particular project is more than ten thousand lines of code, so there is no way I will be able to have everything explained to me.

Written in Delphi: I'm just going to put this out there, although I don't believe the language to be germane to the question, as I believe this type of problem to be language-agnostic.

I was wondering how the time until his departure would best be spent. Here are a couple of ideas:

Get everything to build on my machine: Even though everything should be checked into source code control, who hasn't forgotten to check in a file once in a while, so this should probably be the first order of business.

More tests: While I would like more class-level unit tests so that when I will be making changes, any bugs I introduce can be caught early on, the code as it is now is not testable (huge classes, long methods, too many mutual dependencies).

What to document: I think for starters it would be best to focus documentation on those areas in the code that would otherwise be difficult to understand e.g. because of their low-level/highly optimized nature. I am afraid there are a couple of things in there that might look ugly and in need of refactoring/rewriting, but are actually optimizations that have been out in there for a good reason that I might miss (cf. Joel Spolsky, Things You Should Never Do, Part I)

How to document: I think some class diagrams of the architecture and sequence diagrams of critical functions accompanied by some prose would be best.

Who to document: I was wondering what would be better, to have him write the documentation or have him explain it to me, so I can write the documentation. I am afraid, that things that are obvious to him but not me would otherwise not be covered properly.

Refactoring using pair-programming: This might not be possible to do due to time constraints, but maybe I could refactor some of his code to make it more maintainable while he was still around to provide input on why things are the way they are.

Please comment on and add to this. Since there isn't enough time to do all of this, I am particularly interested in how you would prioritize.

Update: As the hand-over project is over I have expanded this list with my own experiences in this answer below.

答:
I would consider the most complicated, optimized-for-performance parts first. I would get him to first document those parts and explain them to you one at a time, then I would try to write tests against those parts (incuding before and after performance tests, so you can see if a new optimization makes things better or worse) and have the other person review the tests. This way, he documents and explains, you use the explanation to write tests (while he is documenting a different area), and his review will help make sure you understood what you should be be testing. That way you also get additional test converage for some of the most critical parts of the application and documentation of the specialized performance optimizations.

If there is time after covering those, I would next go through a similar process with the parts of the application which have most frequently needed change through the years but which are not in the first group of things documented.

Then document anything that's left.

OwnerDisplayName: PersonalNexus

OwnerDisplayName: HLGEM


答:
As you have access to the developer you code ask:-

Which modules were the most difficult to code/implement. What were the problems and how were they overcome.

Which modules have generated the most bugs.

Which modules have resulted in the most difficult to solve bugs.

Which bits of code he is most proud off.

Which bits of code he would really like to refactor, but, has not had the time.

These questions will give you an insight into whats going to cause you the most problems, and, perhaps more importantly a handle on the thought processes and perspectives original developer.

Title: Best Practices for Handing over Legacy Code

Body:
In a couple of months a colleague will be moving on to a new project and I will be inheriting one of his projects. To prepare, I have already ordered Michael Feathers' Working Effectively with Legacy Code.

But this books as well as most questions on legacy code I found so far are concerned with the case of inheriting code as-is. But in this case I actually have access to the original developer and we do have some time for an orderly hand-over.

Some background on the piece of code I will be inheriting:

It's functioning: There are no known bugs, but as performance requirements keep going up, some optimizations will become necessary in the not too distant future.

Undocumented: There is pretty much zero documentation at the method and class level. What the code is supposed to do at a higher level, though, is well-understood, because I have been writing against its API (as a black-box) for years.

Only higher-level integration tests: There are only integration tests testing proper interaction with other components via the API (again, black-box).

Very low-level, optimized for speed: Because this code is central to an entire system of applications, a lot of it has been optimized several times over the years and is extremely low-level (one part has its own memory manager for certain structs/records).

Concurrent and lock-free: While I am very familiar with concurrent and lock-free programming and have actually contributed a few pieces to this code, this adds another layer of complexity.

Large codebase: This particular project is more than ten thousand lines of code, so there is no way I will be able to have everything explained to me.

Written in Delphi: I'm just going to put this out there, although I don't believe the language to be germane to the question, as I believe this type of problem to be language-agnostic.

I was wondering how the time until his departure would best be spent. Here are a couple of ideas:

Get everything to build on my machine: Even though everything should be checked into source code control, who hasn't forgotten to check in a file once in a while, so this should probably be the first order of business.

More tests: While I would like more class-level unit tests so that when I will be making changes, any bugs I introduce can be caught early on, the code as it is now is not testable (huge classes, long methods, too many mutual dependencies).

What to document: I think for starters it would be best to focus documentation on those areas in the code that would otherwise be difficult to understand e.g. because of their low-level/highly optimized nature. I am afraid there are a couple of things in there that might look ugly and in need of refactoring/rewriting, but are actually optimizations that have been out in there for a good reason that I might miss (cf. Joel Spolsky, Things You Should Never Do, Part I)

How to document: I think some class diagrams of the architecture and sequence diagrams of critical functions accompanied by some prose would be best.

Who to document: I was wondering what would be better, to have him write the documentation or have him explain it to me, so I can write the documentation. I am afraid, that things that are obvious to him but not me would otherwise not be covered properly.

Refactoring using pair-programming: This might not be possible to do due to time constraints, but maybe I could refactor some of his code to make it more maintainable while he was still around to provide input on why things are the way they are.

Please comment on and add to this. Since there isn't enough time to do all of this, I am particularly interested in how you would prioritize.

Update: As the hand-over project is over I have expanded this list with my own experiences in this answer below.


答:
Keep in mind that Java was developed in 1991-1995 when C++ was a much different language.  Exceptions (which made RAII necessary) and templates (which made it easier to implement smart pointers) were "new-fangled" features.  Most C++ programmers had come from C and were used to doing manual memory management.

So I doubt that Java's developers deliberately decided to abandon RAII.  It was, however, a deliberate decision for Java to prefer reference semantics instead of value semantics.   Deterministic destruction is difficult to implement in a reference-semantics language.

So why use reference semantics instead of value semantics?

Because it makes the language a lot simpler.

There is no need for a syntactic distinction between Foo and Foo* or between foo.bar and foo->bar.

There is no need for overloaded assignment, when all assignment does is copy a pointer.

There is no need for copy constructors. (There is occasionally a need for an explicit copy function like clone().  Many objects just don't need to be copied.  For example, immutables don't.)

There is no need to declare private copy constructors and operator= to make a class noncopyable.  If you don't want objects of a class copied, you just don't write a function to copy it.

There is no need for swap functions.  (Unless you're writing a sort routine.)

There is no need for C++0x-style rvalue references.

There is no need for (N)RVO.

There is no slicing problem.

It's easier for the compiler to determine object layouts, because references have a fixed size.

The main downside to reference semantics is that when every object potentially has multiple references to it, it becomes hard to know when to delete it.  You pretty much have to have automatic memory management.

Java chose to use a non-deterministic garbage collector.

Can't GC be deterministic?

Yes, it can.  For example, the C implementation of Python uses reference counting.  And later added tracing GC to handle the cyclic garbage where refcounts fail.

But refcounting is horribly inefficient.  Lots of CPU cycles spent updating the counts.  Even worse in a multi-threaded environment (like the kind Java was designed for) where those updates need to be synchronized.  Much better to use the null garbage collector until you need to switch to another one.

You could say that Java chose to optimize the common case (memory) at the expense of non-fungible resources like files and sockets.  Today, in light of the adoption of RAII in C++, this may seem like the wrong choice.  But remember that much of the target audience for Java was C (or "C with classes") programmers who were used to explicitly closing these things.

But what about C++/CLI "stack objects"?

They're just syntactic sugar for Dispose (original link), much like C# using.  However, it doesn't solve the general problem of deterministic destruction, because you can create an anonymous gcnew FileStream("filename.ext") and C++/CLI won't auto-Dispose it.

ContentLicense: CC BY-SA 4.0


答:
There is already an excellent answer by Aaronaught, but since there were other answers, now removed, which were totally wrong about what a non-functional requirement is, I think it would be useful to add a few explanations to avoid the mistakes about what a non-functional requirement is.

A non-functional requirement is "a quality or property that the product must have" ¹. James Taylor tells that a non-functional requirement "[...] is [nonetheless] a requirement, and it is important to the customer—sometimes even more important than a functional requirement". He then gives two examples: the logo of the product, and the accuracy and reliability of the equipment. Those both examples show very well that:

The non-functional requirements are not a marketing jibber-jabber like: "Internet is important nowadays and we wanna have a website".

The non-functional requirements concern the customers, since they can heavily impact their productivity and the ability itself to use the product.

The non-functional requirements are totally objective.

The last point is essential. If the requirement is subjective, it has nothing to do in the list of requirements. It would be impossible to build validation tests from something which is subjective. The sole purpose of the list of requirements is to enumerate the non-ambiguous expectations of the customer. "I want this square to be red" is a requirement. "I want this square to have a nice color" is a wish which requires explanation.

Remember that the list of requirements is like a contract (and in most cases is a part of a contract). It is signed by the customer and the development company, and in a case of a litigation, it will be used legally to determine if you've done your work correctly. What if I order you a software product, specify that "the product must be great", and refuse to pay when the product is done, because for me, what you've actually done is not a great product?

So, let's see some examples.

  1.  The software product is responsive to the end user.

This is not a requirement. Not a functional. Not a non-functional. It's just not a requirement. At all. It has zero value. You can't check if the software system meets this requirement during validation testing. Neither you — the QA department, nor the customer.

  2.  The reloading of the user statistics performs 90% of the time below 100 ms. when tested on machine with the performances specified in appendix G part 2 and the load below 10% for the CPU, below 50% for memory and no active R/W disk operations.

It is a requirement. If the appendix G part 2 is precise enough, I can take the machine with the similar hardware and perform the validation test in QA department, and I will always obtain a binary result: passed or failed.

Is it a functional requirement? No. It does not specify what the system must do. There were probably a functional requirement before, specifying that the software application must be able to reload user statistics.

Is it a non-functional requirement? It is. It specifies a property that a product must have, i.e. the maximum/average response time, given the percentage threshold.

  3.  The application is written in C#.

Is this a requirement? We don't really know without a context. It might be a wish of the lead developer, who wants, by inserting this requirement, to avoid later a discussion with his colleagues about the language to use. It might also be a requirement based on hardware/software, legacy or compatibility elements. We don't know.

  4.  The C# codebase of the product follows Microsoft Minimum Recommended Rules and Microsoft Globalization Rules.

This is a strange thing. Personally, I would rather not call it a requirement, and put it into a separate document specifying the standards and best practices.

  5.  The main window of the application has a blue (#00f) 10px border with pink (#fcc) filled circles, those circles being placed at the inner edge of the border and being 3px in diameter, separated by 20px from each other.

It is a requirement, and a non-functional one. It specifies something we may test during validation testing, and it specifies a property of the product, not what the product is intended to do.

  6.  The vehicle tracking system measures the speed with a precision of ±0.016 mph.

Also a non-functional requirement. It gives a measurable threshold of the precision of the system. It doesn't tell what the system must do, but tells how precise is it doing its work. But wait? It tells that the vehicle tracking system measures the speed, isn't it? So it's a functional requirement too? Well, no, since we put an accent on the precision of the measurement, not on the fact that the measurement is done.

  7.  The vehicle tracking system measures the speed of the vehicle.

Now it's a functional requirement. It doesn't tell how the system works, but what it's doing. Through functional requirements, we could learn that the vehicle tracking system measures the speed, the battery power, the pressure of I don't know what and if the lights are on or not.

  8.  The pages of the website take 850 ms. to load.

This is not a requirement. Is tries to be one, but is totally invalid. How would you asset this? What pages? All? Tested through a local 1Gbps network on a quad-core client machine and a eight-core server with SSDs used at 2%, or through a modem of a old and crappy laptop while the website is being hosted by a small server used at 99%? What is meant by "to load"? Does it mean downloading the page? Downloading and displaying it? Sending the POST request with some large data, then loading the response and displaying it?

To conclude, a non-functional requirement is always a requirement, which means that it describes something which is totally objective and can be checked through an automated or manual validation test, but instead of telling what the system is doing, it explains how the system is doing something or how the system is itself.

¹ Managing Information Technology Projects: Applying Project Management Strategies to Software, Hardware, and Integration Initiatives, James Taylor, ISBN: 0814408117.


答:
I think the best way to grok some large code is top-down approach. Try to understand the big picture first, and then gradually dig deeper into components one by one.

Now at each level of digging, ask him to prioritize the parts that need most attention. Have him explain you as much as possible, but always document it yourself.

The best part about documenting it yourself is that when you'll come back later, you'll have no problem recollecting the same cognitive state you were in, when he explained it to you. You can far more easily understand what you wrote than what someone else did. In my experience two people documenting the same piece of code don't produce similar looking pieces of text.

This, I guess also solves your "what & how to document" issues. When he explains you everything, you can then decide yourself what you'll wish were documented when you return to the code -- and document only those parts.

The idea is to first completely understand the code (in his presence), and then write/do everything that will make it possible for you to grok it later (in his absence).

By completely understanding the code I mean you need to get a feel of the big picture -- and how each component relates to this big picture. I've found it particularly helpful to keep track of how each piece adds up the whole. Don't try to comprehend anything in isolation -- never lose the sight of it's context.

Lastly, once you have done the above, proactively take the control. Decide yourself what pieces you need unit-test coverage for. what parts need to be (or can be) optimized, how can you refactor some component, etc. Trust that if you know the system, you can take all the decisions once he is gone.


问:
Should you use C# and F# together
I know you can use C# and F# together in the same project however I'm not sure if its a good idea to do so.

It seems to me that mixing two very different coding styles (functional vs OOP) could cause a lack of cohesion in the design. Is this correct?

答:
Yes I agree with ChrisF.  Also C# currently already incorporates F# principles, such as anonymous types:

```<code>var unitanon = new[]
{
    new { Field1="new car", Field2 = 1},
    new { Field1="old car", Field2 = 20}
};
</code>```

That said, I personally think it's a step backward in code readability, though it is very convenient.

Title: Should you use C# and F# together

Body:
Yes I agree with ChrisF.  Also C# currently already incorporates F# principles, such as anonymous types:

var unitanon = new[]
{
    new { Field1="new car", Field2 = 1},
    new { Field1="old car", Field2 = 20}
};

That said, I personally think it's a step backward in code readability, though it is very convenient.