问:
Encapsulating a class within another class to hide its exposed properties and details
I have essentially a data model class that represents an XML data structure that we use to model our system.  The model class is in a shared project that is used by a number of different solutions in order to generate a common XML data structure for usage by any number of applications.

In one application I am involved in we have provided a wrapper class for one of these XML model classes as we wish to perform a number of operations on the model data.  However other parts of my program also needs to access this data for calculations they need to do.

At the moment I have this setup (note this is an example only but represents my code structure)

1)

```<code>public class ModelWrapper
{
    private readonly ModelClass _model;

    public int PropertyX
    {
      get
      {
         return _model.PropertyX;
      }
    }

    public ModelWrapper(ModelClass model)
    {
       _model = model;
    }

    // and other methods we need that uses the properties we have exposed e.g
    public void PerformOperation()
    {
        if(this.PropertyX > 10)
           // do something
        else
           // do something else
    }
}
</code>```

This appears ok, but I've run into the problem where I or another programmer has un-intentially used the private _model variable.  It seems to me that we could end up with hidden issues in this method in the fact that there are two ways to get to the same data and if we put some logic in the public exposed get property then we could miss that if we directly reference the private variable.

The other alternative I thought of was

2)

```<code>public class ModelWrapper
{
    public readonly int PropertyX;

    public ModelWrapper(ModelClass model)
    {
       PropertyX = model.PropertyX;
       // set other properties here we wish to expose on the ModelClass ...
    }

    // and other methods we need that uses the properties we have exposed e.g
    public void PerformOperation()
    {
        if(this.PropertyX > 10)
           // do something
        else
           // do something else
    }
}
</code>```

Or another option after reading some posts about this is:

3)

```<code>public class ModelWrapper
{
    private readonly int _propertyX;
    public int PropertyX
    {
      get { return _propertyX; }
    }

    public ModelWrapper(ModelClass model)
    {
       _propertyX = model.PropertyX;
    }

    // and other methods we need that uses the properties we have exposed e.g
    public void PerformOperation()
    {
        if(this.PropertyX > 10)
           // do something
        else
           // do something else
    }
}
</code>```

Why do this?  I thought it would be a good idea to hide the model from the our code as we wanted a wrapper class anyway to do the methods so why then expose the model as well?  I thought it might be overkill but it does save in other parts of the code going something like ModelWrapper.Model.PropertyX etc

So to the question.  Which method if any would be a better solution.  Is it overkill or are there better practices out there for this?

EDIT:
I added another option (3) as it there is no need to set the properties I am exposing so I didn't necessarily want to have a private set as it's only being set in the constructor.  Hence the readonly private variable that is used in the get part of the exposed property?

I've also found a stack overflow question about this at https://stackoverflow.com/questions/2249980/c-immutability-and-public-readonly-fields but it doesn't necessarilly say which was better/preferred solution with the current c# limitations.

Any ideas on the 3 implementations as to the best practice?

答:
Inside the wrapper, this should not be an issue. Since this.PropertyX is read-only you cannot unintentionally assign it a value and reading it returns the same value as _model.PropertyX.

I do not know any object oriented construction, which hinders a programmer to produce errors.

If you should add logic to the getter in the future, it would be a good idea to give a different name to the property like NormalizedPropertyX or LowerCasePropertyX or the like explicitly stating the intention behind it.


问:
How can I quickly weed out "copy & paste" coders?
I need a way to filter out resumes of folks who just copy-and-paste code then hope it works, and check it in if it does.  All this happens without having an understanding (or care) to understand the rest of the code in the system.

Sure I know that copying and pasting code is part of learning a new object, control, etc... but how can one tell if that accounts for 70% (or more) of their development career?

I've come across some senior level guys perhaps whose skills are so outdated or irrelevant for the project, that all they do is google, copy-then-paste some code without thinking about the solution as a whole.  As a result we have a mismash of JSON, AJAX, callbacks, ASMX, WCF and postbacks in the same project.  It is clear there is no consistency or logic behind where each technology is being used.

In the worst case, this type of developer creates security issues and vectors for attack.

Question

How would you recommend I filter out people who have a poor programming background?  Can I do it at the resume level?  If not, how do I do this during the interview.

答:
If you want to "weed out" poor coders you can try for example Programmer Competency Matrix (useful but it rather doesn't apply for all possible areas - of course you can make own) or codility.com (the tasks are very good and it saves a lot of time).

Generally, hiring good coders is hard and often requires many years of practice. You can start your own database of interview questions, not only asking about coding stuff but also with math, logic, not to mention motivation questions.

ContentLicense: CC BY-SA 2.5

ContentLicense: CC BY-SA 3.0


问:
What does mathematics have to do with programming?
I just started a diploma in software development. Right now we're starting out with basic Java and such (so right from the bottom you might say) - which is fine, I have no programming experience apart from knowing how to do "Hello World" in Java.

I keep hearing that mathematics is pertinent to coding, but how is it so? What general examples would show how mathematics and programming go together, or are reliant on one another?

I apologize of my question is vague, I'm barely starting to get a rough idea of the kind of world I'm stepping into as a code monkey student...

答:
Ok, I'm probably going to get a ton of down-votes for this, but programming and maths are two completely unrelated things. Someone can be an amazing developer knowing only the basics like addition, multiplication and basic logical operations.

Most of the developers will not solve a single equation during their professional career, and things like big O notation can be grasped in non mathematical way as well. You just think about the stuff, imagine bits flipped in your head, and voila, you can tell what kind of big O the stuff is, if someone explains what log and power is.

Sometimes math can make it simple, or it can make you feel proud that you proved something, since you can extend the meaning of programming to a mathematical domain via naming it discrete maths and such, but learning a lot of differential equations and integrals, and how to prove that, is IMHO not exactly the best idea what to do if you want to succeed as a programmer.

At least I haven't touched the maths for 10 years, I had arguments with my math professors all the time, and when I needed a math for realtime rendering, I learned everything from programmers side of view, without any proving any theorems, and for me it was simple and easy to grasp compared to all the stuff math professors where putting in our heads with a comment of "you can't be a good programmer if you don't know the math". Sure you can, easy!

I now know the mathematical stuff, so that I can talk with math-background programmers with all the log's differentials and stuff, but only for the reason so that they wouldn't faint. Because that stuff is useless 99.9% of the time, and when it is, it can be learned 1000x more effectively from programmers viewpoint.

Heck, programmers need at least 5 years to master a programming language+frameworks+best practices. Why on earth they should learn how to prove the theorems? Math student's do the math stuff, programmers get that stuff running, that's how it should work.


问:
Most common website scalability pitfalls
We are designing a website/web application where we hope to to achieve high user counts and, in general, lots of use. More specifically, we intend to be using PHP as the programming/scripting language and MySQL for the relational DB needs as a start. We have not yet figured out whether to use a NoSQL database or not.

Related to that, we want to design with scalability in mind. What are the most common scalability pitfalls for websites? What are the key areas that we need to take into consideration, so that the system can be easily scalable?

答: The most common scalability pitfall is not doing load tests early on. If you set up tests that simulate something comparable to your expected load early during development, then you'll be able to detect and correct any technological or architectural impediments to scalability before they become too expensive to fix.</p>


问:
What are good strategies in C for dealing with pointer errors of this type?
In C, I often come across errors with code like this

```<code>prio_queue->head[index] = newEntry;
</code>```

Yields a " "Cannot assign Entry** to Entry* "
How do you prevent/debug errors of this type, in general?

答:
If head is an array of elements, and index is < size of that array, and newEntry is of the same type as the array, and prio_queue is a pointer to a data structure containing head, then there nothing wrong with this code.

A lot of ifs, but without knowing your data structures, I (and no one else) can tell if it's right or wrong.

Update:
Based on the update to the question, a strategy would be to keep careful track of how many levels of indirection a variable has.


答:
The only real way to tell if you have scalability issues is to test it, so  test early, test often as Michael Borgwardt says.

Other than that, a common reason why systems don't scale is because of resource contention.  And that usually shows itself in the database --- trying to read and write at the same time. So you might want to think about using a CQRS approach that disconnects the read (Query) side from the write (Command) side.

Title: Most common website scalability pitfalls

Body:
We are designing a website/web application where we hope to to achieve high user counts and, in general, lots of use. More specifically, we intend to be using PHP as the programming/scripting language and MySQL for the relational DB needs as a start. We have not yet figured out whether to use a NoSQL database or not.

Related to that, we want to design with scalability in mind. What are the most common scalability pitfalls for websites? What are the key areas that we need to take into consideration, so that the system can be easily scalable?


答:
I would add to that one very common thing - optimizing in the wrong place. I have seen tons of articles around that discuss nanosecond differences in PHP syntax constructs but much less that discuss how to properly design caching infrastructure for an application. So as it was already noted, test. But not just test - profile and find out what exactly is slow - is it CPU-bound? I/O bound? Memory bound? Is it database queries that bring you down, is it reading the files, is it calculations? Can you eliminate that or redo it so it works faster? Etc. Do not start with "let's use NoSQL because it's faster". Start with "we want to do this and that, what would be the bottlenecks? How we eliminate them? How it would behave if we get times 100 users?"
Without knowing more of the workload and app it's hard to say anything concrete, but I would start with thinking what you can cache and how to reduce filesystem/database/etc. accesses and especially modifications (since those would also invalidate the caches).


问:
Is there an alternative to Google Code Search?
Per the Official Google Blog:

Code Search, which was designed to help people search for open source
  code all over the web, will be shut down along with the Code Search
  API on January 15, 2012.

Google Code Search is now gone, and since that makes it much harder to understand the features it presented, here's my attempt to render them via information I gathered from a cache of the page for the Search Options:

The "In Search Box" just notes the syntax to type the command directly in the main search box instead of using the advance search interface.

Package (In Search Box: "package:linux-2.6")

Language (In Search Box: "lang:c++")

(OPTIONS: any language, actionscript, ada, applescript, asp, assembly, autoconf, automake, awk, basic, bat, c, c#, c++, caja,
cobol, coldfusion, configure, css, d, eiffel, erlang, fortran, go,
haskell, inform, java, java, javascript, jsp, lex, limbo, lisp,
lolcode, lua, m4, makefile, maple, mathematica, matlab,
messagecatalog, modula2, modula3, objectivec, ocaml, pascal, perl,
php, pod, prolog, proto, python, python, r, rebol, ruby, sas, scheme,
scilab, sgml, shell, smalltalk, sml, sql, svg, tcl, tex, texinfo,
troff, verilog, vhdl, vim, xslt, xul, yacc)

File (In Search Box: "file:^.*.java$")

Class (In Search Box: "class:HashMap")

Function (In Search Box: "function:toString")

License (In Search Box: "license:mozilla")

(OPTIONS: null/any-license, aladdin/Aladdin-Public-License, artistic/Artistic-License, apache/Apache-License,
apple/Apple-Public-Source-License, bsd/BSD-License,
cpl/Common-Public-License, epl/Eclipse-Public-License,
agpl/GNU-Affero-General-Public-License,
gpl/GNU-General-Public-License,
lgpl/GNU-Lesser-General-Public-License,
disclaimer/Historical-Permission-Notice-and-Disclaimer,
ibm/IBM-Public-License, lucent/Lucent-Public-License, mit/MIT-License,
mozilla/Mozilla-Public-License, nasa/NASA-Open-Source-Agreement,
python/Python-Software-Foundation-License, qpl/Q-Public-License,
sleepycat/Sleepycat-License, zope/Zope-Public-License)

Case Sensitive (In Search Box: "case:no")

(OPTIONS: yes, no)

Also of use in understanding the search tool would be the still live FAQs page for Google Code Search.

Is there any code search engine that would fully replace Google Code Search's features?

答:
Seven similar code search engines are presented as alternatives at alternativeTo.net:

Koders.com

Koders is a syntax-specific (33 languages, soon to be 43) open source code search engine that enables developers to find, understand, and use open source code. Koders has a search index of several billion lines of code, and will further expand this to include the extensive project list on ohloh.net.

search[code]

search[code] is a code specific search engine. API documentation, code snippets and open source (free sofware) repositories are indexed and searchable. Most information is presented in such a way that you shouldn't need to click through, but of course you always can.

SymbolHound

SymbolHound offers symbol-inclusive search of open source code repositories, in addition to a feature that allows regular web searches for otherwise-ignored special characters.

Black Duck Code Sight

Black Duck® Code Sight™ is a scalable, syntax-specific (43 languages) source code search engine that enables developers to find, understand, and use shared code. Code Sight's out-of-the-box adapters allow a search index to be created from a file system or across multiple source code management systems and types. The free version limitation is 5 million LOCs

Codase

Codase is the leading source code search company with advanced source code understanding and xml index/search technologies. Rather than treating code as text, Codase understands programming languages, and treats code as code, the way it's supposed to be. This unique and syntax-aware approach provides the most accurate and detailed search results with fine granularity levels of controls. With Codase, one can search functions, classes, strings, constants, macros, comments and other programming language constructs.

GrepCode

GrepCode.com is a code search engine built by developers for developers to search and browse open source Java projects.

zGrepCode

zGrepCode.com is your helper to browse open source code online. It lets you navigate code in IDE style where you can follow references, read inline documentation, and share the code snippets anywhere easily.

A very similar service is Snipplr, a code snippet search engine. I don't think there's an obvious alternative, all services have their distinct features, you will have to evaluate them for yourself and see which one you enjoy the most.

Worth noting that Google Code Search is not really dead yet.

ContentLicense: CC BY-SA 4.0


问:
Greenspun's Tenth Rule, does every large project include a Lisp interpreter?
Greenspun's tenth rule (actually the only rule) states that:

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

My memory is that there are some papers on the topic, perhaps for Borland's Quattro (spreadsheet) project and possibly others.  Google is unhelpful, maybe the right search terms are not coming to mind.  I am looking for papers or articles supporting this claim, if any.

答:
Unfortunately not!

While its best to just embed a real lisp(y) interpreter (javascript or lua alos does a fine job), adding a homebrew 4gl to a project reduces the overall size while increasing the flexibility.

Projects which "code everything" have vastly bigger module counts and become unwieldy and inflexible.


答:
The statement is hyperbole. But there are obvious signs of Lisp envy in other languages. Look at C# and how it is becoming more functional in nature. Look at the various Business Process Management, workflow, and EAI frameworks that go out of their way to make it possible to program the system without changing the program.

There's a book on Domain Specific Languages by Martin Fowler that talks about how to do meta-programming in Object-Oriented languages. So there is some truth to the hyperbole.

Paul Graham called Lisp the most powerful language looking at the list of firsts that came with Lisp, it's easy to see why many languages pale in comparison.

The way around the tenth rule is polyglot programming. Realizing that one language/framework is not the golden hammer. Then instead of creating a poor, ad hoc implementation of Lisp, you can just use Lisp.

Title: Greenspun's Tenth Rule, does every large project include a Lisp interpreter?

Body:
Greenspun's tenth rule (actually the only rule) states that:

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

My memory is that there are some papers on the topic, perhaps for Borland's Quattro (spreadsheet) project and possibly others.  Google is unhelpful, maybe the right search terms are not coming to mind.  I am looking for papers or articles supporting this claim, if any.


问:
How do you dive into large code bases?
What tools and techniques do you use for exploring and learning an unknown code base?

I am thinking of tools like grep, ctags, unit-tests, functional test, class-diagram generators, call graphs, code metrics like sloccount, and so on. I'd be interested in your experiences, the helpers you used or wrote yourself and the size of the code base with which you worked.

I realize that becoming acquainted with a code base is a process that happens over time, and familiarity can mean anything from "I'm able to summarize the code" to "I can refactor and shrink it to 30% of the size". But how to even begin?

答:
Print out the source code and start reading through it. If it's especially large, only print out select portions of it to better understand it and make as many notes/comments as you need.

Trace through the program starting from the beginning of its execution. If you are assigned to a particular portion of the code base, trace the execution within that portion and figure out what data structures are used.

If you're using an object-oriented language, try to make a general class diagram. This will give you a good high-level overview.

Unfortunately, in the end, you will have to read through as much code as possible. If you're lucky, the previous programmers have written as much documentation as possible to help you understand what's going on.

Title: How do you dive into large code bases?


问:
Corporate vs personal email for corporate sponsored OSS
In the absence of a written policy, what is the preferred email domain (corporate or personal)   when contributing to an open source project that your employer sponsors?

I'm interested in the programmer's preference assuming the company doesn't care either way.

答:
Your employer has full access to your email. If you are comfortable with the conversation being stored in your employer's archives forever, then go with their email address.

If you're interested in continuing to contribute even after you leave your company, use your personal email address.

Just remember, if you change your email address, change it in the documentation of all your open source projects and in your version control (I have configured git to use my personal email address while on my home computer, and my corporate email while at work).

OwnerDisplayName: Error 454


问:
Does giving a developer a slower development machine result in faster/more efficient code?
Suppose I give my developers a screaming fast machine.  WPF-based VS2010 loads very quickly.  The developer then creates a WPF or WPF/e application that runs fine on his box, but much slower in the real world.

This question has two parts...

1) If I give a developer a slower machine, does that mean that the resulting code may be faster or more efficient?

2) What can I do to give my developers a fast IDE experience, while giving 'typical' runtime experiences?

Update:

For the record, I'm preparing my even-handed response to management. This isn't my idea, and you folks are helping me correct the misguided requests of my client.  Thanks for giving me more ammunition, and references to where and when to approach this.  I've +1'ed valid use cases such as:

- specific server side programming optimizations

- test labs

- the possibly buying a better server instead of top of the line graphics cards

答:
Embedded systems programmers run into this all the time! And there's a two part solution:

Your requirements need to specify X performance on Y hardware.

Test on Y hardware, and when you don't get X performance, file bugs.

Then it won't matter what hardware your developers work on.

Once you've done that, let's say faster equipment can save your programmers a half-hour a day, or 125 hours in a year. And let's say they cost $100,000 a year with benefits and overhead (ridiculously low for Silicon Valley), or $50 an hour. That 125 hours * $50/hour is $6250. So if you spend anything less than $6250 a year on rockin' development hardware per programmer, you're saving money.

That's what you should tell your management.

Tim Williscroft pretty much said the first half of this in a comment, and in a just world, he would get half of any points this answer gets.

Added Oct. 24:

My ex-employer had that theory, and it helped them piss away about $100 million.

They're a Japanese-based conglomerate that was used to hiring programmers in Japan, Korea and China. Folks there are cool with using crappy development hardware, 13-hour work days, sleeping at their desks, and not having a life. So they figured when they acquired a noted Silicon Valley company to do a Linux-based cell phone OS, those silly Californians who wanted modern gear were just whiny prima-donnas and didn't actually have a good reason for it (like productivity).

Four years later, the OS worked like crap, all the schedules were blown, and the customers were pissed off and terminating contracts right and left. Finally, the OS project was cancelled, and a large percentage of the conglomerate's worldwide workforce was laid off over the last year. And frankly, I wouldn't want to have been one of the executives who had to explain to the stockholders where all that money and effort went.

It wasn't just the slow development machines that caused this fiasco. There were a lot of other strategic and tactical blunders - but they were that same kind of thing where the people working in the trenches could see the train wreck coming, and wondered why the decision-makers couldn't.

And the slow gear was certainly a factor. After all, if you're under the gun to deliver on time, is it really a smart thing to deliberately slow down the work?


答:
Math describes (say) a cubic equation.

An algorithm describes how to solve that cubic equation.

Constructing that (or any) algorithm in a way that can be executed by a machine is programming.

Computer science is the analysis of the algorithm - its theoretical time/space efficiency, error bounds, etc.  This much could be considered a branch of mathematics.  Note however that computer science and programming are not actually the same thing.  It is important to have a foundation in computer science if you want to be a good programmer, because it helps you to better design and reason about the algorithms you develop.  But it is not a requirement.

A good programmer may not be (in fact, often is not) a good mathematician, and vice versa.  They are separate identifiable skills.

Title: What does mathematics have to do with programming?

Body:
I just started a diploma in software development. Right now we're starting out with basic Java and such (so right from the bottom you might say) - which is fine, I have no programming experience apart from knowing how to do "Hello World" in Java.

I keep hearing that mathematics is pertinent to coding, but how is it so? What general examples would show how mathematics and programming go together, or are reliant on one another?

I apologize of my question is vague, I'm barely starting to get a rough idea of the kind of world I'm stepping into as a code monkey student...


问:
Why Use !boolean_variable Over boolean_variable == false
A comment on this question: Checking if a method returns false: assign result to temporary variable, or put method invocation directly in conditional? says that you should use !boolean instead of boolean == false when testing conditions. Why? To me boolean == false is much more natural in English and is more explicit. I apologise if this is just a matter of style, but I was wondering if there was some other reason for this preference of !boolean?

答:
For some folks, the sooner a meaning is expressed the better.

For those folks having "if ! ..." compares faster to "if ..." then having to read through the entire condition (which could actually be pretty long, e.g. (thisThing = thatThing or something = the other thing) OR (thinga = thingb and thinga = thingd), etc.) just to find the ==false at the end.

Having the ! (I actually prefer a not when the language allows it) right up front gets the english 'not' for this condition in there sooner.

This issue also leads to consideration for using until in languages that support it, e.g. do 'common stuff' until thing completes.  As others say, natural language expression is the goal.  I like the "sun is shining" example above.


答:
There are two types of problems you may run into:

The compilation level where pointer data types are not matching

The run time issues where array bounds overflows and hence either violates the memory access or corrupts the internal data structure which will result in memory problem later in the execution.

Your problem looks like compilation problem than run time so it looks more like data type mismatch problem mostly but we need more information to dig up this.
Please elaborate.

Title: What are good strategies in C for dealing with pointer errors of this type?

Body:
In C, I often come across errors with code like this

```<code>prio_queue->head[index] = newEntry;
</code>```

Yields a " "Cannot assign Entry** to Entry* "
How do you prevent/debug errors of this type, in general?


问:
Do gantt charts have a role in agile software development?
I've heard it said that gantt charts are a relic of waterfall project management techniques.

I typically use an agile-like approach to project planning and tracking progress which provides good visibility into feature-time trade-offs as the project progresses.

We're at the outset of a project in in which, while the exact front-end user interaction design is somewhat unclear at this early stage, the back-end requirements are fairly clear (components that communicate with various third-party APIs, the server infrastructure, etc).

We'll be going through a process to develop good user interaction design for the front-end (starting with user stories and working forward from there), but we also wanted to get an idea of how long the back-end would take.

I decided the best approach was to break it down into sub-components, where each component consisted of tightly coupled code that should probably be worked on in a contiguous period of time.

I assigned rough time estimates to each component and sub-component, typically ranging from 1 to 10 days.  I then used OmniPlan to indicate dependencies between these various components, and assigned developers to each task, with the goal of distributing effort as equally as possible.

I then used OmniPlan's leveling tool. All, I think, a fairly standard way to use OmniPlan, and I thought reasonable way to come up with a rough time estimate.

I should clarify that the intention was not to come up with a rigid blueprint about who would work on what and when, but more come up with at least one plausible way that we could build what we needed to build in a two month period.  The gantt chart suggested that this was feasible.

To my surprise, I received quite strong pushback from another team-member familiar with the agile development process, who accused me of adopting a waterfall methodology.

Their more specific criticism was that the gantt chart was specified in terms of architectural components, rather than on user-visible features.  They were frustrated that it didn't lend itself to saying "we should have functionality X by Y date".

Where, if anywhere, did I go wrong?

答:
The big issue that I have with using Gantt charts is this. They don't do a good job of illustrating how the total amount of work left on a project changes with each iteration.  That being said, most of the business owners in our organization are familiar with Gantt charts.  This makes them an easier medium for communicating progress than the preferred (in my opinion) burn-up chart.  The burn-up does show the both the progress of the team as well as the change in scope of the project throughout it's lifecycle.  So I think there is room for compromise, but I would always have a burn-up at the ready to help fill in some of the missing information from the Gantt chart.

If you are just using it for an initial estimate, I don't see a big issue with that.  Using it to track progress does seem dated and "waterfally" to me.

OwnerDisplayName: sanity

OwnerDisplayName: garrmark


问:
How do you measure the effectiveness of your hiring & interview process?
Although I've seen many discussions on how to do an interview and develop your brand, I haven't seen many discussions on how to determine if your hiring & interview process is actually working well. I think this question has two parts:

How do you know your hiring process is getting the right candidates to apply and go through the interview process?

Of the people that you end up interviewing, how can you tell that the ones you choose to hire are better (on average) than those that you rejected?

I suppose the "extreme" cases - when you end up with a superstar or a total dud - are pretty obvious, but what about the rest?

答:
One thing that has been really useful for me in this regard is to review my interview notes on the one year anniversary of hiring an employee.

I have a standard interview script, although I usually tweak it for the particular candidate. In any case, I type up the questions that I asked and summarize the answers into a word document directly after the interview while the information is still fresh. I also have a section for my general gut feel about the candidate and what stands out about them either positively or negatively.

Of course I use this document extensively throughout the rest of the hiring process, especially when I am talking to a lot of candidates when it is easy to get confused about who said what, but it really comes in handy for fine tuning my interviewing process.

On or about one year after the hire, I think about how well the person has worked out. I look at both the positive and negative surprises over their first year. Then I go back to my interview notes and evaluate how well my questions drew out that information. Finally, I use this analysis to tweak my template interview script so that I can make sure to extract that information in future interviews. Also, I use this to get rid of questions that aren't contributing useful information and wasting valuable time during the interviews.

Over time this has really honed my recruiting process and the quality of my hires has improved steadily. I think the most important lesson I have learned from doing this is to never ignore your gut when you have qualms about a candidate, even when you can't put your finger on what the specific issue is. Not once did I have a concern from an interview that didn't manifest itself over that first year.

I blogged about this a while back in my article "19 Tips For Recruiting Great Developers".


答:
Be ready to shard everything. If you can partition it over multiple hosts you are much closer to building something that can scale.

Also design for the case of a million users and scale down. Do not design for 1,000 users and scale up.

Honestly PHP and MySQL would not be my choice to do this. Trying to do sharded data in MySQL is a pain in the neck.


问:
In integration testing, do you use the data access objects for setup and validation or a different data access method?
When writing integration tests for business logic objects and data access objects, what makes the most sense to use for setup and validation?  In my case, I'm using an ORM in the implementation of my data access interface that will be used in production, and I plumb that ORM implementation together with the business logic objects for integration testing.  Given that the ORM implementation is tested separately using INSERT and SELECT statements for setup and validation, is it best for integration testing setup and validation to use the ORM implementation of the data access interface, to use the ORM directly, to use those INSERT and SELECT statements, or to do something else, edit: and why?

The ORM in this case is NHibernate, the ORM implementation of the data access interface is a simple pass-through to NHibernate's LINQ provider that also provides simple pagination and sorting mechanisms.  I'm curious to know what you think, either generally or with this specific scenario.

edit:  I'm not looking to know what DAO I should connect to the BL objects.  That clearly should be the same DAO that will be used in production.  The question is about the mechanism used to put data into the database to set up the test before the business logic function is tested.  Presumably, the same mechanism would be used to poll the database after the business logic function is tested.  Here's some very high-level pseudo-code to demonstrate what I mean:

```<code>MyIntegrationTest()
{
    Foo fooBefore = GenerateFooForTesting();
    SomehowInsertIntoDatabase(foo); // What should be used here and why?

    // Plumb things together; actually done using IoC, not hard-coded.
    DaoFactory realDaoFactory = GetRealDaoFactory();
    BizFactory realBizFactory = GetRealBizFactory();
    realBizFactory.DaoFactory = realDaoFactory;

    BusinessLogicObject biz = realBizFactory.BuildBusinessLogicObject();
    biz.DoBusinessWithFooById(fooBefore.Id);

    Foo fooAfter = SomehowGetFooFromDatabase(fooBefore.Id); // Same question.

    Assert.AreEqual(5, fooAfter.SomethingThatShouldBeFiveAfterBusinessIsDone);
}
</code>```

答:
Even though you are testing the data access layer directly, you may want to add some redundancy to your tests by also including it in an integration test and see how it collaborates with dependant code.

It depends on what you are trying to test really. For some tests you may want to fake the entire data access layer to keep your tests fast and have tighter control over your test setup.


问:
How to simplify my complex stateful classes and their testing?
I am in a distributed system project written in java where we have some classes which corresponds to very complex real-world-business objects. These objects have a lot of methods corresponding to actions that the user (or some other agent) may apply to that objects. As a result, these classes became very complex.

The system general architecture approach has lead to a lot of behaviors concentrated on a few classes and a lot of possible interaction scenarios.

As an example and to keep things easy and clear, let's say that Robot and Car were classes in my project.

So, in the Robot class I would have a lot of methods in the following pattern:

sleep(); isSleepAvaliable();

awake(); isAwakeAvaliable();

walk(Direction); isWalkAvaliable();

shoot(Direction); isShootAvaliable();

turnOnAlert(); isTurnOnAlertAvailable();

turnOffAlert(); isTurnOffAlertAvailable();

recharge(); isRechargeAvailable();

powerOff(); isPowerOffAvailable();

stepInCar(Car); isStepInCarAvailable();

stepOutCar(Car); isStepOutCarAvailable();

selfDestruct(); isSelfDestructAvailable();

die(); isDieAvailable();

isAlive(); isAwake(); isAlertOn(); getBatteryLevel(); getCurrentRidingCar(); getAmmo();

...

In the Car class, it would be similar:

turnOn(); isTurnOnAvaliable();

turnOff(); isTurnOffAvaliable();

walk(Direction); isWalkAvaliable();

refuel(); isRefuelAvailable();

selfDestruct(); isSelfDestructAvailable();

crash(); isCrashAvailable();

isOperational(); isOn(); getFuelLevel(); getCurrentPassenger();

...

Each of these (Robot and Car) is implemented as a state machine, where some actions are possible in some states and some aren't. The actions changes the object's state. The actions methods throws IllegalStateException when called in an invalid state and the isXXXAvailable() methods tell if the action is possible at the time. Although some are easily deducible from the state (e.g, in the sleeping state, awake is available), some aren't (to shoot, it must be awake, alive, having ammo and not riding a car).

Further, the interactions between the objects are complex too. E.g, the Car can only hold one Robot passenger, so if another one try to enter, an exception should be thrown; If the car crashes, the passenger should die; If the robot is dead inside a vehicle, he can't step out, even if the Car itself is ok; If the Robot is inside a Car, he can't enter another one before stepping out; etc.

The result of this, is as I already said, these classes became really complex. To make things worse, there is hundreds possible scenarios when the Robot and the Car interacts. Further, much of that logic does needs to access remote data in other systems. The result is that unit-testing it became very hard and we have a lot of testing problems, one causing the another in a vicious circle:

The testcases setups are very complex, because they need to create a significantly complex world to exercize.

The number of tests is huge.

The test suite takes some hours to run.

Our test coverage is very low.

The testing code tends to be written weeks or months later than the code that they test, or never at all.

A lot of tests are broken too, mainly because the requirements of the tested code changed.

Some scenarios are so complex, that they fail on timeout during the setup (we configured a timeout in each test, in the worst cases 2 minutes long and even this time long they timeouts, we ensured that it is not an infinite loop).

Bugs regularly slips into production environment.

That Robot and Car scenario is a gross over-simplification of what we have in reality. Clearly, this situation is not manageable. So, I am asking help and suggestions to: 1, Reduce the classes complexity; 2. Simplify the interactions scenarios between my objects; 3. Reduce the test time and the amout of code to be tested.

EDIT:

I think I was not clear about the state machines. the Robot is itself a state machine, with states "sleeping", "awake", "recharging", "dead", etc. The Car is another state machine.

EDIT 2:
In the case that you are curious about what my system actually is, the classes that interact are things like Server, IPAddress, Disk, Backup, User, SoftwareLicense, etc. The Robot and Car scenario is just a case that I found that would be simple enough to explain my problem.

答:
I don't know your code, but taking the example of the "sleep" method, I'll assume it is something along the like of the following "simplistic" code:

```<code>public void sleep() {
 if(!dead && awake) {
  sleeping = true;
  awake = false;
  this.updateState(SLEEPING);
 }
 throw new IllegalArgumentException("robot is either dead or not awake");
}
</code>```

I think you have to make a difference between integration tests and unit tests. Writing a test that runs trough your whole machine state is certainly a big task. Writing smaller unit tests that test whether your sleep method works properly is easier. At this point you don't have to know whether the machine state has been properly updated or if the "car" correctly responded to the fact that the machine state has been updated by the "robot"... etc. you get it.

Given the code above, I would mock the "machineState" object and my first test would be:

```<code>testSleep_dead() {
 robot.dead = true;
 robot.awake = false;
 robot.setState(AWAKE);
 try {
  robot.sleep();
  fail("should have got an exception");
 } catch(Exception e) {
  assertTrue(e instanceof IllegalArgumentException);
  assertEquals("robot is either dead or not awake", e.getMessage());
 }
}
</code>```

My personal opinion is that writing such small unit tests should be the first thing to do. You wrote that:

The testcases setups are very complex, because they need to create a
  significantly complex world to exercize.

Running these small tests should be very fast, and you should not have anything to initialize beforehand like your "complex world". For example, if it's an application based on an IOC container (say, Spring), you should not need to initialize the context during unit tests.

After you have covered a good percentage of your complex code with unit tests, you may start building more time-consuming and more complex integration tests.

Finally, this can be done whether your code is complex (as you said it is now), or after you have refactored.

Body:
I don't know your code, but taking the example of the "sleep" method, I'll assume it is something along the like of the following "simplistic" code:

public void sleep() {
 if(!dead && awake) {
  sleeping = true;
  awake = false;
  this.updateState(SLEEPING);
 }
 throw new IllegalArgumentException("robot is either dead or not awake");
}

I think you have to make a difference between integration tests and unit tests. Writing a test that runs trough your whole machine state is certainly a big task. Writing smaller unit tests that test whether your sleep method works properly is easier. At this point you don't have to know whether the machine state has been properly updated or if the "car" correctly responded to the fact that the machine state has been updated by the "robot"... etc. you get it.

Given the code above, I would mock the "machineState" object and my first test would be:

testSleep_dead() {
 robot.dead = true;
 robot.awake = false;
 robot.setState(AWAKE);
 try {
  robot.sleep();
  fail("should have got an exception");
 } catch(Exception e) {
  assertTrue(e instanceof IllegalArgumentException);
  assertEquals("robot is either dead or not awake", e.getMessage());
 }
}

My personal opinion is that writing such small unit tests should be the first thing to do. You wrote that:

The testcases setups are very complex, because they need to create a
  significantly complex world to exercize.

Running these small tests should be very fast, and you should not have anything to initialize beforehand like your "complex world". For example, if it's an application based on an IOC container (say, Spring), you should not need to initialize the context during unit tests.

After you have covered a good percentage of your complex code with unit tests, you may start building more time-consuming and more complex integration tests.

Finally, this can be done whether your code is complex (as you said it is now), or after you have refactored.


答:
The rule is a joke, but there is a bit of truth in it. Any complex system would contain a number of interpreted parts (see, how the "Interpreter pattern" is popular among those who believe in all that patterns mumbo-jumbo). Any complex system must provide some means of configuration, often structured, often interpreted.

Any complex system is very likely to have several code generation passes and various customised preprocessors in its build process (think of the things like moc in Qt or tablegen in LLVM).

Many systems are juggling the complex tree-like data-structures using set of (almost always) poorly designed tree walking and transforming tools closely resembling the library functionality from Common Lisp.

All these things comes for free with Lisp, and in most cases all that ad hoc, unplanned, not thought through thoroughly enough implementations would be utterly inferior.


答:
The State design pattern might be of use, if you're not already using it.

The core idea is that you create an inner class for each distinct state - so to continue your example, SleepingRobot, AwakeRobot, RechargingRobot and DeadRobot would all be classes, implementing a common interface.

Methods on the Robot class (like sleep() and isSleepAvaliable()) have simple implementations that delegate to the current inner class.

State changes are implemented by swapping out the current inner class with a different one.

The advantage with this approach is that each of the state classes is dramatically simpler (as it represents just one possible state), and can be independently tested. Depending on your implementation language (not specified), you may still be constrained to having everything in the same file, or you may be able to split things out into smaller source files.

Title: How to simplify my complex stateful classes and their testing?

Body:
I am in a distributed system project written in java where we have some classes which corresponds to very complex real-world-business objects. These objects have a lot of methods corresponding to actions that the user (or some other agent) may apply to that objects. As a result, these classes became very complex.

The system general architecture approach has lead to a lot of behaviors concentrated on a few classes and a lot of possible interaction scenarios.

As an example and to keep things easy and clear, let's say that Robot and Car were classes in my project.

So, in the Robot class I would have a lot of methods in the following pattern:

sleep(); isSleepAvaliable();

awake(); isAwakeAvaliable();

walk(Direction); isWalkAvaliable();

shoot(Direction); isShootAvaliable();

turnOnAlert(); isTurnOnAlertAvailable();

turnOffAlert(); isTurnOffAlertAvailable();

recharge(); isRechargeAvailable();

powerOff(); isPowerOffAvailable();

stepInCar(Car); isStepInCarAvailable();

stepOutCar(Car); isStepOutCarAvailable();

selfDestruct(); isSelfDestructAvailable();

die(); isDieAvailable();

isAlive(); isAwake(); isAlertOn(); getBatteryLevel(); getCurrentRidingCar(); getAmmo();

...

In the Car class, it would be similar:

turnOn(); isTurnOnAvaliable();

turnOff(); isTurnOffAvaliable();

walk(Direction); isWalkAvaliable();

refuel(); isRefuelAvailable();

selfDestruct(); isSelfDestructAvailable();

crash(); isCrashAvailable();

isOperational(); isOn(); getFuelLevel(); getCurrentPassenger();

...

Each of these (Robot and Car) is implemented as a state machine, where some actions are possible in some states and some aren't. The actions changes the object's state. The actions methods throws IllegalStateException when called in an invalid state and the isXXXAvailable() methods tell if the action is possible at the time. Although some are easily deducible from the state (e.g, in the sleeping state, awake is available), some aren't (to shoot, it must be awake, alive, having ammo and not riding a car).

Further, the interactions between the objects are complex too. E.g, the Car can only hold one Robot passenger, so if another one try to enter, an exception should be thrown; If the car crashes, the passenger should die; If the robot is dead inside a vehicle, he can't step out, even if the Car itself is ok; If the Robot is inside a Car, he can't enter another one before stepping out; etc.

The result of this, is as I already said, these classes became really complex. To make things worse, there is hundreds possible scenarios when the Robot and the Car interacts. Further, much of that logic does needs to access remote data in other systems. The result is that unit-testing it became very hard and we have a lot of testing problems, one causing the another in a vicious circle:

The testcases setups are very complex, because they need to create a significantly complex world to exercize.

The number of tests is huge.

The test suite takes some hours to run.

Our test coverage is very low.

The testing code tends to be written weeks or months later than the code that they test, or never at all.

A lot of tests are broken too, mainly because the requirements of the tested code changed.

Some scenarios are so complex, that they fail on timeout during the setup (we configured a timeout in each test, in the worst cases 2 minutes long and even this time long they timeouts, we ensured that it is not an infinite loop).

Bugs regularly slips into production environment.

That Robot and Car scenario is a gross over-simplification of what we have in reality. Clearly, this situation is not manageable. So, I am asking help and suggestions to: 1, Reduce the classes complexity; 2. Simplify the interactions scenarios between my objects; 3. Reduce the test time and the amout of code to be tested.

EDIT:

I think I was not clear about the state machines. the Robot is itself a state machine, with states "sleeping", "awake", "recharging", "dead", etc. The Car is another state machine.

EDIT 2:
In the case that you are curious about what my system actually is, the classes that interact are things like Server, IPAddress, Disk, Backup, User, SoftwareLicense, etc. The Robot and Car scenario is just a case that I found that would be simple enough to explain my problem.


问:
Programming *into* a language vs. writing C code in Ruby
Code Complete states that you should aways code into a language as opposed to code in it. By that, they mean

Don't limit your programming thinking only to the concepts that are supported automatically by your language. The best programmers think of what they want to do, and then they assess how to accomplish their objectives with the programming tools at their disposal. (chapter 34.4)

Doesn't this lead to using one style of programming in every language out there, regardless of the particular strengths and weaknesses of the language at hand?

Or, to put the question in a more answerable format:

Would you propose that one should try to encode one's problem as neatly as possible with the particulars of one's language, or should you rather search the most elegant solution overall, even if that means that you need to implement possibly awkward constructs that do not exist natively in one's language?

答:
There is an even better approach: forget about your pathetic fixed programming language at all. Encode your problem in a language you've just invented, derived from the very terms of the relevant problem domain, encode it as naturally as possible, and only then think of implementing this new programming language or dumbing your code down to the limitations of the existing language.

This approach is called Language-oriented programming. There are many techniques of implementing the domain-specific languages efficiently, and it is an especially hot topic for the Ruby community.


问:
Is this bad design for a Shape interface?
I'm creating a vector editing program in C++, and I need a Shape interface which other concrete classes will implement. There is a requirement that no implementation inheritance is allowed. The design doc says that if you need polymorphism, use interfaces. If you need code reuse, use composition.

The Shape interface is:

```<code>class Shape
{
  public:

   virtual void get_name()=0;
   virtual void set_name()=0;
   virtual void get_linewidth()=0;
   virtual void set_linewidth()=0;

   ...
   ...about 20 other getters/setters
   ...

   virtual void draw()=0;
   virtual int area()=0;
   virtual void rotate(int angle)=0;

}
</code>```

The Circle class:

```<code>class Circle: public Shape
{
  string name;
  int line_width;
  int angle_of_rotation;
  int radius;
public:
  string get_name(){ return name; }
  string set_name(string name){ this->name=name; }
  ...
  ...about 20 other getters/setters
  ...

  int area()
  {
    return PI*pow(this->radius,2);
  }

}
</code>```

I have no problem with this, except common properties have to be repeated for each type of shape! This is solved using inheritance, but I am not allowed to use that.

So, I create a ShapeProperties class

```<code>class ShapeProperties
{
  string name;
  int line_width;
  int angle_of_rotation;

public:

  string get_name(){ return name; }
  string set_name(string name){ this->name=name; }

  ...
  ...about 20 other getters/setters
  ...

}
</code>```

and a properties() method for the interface:

```<code>virtual ShapeProperties* properties()=0;
</code>```

A user would then do:

```<code>Shape *shape = new Circle();
shape->properties()->set_name("my shape");
shape->properties()->set_line_width(4);
int area = shape->area();
</code>```

My question: Is this good design? Is this bad design? Are there any obvious problems? How could it be made better?

答:
shape->properties()->set_name("my shape");

This is called train wreck, therefore it is better to avoid, because the method that needs to call properties() and then set_name() needs to know too much.
Unless the shape is a data structure, and in your case doesn't seems to be.

If you must use method to get properties, then make them data structure (without any methods, and with all public member variables), and return const reference :

```<code>const ShapeProperties& properties() const
</code>```

then the properties looks like :

```<code>struct ShapeProperties
{
  std::string name;
  int line_width;
  int angle_of_rotation;
  // ...
};
</code>```

Body:
shape->properties()->set_name("my shape");

This is called train wreck, therefore it is better to avoid, because the method that needs to call properties() and then set_name() needs to know too much.
Unless the shape is a data structure, and in your case doesn't seems to be.

If you must use method to get properties, then make them data structure (without any methods, and with all public member variables), and return const reference :

const ShapeProperties& properties() const

then the properties looks like :

struct ShapeProperties
{
  std::string name;
  int line_width;
  int angle_of_rotation;
  // ...
};


答:
It's a bad design because you have implemented a subclass for something that isn't a genuine subclass. A Circle is simply one example of a FunctionalShape, as opposed to a VertexShape. Examples of FunctionalShapes are circles, and also ellipses, and similar things. The function used to generate the shape is just data, and it's a bad idea to create different subclasses to represent different things which are just data.

What your code demonstrates is that the restriction to an interface is pointless, because your logic can be trivially reduced to not requiring a dynamic dispatch. Most of it could just be even a public member variable. Technically, you haven't used implementation inheritance, but in reality, you have, you've just coded it in a slightly different fashion.

The reality is that without using implementation inheritance, there is no way in C++ to make this code usable. There's a reason that that language feature exists and it's because not having it is dumb, and pointless, and makes your life very hard for no valid reason whatsoever.

Composition can re-use logic. It can't re-use class description, which is the part that you're endlessly (and pointlessly) repeating. There is no solution within your given constraints.

Title: Is this bad design for a Shape interface?

Body:
I'm creating a vector editing program in C++, and I need a Shape interface which other concrete classes will implement. There is a requirement that no implementation inheritance is allowed. The design doc says that if you need polymorphism, use interfaces. If you need code reuse, use composition.

The Shape interface is:

```<code>class Shape
{
  public:

   virtual void get_name()=0;
   virtual void set_name()=0;
   virtual void get_linewidth()=0;
   virtual void set_linewidth()=0;

   ...
   ...about 20 other getters/setters
   ...

   virtual void draw()=0;
   virtual int area()=0;
   virtual void rotate(int angle)=0;

}
</code>```

The Circle class:

```<code>class Circle: public Shape
{
  string name;
  int line_width;
  int angle_of_rotation;
  int radius;
public:
  string get_name(){ return name; }
  string set_name(string name){ this->name=name; }
  ...
  ...about 20 other getters/setters
  ...

  int area()
  {
    return PI*pow(this->radius,2);
  }

}
</code>```

I have no problem with this, except common properties have to be repeated for each type of shape! This is solved using inheritance, but I am not allowed to use that.

So, I create a ShapeProperties class

```<code>class ShapeProperties
{
  string name;
  int line_width;
  int angle_of_rotation;

public:

  string get_name(){ return name; }
  string set_name(string name){ this->name=name; }

  ...
  ...about 20 other getters/setters
  ...

}
</code>```

and a properties() method for the interface:

```<code>virtual ShapeProperties* properties()=0;
</code>```

A user would then do:

```<code>Shape *shape = new Circle();
shape->properties()->set_name("my shape");
shape->properties()->set_line_width(4);
int area = shape->area();
</code>```

My question: Is this good design? Is this bad design? Are there any obvious problems? How could it be made better?


问:
Is Java a good choice for cross-platform games?
I'm looking to create a game in Java and would like it to work on Windows, Linux, and Mac. I'm pretty sure C# is a bad choice for this, and I don't have enough experience in C or C++. I want to stay away from Flash. Therefore, is Java a good choice for me? Mostly, I use C#, and think that Java is similar, so I assume it won't be that hard to learn. But is it fast enough? Is there a language more suited for my needs than Java?</p>

答:
You can use Scala and Scheme Bigloo on Eclipse to use JVM for stressed code or parrallel action inside your Java game.

With Pattern Design and UML2, you can also secure code with OCL, all is in Topcased.org .

Mastering those tools take time, but they are the Java's background, the base which will push you at the top.


答:
First off: I am a mathematician - a professional one (in that I get paid for doing maths).  I am not a programmer.  I do do some programming, but very definitely of the Cargo Cult variety (see first comment to https://tex.stackexchange.com/q/451/86 and my response) and nothing of the sort that would normally bring me to this site (indeed, I registered here to post this answer after seeing a link to it in the TeX chat room).

The summary of my answer is: Mathematics is Programming.

I recently got to teach a mathematics course to a non-mathematical group of students.  They were the programming section.  I thought this was fantastic!  At last, I was going to be able to teach mathematics to people who already understood the basic ideas and who already had a rudimentary toolkit for doing maths.  I was incredibly disappointed when I asked how many of them had actually written a program and got an answer somewhere between 0 and 1.

Before I go on, I should clarify a few things.  There are areas of mathematics that concern themselves directly with programming and are to do with evaluating algorithms and classifying languages and such-like.  I'm not talking about those.  There is also a program which is trying to translate all of mathematics into a formal language that can be evaluated by a computer.  This is a bit closer to what I'm talking about, but even so to focus on that would miss the main part of what I'm trying to say.  The mathematics that I do and the programming that I do are almost completely unrelated by topic.  The connection between them is on a different level.

Where I'd like to start is with the comment on the main question:

If that is doing math, then all human activity is a form of math. If that's the case then the word math doesn't have a useful meaning, because it can't be used to distinguish one activity from another.

Yes, that is doing maths.  But "maths" is still a useful word because, as the song says, "It ain't what you do, it's the way that you do it.".  I would say that I am doing maths when I am approaching something in a mathematical way.  Sometimes, that is "hard core" mathematics: formulating definitions, proving theorems.  Sometimes, it isn't.  Sometimes, it's writing silly little programs so that my kids can learn their spelling words.

This is what mathematics helps me with when I program:

Abstraction This is probably the most important transferable skill from mathematics.  By this, I mean the ability to strip away all the unnecessary stuff and focus on the important properties.

Perspective If I could only choose one thing that all my students were to learn, this would be it: The ability to change ones point of view to suit the problem.  We commonly treat this in linear algebra with change-of-basis formulae (that lead to horrendous matrices and horrendous complications), but it is much more applicable than that.  At heart, it is the idea that just because something has been presented to you in one fashion, that doesn't have to be the way you work with it.  This separates ones view of the thing itself from the way it has been presented.  This can be extremely practical: it is all about making something useful or efficient.  If I have a list of vectors and it is more efficient to store them as a list of x-coordinates and a list of y-coordinates, so be it.

Form versus Function Leading on from the above; if a thing can be presented in many different ways then it is no longer fair to say that one particular presentation is the thing.  To misquote that song again: "It ain't what you are it's what you do" that matters.

I could go on, but those are the ones that spring to mind.

Now, there are probably lots of (negative) reactions to what I've written so far.  One will be "That's not maths, that's just good sense." (or bad sense) to which I refer to my remark above agreeing with the sentiment that "all human activity is a form of math".  Another will be "That isn't the type of maths meant in the question.".  This is almost certainly true and here I actually have a lot more sympathy with the person who said "At least I haven't touched the maths for 10 years,".  He or she is wrong, of course, they have been doing maths for 10 years because whenever they wrote a program they were doing maths.  They just didn't realise it.  And here we get to the point about why I was delighted with the (sadly unrealised) possibility of teaching mathematics to students who were already programmers.

I do actually use some "real maths" in my programs.  I recently coded a fun 3D shape explorer which involved using some maths to figure out the projections and other transformations that I had to apply to my data.  I was mildly amused to find myself actually coding quaternions!  But of course, the maths that was involved was trivial compared to the maths that I do when I'm working.  It was "back of envelope" stuff.  That type of maths, then I agree with the sentiment that you pick it up when you need it, and if you need something more complicated than you can find on Wikipedia then you find a real mathematician to do it for you.  However, in order that you can pick it up when you need it then you need to have learnt something.  That thing might not be anything you ever actually use, but having learnt that something makes it all the easier to pick up what you do actually use later in life.  So this is where I disagree with Coder: you do need to learn some mathematics if you are ever going to use any mathematics and you need to learn it from the mathematical side (which doesn't mean proving theorems, by the way).

And so finally to the "Mathematics is Programming".  You can learn all of these things from being a good programmer.  And if you've learnt these things, you will find mathematics much easier because you will understand that when we talk about a vector in a vector space then it's just an instance of the class Vector which means that we can do all the things that Vector does to that instance: add, subtract, scale, and so forth.  That's why I would love to teach mathematics to programmers.  But, speaking as a mathematician, I would say that the first of these, "Abstraction", is easier to learn in mathematics than in programming because mathematics is the pursuit of abstraction.  Whenever we see some behaviour our training is always to ask "What is it about that thing that makes it behave in that way?  What if I took another thing that was similar, would it behave in the same way?  How much of what that thing is would I have to lose for it to stop behaving like that?"  (Taking this to the extreme leads to "centipede mathematics" - search for the term).  But we don't do this with (just) "real world" objects (whatever they are), we do this with things that have already been abstracted.

This has gone on long enough, so let me close with one of the classic mathematician jokes:

A mathematician and a physicist both attended a seminar on some new model involving 24 dimensional space.  Afterwards, they were discussing it and the physicist remarked: "That was really hard.  I mean, how does one visualise 24-dimensional space?" to which the mathematician replied: "Oh, it's easy.  Just visualise n-dimensional space and then set n = 24.".

Added 2012-03-2

There were quite a few comments on this answer expressing a variety of views.  These have now been deleted by a moderator on the understanding that I would try to take into incorporate them (or respond to them) in my answer.

However, I'm not sure that I can.  Reading those comments and the rest of what's on this page, I can only come to the conclusion that there is a huge misunderstanding as to what mathematics actually is.  Moreover, I don't feel competent enough to explain it.  Fortunately, someone has already linked to Lockhart's Lament so I'll defer the explanation to that.  Whilst I might have put it differently (as I grew up in a scientific environment, I would have put more emphasis on the experimental nature of mathematics), I don't think I could put it better.

I do still think I can add something.  As well as the misunderstandings as to what mathematics is, there are also misunderstandings as to what "doing mathematics" means.  I see two almost contradictory stances:

Mathematics is about equations and formulas.  So there's no need to study it because Wikipedia exists (this is almost the converse of Euler's apocryphal challenge to Diderot).

Mathematics is about theorems and definitions.  So there's no need to study it as programs never prove anything (which is about as complete a fallacy as ... insert favourite fallacy here).

Whilst the two stances contradict each other, they end up in the same place: there's no point in a programmer learning any mathematics - and most assuredly not from a mathematician!  After all, what do they know about anything?  Anything that a programmer really needs to know can be found in Wikipedia, or cribbed off someone else.

Above, I described myself as a Cargo Cult Programmer.  I bet most of you had a private giggle to yourself and thought, "Ah yes, I bet I know what your programs look like then.".  You probably felt a bit smug and superior (though I'm sure you felt bad about feeling smug and superior).

What I've described just above is Cargo Cult Mathematics.

So when I say that you should learn a bit of mathematics to understand how mathematics works, I'm saying it for exactly the same reason as you might if you saw a bit of code that I'd written: "How much easier your life would be if you'd stop cut-and-pasting code from StackOverflow and learnt just a bit about how to do it properly.".

The most important thing, though, is that you should learn it from mathematicians.  Why so?  Here's an analogy.  The language that I'm most adept at is TeX.  (Says it all, really!).  Now, suppose I want to learn a bit more about TeX and it just so happens that Don Knuth is in town and has offered to give some tutorials on TeX.  Or I could just read about it on Wikipedia.  Or maybe it's Perl and Larry Wall, or C# (is that the right one?) and Jon Skeet.  It may well be that these people are not the best teachers, but they sure make up for it in the amount that they know!

And that's what mathematicians are.  We're the people who write the actual language, who then write the libraries that you use.  Of course, you don't have to know how to prove a theorem - you're not going to write a library!  But if you know a bit about how we think, then it might help you understand why we wrote the library the way we did, and if you understand that it might help you make better use of it.

There is a middle ground between looking up equations on Wikipedia and proving the Poincaré conjecture, just as - to refer to Lockhart's lament - there is a middle ground between "I don't really know much about art, but I know what I like" and being Monet, and between "Where's the 'ANY' key?" and being Don Knuth.  If you are still in university then you have an amazing opportunity to learn from people who are experts in their area and who - for some reason - are willing to spend their time explaining it to you.

The other point I wanted to expand on a bit was why as a programmer you should not be scared of learning a bit more mathematics.  It's not the Deep Connections, nor the usefulness.  It's that your ability to program a computer can directly help you learn mathematics.  I just want to mention a few.

Understanding variables.  So many people get confused by simple statements like "Let n be a natural number ...".  Or "Let epsilon > 0".  There are places in mathematics where it's important to remember the scope of a variable.  These are all commonplace in programming.  Learn to translate a mathematical statement into a program and you'll find it much easier to keep track of what's what.

The nature of proof.  If you've ever written a test, or written a program to be used by someone else, then you understand the core of proofs.  When you do that, you have to know that whatever the user puts in, you can deal with it (insert obligatory xkcd reference here).  That's all a proof is!  A demonstration that whatever the "user/universe" puts in, the statement will hold.  Experimentalists will lean to the "If it works under normal circumstances, it's true" but programmers know that there is always that kid who will try Alt+G+Shift+ÅØÆ just to see what happens.

DRY.  Sorry to break this to you, but we invented it, not you.  We've been "not repeating ourselves" for millennia.  That's why I have a copy of Euclid's elements on my shelves and it's still useful.

And there's more.  If I knew a bit more about programming, I'd write a book called "Mathematics for Programmers" where the aim wasn't to teach "The mathematics that programmers should know" but "mathematics that everyone should know, but optimised for programmers".  But I'll probably never know enough about programming to write it - unless someone offers to collaborate with me!

I'll leave it there.  Probably if I thought more, I'd change what I've written; hopefully I'd explain it better.  In a months' time I might even disagree with parts of it.  If anyone wishes to argue further, or comment otherwise, probably best not to do so in the comments here.  You know where to find me.


答:
Some good examples of scaling with PHP: Tumblr, Flickr, Netlog

The common advice given on scalability:

Keep it simple!
Don't overengineer or buy into fancy vendor-specific solutions.

Shared-nothing architecture
Keep your state in the database and off your application servers (avoid even session data on the server). This way you can easily add additional app servers as needed.

Focus on front-end (static file) caching
Use a reverse proxy and later on a CDN. Whatever doesn't have to get served from the app server is less load on that server.

Measure the real system
Build in monitoring so you know where your bottlenecks are. Ensure that you can predict future load based on growth curves.

Pay attention to your DB design
Tune your queries, use memcached to avoid querying at all, and shard your data across instances when you run out of breathing space on one DB instance (monitor to know this ahead of time).

Some pitfalls:

NoSQL vs SQL is a red herring.
All the big guys are running their core on SQL databases. Use NoSQL if you're sure that it makes sense, but don't use it assuming it will solve your scaling issues. It won't.

Be careful about ORM's.
They're state-heavy on the app server (contradicts shared-nothing architecture), and they require you to understand not just how to tune SQL queries, but how to tune the ORM on top of the SQL queries (in other words, they only simplify things if performance doesn't matter). Give preference to hand-designed queries and liberal use of memcached instead.

Heavy templating/routing systems on the server. Keep the server stack deliberately light-weight.

Don't worry about line-by-line code performance.
You can always go in and fix hotspots later on (use xdebug or similar profiling tools). Having a scalable architecture matters MUCH more than code performance, so invest your brainpower accordingly.


问:
How to name event types?
Clean code recommends to name methods to be a verb, and classes to be a noun.

I am developing an c++ application using boost::signal as some kind of event framework, and have defined various events, but naming them to make the code cleaner seems to be problematic.

So, how to name event types?

答:
Robert C. Martin mentioned that your names have to be meanful and searchable. It should be a verb or a verb phrase. So from my point of view I would allways clarify that this method is a event by building a verb phrase.

Some examples could be:
- SaveEvent()
- RenderEvent()
- CloseEvent()

Whit this format I am allways able to find the Event-Method. I know exactly that this method is a event and I dont need to seach for some points that let me know that this method is a event.

Title: How to name event types?


问:
What php programmer should know?
I've dig the database here and didn't found any answer for my question.

What is a standard for a php programmer to know? I mean, literally, what group of language functions, mechanisms, variables should person know to consider oneself a (good) php programmer? (I know 'being good' is beyond language syntax, still I'm considering syntax of plain php only)

To give an example what I mean:

functions to control http sessions, cookies

functions to control connection with databases

functions to control file handling

functions to control xml
etc..

I omit phrases like 'security' or 'patterns' or 'framework' intentionally as it applies to every programming language.

Hope I made myself clear, any input appreciated :)

EDIT 1:

Note:

Michael J.V. is right claiming that databases are independent from language, so to put my question more precisely and emphasise differences:

Practises or security, are some ideas to implement (there is no 'Pattern' object with 'Decorator()' method, is there?) while using databases means knowing a mysqli and a set of its methods.

EDIT 2:
It all came to me after some interview task:

Count seconds, days, months, years elapsed since date input till now.

So I had opened the php docs to check date functions. After I had done tasks the interviewer told me he wasn't satisfied with my actions since datetime() is something everyone should know. That's why I'm asking all this. What everybody should know..

答:
A php programmer should know:

how the http protocol works

the php syntax

that he can find 90% of the answers to his questions in the php doc

what is available in the array, string, xml, filesystem php API so he does not reinvent the wheel everyday

how to handle sessions

if using some database: how to use joins and group functions

A decent php programer should know:

how to get user inputs safely

that you use prepared statements to query a database

output buffering

what a REST, SOAP or XML-RPC API is and how to use one

if using databases: how to normalize his data

at least one framework

at least one templating system

The two last ones so he can assess if they'll benefit him for a project

A good php programmer should know:

how to use a unit test framework to test his work

continuous integration

how to document his code

a style checking app for his code

some design patterns and when to use them

if using databases: triggers, stored procedures and when to use them.

As any programmer : how to use his IDE and some version control software.

Title: What php programmer should know?


问:
Functional Programming -- Immutability
I am trying to understand dealing with immutable data in FP (specifically in F#, but other FP’s are ok as well) and break the old habit of state-full thinking (OOP style).
A part of the selected answer to the question here reiterated my search for any write-ups around problems that are solved by stateful representations in OOP with immutable ones in FP (For ex: A queue with Producers & Consumer). Any thoughts or links are welcome? Thanks in advance.

Edit: To clarify the question a little more, how would immutable structures (ex: queue) be shared concurrently across multiple threads (ex: producer and consumer) in FP

答:
...problems that are solved by stateful representations in OOP with immutable ones in FP (For ex: A queue with Producers & Consumer)

Your question is what is called an "XY problem". Specifically, the concept you cite (queue with producers & consumer) is actually a solution and not a "problem" as you describe. This introduces a difficulty because you are asking for a purely functional implementation of something that is inherently impure. So my answer starts with a question: what is the problem you are trying to solve?

There are many ways for multiple producers to send their results to a single shared consumer. Perhaps the most obvious solution in F# is to make the consumer an agent (aka MailboxProcessor) and have the producers Post their results to the consumer agent. This uses a queue internally and it is not pure (sending messages in F# is an uncontrolled side effect, an impurity).

However, it is quite likely that the underlying problem is something more like the scatter-gather pattern from parallel programming. To solve this problem you might create an array of input values and then Array.Parallel.map over them and gather the results using a serial Array.reduce. Alternatively, you might use functions from the PSeq module to process the elements of sequences in parallel.

I should also stress that there is nothing wrong with stateful thinking. Purity has advantages but it is certainly not a panacea and you should make yourself aware of its shortcomings as well. Indeed, this is precisely why F# is not a pure functional language: so you can use impurities when they are preferable.

Title: Functional Programming -- Immutability


问:
How important is maths depending on what your coding?

Possible Duplicate:

  What does mathematics have to do with programming?

  How often do you have to solve pure mathematical or algorithmical problems?

I heard that math can be very important in programming. I am a confident python programmer, and have started C++.

So far I have not encountered anything where I need to use any real math.

I have had to use logic and a bit of problem solving, but that's about it.

I also wanted to know: does a particular part of coding (software engineering or game development) use maths more?

答:
It depends completely on what kind of systems you program. But your experience is common: most programming is done on workflow support systems of one kind or another, which rarely require any math.

But there are fields where this is different: scientific computing, obviously. 3D graphics (but not so much if you use an engine someone else developed). Algorithmic trading.


问:
Should a test plan account for configuration values?
Should a test plan for internal software account for the error states of all possible configurations?

Ie: I have an app.config with some file paths.  Should the test plan have steps for testing what happens when those values are incorrect?

答:
In an ideal world, yes.

Even if it an internal app, you can't control its use by users and the more it is used, the more it will probably be used in ways you hadn't thought of.

However, we don't always live in an ideal world, so justifying the "budget" may be tricky - "it works, move on".

At the very least, I would advise implementing some form of logging so when (if?) problems do arise, you have a head start on recreating them.  As it is an internal app, getting hold of the log files shouldn't be a problem.


问:
when to load partial views
When creating a website, when should you load partial view and when should you do a complete page refresh?

I was looking at github's site and noticed that pretty much the only place they do partial loading is in a project's folder area.  I could see a couple places where they could have but didn't(tab navigation: feed, your actions, ...). But, Google plus does partial loads for search, and clicking on any of the header navigation buttons (pictures, games, circles, ...).

Why would you not do partial loading if the main container stays the same and the content is the only thing that is changing?

答:
I use a simple rule of thumb:

If the data's dynamic, then partial loading should be used where possible.
 If the data's static, then a full page load is probably better. This is better for SEO purposes, too.

Basically it comes down to a static vs dynamic thing for me. I don't really see the point in allowing dynamic loading of two completely different data sets (for example through clicking a menu item / tab option).

Title: when to load partial views


问:
How do you integrate Testing into a Scrum process?
This is really perplexing me. We have a 'definition of done' and it includes dev 'done', unit tests 'done', dev test 'done'. However we also have a user acceptance test that needs to be 'done' but the business wants to know when users stories are complete so that they can see stuff (the uat really isnt a priority until release). But because this is outside of the initial done (where we pass our user stories) how can we say its done? And where does this fit into estimating?

Where can I find information on integrating testing with a scrum process? I think I need to read up this...

答:
Typically, the definition of done includes more than what you are including, such as integration tests, acceptance tests, and documentation (both developer-oriented and user-oriented). Once unit tests pass, you can integrate the new feature/components and run integration tests. Once the feature is integrated, you execute the acceptance tests. Once acceptance tests pass, you can make sure any documentation is reflective of any recent changes and the feature is done. One problem is that acceptance testing shouldn't be a priority for a release, but a priority to verify and validate the completion of a story.

As far as estimating goes, your estimate should include everything from validation of the user story through acceptance testing. If you don't account for all of the activities and tasks needed to fully complete, integrate, verify, and validate the user story, the estimate doesn't add that much value. It might be a fairly simple feature to create and test, but incredibly difficult to integrate with your current design, meaning other features need to be refactored and retested. Not accounting for this means your velocity tracking will be off.


答:
but the business wants to know when users stories are complete

It ain't done until your customer says it's done: any other definition of "done" is delusional. User acceptance tests are the success criteria for a user story: which is why they're called "user stories" not "management stories".

Title: How do you integrate Testing into a Scrum process?

Body:
This is really perplexing me. We have a 'definition of done' and it includes dev 'done', unit tests 'done', dev test 'done'. However we also have a user acceptance test that needs to be 'done' but the business wants to know when users stories are complete so that they can see stuff (the uat really isnt a priority until release). But because this is outside of the initial done (where we pass our user stories) how can we say its done? And where does this fit into estimating?

Where can I find information on integrating testing with a scrum process? I think I need to read up this...


答:
Other naming options may include:

Format 1:
On[Objectname][DetailedEventName]

Example:

OnMouseClick

OnMouseRightButtonClick

Format 2:
On[DetaieldConditionName]

Examples:

OnRecordNotFound

OnCustomerRowNotFound

Other posts related to this:
StackOverFlow-EventNames

Title: How to name event types?

Body:
Clean code recommends to name methods to be a verb, and classes to be a noun.

I am developing an c++ application using boost::signal as some kind of event framework, and have defined various events, but naming them to make the code cleaner seems to be problematic.

So, how to name event types?


问:
Getting involved on Github (how to find projects)
I want to contribute to open source projects on Github. Mostly, I'd like to just start out fixing small bugs or adding features. I don't have a particular project in mind. I'd like to work on C, C++, Python, .NET, Java, etc projects. However, my problem is I can't figure out how to find anything on Github.

I did find a page on Explore Github, that lists C projects. Basically, it lists the top 5 "watched" C projects. OK, that's fine, but I want to see more than 5.

Sourceforge was/is great because you can browse projects by programming language. Also, SourceForge has or used to have a forum for finding projects that are asking for help. I can't find any of that on Github. There is a "Search" feature that, seems fairly useless for finding projects to contribute to. I tried the advanced search, setting it to "Repositories" and "C" for the programing language. However, you have to put something int he search; although I just want to browse titles and descriptions of projects.

So, I tried putting "network" just to see what comes up. It gives just a list of everybody's fork of every project there is.

Is there any way I can search, say through a third party or something, for projects in a sane way? It seems like Github should have such a thing; I would just choose from Sourceforge since I can search there, but I want to establish a Github profile, since that is the flavor of the month and there are all these fanboys on Hacker News that seem to think a Github profile is better than a Resume/CV. :)

答: If you search for language:csharp for instance using the box, it will show you all the csharp projects, and sort them by the number of watchers. No need to pick the language in the dropdown, it will ignore that setting.


问:
What's the difference between computer science and programming?
I'm new at computer science and programming, and I was wondering, is there a difference between computer science and programming? and do you get to choose to study only one of them at the university, or both of them?</p>

答:
Computer science is the theory of programming. Programming is the implementation.

Computer science ...is the scientific and practical approach to computation and its applications. A computer scientist specializes in the theory of computation and the design of computational systems.

Its subfields can be divided into a variety of theoretical and practical disciplines. Some fields, such as computational complexity theory (which explores the fundamental properties of computational problems), are highly abstract, while fields such as computer graphics emphasize real-world visual applications. Still other fields focus on the challenges in implementing computation. For example, programming language theory considers various approaches to the description of computation, whilst the study of computer programming itself investigates various aspects of the use of programming language and complex systems. Human-computer interaction considers the challenges in making computers and computations useful, usable, and universally accessible to humans...


答:
If programming is carpentry, then computer science is architecture/design.

Edit

More info: in carpentry, you're interested in things like what what order to build things in (frame, then subfloor, then interior walls, then drywall, etc.).  How do you build it so that it takes less time to construct, but can be modified later.

In the case of architecture (the part of it like CS anyway), you're concerned with things like what are the capabilities of the materials, how big of a beam do you need to support this span of wall/roof?

Similarly CS is about the theoretical capabilities of computers, where programming is about the practical application of that knowledge.

Title: What's the difference between computer science and programming?

Body: I'm new at computer science and programming, and I was wondering, is there a difference between computer science and programming? and do you get to choose to study only one of them at the university, or both of them?</p>


答:
Computer science is the study of what computers [can] do; programming is the practice of making computers do things.

Take a look at the courses/syllabi offered by universities you're interested in to find out whether the course is a CS course, a programming course, something else (for example Software Engineering) or even a combination of the above. Many courses advertised as "computer science" offer a significant programming component, which may be so that you can put the theoretical parts of the course into practice, or may be for their own sake so that you can learn the skill of making programs.


答: Programming is about people. People read, write, and maintain code. Computer science is about mathematics- they implement and describe algorithms.</p>


答:
Computer Science is, from my point of view, supposed to be a Hard Science like Physics.

It involves the study of compilers and compiler generators, hardware architecture concepts, various forms of number systems, algorithms and algorithmic efficiency / performance and the theory behind arithmetic operations on the processor.  When I did CS at university we spent a lot of time mucking around with assembler, learning about the difference between compiling, linking and interpreting, etcetera.

A lot of this was done by programming - that is, the act of writing code which was then compiled or run via an interpreter, with the intention of generating results to solve a problem.  That is, Programming is the act of solving problems which can be described with knowledge from Computer Science.  It's kind of a Pure Maths / Applied Maths split.

You don't need a Computer Science degree to be a programmer, but a programmer with a CS background will likely have a deeper understanding of the behaviour of computer programs.


答:
I would reword your question as "What's the difference between Computer Science and Software Engineering?" After all both involve programming.

Computer Science is the theortical study of what computation is and what is and is not possible. It looks at things like Godels Theorem and the Halting problem.

Software engineering is how to write programs that do what they have been designed to do and are maintanable.


问:
What are good strategies in C for dealing with pointer errors of this type?
In C, I often come across errors with code like this

```<code>prio_queue->head[index] = newEntry;
</code>```

Yields a " "Cannot assign Entry** to Entry* "
How do you prevent/debug errors of this type, in general?

答:
I've been away from a C compiler for quite a few years, but isn't it telling you that prio_queue->head[index] is a pointer to Entry and newEntry is a pointer to a pointer to Entry?  Try:

prio_queue->head[index] = *newEntry;


答:
Computer science deals with the theoretical foundations of
  information, computation, and with practical techniques for their
  implementation and application.
  http://en.wikipedia.org/wiki/Computer_science

~

Computer science is no more about computers than astronomy is about
  telescopes.
  Edsger Dijkstra

Programming is the craft of creating a computer program.


问:
Rigorous Definition of Syntactic Sugar?
It seems like in language holy wars, people constantly denigrate any feature they don't find particularly useful as being "just syntactic sugar".  The line between "real features" and "syntactic sugar" tends to get blurred in these debates.  What do you believe is a reasonable and unambiguous definition of syntactic sugar that avoids it being defined as any feature the speaker/writer doesn't find useful?</p>

答: syntactic sugar is a feature that doesn't extend the language expressivity itself, hence being redundant and sometimes an abuse of notation, but that both simplifies writer's life and gives the reader more insight.</p>

Title: Rigorous Definition of Syntactic Sugar?


问:
Clever PHP Application Organization Structures?
There are a million-and-one file-system structures that go into the myriad of Open Source projects available. Things like modules, language files, domains, third-party libraries, migrations, internationalization, backups, and syslinks to other parts of the system have given rise to many approaches to organize the filesystem of a project.

As a PHP developer I'm wondering if any type of standardization is starting to emerge among projects. With PSR-0 we finally have a standard for naming and loading files - but it nothing to my knowledge about the rest of the components that make up the system or how they can be handled in a sane way.

We are dealing with a lot more than just MVC, so what examples are there of  large projects correctly handling all of these things?

答:
You can follow the project layout for the two most popular application frameworks:

Zend Framework - http://www.framework.zend.com/manual/en/project-structure.project.html

Symfony - http://symfony.com/doc/current/book/installation.html

These will provide an extensible structure based on best practices and experiences from users


问:
How to test the tests?
We test our code to make it more correct (actually, less likely to be incorrect). However, the tests are also code -- they can also contain errors. And if your tests are buggy, they hardly make your code better.

I can think of three possible types of errors in tests:

Logical errors, when the programmer misunderstood the task at hand, and the tests do what he thought they should do, which is wrong;

Errors in the underlying testing framework (eg. a leaky mocking abstraction);

Bugs in the tests: the test is doing slightly different than what the programmer thinks it is.

Type (1) errors seem to be impossible to prevent (unless the programmer just... gets smarter). However, (2) and (3) may be tractable. How do you deal with these types of errors? Do you have any special strategies to avoid them? For example, do you write some special "empty" tests, that only check the test author's presuppositions? Also, how do you approach debugging a broken test case?

答:
Short answer: The production code tests the tests.

Compare this to the credit / debit model used in economics. The mechanics are very simple - If the credit differs from the debit there is something wrong.

The same goes for unit tests - If a test fails it indicates something is wrong. It might be the production code, but it might aswell be the test code! This last part if important.

Note that your type (1) bugs cannot be found by unit tests. To avoid this types of bugs you need other tools.

Title: How to test the tests?