答:
All those books seem very, very, very old. Don't you think there's a difference between nowadays and when those book were written?

IMHO it is not a surprise that very good books stay popular over decades - that shows how good they are. But I think I can tell you something for each of the candidates you listed:

```<code>Code complete: 2nd edition = may, 2004
</code>```

Actually the first edition of "Code complete" was from 1993, so this one is really a "classic". It is about basic coding style, using examples which apply to almost every programming language of the C family, which contains the most popular languages nowadays (C/C++/Java/C#/Objective-C/D/...). So yes, this book is up-to-date.

```<code>Introduction to algorithms (Cormen, Leiserson, Rivest, Stein)
</code>```

Well, I actually did not read that book (my algorithms text book was from "Sedgewick"), but learning algorithms and algorithm construction is really language agnostic. Of course, this craft is getting some underrating the last years since you find many basic algorithms nowadays in standard libraries, but IMHO every professional programmer should have some basic knowledge in this field.

```<code>The Pragmatic Programmer
</code>```

This is a very good book about programming as a craftmanship. Language agnostic and very, very up-to-date, as long as programming is done by programmers as a manual task, using text editors, IDEs, version control etc.

```<code>Structure and Interpretation of Computer Programs: = September 1, 1996
</code>```

This is my personal favorite, even though (or perhaps because) the book uses Scheme to teach you the differences between different programming paradigms. I don't know any other book which has such a strong focus on building abstractions. And building abstractions is a key ability which make the difference between a mediocre programmer and a top programmer - that has not changed the last decades, so really, this book is timeless. Furthermore,  functional languages and language elements have become more popular recently, so IMHO the ideas presented in this book got a renaissance.

```<code>The C Programming Language
</code>```

Well, this book may be not so timeless as the other four. But since C is something like the "mother" of all those popular languages I listed above, it may be a good idea to read this book either - I don't think there some modern "C" books which are really better. And if you have to do maintenance programming of C++ code which was written by someone who knew C better that C++, then this book is a must.

Finally, you were asking for books that take more of the "current reality" into account, without being too technology specific. So what is the "current reality" and what has changed on the "non-technology" side? Here are some points from the last decade, without saying that this list is complete or having the right priorites.

There exist more legacy code (especially more legacy code not only in Fortran and Cobol, but also in C++ and Java).

Unit testing and TDD has become more favorite.

There is much more open source code available.

OO has gotten more and more critics

(I don't list here anything about Web or App development, because I think this technology specific).

There exist good books for topics 1 and 2, especially "Clean Code", which is from 2008, and "Working effectively with legacy code" from 2004. Perhaps those are some of the "newer" books you are looking for?

Body:
All those books seem very, very, very old. Don't you think there's a difference between nowadays and when those book were written?

IMHO it is not a surprise that very good books stay popular over decades - that shows how good they are. But I think I can tell you something for each of the candidates you listed:

Code complete: 2nd edition = may, 2004

Actually the first edition of "Code complete" was from 1993, so this one is really a "classic". It is about basic coding style, using examples which apply to almost every programming language of the C family, which contains the most popular languages nowadays (C/C++/Java/C#/Objective-C/D/...). So yes, this book is up-to-date.

Introduction to algorithms (Cormen, Leiserson, Rivest, Stein)

Well, I actually did not read that book (my algorithms text book was from "Sedgewick"), but learning algorithms and algorithm construction is really language agnostic. Of course, this craft is getting some underrating the last years since you find many basic algorithms nowadays in standard libraries, but IMHO every professional programmer should have some basic knowledge in this field.

The Pragmatic Programmer

This is a very good book about programming as a craftmanship. Language agnostic and very, very up-to-date, as long as programming is done by programmers as a manual task, using text editors, IDEs, version control etc.

Structure and Interpretation of Computer Programs: = September 1, 1996

This is my personal favorite, even though (or perhaps because) the book uses Scheme to teach you the differences between different programming paradigms. I don't know any other book which has such a strong focus on building abstractions. And building abstractions is a key ability which make the difference between a mediocre programmer and a top programmer - that has not changed the last decades, so really, this book is timeless. Furthermore,  functional languages and language elements have become more popular recently, so IMHO the ideas presented in this book got a renaissance.

The C Programming Language

Well, this book may be not so timeless as the other four. But since C is something like the "mother" of all those popular languages I listed above, it may be a good idea to read this book either - I don't think there some modern "C" books which are really better. And if you have to do maintenance programming of C++ code which was written by someone who knew C better that C++, then this book is a must.

Finally, you were asking for books that take more of the "current reality" into account, without being too technology specific. So what is the "current reality" and what has changed on the "non-technology" side? Here are some points from the last decade, without saying that this list is complete or having the right priorites.

There exist more legacy code (especially more legacy code not only in Fortran and Cobol, but also in C++ and Java).

Unit testing and TDD has become more favorite.

There is much more open source code available.

OO has gotten more and more critics

(I don't list here anything about Web or App development, because I think this technology specific).

There exist good books for topics 1 and 2, especially "Clean Code", which is from 2008, and "Working effectively with legacy code" from 2004. Perhaps those are some of the "newer" books you are looking for?


问:
Is there an expiration date for well regarded, but old books on programming?
After reading a question about books every programmer should read, I wonder if the following should be considered obsolete:

Code complete: 1st edition in 1993; 2nd edition in May, 2004

Introduction to algorithms (Cormen, Leiserson, Rivest, Stein): 1st edition in 1990; 2nd edition in September, 2001; 3rd edition in 2009

The Pragmatic Programmer: October, 1999

Structure and Interpretation of Computer Programs: 1st edition in 1984; 2nd edition in September, 1996

The C Programming Language: 1st edition in 1978; 2nd edition in April, 1988

All these books seem very old. Isn't there a difference between modern computing and what was current when those book were written?

For example, my 61-year-old teacher explains things very nicely but forgets to take into account all that has been done between when he began to teach 25 years ago and now.

Isn't the same true for those books? Aren't there any more modern books that teach principles and technologies that are closer to current practice? Or do you consider them to be useful and relevant even today?

答:
One of the things you need to realize is that there exists underlying principles which are essentially timeless, and implementations which tend to come and go.

The underlying principles are essentially all the boring theory that Computer Science tends to spend a lot of time on, and that keeps being valid even if the  world changes around it.  This as opposed to things like "How to use Win32s under Windows 3.11" which is very old and outdated.

To put things in perspective - the canonical text on geometry is two thousand years old.  Most math taught up to college level is at least 300 years old.  Only reason the CS books aren't older, is because the field is still new.

ContentLicense: CC BY-SA 3.0


问:
How to measure time lost due to environment problems?
I'm trying to determine how we can measure how much time the developers are loosing to poorly managed environment and inefficient ways-of-working.

The goals are:

Show managment how big the problem really is, in terms they can relate to. I.e $$$

Get a good baseline so that we can measure the progress.

Short background:

We manage the programming environment for 500 developers. This includes IDE (mainly Eclipse and Visual Studio), version control systems (ClearCase), what programs they have available.
Basically, everything related to the computer that involves programming.

Examples:

Not being able to work with tools they are used to due to strict security requirements.
Using version control system in a bad way causing problems when working in parallell.
Setting up project environment is done manually and different each time.
Using homecooked frameworks, rather than what are industry standard.
Building takes longer than needed due to homemade practices.
Deploying takes longer than needed due to homemade practices.

This does not include the actual coding pratices, project management or meetings. Sure, we can influence those things too, but for this questions those things are out of scope.

The question:

So, how can we determine how much time are lost due to the project environment?

The only thing I can think of to get some good data are polls and questionnaires.

Have anyone done something like this? What were the experiences and results?

Are there other literature or reasearch where I can get ideas from or compare results with?

Other questions exists regarding programmers inefficiency (like this), but those relate to coding practices and bugs.

答:
What it appears that you're doing is attempting to measure productivity. Measuring productivity is notoriously difficult. Here's how I go about it...

I've found that you don't want to tackle the situation by measuring losses, you want to measure the gains of potential solutions. From a purely philosophical point of view, the former implies that you're doing something wrong, which may not be true.

Things change, and periodically, someone (like yourself, it seems) needs to take a look at the landscape and see if those changes can provide a better environment. With that said, I look at:

Things That Don't Exist

Tools (e.g. computers, version control)

Practices (e.g. TDD)

Processes (e.g. code reviews, agile)

This is a common problem and I've successfully argued in favour of adopting certain things based on:

Product Documentation and Sales Information

This is always the first place to start. If the product costs money, the sales documentation is almost always targeted or worded for management types. It's easy to find, easy to access, and a human that works for the vendor is almost always available to provide other resources like the following...

Case Studies

A good example I have is the book "Best Kept Secrets of Peer Code Review" was written by Jason Cohen (founder of Smart Bear IIRC) contains case studies in order to make the case for code reviews. Sure, the book was basically written by the vendor, but the case studies were legitimate.

Proofs of Concept

If it's a potential implementation (thinking CI, build system, TCM, or any other process or automation facilitating tool) then the best way to go about it is to get a trial and set it up. After performing some initial investigation (ie, using it on fake projects) it might be a good idea to try it out in a small project, or possibly in tandem with the existing solution.

For processes, it's similar. This is basically the way that a lot of developers introduce unit testing. They maintain their own tests for a while, and when the critical "BAM! Regression Caught!" scenario hits, they perform the reveal and show how it saved the project. A little dramatic, yes, but it makes sense. People need to see the benefit with their own eyes.

Things That Exist but are Broken/Inefficient

This will almost always be a comparative analysis. If you approach it that way, then you should be able to get numbers to work with.

Sales info from the vendor doesn't always work well here, unless it's a product that directly and obviously competes with the currently implemented solution - in that case, you can usually get the vendor to help you out here. (I'm thinking SourceGear Vault vs. SourceSafe as an example)

I've found that case studies rarely exist that compare tools/practices but do exist for processes (think Agile vs. Waterfall studies).

In my experience, proofs of concept are often the most successful ways of converting management/developers from one tool or practice to another. They have to see it working, and more importantly, see it working better than what already exists. Then you hit them with the numbers. "This system, which is only a POC, is still x times faster than our previous one. That translates to y reduced man-hours of work and z reduced overhead" Remember that POCs can sometimes be done on small projects to test out a process, usually after sufficient evidence of potential gains has been given.

Things That We Have No Idea About

Here's where your polls and questionnaires come into play... but these will lead you to the categories outlined above.


问:
How are software tests done at tech startups?
I've seen a lot research articles and tech blogs that boast the benefits of software testing. I've convinced on that. But since all the software testing research are conducted by large software companies, I do not believe they really apply to startups. Since startups have different needs and constraints compared to large software companies.

So this raised the questions. Should tech startups write automated tests? If so, are they done in the same manner as the large software companies? (smoke test, regression test, etc.) It's best if you can refer some research articles on this subject..since I was unable to find any on my own.

(I must admit that even though I'm still early in my career, but I have yet to see a startup that's seriously committed to writing automated tests)

答: It's not about of who should be doing software testing, Software testing it's kind of a software development philosophy. Software Testing set the basis of a good software quality, and in a startup, software quality is a bonus when the acquisition by a large firm is around the corner;)</p>


答:
There is always a conflict between what should be done and what we realistically have time for.  Yes many startups forgo test driven development and automated testing to shave some time off to get a project up and running.

The social networking sites and mobile app companies are the big bubbles now, and they are fiercely competitive.  Sometimes the difference between going live in 4 months versus 5 months means You Lose.

Time to market is key, and then if success happens then it is time to scale, then there will be plenty of time to refactor your piece-of-crap untested software into something worthwhile.

Title: How are software tests done at tech startups?

Body:
I've seen a lot research articles and tech blogs that boast the benefits of software testing. I've convinced on that. But since all the software testing research are conducted by large software companies, I do not believe they really apply to startups. Since startups have different needs and constraints compared to large software companies.

So this raised the questions. Should tech startups write automated tests? If so, are they done in the same manner as the large software companies? (smoke test, regression test, etc.) It's best if you can refer some research articles on this subject..since I was unable to find any on my own.

(I must admit that even though I'm still early in my career, but I have yet to see a startup that's seriously committed to writing automated tests)


答: Best practices are industry wide, whether you are making grandma a website or creating the guidance system for a satellite. They should always be followed by those that want to consider themselves professional, that is why they are called BEST practices.</p>


问:
Single responsibility principle - am I overusing it?
For reference - http://en.wikipedia.org/wiki/Single_responsibility_principle

I have a test scenario where in one module of application is responsible for creating ledger entries. There are three basic tasks which could be carried out -

View existing ledger entries in table format.

Create new ledger entry using create button.

Click on a ledger entry in the table (mentioned in first pointer) and view its details in next page. You could nullify a ledger entry in this page.

(There are couple more operation/validations in each page but fore sake of brevity I will limit it to these)

So I decided to create three different classes -

LedgerLandingPage

CreateNewLedgerEntryPage

ViewLedgerEntryPage

These classes offer the services which could be carried out in those pages and Selenium tests use these classes to bring application to a state where I could make certain assertion.

When I was having it reviewed with on of my colleague then he was over whelmed and asked me to make one single class for all. Though I yet feel my design is much clean I am doubtful if I am overusing Single Responsibility principle

答:
There are three reasons to invoke SRP as a reason to split a class:

so that future changes in requirements can leave some classes unchanged

so that a bug can be isolated more quickly

to make the class smaller

There are three reasons to refuse to split a class:

so that future changes in requirements won't cause you to make the the same change in multiple classes

so that bug-finding won't involve tracing long paths of indirection

to resist encapsulation-breaking techniques (properties, friends, whatever) that expose information or methods to everyone when they are only needed by one related class

When I look at your case and imagine changes, some of them will cause changes to multiple classes (eg add a field to ledger, you'll need to change all three) but many will not - for example adding sorting to the list of ledgers or changing the validation rules when adding a new ledger entry. Your colleague's reaction is probably because it's hard to know where to look for a bug. If something looks wrong on the list of ledgers, is it because it was added wrongly, or there's something wrong with the list? If there's a discrepancy between the summary and the details, which is wrong?

It's also possible your colleague thinks that the changes in requirements that mean you'll have to change all three classes are far more likely than that changes where you'd get away with changing only one. That could be a really useful conversation to have.


答:
Here are some more very old and out-of-date books:

The Art of Computer Programming, vol. 1-3 by D. Knuth. These were
published between 1968 and 1981! We are not using vacuum tubes
anymore, people! Everything in these books are lame. Where is the
discussion on Python and Ruby?

Computers and Intractability: A Guide to the Theory of
NP-Completeness by M. R. Garey and D. S. Johnson, 1979. Super lame!
All these problems have been solved by now, probably.

If a book wasn't written in the last three years with focus on Python, then it's not worth reading.

Title: Is there an expiration date for well regarded, but old books on programming?

Body:
After reading a question about books every programmer should read, I wonder if the following should be considered obsolete:

Code complete: 1st edition in 1993; 2nd edition in May, 2004

Introduction to algorithms (Cormen, Leiserson, Rivest, Stein): 1st edition in 1990; 2nd edition in September, 2001; 3rd edition in 2009

The Pragmatic Programmer: October, 1999

Structure and Interpretation of Computer Programs: 1st edition in 1984; 2nd edition in September, 1996

The C Programming Language: 1st edition in 1978; 2nd edition in April, 1988

All these books seem very old. Isn't there a difference between modern computing and what was current when those book were written?

For example, my 61-year-old teacher explains things very nicely but forgets to take into account all that has been done between when he began to teach 25 years ago and now.

Isn't the same true for those books? Aren't there any more modern books that teach principles and technologies that are closer to current practice? Or do you consider them to be useful and relevant even today?


答:
The core principles of software haven't changed in the past 20 years. A stack, a tree and a linked list still work the same as they did back then. "XOR" still means the same thing. A byte still has 8 bits.

Are you seriously suggesting that "multiplatform development" is a new idea? Why do you think C was invented?

"Cloud" is a marketing buzzword. It used to mean something sort-of-specific, but it's been debased through overuse. Nowadays, anytime you have something that talks to a remote server over a network, the marketers stick the "cloud" label on it. So there's really no point in talking about it, because it's a meaningless word.

I don't know your 61 year old professor, so I can't vouch for him. You, on the other hand, are clearly not as smart as you think you are. Listen to the professor, it's possible you'll learn something.

"You don't get to be old by being no fool. A lot of young wise men, they dead as a motherfucker." - Richard Pryor


答:
Yes startups sometimes cut corners and dont impliment proper testing. Sometimes this is apropriate (for small enough projects or when time/money are critical)

This isnt exclusive to startups though. One of our suppliers IT contractors dosent even have a test environment. Everything is done straight to live and this is a large multi national software company (scary!)


答:
Those books are not obsolete, those books are classics.

To quote Kaplansky, "spend some time every day learning something new that is disjoint from the problem on which you are currently working (remember that the disjointness may be temporary), and read the masters."


答:
Should they? Yes. Do they do so in practice, not as often as they should.

The most typical reason given is a lack of resources which includes developer time, the cost of hiring a dedicated or part-time tester, the cost of setting up a testing environment and so forth. You can even find these excuses in large corporate settings as well as small start-ups.

Looking at in another way, testing is one of the easiest things to cut from a development schedule, especially one with very tight time pressure and/or cost pressure to produce visible results. Along with detailed design work, it's considered 'fluff' by many managers and the first place they'll say "cut it so we can make our schedule and budget work" followed by "Why aren't you coding?".

In some companies, there will be someone who does push testing. Usually this will be the developer hired and usually they'll be someone with experience and probably someone who has a financial stake of some kind in the company. A company that starts with this "DNA" will probably do testing from the start.


问:
Does command/query separation apply to a method that creates an object and returns its ID?
Let's pretend we have a service that calls a business process. This process will call on the data layer to create an object of type A in the database.

Afterwards we need to call again on another class of the data layer to create an instance of type B in the database. We need to pass some information about A for a foreign key.

In the first method we create an object (modify state) and return it's ID (query) in a single method.

In the second method we have two methods, one (createA) for the save and the other (getId) for the query.

```<code>    public void FirstMethod(Info info)
    {
        var id = firstRepository.createA(info);
        secondRepository.createB(id);
    }

    public void SecondMethod(Info info)
    {
        firstRepository.createA(info);
        var key = firstRepository.getID(info);
        secondRepository.createB(key);
    }
</code>```

From my understanding the second method follows command query separation more fully. But I find it wasteful and counter-intuitive to query the database to get the object we have just created.

How do you reconcile CQS with such a scenario?

Does only the second method follow CQS and if so is it preferable to use it in this case?

答:
If you follow a methodology and it seems to take you down bad paths, you should reevaluate it.

I see that the identifier of a newly created object is a valid thing to have as a return parameter- it is not just convenient, but it's also "good"- as you can see code is better when it does.

In any case, I'm not familiar with "command query separation" but I highly doubt that it disallows commands from returning information about the command execution, and if it does, just trash it- success/failure is always there, and I do not think that "your object was created OK" from "your object was created OK and its id is xxx" to be much different.


答:
Software testing isn't a religion. It's just a very good idea.

You say you don't have the manpower to write tests right now? OK, fine. 6 weeks from now, are you gonna have the manpower to find the bug that's crashing your application, which would have been found immediately if you had proper tests in place?

Too much testing can slow down development. Too little testing can also slow it down. You have to find the right balance, and it's usually hard to tell where that is. And none of this is specific to large or small companies.


问:
Correct For Loop Design
What is the correct design for a for loop?

Felix currently uses

```<code>if len a > 0 do
  for var i in 0 upto len a - 1 do
    println a.[i];
  done
done
</code>```

which is inclusive of the upper bound. This is necessary to support the full range of values of a typical integer type. However the for loop shown does not support zero length arrays, hence the special test, nor will the subtraction of 1 work convincingly if the length of the array is equal to the number of integers.
(I say convincingly because it may be that 0  - 1 = maxval: this is true in C for unsigned int, but are you sure it is true for unsigned char without thinking carefully about integral promotions?)

The actual implementation of the for loop by my compiler does correctly handle 0 but this requires two tests to implement the loop:

```<code>continue:
  if not (i <= bound) goto break
  body
  if i == bound goto break
  ++i
  goto continue
break:
</code>```

Throw in the hand coded zero check in the array example and three tests are needed.

If the loop were exclusive it would handle zero properly, avoiding the special test, but there'd be no way to express the upper bound of an array with maximum size.

Note the C way of doing this:

```<code>for(i=0; predicate(i); increment(i))
</code>```

has the same problem. The predicate is tested after the increment, but the terminating increment is not universally valid!

There is a general argument that a simple exclusive loop is enough: promote the index to a large type to prevent overflow, and assume no one will ever loop to the maximum value of this type.. but I'm not entirely convinced: if you promoted to C's size_t and looped from the second largest value to the largest you'd get an infinite loop!

答:
Does Felix support break/continue? Implementing them correctly might affect how you approach things.

My C approach would start thus:

for(int i = 0; i<len(a); i++) {
    // do stuff
  }

As you have noted, this breaks when a hits the int limit. A possible answer is to check before the increment, so we avoid increments that overflow, but we need to check before the increment, because if len(a) == 0, we do not want to execute the body. The following solves the problem:

id: for(int i = 0; i<len(a); i++) {
    // do stuff
    if(i == len(a) - 1) {
      break id;
    }
  }

, where id is a unique label. However this is inefficient, because the for check is redundant for all iterations except the first. At this step, it's tempting to use a while loop, but note that a C for loop is not exactly equivalent to a while loop, as breaks/continues work differently (wrt. to execution of the increment). The simplest transformation I can think that preserves these semantics is

if( len(a) > 0 ) {
    id: for(int i = 0; ; i++) {
      // do stuff
      if(i == len(a) - 1) {
        break id;
      }
    }
  }

Title: Correct For Loop Design


问:
How can I inspire engineers to positively conduct telephone interviews
Our (mid-size) company (with 150 employees) has witnessed considerable growth since last year, and as a result we have been conducting lots of interviews to hire more and more engineers to bring new projects in motion.

To begin with, following is our interview process

Screening resume by HR

Telephone technical interview (conducted by senior engg)

Final technical + HR interview (conducted by team-lead/PM)

After some analysis we found that telephone interviews are not really becoming effective, due to which we are not able to find good number of engineers in final interview. My analysis revealed that engineers don't consider interviewing as important/serious activity, since it's internal and non-billable. Also I see that engineers don't find it really prestigious to carry a label of "interviewer" (at-least telephone interviewer). We do have  set of good experienced engineers in company who can take any interview very effectively, but since number of telephonic interviews is large, this pool is not sufficient. Hence we try to use other engineers as well.

What can be done to inspire engineers to conduct telephone interviews seriously and positively (not treating this as mundane job)?

[Update-2011/12/28]

Thanks for sharing your valuable opinions. It really helped me to look at problem from variety of different angles. Alongside I was discussing issues with few colleagues as well and I personally feel that there is no single silver bullet for such issue. I will need to think recruitment process as a whole unit and plan to improve different areas/stages in it.

答:
For the phone screen, you really only need to ask a few questions to see whether the candidate is capable of being a productive team member. I'm assuming that you are not looking for junior developers that can be trained (I would argue this is the best approach in the long run, but not all companies are setup to take advantage of it).

Pick three questions that only an experienced developer would know for your given framework/language. For example in C#, I like to lead off with "what's the difference between a struct and a class" or "What's the appropriate way to handle unmanaged resources?"

These are questions that you can't really fake through unless you understand the framework well. Sometimes, it requires digging beyond what you might even need to do on a day to day basis. They are good indicators that the candidate is a self-starter, meaning they try to learn on their own above and beyond the call of duty.

Granted, they also might weed out a good candidate who just happened not to have discovered that particular area of C# (that's why I ask three questions...missing one or even two might not be so bad, missing all three probably means the candidate isn't up to snuff).

Provide the phone screener with a list of 3 questions to ask (along with the general, tell me about your experience). Make sure the questions are good screeners and not necessarily detailed "how well have you memorized the framework" questions.

Your job is to fail fast on a bad candidate so you don't waste time on a face to face.

OwnerDisplayName: FutureProof


问:
Trade-offs of local vs remote development workflows for a web development team
We currently have SVN setup on a remote development server. Developers SSH into the server and develops on their sandbox environment on the server. Each one has a virtual host pointed to their sandbox so they can preview their changes via the web browser by connecting to developer-sandbox1.domain.com. This has worked well so far because the team is small and everyone uses computers with varying specs and OSs.

I've heard some web shops are using a workflow that has the developers work off of a VM on their local machine and then finally push changes to the remote server that hosts SVN. The downside to this is that everyone will need to make sure their machine is powerful enough to run both the VM and all their development tools. This would also mean creating images that mirror the server environment (we use CentOS) and have them install it into their VMs. And this would mean creating new images every time there is an update to the server environment.

What are some other trade-offs? Ultimately, why did you choose one workflow over the other?

答:
Local development > Local VM development > Remote VM development

Start with the first. If it doesn't satisfy, you might move right, but consider very carefully why are you doing it:

Huh, I cannot get version a.b.c of XXX for local dev boxes. Huh... is it an ancient version? Why don't you upgrade? Are you sure it still receives security updates?

Ermm.. production OS is different from what my devs can use. Are you sure that you cannot make your code more portable and it might be worthwhile? What if at some point you need to change your production OS (not likely, but it sometimes happens)?

... meaning: it's bad to tie yourself into very specific environments.

Local development is often faster, simpler, more convenient. Esp. using tools locally is normally much better (I think I'd be significantly hindered if I had to run Eclipse remotely, or give it up). But running your code in your own box often means faster turnaround, easier interactive graphical debugging and a lot other niceties.

Sometimes a VM is required, but unless you have no other option, it's good to avoid it.

There might also be performance reasons, but really, beefy machines for developers are great inversions- hardware is cheaper than people. Of course, you might be developing for a massively parallel cluster and you really cannot put one of these in each desk, but that's fairly uncommon.

All of this, of course, doesn't negate the need to have testing/QA environments which mimick as closely as possible production. But then, I'd say, even VMs might not cut it.


答: The computer science industry is still very young. Books written 30 years ago I consider to still be valuable and needed for complete understanding. Abstract concepts sometimes take awhile to digest.</p>


答:
Some books are timeless because they discuss ideas that are so fundamental to the practice of software development, they will always apply.

Take for example the Mythical Man Month, when I was reading this book, I kept forgetting that it was written in 1975. When he sprinkles in the occasional reference about IBM System 360, it always jars me because that is the only content that dates the book. Everything else applies here and now. I still keep my copy of Martin Fowler's Patterns of Enterprise Application Architecture, now 9 years old but again timeless and still applicable to the work I do today.

My favorite book right now is Peter Coad's Java Modeling in Color with UML (1999) even though I'm a C# developer and eschew UML, because the techniques and concepts make me a better coder.

We'd do well to learn from the first generation of developers because they've tread the ground we're walking right now and their hard earned wisdom can help us get a jump start on what we're doing/learning today.


问:
What are the causes that lead to an overbloated software?
Today I decided to perform a clean install for Creative Sound Blaster drivers, as they always start glitching all by themselves after some time. And that meant I had to go through the whole cleanup procedure. And that took me almost 2 hours..

And honestly, I can't see a reason why?! And although Creative, IMHO, is an absolute 1st place winner for producing poor quality software that never works, the bloat problem is not exclusive to them.

PC with Canon digital camera driver will have around 10 Canon entries that are interconnected with all sorts of connections. Visual Studio is also a prime example, there is around 50 or so entries for full install, and repairing that thing is only possible with complete nuking. And once it even managed to ruin the whole OS install when I was upgrading from VS2k8 to VS2k8SP1 or something. As it turns out 5GB of free space was not enough for 300Mb patch...

So this really seem to be a widespread problem. Almost every application nowadays usually contains unpackers, multiple spywarish "friends" that are installed, drivers are usually around 600Mb for everything including printers and so on.

But why? Is it developer fault? Applications like that are nightmare to support, they never work 100% nowadays, and almost all users I know are very negative about all that bloat they get as a mandatory driver install for USB thumb drive/Printer/Camera/Sound Card/Browser.

It seems that NSIS from Nullsoft is the only clean setup system that is not bloated, from what I know, for example, Firefox install. Clean, pretty much xcopy based install without any problems.

So why people are not using simple setups and applications that are not rooted over 30 layers of interconnection? Is it because developers are lazy? Use of codegen tools? Is it because corporations force heavyweight apps as something users will love? What's the cause, and is there a hope software will return back to basics someday? What are the steps to avoid writing bloat when you start new application from scratch?

答:
It is a vicious cycle where everyone in the cycles of despair can be blamed. One cycle of despair consists of the following steps:

Business people asks for bloated features.

Developers implement the bloated features even though they know that they shouldn't.

Customers pay for bloated features even though they only want the product but not the stupid feature.

Business people believe that customers want the bloated features.

Go to step one and repeat.

How do you stop it? There is no easy answer on how, but it is clear that in order to stop the cycle then one of the steps has to be broken. Thus it can only be broken either by business, developers or consumers taking a revolutionary action.


答:
Your last paragraph doesn't make much sense to me. If you use a signed int in the first place, then you make the assumption that your largest possible upper loop bound is the largest positive signed int value. If you use a larger type for your loop, then there won't be an overflow. If there could be an overflow, then by an upper loop bound larger than the maximum positive signed int value, which invalidates your initial assumption.

Additionally, do not assume that no one will ever do this or that. If you are in doubt for a specific loop, then test for it and explicitly express what you assume here.

```<code>assert(UINT_MAX > INT_MAX);

if ((unsigned int)len(a) <= INT_MAX) {
    for (unsigned int i = 0; i < len(a); i++)
}
else {
    Handle an unexpected situation here.
}
</code>```

EDIT (a bit too long for a comment to your comment):

Maybe you're looking at the problem from the wrong direction? Note that C's for loop isn't exclusive by itself. It is just often used this way because of the 0-based array indexing. Nothing stops you from using it inclusive:

```<code>for (i = 0; i <= len(a)-1; i++)
</code>```

In fact, nearly any expression can be used for the three parts, because it is more syntactic sugar than its own command, so you can as well use it to iterate through a linked list:

```<code>for (p = start; p != NULL; p = p->next)
</code>```

So you could first define what you expect from your for loops? Should they be strictly bound to numerical operations? Then you could as well provide them with "growing" ints that never overflow and are automatically scaled up to bigints, according to the needs. Or you could define that 0-1 is always treated as -1, so you have for i in 0 upto -1 which won't execute at all and saves you the additional check for 0.

What's the intended purpose of your language? Is there really a need for me as a programmer to care about the exact types used in the for loop?

Title: Correct For Loop Design

Body:
What is the correct design for a for loop?

Felix currently uses

```<code>if len a > 0 do
  for var i in 0 upto len a - 1 do
    println a.[i];
  done
done
</code>```

which is inclusive of the upper bound. This is necessary to support the full range of values of a typical integer type. However the for loop shown does not support zero length arrays, hence the special test, nor will the subtraction of 1 work convincingly if the length of the array is equal to the number of integers.
(I say convincingly because it may be that 0  - 1 = maxval: this is true in C for unsigned int, but are you sure it is true for unsigned char without thinking carefully about integral promotions?)

The actual implementation of the for loop by my compiler does correctly handle 0 but this requires two tests to implement the loop:

```<code>continue:
  if not (i <= bound) goto break
  body
  if i == bound goto break
  ++i
  goto continue
break:
</code>```

Throw in the hand coded zero check in the array example and three tests are needed.

If the loop were exclusive it would handle zero properly, avoiding the special test, but there'd be no way to express the upper bound of an array with maximum size.

Note the C way of doing this:

```<code>for(i=0; predicate(i); increment(i))
</code>```

has the same problem. The predicate is tested after the increment, but the terminating increment is not universally valid!

There is a general argument that a simple exclusive loop is enough: promote the index to a large type to prevent overflow, and assume no one will ever loop to the maximum value of this type.. but I'm not entirely convinced: if you promoted to C's size_t and looped from the second largest value to the largest you'd get an infinite loop!

Body:
Your last paragraph doesn't make much sense to me. If you use a signed int in the first place, then you make the assumption that your largest possible upper loop bound is the largest positive signed int value. If you use a larger type for your loop, then there won't be an overflow. If there could be an overflow, then by an upper loop bound larger than the maximum positive signed int value, which invalidates your initial assumption.

Additionally, do not assume that no one will ever do this or that. If you are in doubt for a specific loop, then test for it and explicitly express what you assume here.

assert(UINT_MAX > INT_MAX);

if ((unsigned int)len(a) <= INT_MAX) {
    for (unsigned int i = 0; i < len(a); i++)
}
else {
    Handle an unexpected situation here.
}

EDIT (a bit too long for a comment to your comment):

Maybe you're looking at the problem from the wrong direction? Note that C's for loop isn't exclusive by itself. It is just often used this way because of the 0-based array indexing. Nothing stops you from using it inclusive:

for (i = 0; i <= len(a)-1; i++)

In fact, nearly any expression can be used for the three parts, because it is more syntactic sugar than its own command, so you can as well use it to iterate through a linked list:

for (p = start; p != NULL; p = p->next)

So you could first define what you expect from your for loops? Should they be strictly bound to numerical operations? Then you could as well provide them with "growing" ints that never overflow and are automatically scaled up to bigints, according to the needs. Or you could define that 0-1 is always treated as -1, so you have for i in 0 upto -1 which won't execute at all and saves you the additional check for 0.

What's the intended purpose of your language? Is there really a need for me as a programmer to care about the exact types used in the for loop?


答:
My analysis revealed that engineers don't consider interviewing as
  important/serious activity, since it's internal and non-billable.

If that's the problem, then the solution is simple: make interviews billable. If you want to make phone interviews a top priority, make them billable at a higher rate. The customer is the company itself, of course. No real money changes hands, but engineers get credit for the time they spend performing interviews. Make sure that the engineers understand that even though the hours are billed internally, you really do consider such hours to have been billed, and there's no stigma attached to such hours.

Title: How can I inspire engineers to positively conduct telephone interviews

Body:
Our (mid-size) company (with 150 employees) has witnessed considerable growth since last year, and as a result we have been conducting lots of interviews to hire more and more engineers to bring new projects in motion.

To begin with, following is our interview process

Screening resume by HR

Telephone technical interview (conducted by senior engg)

Final technical + HR interview (conducted by team-lead/PM)

After some analysis we found that telephone interviews are not really becoming effective, due to which we are not able to find good number of engineers in final interview. My analysis revealed that engineers don't consider interviewing as important/serious activity, since it's internal and non-billable. Also I see that engineers don't find it really prestigious to carry a label of "interviewer" (at-least telephone interviewer). We do have  set of good experienced engineers in company who can take any interview very effectively, but since number of telephonic interviews is large, this pool is not sufficient. Hence we try to use other engineers as well.

What can be done to inspire engineers to conduct telephone interviews seriously and positively (not treating this as mundane job)?

[Update-2011/12/28]

Thanks for sharing your valuable opinions. It really helped me to look at problem from variety of different angles. Alongside I was discussing issues with few colleagues as well and I personally feel that there is no single silver bullet for such issue. I will need to think recruitment process as a whole unit and plan to improve different areas/stages in it.


问:
Does any programming language use variables as they're in maths?
In maths, a variable means you can put any number there, and an equation will still be true:

```<code>root(square(x)) = abs(x)
</code>```

In programming languages, this is not so: a var can change. In Python:

```<code>y = (x**2)**.5
x *= 2
assert y == abs(x)
</code>```

will raise an exception, since x in the last line is not the same.

Are there programming languages that use immutable variables?

答: C, C++, and Objective-C can specify immutability for function (and method) arguments, as well as other variables (identifiers), with the "const" type qualifier.</p>

ContentLicense: CC BY-SA 2.5


答:
Only the second method follows CQS.

I consider CQS to be a guideline to encourage good coding practices. Make use of good coding practices during development, and if you find out later that this method contains resource-critical code, you can still optimize it.

Premature optimization is the root of all evil :)

Title: Does command/query separation apply to a method that creates an object and returns its ID?

Body:
Let's pretend we have a service that calls a business process. This process will call on the data layer to create an object of type A in the database.

Afterwards we need to call again on another class of the data layer to create an instance of type B in the database. We need to pass some information about A for a foreign key.

In the first method we create an object (modify state) and return it's ID (query) in a single method.

In the second method we have two methods, one (createA) for the save and the other (getId) for the query.

```<code>    public void FirstMethod(Info info)
    {
        var id = firstRepository.createA(info);
        secondRepository.createB(id);
    }

    public void SecondMethod(Info info)
    {
        firstRepository.createA(info);
        var key = firstRepository.getID(info);
        secondRepository.createB(key);
    }
</code>```

From my understanding the second method follows command query separation more fully. But I find it wasteful and counter-intuitive to query the database to get the object we have just created.

How do you reconcile CQS with such a scenario?

Does only the second method follow CQS and if so is it preferable to use it in this case?


问:
Can you successfully keep managing when you are forced back into development?
For about eight months I managed a development team doing a re-write of a web based application. During this time, I was focused on many aspects of the project that did not involve directly writing code, even though by trade that's what I started out as.

Recently the number of developers assigned to the project has dropped and I am now forced to drop back into a developer/management role. Since that time I have found that it's very difficult to focus on a feature and get it completed while at the same time trying to stay ahead of the other developers and make sure that we're keeping on track.

My questions is this: can you successfully keep managing a project when you are forced back into development?

答:
In my experience no - I have failed to manage whilst developing well and equally failed to do much by way of substantial development whilst managing.

I've also witnessed (in a former life) my "boss" having the same problem...

Fundamentally this is a variation on the problem described in the excellent article Makers's Schedule, Manager's Schedule - when you're developing you want to do nothing else 'til you get stuck or you're done at which point you want to go your manager for help/direction. Similarly if you're the manager then you're the point of contact for external interruptions (and indeed you should be working hard to avoid anyone interrupting the devs and getting them out of their groove). What this amounts to is that if you're managing you're, at least potentially, in a state of constant interruption from above and below - and that does for your ability to code at any sustained level as you can never clear the decks. If you do go the other way then you fail to manage your team well (give them too much leeway and interesting things will happen, and it won't be what you want...)

In the end I was able to find a comfortable position where I could deal with bugs and small bits of niggly stuff, where I could deal with stuff at an architectural level, where I was happy to discuss implementation detail (to vary degrees depending on the programmer) and could direct my devs whilst, for the most part, not interrupting them. External interruptions came to me so the rest of the devs got to do stuff. I worried about the big picture, they got to do the big pieces of work.

A further thought - it does seem to me that agile style methodologies with substantially self-organising teams and similar concepts might go some considerable distance towards making it more possible by removing some of the necessary overhead i.e. making it more possible to trust your team to do the right thing on their own more often than not. That still doesn't deal with external factors though.


答:
Screening resume by HR
DON'T have HR pre-screen resumes! Have the hiring manager pre-screen. This ensures the hiring manager gets to see all possible candidates and screen using his or her own bias, not hr.

Telephonic technical interview (conducted by senior engg)
DON'T perform telephone interviews! If you can meet the candidate in person then do that instead. Phone interviews are only acceptable when you can't meet the candidate in person, such as if you are interviewing overseas candidates for an off shore position.

Final technical + HR interview (conducted by team-lead/PM)
Pick through the resumes and throw out any that have obvious deficiencies such as grammatical errors or they contain unrelated experience. Continue until you have about 10 candidates, then STOP! Pass around the 10 resumes to the team and get them to pick the top 5 to interview. Interview with the whole team, anyone gets a thumbs down from anyone on the team gets a "NO HIRE" mark. Make a list of questions and ask the candidate to perform a simple programming task as part of the interview. I like to hand the candidate a blank sheet of paper, show them the PUBS database and say "write me the Books class. Just get started for a few minutes, then we'll talk". You can get a pretty good idea of how someone is by this alone. Anyone who makes the grade gets a "HIRE" mark. Have the team vote for the one they want out of the hire column. Repeat as necessary. Finally, realize that you aren't always going to make correct hiring decisions and you must be willing to let poor performers go if they can't make the grade. Good luck!


答:
Some minor parts are obsolete in all those books, but 99% is still great.

Algorithms books will age slowly.  Algorithms are math, and the math is not changing rapidly.  Sure, there's still research into new algorithms that are superior in certain circumstances (e.g., Furer's algorithm (2007) Schonhage-Strassen for multiplying 40000+ digit long numbers together), but the introduction you need to learn the basics (divide-and-conquer/Dynamic Programming/Linear programming/etc) so you can learn to think sensibly about algorithms.

Learning standard C from K&R is still the best source; though I'm not sure if I would trust their sections on how to setup your environment.

SICP is a wonderful book and teaches the foundations of modern CS through teaching lisp which is a wonderful language. However, lisp is arguably not the most useful language nowadays; though others will argue lisp is their secret weapon and that learning languages like java or python first makes very bad programmers who never need to learn how to implement sort or linked-lists or arrays or big-O notation and end up doing very inefficient things.

Some of Code Complete or Pragmatic Programmer are less relevant, esp if you are programming in newer languages (e.g., python / ruby / C++11), as its often focused on how to do something in C or gives recommended solutions using the best tools available at the time (like CVS/RCS for version control rather than a modern tool like git/bzr/hg/svn).  But its still good to be thinking about how version control is a must and how it needs to be seamless and self-documenting and go through the logic of why it is an absolute must.

Or PP's recommendations against IDEs for basic unix editor + unix tools -- not to say you shouldn't learn how to use find/awk/locate/grep/sed, but a good IDE can often save lots of time.  E.g., emacs can do syntax highlighting or simple code completion; but say a good IDE will say give tool-tips with function declarations when you type them in, or analyze code and mark off unused variables, make it easy to collapse sections of code, etc.


问:
What would a piecework-based payment system for software development look like?
In software development, a developer is usually paid either annually (by fixed salary) or by the hour. For the most part, it seems like this works. However, I've seen industries where professionals are paid for the task. For instance, in agriculture a worker is paid per bushel. In sales, a worker is paid by commission most commonly.

Would it be possible to pay a developer by delivered item? How could we calculate what a single "item" of software would be? Would this incentivize more efficient development? Would it be more/less fair to the developer, or the employer? Would this be similar/different from a "results-only-work-environment"?

答:
Here is your thought experiment re-worded; Imagine a system metric that would not be completely contrived and completely gamed by a system that would do nothing but produce the worst product imaginable, and attach monetary gain to it.

Real World Example: from the not to distant past

Pay by the line of code == lots of lines of code as a goal

Do you really want someone paid this way?


答:
www.TopCoder.com sounds like it fits your description.

It assigns a task, and developers code to "win".  If yours is the best, you get paid a predefined amount of money.  Take away the win/lose competition idea, and you have a fixed bid for a specific small-ish task.

Title: What would a piecework-based payment system for software development look like?

Body:
In software development, a developer is usually paid either annually (by fixed salary) or by the hour. For the most part, it seems like this works. However, I've seen industries where professionals are paid for the task. For instance, in agriculture a worker is paid per bushel. In sales, a worker is paid by commission most commonly.

Would it be possible to pay a developer by delivered item? How could we calculate what a single "item" of software would be? Would this incentivize more efficient development? Would it be more/less fair to the developer, or the employer? Would this be similar/different from a "results-only-work-environment"?


答:
What you're looking for is story points. Breaking down functionality into discrete deliverables would help when the client wants more control over the budget and/or schedule for the project (for example, if you want this project delivered in 6 months, we can only fit X number of story points, here is your list let's prioritize according to what you absolutely need in the system).

In practice it takes a very experienced developer/team to deliver to this level and make it useful for the client.


问:
Copyright statements in source code
Ever since I started programming I've seen a header at the top of most code files indicating some sort of copyright: e.g.

```<code>/* Copyright (c) 1998 Innotech */
</code>```

or

```<code>/* Copyright (c) 1998-2008 Innotech */
</code>```

Conceptually I get the idea... depending on your wants/needs it roughly translates somewhere between:

Hey check it out! I made this! I'm awesome!

to

Don't copy/redistribute this! Our lawyers will come after you if you do!

On the one hand I find the whole thing somewhat humorous as often this is a file that no one outside of in-house developers will ever see, but presuming this line may actually one day "mean something" I'm curious about the date part.

Does a single date imply that the author claims copyright of the file from that date until eternity?

If a date range is used, and not kept up to date has the developer invalidated his/her own copyright beyond the date range?

Without some additional legal filing of some kind - does the copyright header provide any real legal strength of any kind? or are we all just fooling ourselves.

答:
From plagiarism today:

In the United States, since 1978 there has been no formal requirement
  to mark your work with the copyright symbol, in fact, there are no
  formalities at all. Copyright is created in a work once it is fixed
  into a tangible medium of expression. This means your novel is
  protected the second you hit the “save” button.

Registration isn't mandatory, but it is required in the US to sue someone for damages

you can only get statutory damages for infringements that took place
  either after the registration or after publication if the work was
  registered within three months.

A work is protected by copyright the moment it is created, but if you
  want to enforce that copyright in a court, you need to register it.

There is also the act of protecting your work, although not mandatory, it can affect how a judge or jury sees the damages, if you let something be copied for years you dilute the perceived value of the work.

From plagiarism today:

the level of enforcement or protection you’ve provided a work can be a
  factor in how much damages are awarded. For example, if a photo you
  took has been circulating widely for years with no action and you sue
  one user of the work, that would mitigate the market value of the
  work, the damage the infringement could have done and how the court
  feels about the infringement itself. All of these things can affect
  the final judgment.

Copyright statements are the least you can do to inform someone that what they have isn't their's and who's it really is.

It is a grown up legal consequence retort to the child's "I don't see your name on it".

For all your other questions See a lawyer in your jurisdiction!

Title: Copyright statements in source code


问:
Which languages use "paired" header/implementation files?
C is ubiquitous, and C++ nearly as much, but I'm curious which other languages follow a similar model of header files.  Specifically, in which other languages is it idiomatic to edit pairs or groups of "header" and "implementation" files?  (A group as in multiple headers with one corresponding implementation file or a single header with multiple implementation files, as also seen in C.)  For example, the pair "blah.h" and "blah.c".

C's header files are tied into the C preprocessor, but that's not the detail I'm focusing on here.  For example, PHP has various include mechanisms, but you don't have a pair/group of "blah-header.php" plus "blah-notheader.php".

Some languages generate a file from source in a one-to-one mapping, such as Java, but that's not what I'm talking about either.  I'm interested in cases where the programmer directly edits both/all files in the pair/group.

Perhaps to put it another way: which languages have a declaration file ("header") and definition file ("implementation") such that a person would generally edit both files in tandem?

答: I think Modula 2 uses a similar pattern</p>

OwnerDisplayName: Roger Pate

LastEditorDisplayName: Roger Pate

Body: I think Modula 2 uses a similar pattern


答:
Does a single date imply that the author claims copyright of the file from that date until eternity?

The date is usually when the file was created (i.e.: first copyright). If the file was changed, then the date range (or list of years) covers the period of changes until the last change (last copyright). Copyright is time-limited, so the timestamp is important.

If a date range is used, and not kept up to date has the developer invalidated his/her own copyright beyond the date range?

No, but it may expire earlier than it should have.

Without some additional legal filing of some kind - does the copyright header provide any real legal strength of any kind? or are we all just fooling ourselves.

Yes, it does.

I'm not a lawyer, and the above is my understanding of things, if you want a legal advice - you should talk to an attorney.

Title: Copyright statements in source code

Body:
Ever since I started programming I've seen a header at the top of most code files indicating some sort of copyright: e.g.

```<code>/* Copyright (c) 1998 Innotech */
</code>```

or

```<code>/* Copyright (c) 1998-2008 Innotech */
</code>```

Conceptually I get the idea... depending on your wants/needs it roughly translates somewhere between:

Hey check it out! I made this! I'm awesome!

to

Don't copy/redistribute this! Our lawyers will come after you if you do!

On the one hand I find the whole thing somewhat humorous as often this is a file that no one outside of in-house developers will ever see, but presuming this line may actually one day "mean something" I'm curious about the date part.

Does a single date imply that the author claims copyright of the file from that date until eternity?

If a date range is used, and not kept up to date has the developer invalidated his/her own copyright beyond the date range?

Without some additional legal filing of some kind - does the copyright header provide any real legal strength of any kind? or are we all just fooling ourselves.


问:
Are there benefits to deriving versions from SCM branch?
Currently, we have a versioning scheme following the major.minor.patch pattern. Development is done in a branch (i.e. - branches/b4_2); a release is a tag (tags/r4_2_0). To determine the version inside the code, we have a class which can parse the SCM URL (FooVersion.java). If the URL represents a branch, the SVN revision is appended (for QA builds).

We're re-evaluating versioning and, more pointedly, what sort of environments we have up. The big change here is adding the concept of a beta environment for our "super users". Along with this, I'm rethinking this potentially over-engineered version derivation system.

How do you determine, in the code, what the version of the software is? Creating a release is already a manual process (create tag, check in JARs for the related libraries we develop, etc.) which could probably be scripted, so is there a benefit to the way we do it over having a text file which is updated when a version is cut?

答:
We distinguish between a build identifier (the SVN URL + revision, although this could be a git identifier as well) and a "marketing" version number, the latter managed in a text file and updated by hand.

There is very little use and some harm in having these two numbers depend upon one another. They are very rarely used together. There is a heavy n:1 relationship between SVN commits and marketing number increases. Users get confused when version numbers jump wildly. When you start shipping binaries together (like your related-libraries-JARs), you need a release identifier that is independent of binary identifiers. We, for example, combine 5 packages for a binary release, each of which needs a version identifier, so you can't derive your version number from any of these 5 URLs in any way.

Thus, I'd advise you to drop the version derivation scheme and manage the marketing version independently. Use the SVN URL+revision as a build identifier, put it in some remote menu in your software and in the error logs that are generated for bug report purposes, and never touch it programatically.


答:
These answers were extracted from the book Patents, Copyright and Trademark, highly recommended. If you plan to buy one, notice that there's a newer edition than that I have.

Does a single date imply that the author claims copyright of the file from that date until eternity?

"The copyright lasts for the life of the author plus 70 years. However, under the following circunstances, the copyright lasts between 95 and 120 years, depending on the date the work is published:"

...

"The work belongs to the author's employer under work made for hire
principles."

...

(page 192)

If a date range is used, and not kept up to date has the developer invalidated his/her own copyright beyond the date range?

No, simply the copyright will last from the last recorded date onwards.

Without some additional legal filing of some kind - does the copyright header provide any real legal strength of any kind? or are we all just fooling ourselves.

"Contrary to popular belief, providing a copyright notice or registering the work with the USCO is not necessary to obtain basic copyright protections. But there are some steps that can be taken to enhance the creator's ability to sue or stop others from copying:"

...

"Place a copyright notice on a published work. (...) Placing this notice on a published work (...) prevents others from claiming that they did not know that the work was covered by copyright. This can be important if the author is forced to file a lawsuit to enforce the copyright, since it is much easier to recover significant money damages from a deliberate (as opposed to innocent) copyright infringer."

...

(Pages 190-191)

For clarification on the issue of registration, mentioned in the comments, the book states, under the same bullet list as the previous excerpt:

...

Register works with the USCO. Timely registration (...) makes it much easier to sue and recover from an infringer. Registration creates a legal presumption that the copyright is valid and, if accomplished prior to someone copying the work, allows the copyright owner to recover up to $ 150,000 (and possibly attorney fees) without proving any actual money harm. (...)

Title: Copyright statements in source code


答:
Isn't there a difference between modern computing and what was current when those book were written? Do you think it changes what we should learn? Shouldn't we take into account the developments of the last 20 years?

Yes, yes, and yes.

That doesn't make those books obsolete. "Modern computing" is an incredibly broad term. However, it includes C programming, so "The C Programming Language" is still a relevant book. It includes algorithms, so "Introduction to Algorithms" is still a relevant book. So on and so forth.

Should the current emphasis on multiplatform development multiplatform development (see phonegap) change what we learn today?

Most apps on the App Store (to use the most popular mobile platform as an example) are written in Objective C, a language from the early 80s which is a superset of C. So, again, C is still relevant.

Do you think the "cloud" is a fad or the future?

It's our present.

When students get out of university, they are supposed to be real developers and be able to work immediately

But what does that mean?

There are too many languages, APIs, frameworks, platforms, tools, collaboration strategies, etc. for school to prepare you for a specific job. The school can only lay the foundation, giving you a basic working model of how the machine works, about algorithms, data structures, code construction, decomposition strategies, some tools, etc.

A "real developer" is not someone who knows everything, it's someone with the capacity for this kind of work, who has a foundation in theory and practice, and who knows how to learn, because your education never ends.


答:
Absolutely you can wear both hats at the same time, how effectively you can do so is largely a matter of time management.

Management is both a skill set and a job description.  From that it encompasses various tasks that you perform.  When I managed a team of 10, I was the "HR" manager as well as their technical team lead.  I assigned work (yes, not agile...) dealt with small budgetary matters, general HR hire/fire/review/holiday/etc. stuff and the like.

Some of that work goes up with the number of people managed, and some is more fixed based on yes/no.  The number of staff you have does not really impact how long you spend on your budget, but does impact how long it takes to perform their mid-year reviews and document them to HR satisfaction.

With a team of 10, I primarily oversaw, reviewed code, and was the person to bounce ideas off.  With a team of only 5, however, there was much more time for actual coding.

To use a crude made-up formula as an analogy, my personal experience would be something like

```<code>Dev-Time-As-Percent = 100 - Fixed-Managerial-Overhead - (Staff-Count * 5)
</code>```

Here I am presuming that each individual is 5% of my working time - averaged out.  Some need more on some days, etc.  The fixed part is the stuff I mentioned like budgets, which tends to be invariant - either I have to make one or I do not.  The staff count is also an input to the numbers in the budget, but the staff count doesn't change the effort of creating the budget much.

What you do with that leftover time is up to you, and your boss!  In my case, I mostly fixed bugs in order to keep my hands dirty in the code, and because my time did indeed vary, I was therefore not a bottleneck for larger features.

Any job, like bits on a hard disk, or furniture in a house, can expand to fill space (time) available.  So it all goes back to time management.  Do you get the management stuff done-done and can you then do other things?  Or is the management stuff taking 100% of your time regardless of the size of team?

Title: Can you successfully keep managing when you are forced back into development?

Body:
For about eight months I managed a development team doing a re-write of a web based application. During this time, I was focused on many aspects of the project that did not involve directly writing code, even though by trade that's what I started out as.

Recently the number of developers assigned to the project has dropped and I am now forced to drop back into a developer/management role. Since that time I have found that it's very difficult to focus on a feature and get it completed while at the same time trying to stay ahead of the other developers and make sure that we're keeping on track.

My questions is this: can you successfully keep managing a project when you are forced back into development?

Body:
Absolutely you can wear both hats at the same time, how effectively you can do so is largely a matter of time management.

Management is both a skill set and a job description.  From that it encompasses various tasks that you perform.  When I managed a team of 10, I was the "HR" manager as well as their technical team lead.  I assigned work (yes, not agile...) dealt with small budgetary matters, general HR hire/fire/review/holiday/etc. stuff and the like.

Some of that work goes up with the number of people managed, and some is more fixed based on yes/no.  The number of staff you have does not really impact how long you spend on your budget, but does impact how long it takes to perform their mid-year reviews and document them to HR satisfaction.

With a team of 10, I primarily oversaw, reviewed code, and was the person to bounce ideas off.  With a team of only 5, however, there was much more time for actual coding.

To use a crude made-up formula as an analogy, my personal experience would be something like

Dev-Time-As-Percent = 100 - Fixed-Managerial-Overhead - (Staff-Count * 5)

Here I am presuming that each individual is 5% of my working time - averaged out.  Some need more on some days, etc.  The fixed part is the stuff I mentioned like budgets, which tends to be invariant - either I have to make one or I do not.  The staff count is also an input to the numbers in the budget, but the staff count doesn't change the effort of creating the budget much.

What you do with that leftover time is up to you, and your boss!  In my case, I mostly fixed bugs in order to keep my hands dirty in the code, and because my time did indeed vary, I was therefore not a bottleneck for larger features.

Any job, like bits on a hard disk, or furniture in a house, can expand to fill space (time) available.  So it all goes back to time management.  Do you get the management stuff done-done and can you then do other things?  Or is the management stuff taking 100% of your time regardless of the size of team?


问:
How to apply dynamic programming to optimization problems with 2 constraints
Suppose you have a collection of blocks, each with a certain height and a certain weight. For example:

```<code>Sample input:
(190, 190) (120, 40) (100, 10) (90,130) (70, 40) (60, 70) (30, 30) (10, 90)

Sample output:
4
</code>```

You want to find the maximum number of blocks you can pile, with 2 constraints: each block must be lighter than the one below it and it must also be shorter than the one below it. How do you solve it?

My approach was to solve it more or less like the knapsack problem. I order the blocks from light to heavier, and I start at the end of the array. Then for each block I am considering, I find the maximum between piling that block and don't piling it, and return it. Here's the C code:

```<code>int maxPile(Blocks array[], int block, int maxHeight, int maxWeight){

    /* base case with just 1 block left to consider */
    if (block==0){
        if ((array[0].height < maxHeight) && (array[0].weight < maxWeight))
            return 1;
        else
            return 0;
    }

    /*case where current block can be piled, check the max between piling or not*/
    if ((array[block].height < maxHeight) && (array[block].weight < maxWeight))
        return max(1+maxPile(array,blockk-1,array[block].height,array[block].weight),maxPile(array,block-1,maxHeight,maxWeight));

    /*case where current block can't be piled, so move to next*/
    else
        return maxPile(array,block-1,maxHeight,maxWeight);
}
</code>```

The algorithm above seems to solve the problem correctly. The problem, as you might have guessed, are the overlapping sub-problems, so the complexity is exponential.

The usual way to solve this is dynamic programming, but I am having a hard time to implement it, specifically because of the 2 constraints.

If there was a single constraint, say weight, I would build a 2-dimensional array where the rows would represent the sub-set of blocks you are working with, and the columns would represent the max weight available.

But with 2 constraints I would need to have a 3-dimensional array to store the solutions of the subproblems, and as soon as the dataset grows a bit this becomes unfeasible.

Another idea I considered was to take the 3 factors (current block, max weight and max height), pass them through a hash function and store the result in a hash table. For some reason this is not working.

Any ideas on how to add dynamic programming to the above solution? (or on how to solve it more efficiently?).

Update: It seems that it's also necessary to sort the array by the second constraint (i.e., height in this case) and run the function again, cause with this order the maximum might be larger.

答:
I fail to see the need for dynamic programming. The following algorithm is O(n^2) in both time and space complexity (could be improved), but gets an exact answer--a significant improvement if you consider that dynamic programming is commonly used to solve problems with exponential complexity.

To start with, place every block on a graph that plots weight vs. height:

Next, create a directed graph based on the constraints of the problem (connections go from top-right to bottom left, by necessity):

Next, place all nodes with no incoming links into a queue (marked as green--Merry Christmas :) )

Simple breadth-first search (using your queue as the starting state) should allow you to find the longest path through the graph. The longest path represents the tallest tower possible. No worries about loops, as it is not possible given the constraints of the problem.

We can provide evidence of this algorithm's correctness by proving our initial step:

The base of the optimal tower will be represented by a node with no incoming links. Proof by contradiction: Assume the base node of an optimal tower has an incoming link. The incoming link implies that that node (and by necessity, the entire tower) could be placed on the node that is connected by the incoming node. This tower would be taller than the optimal tower--a contradiction, thus the original assumption must have been wrong.

Let me know if I missed a key point of the problem (or an edge case that is not solved by this method).


问:
When can you call yourself good at language X?
This goes back to a conversation I've had with my girlfriend. I tried to tell her that I simply don't feel adequate enough in my programming language (C++) to call myself good. She then asked me, "Well, when do you consider yourself good enough?"

That's an interesting question. I didn't know what to tell her. So I'm asking you.

For any programming language, framework or the like, when do you reach a point were you sit back, look at what you've done and say, "Hey, I'm actually pretty good at this."? How do you define "good" so that you can tell others, honestly, "Yeah, I'm good at X".

Additionally, do you reach these conclusions by comparing what others can do?

Additional Info

I have read the canonical paper on how it takes ten-thousand hours before you are an expert on the field. (Props to anybody that knows what this paper is called again)

I have also read various articles from Coding Horror about interviewing people. Some people, it was said, "Cannot function outside of a framework." So they may be "good" for that framework, but not otherwise in the language. Is this true?

答:
I think you can call yourself good at something when you develop the required knowledge to be able to look at yourself as if from another person's perspective, and then determine if you are good. In other words, you should have strong "meta" skills.

For example, I'm a hobbyist writer, and when looking at my own writing I can tell:

what aspects of it are good and why

what aspects of it are bad and why

what do I need to do to improve the bad ones, and why

which bad aspects are specific to the written piece, and which are a symptom of my abilities

what are the elements that other people may criticize, and why

which criticisms are not relevant to my specific piece, even if others may voice them, and why

etc. etc.
Because of this I feel that I'm qualified to decide if I'm good at writing or not. The same applies to X.


答: I've seen the C Preprossessor used in Haskell to include code from a header. Its not that common as far as I know though.</p>

Title: Which languages use "paired" header/implementation files?

Body:
C is ubiquitous, and C++ nearly as much, but I'm curious which other languages follow a similar model of header files.  Specifically, in which other languages is it idiomatic to edit pairs or groups of "header" and "implementation" files?  (A group as in multiple headers with one corresponding implementation file or a single header with multiple implementation files, as also seen in C.)  For example, the pair "blah.h" and "blah.c".

C's header files are tied into the C preprocessor, but that's not the detail I'm focusing on here.  For example, PHP has various include mechanisms, but you don't have a pair/group of "blah-header.php" plus "blah-notheader.php".

Some languages generate a file from source in a one-to-one mapping, such as Java, but that's not what I'm talking about either.  I'm interested in cases where the programmer directly edits both/all files in the pair/group.

Perhaps to put it another way: which languages have a declaration file ("header") and definition file ("implementation") such that a person would generally edit both files in tandem?


答:
aI have been working for the past 4 years in variations of the environment you described. Here is my experience with them:

Local environment (http server installed locally + other systems)

Although it is arguably possible to deploy the environment in all OS, the reality is that you will face with a lot of problems regaring different configurations, available modules, library versions... It means that lots of developers will work on his very own environment, different among them and different from production environment.

This setup is very nice with the developer: it is very fast, he obtains knowledge about the whole picture, very useful for trying new configurations or alternative software. If the developer has some sysadmin skills, he can fix configuration options, change the enviroment so some specific feature is easy to develop or test...

As the code and development tools are also local, daily work is very fast.

Local VM (dev environment in a VM, running locally)

You will need to create a dev virtual machine and send it to your developers. Also, you need to provide updates (probably as another VM), but some developers will not install it if they have customized their personal VMs too much. You also need some kind of global configuration, while still allowing particular settings for each developer. But then you will face the problem of developers tunning their VMs so much that it becames to different from production.

The developer needs a very powerfull machine, specially for web development. Nowadays I'm using a dev VM, a windows VM (to test things in IE browsers, for example) and the dev environment. My dual core and 8Gb of RAM can't handle that nicely, is a real mental pain to work with that setup.

There are three alternatives about code:

Code is local, deployed to the VM to run it:  Working with local development tools is very fast. Although most tools have automated deploy options, in my experience they didn't work very well when you need to work in the other way (update local code with VM code). . Works better using a SSH connection for particular tasks (i.e. global searchs)

Code is in the VM, shared with local development tools using some remote-acces solution (samba, sftp...): Depending on the developer SO or personal setup, it might not work very well. Potentially you will face problems about permissions, polluted directories (aka Thumbs.db and .DS_Store everywhere)  and random disconnections. Some tools features (like indexing or global searchs) will be very slow. Works better using a SSH connection for particular tasks (i.e. global searchs)

Code is in the VM, the developer works using server tools through a remote shell. Good solution if your developers like this setup and you can find a good replacement for each local softare used by your team (very unlikely, specially for designers)

Remote Environment (dev environment is in another machine)

This setup is the easiest to to maintain, as new configuration options or software just need to be deployed in one place. With a good server you can host up to 50 developers, so the worst case for mid-sized companies will be to maintain 3 or 4 development servers.

You will face privileges and security problems: some of the developers might need root access to do their job, so they will be able to change the environment,  potentially breaking it and stopping the whole team (or worse, losing the in-progress code). As the number of developer grows this will become a serious risk. In my experience, in a machine shared by 20 developers expect a broken environment at least once per month.

Obviously, it has network dependency: if the developer does not have network access, he can't work. You will need a VPN setup to provide access to out-of-office developers, access to remote clients or testers, access to dev environment from your sales people outside the office... Security becomes more important than ever.

For code, very much like Local VM setup, plus adding networking issues. Expect frustrating slowdowns and random disconnections.

Remote VM (dev environment is in a VM, running in a remote machine)

Pretty much like Remote Environment setup, but you can scale it better. On the other hand, you get the problems of deploying the dev environment to too much different machines, so chances of differences among them and production environment are higher.

My personal choice

Use LocalVM and local code. Speed in every day task is very important if you don't want to make your team angry, so local code is important. Most tools works fine for remote deploying, and any "advanced" developer using the reverse way (vm->local) probably can figure out how to do that nicely by himself.

Invest money in powerful machines for the team so the machine speed is not a stopper for anyone. A remote cluster of VMs or a auxiliary and cheap laptop can be very helpful for developers working with heavy development tools.

Title: Trade-offs of local vs remote development workflows for a web development team

Body:
We currently have SVN setup on a remote development server. Developers SSH into the server and develops on their sandbox environment on the server. Each one has a virtual host pointed to their sandbox so they can preview their changes via the web browser by connecting to developer-sandbox1.domain.com. This has worked well so far because the team is small and everyone uses computers with varying specs and OSs.

I've heard some web shops are using a workflow that has the developers work off of a VM on their local machine and then finally push changes to the remote server that hosts SVN. The downside to this is that everyone will need to make sure their machine is powerful enough to run both the VM and all their development tools. This would also mean creating images that mirror the server environment (we use CentOS) and have them install it into their VMs. And this would mean creating new images every time there is an update to the server environment.

What are some other trade-offs? Ultimately, why did you choose one workflow over the other?


问:
Should I provide synonyms in an API?
I'm designing a small library and there is a strong temptation to provide synonyms to some of the exported functions.

```<code>var foldl = function(){ ... };
var reduce = foldl; //reduce is a synonym for foldl
</code>```

I imagine that the multiple names might help the initial learnability of the API (since the user is more likely to stumble on the function he wants) but at the same time I worry the duplication will bring needless complexity.

What rules should I keep in mind when thinking about adding a synonym to a function in my API?

When whould I choose a "there is more then one way to do it" api and when should I incentivize there is one way to do it" instead?

答: Not only is it confusing to use multiple names for the same thing, but this will also pollute the namespace of whoever is using your API. In c# i am often tortured by not being able to name my variables default or checked =P. Knowing a bit of Perl, my intuition is also that functions which seems like they do the same thing are usually subtly different (chop, chomp).</p>

Title: Should I provide synonyms in an API?


问:
Why pointer symbol and multiplication sign are same in C/C++?
I am writing a limited C/C++ code parser. Now, multiplication and pointer signs give me really a tough time, as both are same. For example,

```<code>int main ()
{
  int foo(X * p); // forward declaration
  bar(x * y);  // function call
}
</code>```

I need to apply special rules to sort out if * is indeed a pointer. In above code, I have to find out if foo() is a forward declaration and bar() is a function call. Real world code can be lot more complex. Had there been different symbol like @ for pointers, then it would have been straight forward.

The pointers were introduced in C, then why some different symbol was not chosen for the same ? Was keyboard so limited ?

[It will be an add-on if someone can throw light on how modern day parser deal with this ? Keep in mind that, in one scope X can be typename and another scope it can be a variable name, at the same time.]

答:
The typedef was a relatively late addition to the C language.

In earlier versions of C, the grammar defined what is or is not a type name fairly straightforwardly.  Many type names: int, char, double, etc. were (and still are) single keywords.  Other type names included keywords or symbols: struct foo, char *, int[42].  A non-keyword identifier could never be a type name.

When the typedef construct was added to the existing language, it wasn't possible to change the grammar to be able to treat a non-keyword identifier as a type name without either creating ambiguities or breaking existing code.  For example, in:

```<code>int foo() {
    x*y;
}
</code>```

x*y could be either an expression statement that multiplies x by y and discards the result, or a declaration of y as a pointer to type x.

One way of looking at it is that a typedef creates a new keyword, one that exists only until the end of the scope in which it's defined.  That means that the parser has to look at the symbol table to know how to interpret things (something that's not true for a lot of other languages; for example, in Pascal an identifier can be a type name, and this doesn't introduce an ambiguity).

For example:

```<code>int x, y;
int foo() {
     x * y; /* x isn't type name, so this is an expression statement */
     {
         typedef int x;
         x *y; /* Now x is a type name (effectively a keyword),
                  so this is a declaration */
     }
     x * y; /* The type name x is now out of scope,
               so it's an expression statement again */
}
</code>```

(Treating typedef names as keywords is just one way to look at it; I don't mean to suggest that compilers actually do that internally.)

Body:
The typedef was a relatively late addition to the C language.

In earlier versions of C, the grammar defined what is or is not a type name fairly straightforwardly.  Many type names: int, char, double, etc. were (and still are) single keywords.  Other type names included keywords or symbols: struct foo, char *, int[42].  A non-keyword identifier could never be a type name.

When the typedef construct was added to the existing language, it wasn't possible to change the grammar to be able to treat a non-keyword identifier as a type name without either creating ambiguities or breaking existing code.  For example, in:

int foo() {
    x*y;
}

x*y could be either an expression statement that multiplies x by y and discards the result, or a declaration of y as a pointer to type x.

One way of looking at it is that a typedef creates a new keyword, one that exists only until the end of the scope in which it's defined.  That means that the parser has to look at the symbol table to know how to interpret things (something that's not true for a lot of other languages; for example, in Pascal an identifier can be a type name, and this doesn't introduce an ambiguity).

For example:

int x, y;
int foo() {
     x * y; /* x isn't type name, so this is an expression statement */
     {
         typedef int x;
         x *y; /* Now x is a type name (effectively a keyword),
                  so this is a declaration */
     }
     x * y; /* The type name x is now out of scope,
               so it's an expression statement again */
}

(Treating typedef names as keywords is just one way to look at it; I don't mean to suggest that compilers actually do that internally.)


问:
What should we provide to a dev team hired to complete a new project?
We are wanting to have developers build an in-house payroll and time sheet application using symfony2/doctrine2.

We are simply at conceptual stage at this point and this will be our first time and getting developers to build an application for our company. Hence, it is very important to us that we provide the most valid and important information to what will be our new developer team.

What documents or tools should we provide to the new team to maximize the odds of success with the project and help the developers be productive from day dot?

答:
First, I'm curious as to why you're pigeon-holing yourself with symfony2/doctrine2 - is this due to legacy systems? If not, I'd suggest having your potential developers sell you on tech stacks, not the other way around.

If I walked into a meeting where the following was already prepared, I'd leave that room with a big smile:

An executive summary. There should be a mission statement somewhere in here. A single sentence that defines the objective of the project. This will not only help your developers keep the end goal in mind, but will also help the design team while developing features (should x actually be a feature of the system?)

Subsystem design (high level). Does your application contain logically modular systems? If so, break it up (these could be seen as milestone deliverables).

Prototypes. Use programs like Pencil (free) or Balsamiq (commercial) to mock up what you want in your application.

Of course, things will always change, so while there should definitely be much though put into each of these points, you should definitely not come away thinking that the design is set in stone and won't change.


答:
Objective-C (and and its C++ counterpart, Objective-C++) can #include C (C or C++) header files as well as #import Objective-C header files. That pairs are even used is by convention.

In additon, ASP, Perl, Python, Pascal, and, since the file extension used for its includes doesn't have to follow a standard, PHP.

Edit: Most assembler source code also use "paired" included/implementation files by convention.

EDIT2 - ADDENDUM
Apparently there's some confusion as to the use cases that prompted the use of separate header files in C, and so some developers are dubious that certain other languages would also use header files to deal with those use cases in the same way.

as the earliest C compilers ran on machines with a small amount of memory, it wasn't possible to load up symbol tables with all the source that would be incorporated into the final build. So each source file was run through multiple passes separately to generate the object code with necessary interfaces for other sources included in headers;

as the earliest C compilers ran on machines with a small amount of memory, it was more efficient to distribute the shared elements of a module among more specialized headers which could be included selectively by sources rather than in one;

as the earliest C compilers ran on slow machines, especially since they had a small amount of memory, it was time-consuming to compile lots of source files belonging to a module when only a few had been changed;

sometimes source code maintainers don't share their code with outside groups, but instead make the object code available with headers of the required interfaces to aid in proper integration with linked code;

and most importantly these days, programs and the language runtime sometimes deal with libraries, especially platform-dependent libraries, which are from an external environment or other language but which they can integrate with appropriate interface specifications in a header.

The last point is particularly true when a language supports a platform's GUI. I know it's been true on the Mac since its earliest days (when Pascal was its first high-level language) to now for Perl (now automated), Python, and PHP. Its runtime environment may not make the inclusion process visible to you, but it's happening; especially if you use platform-specific symbols.

Creating bindings for C libraries in Free Pascal

h2xs builds a Perl extension from C header files, or use SWIG, or support C++

Interfacing Python to a C lib doesn't require just a header, but writing an extension!