答:
I just wanted to contribute some advice which is not going to be useful in your current situation, but you can start implementing it now to help in the future.

Of course there are the obvious candidates such as todo lists and issue logs; looking at the recently added issues should give you a clue as to what you were doing when you were pulled off the project.

On previous projects I have worked on, people were expected to keep a project log as part of the quality management process. The contents were not very clearly specified, but the idea was to keep a daily log of things related to the project that may be useful for continued work in the future or for review activities on completion; for example:

Observations about the quality of the project

this code can use some refactoring

did a quick implementation to get this to work but ABC would be better.

Todo items / issues that you would not want to formally record in an issue tracker

"should make this method work for x < 0 but that's currently out of scope.

Design decisions - especially non-trivial ones.

Our standard sort function performs a quick sort, but that does not preserve the order of items equal under the sorting condition, which we need here.

The obvious algorithm would be ABC but that fails here because x could be negative so we need the generalized form (Wikipedia link).

Problems encountered and how you solved them. A very important one, in my personal opinion: whenever you run into a problem note it in the log.

Checked out the code but it gave error XYZ0123, turns out I first had to upgrade component C to version 1.2 or higher.

The latter two points are very important. I've often encountered a similar situation or problem - sometimes in a completely different project - and thought "hmm, I remember spending a day on this, but what was the solution again?"

When you come back to a project after a while, reading back the project log (whether it's your own or the latest developer's) should put you back into the flow that you had when you left, and warn you of some of the traps that you may otherwise fall into again.


问:
Is it useful to keep 'definition' entities in a database vs using an enum?
In a project that I have started working on, the database has a lot of FooDefinition tables which act like an enum. It's a C# project using Entity Framework although that is not central to the question.

The entities have an ID, a string Name field and an int Type field that is converted to an enum. For example:

```<code>public class FooDefinition
{
    public int Id { get; set; }
    public string Name { get; set; }
    public FooType FooType { get; set; } // this is an enum that defines the entity
}
</code>```

The FooDefinition table is populated with an entity for each defined enum value, and does not change unless there is a new enum value added.

I am struggling to see the use in this pattern over just using the enum directly as opposed to joining on this Definition table. What are the possible benefits of this approach?

答:
There are several issues that need to be resolved.

Categories

The usual use of categories is to identify classes or groups of records. If you create reports, having the values kept in a category table makes it easy for report generators or external data warehouses to properly categorize items.

Control Flavors

Very often, the values control the operation of the program, changing the interpretation of the data or influencing other decisions. For these, I tend to favor enumerations. Because these values directly impact the operation of the program, changing or adding values goes along with the new or modified code, so rebuilding and deploying the software is almost always required.

Descriptions and Augmented Values

Category values are seldom of interest to humans; you would never put up "1", "2", "3" in a drop down list to indicate "Forward", "Backward", or "Stopped". Having a descriptive field to show user-selectable values corresponding to the in-program value is fairly important. Similarly, having a short-form (for drop downs) and a long-form (for report generators) is also quite valuable.

C#, to my understanding, does not allow augmenting the value of an enum. Recent versions of Java do, which I have found quite useful. For a C# implementation, it is likely best to use a category table for any such value that has an external representation.

Structured Categories

Categories are seldom unqualified. A category of PERIODICAL might have sub-categories of REFEREED and NONREFEREED. If your software needs to be able to gather data about periodicals, then you need a way to roll up the sub-categories. Using a table to hold the category listing, with parent-child relationships, is likely the best way to accomplish this.

Mix and Match

Often, I have combined both approaches for a category. Using an enumerated type, I can do switch statements and control the flow. Mapping the enumerated type underlying value to a database primary key requires a little care. This method is most useful when you need to regularly change the flavor text of a category, since that will not actually affect the operation of the program.

So, the content of the category table gets loaded at application start up. The enumerated type value can be used to index this table in the rare cases when you need to refer to an aspect of the category, such as the short name.

ContentLicense: CC BY-SA 3.0


问:
Need overview of concepts and tools to translate a DSL to regular expressions
I'm looking for a little guidance. Until this morning, this was all over my head. After spending today researching Wikipedia, StackOverflow, etc., I'd say I've got my nose above the water. I'm tasked with researching a project that, as I understand it, would involve reverse-engineering a domain-specific language that is basically a type of regular expression syntax and translating that into conventional (meaning, Perl-like) regular expressions. I'm hoping someone can fill in the gaps in my understanding, so let me explain what I've got and my understanding, thus far.

Regarding the DSL, it basically has two components to it. One is grep-like regular expressions, more or less. The other component consists of what you could call macros. These macros are used when you want to find Social Security numbers, credit card numbers and so forth in the text being analyzed. The DSL is a simpler way for the end-user to specify matching text and exceptions. (Honestly, it's still pretty complicated to use -- but easier than regular expressions.)

The DSL is used to write "rules," a rule being a one-line statement describing target text.

What I want to do is, taking a rule as input, translate that rule into a conventional regular expression where possible. If a macro doesn't break down into a single regular expression, I will translate the macro into one or more RE's, or any kind of text processing code needed.

My largest point of ignorance is the "translating." Here's my first question: will that involve what's called "parsing"? (As you can guess, I'm a self-taught programmer.) Would I be using a tool like ANTLR or PyParsing, or something like that? (I just found out about these tools today, during my research.) I'm guessing yes, but I'd appreciate confirmation.

How much do I have to learn? I'm not going to need to get the "Dragon book," right? I am not writing a DSL, but if I'm reverse-engineering one, then I'm guessing I will more or less need to learn how to create a DSL in the first place (since how else would I know how to do the parsing). Yes?

What do I need to get under my belt? That's what I'm trying to figure out. I've parsed configuration files; I've written a simple YAML to Java Bean code generator; I've written a simple HTML-stripper; I know a bit about regular expressions and text processing; but this particular endeavor is more sophisticated than anything I've done before. It seems doable, but as a sanity check please tell me if, in my ignorance, I've miscalculated and what I'm describing actually needs 4 years of being a computer science major to accomplish.

Can anyone point me in the right direction or give me some pointers? Thanks.

答:
I have never written a compiler, so I am out of my depth here, but here is a try:

I would start by writing a lexer and parser for the language. There are many tools for this. ANTLR is one of them; it can handle both lexing and parsing. Alternatively, you can use Lex or GNU Flex to create a lexer and create a parse tree with Yacc and its implementation Bison are others. I am sure that there are many other lexer and parser generators I have not covered here.

As far as the code generation, I don't really know what the best way to do this is. However, there are many resources on the subject.

The main answer to this question lists many resources that you could use for both the lexing/parsing and code generation.

If you know a functional language (such as OCaml), this would be a good language to implement your compiler in, as I believe (never done it) they make working with trees relatively easy.


答:
I recommend become familiar with several programming languages (including Scheme or CommonLisp and Ocaml or Haskell).

It is probable that implementing your translator in such languages would be good for you.

Then I suggest to read Programming Language Pragmatics (by M.Scott) and Lisp In Small Pieces (by C.Queinnec).

Of course, you'll need to read a good compiler textbook.

The lexing & parsing phase is probably the simplest. Most of the issues are elsewhere.

Of course you may want to use a parser generator like menhir or antlr. You could also avoid them and write your own parser by hand (this answer is explaining why you would want to do that). But parsing is quite "easy" (but a lot of work!). Most of the issues are elsewhere.

BTW, you are re-implementing a DSL. You might try to (compatibly) improve it. And it is a significant amount of work (months, not days).

Of course your translator will involve making some internal abstract syntax tree of the parsed DSL code (and the evil is in the details) and transforming them to some other AST representing the output code.

My DSL2011 paper on MELT might be relevant for you.

Reading the Garbage Collection Handbook should also be useful.

Title: Need overview of concepts and tools to translate a DSL to regular expressions

Body:
I'm looking for a little guidance. Until this morning, this was all over my head. After spending today researching Wikipedia, StackOverflow, etc., I'd say I've got my nose above the water. I'm tasked with researching a project that, as I understand it, would involve reverse-engineering a domain-specific language that is basically a type of regular expression syntax and translating that into conventional (meaning, Perl-like) regular expressions. I'm hoping someone can fill in the gaps in my understanding, so let me explain what I've got and my understanding, thus far.

Regarding the DSL, it basically has two components to it. One is grep-like regular expressions, more or less. The other component consists of what you could call macros. These macros are used when you want to find Social Security numbers, credit card numbers and so forth in the text being analyzed. The DSL is a simpler way for the end-user to specify matching text and exceptions. (Honestly, it's still pretty complicated to use -- but easier than regular expressions.)

The DSL is used to write "rules," a rule being a one-line statement describing target text.

What I want to do is, taking a rule as input, translate that rule into a conventional regular expression where possible. If a macro doesn't break down into a single regular expression, I will translate the macro into one or more RE's, or any kind of text processing code needed.

My largest point of ignorance is the "translating." Here's my first question: will that involve what's called "parsing"? (As you can guess, I'm a self-taught programmer.) Would I be using a tool like ANTLR or PyParsing, or something like that? (I just found out about these tools today, during my research.) I'm guessing yes, but I'd appreciate confirmation.

How much do I have to learn? I'm not going to need to get the "Dragon book," right? I am not writing a DSL, but if I'm reverse-engineering one, then I'm guessing I will more or less need to learn how to create a DSL in the first place (since how else would I know how to do the parsing). Yes?

What do I need to get under my belt? That's what I'm trying to figure out. I've parsed configuration files; I've written a simple YAML to Java Bean code generator; I've written a simple HTML-stripper; I know a bit about regular expressions and text processing; but this particular endeavor is more sophisticated than anything I've done before. It seems doable, but as a sanity check please tell me if, in my ignorance, I've miscalculated and what I'm describing actually needs 4 years of being a computer science major to accomplish.

Can anyone point me in the right direction or give me some pointers? Thanks.


问:
When I test out the difference in time between shifting and multiplying in C, there is no difference. Why?
I have been taught that shifting in binary is much more efficient than multiplying by 2^k. So I wanted to experiment, and I used the following code to test this out:

```<code>#include <time.h>
#include <stdio.h>

int main() {
    clock_t launch = clock();
    int test = 0x01;
    int runs;

    //simple loop that oscillates between int 1 and int 2
    for (runs = 0; runs < 100000000; runs++) {

    // I first compiled + ran it a few times with this:
    test *= 2;

    // then I recompiled + ran it a few times with:
    test <<= 1;

    // set back to 1 each time
    test >>= 1;
    }

    clock_t done = clock();
    double diff = (done - launch);
    printf("%f\n",diff);
}
</code>```

For both versions, the print out was approximately 440000, give or take 10000. There was no (visually, at least) significant difference between the two versions' outputs. So my question is, is there something wrong with my methodology? Should there even be a visual difference? Does this have something to do with the architecture of my computer, the compiler, or something else?

答:
Multiplication of signed or unsigned values by powers of two is equivalent to left-shifting, and most compilers will make the substitution.  Division of unsigned values, or signed values which the compiler can prove are never negative, is equivalent to right-shifting, and most compilers will make that substitution (though some aren't sophisticated enough to prove when signed values can't be negative).

It should be noted, however, that division of potentially-negative signed values is not equivalent to right-shifting.  An expression like (x+8)>>4 is not equivalent to (x+8)/16.  The former, in 99% of compilers, will map values from -24 to -9 to -1, -8 to +7 to 0, and +8 to +23 to 1 [rounding numbers almost symmetrically about zero].  The latter will map -39 to -24 to -1, -23 to +7 to 0, and +8 to +23 to +1 [grossly asymmetrical, and likely not what was intended].  Note that even when values are not expected to be negative, use of >>4 will likely yield faster code than /16 unless the compiler can prove the values can't be negative.


问:
How can I fetch data from more than one web services simultaneously in PHP?
I have 3 web services that are providing me data for my hotel booking engine. It is taking too long if I run them sequentially. Therefore I wanted to run them using threads, but I am not sure if php threading will support this and if it is safe, since all 3 processes that will handle the web service will read and write into shared tables.

Can anyone advise me on how should I proceed?

答:
The problem your describing is complicated.  Using your approach, you are going to run into problems with reading and writing data to the database.  I know your question wasn't about the validity of your solution, but I feel it is unnecessarily complicated.  Could you elaborate a bit on why your solution is necessary for solving this problem?

Here is an example of the kind of problems you will run into: https://stackoverflow.com/questions/2199559/what-are-concurrency-conflicts

I think a simpler approach should be explored.  I suggest making one service call to retrieve and another to save all the information.  This is the preferred way to have clients and servers communicate because it minimizes problems such as the one you are describing.

Implementing the solution will require the following:

Write a Retrieve web service to call from your page

Retrieve web service will make 1 call to the database to retrieve all your data

Write a Save web service to save information

Save web service will make 1 call to the database to save all your data

I don't know PHP, so I can't write any code or refer you to any PHP specific resources to help.


问:
How should I remember what I was doing and why on a project three months back?
I was working on a project three months back, and then suddenly another urgent project appeared and I was asked to shift my attention.

Starting tomorrow, I'll be heading back to the old project. I realize that I do not remember what exactly I was doing. I don't know where to begin.

How can I document a project such that anytime I look back it shouldn't take me more than a few minutes to get going from wherever I left. Are there best practices?

答: You can look up the project's history in your version control software from three months ago. Read your commit messages and most recent diffs to get an idea of what you were working on.</p>


问:
Can I refactor "safely" without specs?
I have inherited a legacy web application many years which:

Does not make use of Object Oriented principles, even though the language would permit it

Has no unit tests, nor any sort of test suite, automated or not

Generally ignores various general best practices making the code very hard to read and maintain

Splits its workings (including code for business rules) across the web application, database views and stored procedures. Some of the code is even externalized in that outside applications (not under me or my team's control) often read or write directly into the database

Has only the barest documentation (including some I've created)

No documented technical or functional specs to speak of either

Has changed rules so many times and so fast that no one truly knows how it's supposed to work anymore. Rules are stacked on as missing features or specific cases are discovered on a daily basis.

Happens to be the most business-critical application of the company

Is still constantly evolving

Refactoring almost always comes with the main suggestion of adding unit tests to make sure you don't break anything. How do you do this when you do not even know how the thing is supposed to work (and no one else can tell you for sure)?

Is this a case where you'd need to go back to square 1 and slowly, iteratively, as new features are requested, ask for specs focused on the modified section and then refactor what's there? Is there any other way to deal with this situation?

This question focuses mostly on the lack of specs in opposition the refactor safety rule of creating unit tests to ensure the rules are respected throughout refactoring.

That said, a few more bits on the situation beyond lack of specs:

The "best" programming structure found in the code so far is the function. They tend to not be self-contained and call on many global variables (even local variables were erroneously set as global variables risking unexpected behaviors). I get the feeling the first step might be to refactor this to even allow unit testing.

The issues mentioned apply to the whole application, the database procedures and even sister applications. Everything is intermingled together and almost never through interfaces. It's still possible to find

Code tends to be duplicated in various places. It happens with business-rules code, meaning you may get different results depending on where in the application you call up a feature. Obvious maintenance complexity and risk.

答:
As long as there isn't an explicit list of known defects that management wants fixed anyway, you should assume that the behaviour as it is now is correct, and you should strive to keep it unchanged during refactoring.

In other words, absent explicit an explicit spec, the current semantics of the code base are the requirements. That may not be true in every single respect, but since the application as a whole is perceived to have business value (otherwise no effort would be allocated to maintaining it), presumably it does more things right than wrong. Therefore you shouldn't spend your time figuring out what was correct and what wasn't; if someone is unhappy with what the new version does, they'll let you know soon enough, and that's your opportunity to request some actual requirements.

Title: Can I refactor "safely" without specs?


问:
Daily builds with SVN for a small team
I have a general question regarding best practices. I have a small team working on a medium-scale software project, which involves integrating code from different environments, etc. The project is a standalone piece of desktop software.

Based on lessons learned from a similar prior project that went badly, I am trying to implement some better software engineering practices.

I'd like to start by automating daily builds. We use SVN for source control, and all the developers are working in the trunk, including me. My question is rather simple:

Where locally do we do the daily builds? Should I make another folder on my local machine that is the "daily build" folder? Should I set up a virtual machine? Should I suck it up and do it in my development folder?

I understand the revision control paradigms pretty well. I'm mostly looking for how folks implement it in practice.

答:
A build machine is the way to go, even for small projects/teams.

Get any random spare machine (ie. an old dev box).

Install some continuous integration software on it like jenkins or teamcity.

Done

It's been a while since I had to set one up or maintain a build machine, but unless it's gotten worse since a year or 2 ago, you can have continuous builds on each checkin, and a nightly build that gets dumped to a network share setup in maybe an hour with either of these products.

Title: Daily builds with SVN for a small team


问:
In plain English, what is recursion?
The idea of recursion is not very common in real world. So, it seems a bit confusing to the novice programmers. Though, I guess, they become used to the concept gradually. So, what can be a nice explanation for them to grasp the idea easily?</p>

答:
Terminate if exit condition reached

do something to alter the state of things

do the work all over starting with the present state of things

Recursion is a very concise way to express something that has to be repeated until something is reached.

Title: In plain English, what is recursion?

ContentLicense: CC BY-SA 2.5


问:
Which hashing algorithm is best for uniqueness and speed?
Which hashing algorithm is best for uniqueness and speed? Example (good) uses include hash dictionaries.

I know there are things like SHA-256 and such, but these algorithms are designed to be secure, which usually means they are slower than algorithms that are less unique. I want a hash algorithm designed to be fast, yet remain fairly unique to avoid collisions.

答:
I've plotted a short speed comparison of different hashing algorithms when hashing files.

The individual plots only differ slightly in the reading method and can be ignored here, since all files were stored in a tmpfs. Therefore the benchmark was not IO-bound if you are wondering.

Linear Scale

Logarithmic scale

Algorithms include: SpookyHash, CityHash, Murmur3, MD5, SHA{1,256,512}.

Conclusions:

Non-cryptographic hash functions like Murmur3, Cityhash and Spooky are pretty close together. One should note that Cityhash may be faster on CPUs with SSE 4.2s CRC instruction, which my CPU does not have. SpookyHash was in my case always a tiny bit before CityHash.

MD5 seems to be a good tradeoff when using cryptographic hash functions, although SHA256 may be more secure to the collision vulnerabilities of MD5 and SHA1.

The complexity of all algorithms is linear - which is really not surprising since they work blockwise. (I wanted to see if the reading method makes a difference, so you can just compare the rightmost values).

SHA256 was slower than SHA512.

I did not investigate the randomness of the hash functions. But here is a good comparison of the hash functions that are missing in Ian Boyds answer.
This points out that CityHash has some problems in corner cases.

The source used for the plots:

https://github.com/sahib/rmlint/tree/gh-pages/plots (sorry for the ugly code)


答:
This is pretty much word-by-word how I described a project I got about a year ago. And as unfortunate as it is - it's quite a common situation.

OK, so first thing's first - If it is a black-box kind of module that you don't need to fix - don't fix it. Try to document the behaviour, maaaybe add some tests, but don't fix something you don't know how to fix or even how it works.

Now, assuming that this thing does, in fact, need fixing. Your first step is to try to understand the piece of code you're working with, but after that...

There's a bug in it:

Unit tests is first priority. Try to cover the part of the code and the code that depends on it or uses results from it with tests to make sure you change only the thing you intend to change.

There's a new feature that needs to be put in:

In this case I would usually use the least amount of existing code as possible. If something is clear - like DB calls - that's fine to reuse. If something is going through a spaghetti grinder logic - try to have a parallel call to your logic at one single point. This will not produce good code, but it will produce several "clear outs" of code, where the logic is sound, simple, documented and tested. The more of these, the easier it will be later when...

It's so tied up with everything that it just needs to go:

Try to figure out things you do understand about the code. Some non-trivial function whose side effects and output you understand. A standalone module that is kinda separated from everything else and is easier to tangle with. A set of features and specs that you can get out of people or docs. Divide and conquer is your best tactic - the smaller the piece of code you deal with at any moment, the better your chances to understand it well. Once you have knowledge, tests and docs about the entire thing, you can start working on its architecture.

Title: Can I refactor "safely" without specs?

Body:
I have inherited a legacy web application many years which:

Does not make use of Object Oriented principles, even though the language would permit it

Has no unit tests, nor any sort of test suite, automated or not

Generally ignores various general best practices making the code very hard to read and maintain

Splits its workings (including code for business rules) across the web application, database views and stored procedures. Some of the code is even externalized in that outside applications (not under me or my team's control) often read or write directly into the database

Has only the barest documentation (including some I've created)

No documented technical or functional specs to speak of either

Has changed rules so many times and so fast that no one truly knows how it's supposed to work anymore. Rules are stacked on as missing features or specific cases are discovered on a daily basis.

Happens to be the most business-critical application of the company

Is still constantly evolving

Refactoring almost always comes with the main suggestion of adding unit tests to make sure you don't break anything. How do you do this when you do not even know how the thing is supposed to work (and no one else can tell you for sure)?

Is this a case where you'd need to go back to square 1 and slowly, iteratively, as new features are requested, ask for specs focused on the modified section and then refactor what's there? Is there any other way to deal with this situation?

This question focuses mostly on the lack of specs in opposition the refactor safety rule of creating unit tests to ensure the rules are respected throughout refactoring.

That said, a few more bits on the situation beyond lack of specs:

The "best" programming structure found in the code so far is the function. They tend to not be self-contained and call on many global variables (even local variables were erroneously set as global variables risking unexpected behaviors). I get the feeling the first step might be to refactor this to even allow unit testing.

The issues mentioned apply to the whole application, the database procedures and even sister applications. Everything is intermingled together and almost never through interfaces. It's still possible to find

Code tends to be duplicated in various places. It happens with business-rules code, meaning you may get different results depending on where in the application you call up a feature. Obvious maintenance complexity and risk.


问:
Is there a design pattern for dynamically applying transformations or filters to a model?
For example, there is a model of an event with certain attributes that can be adjusted by existing processes: maybe one that looks at a geo-location stamp and determines a nearby city; another that looks at the number of registrations and applies rounding; another that calculates local popularity based on attendees vs. nearby events.

The important piece is having a way to dynamically order the operations--the filters/transformations/processing tasks--so that you can pass the events to a processing object that arranges the tasks in the correct order for the configuration/situation, and then passes the models through to apply them.

I can think of some ugly ways to make this happen, but want to know if there is a SOLID pattern that would allow for better, more-testable code.

答: I have seen similar things done using the Chain of Responsibility pattern. Basically, each transformation/filter is a single command, and your configuration specifies the order in which they execute. The result of each transformation command can be passed to the next along with a command context to contain other metadata that should not be in the data being operated on.</p>


问:
C# Single Instance of a Form
I have 3 forms. Form 1 has information inserted into Form 2. After clicking a button on Form 2 to get to Form 3; on Form 3 I pull data and put it on Form 2. The problem with this is that I don't know how to get a single instance of Form 2 so that I can keep the data from Form 1 after pulling data from Form 3. This is a WinForms application. Any help would be much appreciated. I have looked into the Singleton way of doing it but everything I research seems too confusing to follow. Thanks!</p>

答:
Forms are objects, so you can pass them into the constructor of each other form:

```<code>Class Form2{
Form form1;

Form Form2(Form form1){ // Constructor
this.form1 = form1;
</code>```

}
}

Now, you have a reference to the Form1 object in a field of Form2. If you need information, you use Form1.information

Title: C# Single Instance of a Form

Body:
Forms are objects, so you can pass them into the constructor of each other form:

Class Form2{
Form form1;

Form Form2(Form form1){ // Constructor
this.form1 = form1;

}
}

Now, you have a reference to the Form1 object in a field of Form2. If you need information, you use Form1.information


答:
Preface: +1 @Kilian_Foth

Quote from Gold Master Testing Automatically Validating Millions of Data Points

Gold Master Testing

Gold master testing is common when working with legacy code. Rather
  than trying to specify all of the logical paths through an untested
  module, you can feed it a varied set of inputs and turn the outputs
  into automatically verifying tests. There’s no guarantee the outputs
  are correct in this case, but at least you can be sure they don’t
  change (which, in some systems is even more important).

For us, given that we have a relatively reliable and comprehensive set
  of unit tests for our analysis code, the situation is a bit different.
  In short, we find gold master testing valuable because of three key
  factors:

The inputs and output from our analysis is extremely detailed. There
  are a huge number of syntactical structures in Ruby, and we derive a ton of information from them.

Our analysis depends on external code that we do not control, but do want to update from time-to-time (e.g. RubyParser)

We are extremely sensitive to any changes in results. For example, even a tiny variance in our detection of complex methods across the 20k repositories we analyze would ripple into changes of class ratings, resulting in incorrect metrics being delivered to our customers. These add up to mean that traditional unit and acceptance testing is necessary but not sufficient. We use unit and acceptance tests to provide faster results and more localized detection of regressions, but we use our gold master suite (nicknamed Krylon) to sanity check our results against a dozen or so repositories before deploying changes.

The Golden Master approach

Before making any change to the production code, do the following:

Create X number of random inputs, always using the same random seed, so you can generate always the same set over and over again. You will probably want a few thousand random inputs.

Bombard the class or system under test with these random inputs.

Capture the outputs for each individual random input

When you run it for the first time, record the outputs in a file (or database, etc). From then on, you can start changing your code, run the test and compare the execution output with the original output data you recorded. If they match, keep refactoring, otherwise, revert back your change and you should be back to green.

Title: Can I refactor "safely" without specs?


问:
Is SourceSafe really safe?
Having spent all morning trying to check something in - I now realise I've lost a couple of days worth of work.

Its happened before - and is apparently common occurrence with SourceSafe.  Can SourceSafe be used successfully, without problems, and if so, how?

答:
I cannot figure out why everybody wants to badmouth VSS. VSS is not distributed, and distributed version control is

better

allows for non-distributed version control in practice

Please read this.

Title: Is SourceSafe really safe?


问:
General thought process for "How would you build this website/app" interview questions
I've collected a bunch of interview questions like "Describe how you would design a photo album application", "Describe how you would design this particular feature of this particular website" (e.g. likes on Facebook, recommendation on Amazon, shopping cart, game of black jack). Then, what if there are millions of this thing? What would you change?

It looks like this is either expecting a database schema or a bunch of class definitions (or both?). I have learned about databases in school but I've never actually architected an application before and am having trouble knowing where to start, whether the designs I come up with are "good" and what I can change to make it scalable.

Is there a general approach or thought process when designing these systems? And general issues/problems that seem to come up a lot in the design that I should try to avoid? Could someone maybe walk me through one (or preferably all, while comparing the needs of each) of these and explain:

1) How do you come up with what entities are needed?
2) How do you decide on what relationships everything will have?
3) How do you incorporate performance optimization into your design?
4) Do I do this using classes or databases? Does it make a difference (i.e. would I have a class that can't really be translated to a database table, for example?)

The main reason I'm asking is because I was going through "Cracking the Coding Interview" and my answers were completely different from the author's - I had very different ideas of what classes were important.

MY ATTEMPT:
With the photo sharing app, I would have the classes/tables:
Photo and User for sure.

Then, I think if we're trying to create a schema, there would be a table linking photo and user if we assume each person in the photo is linked to the photo (is this table necessary? If not, is it still common practice to have a separate table for many-to-many relationships or not?).

But if we're trying to take an object oriented approach, maybe instead we'd have a class called album which does all the work and has all the info from the two other tables/classes. This is one thing I noticed in the book- there are a bunch of classes and then one class which basically has all the info and connects the other classes- is this common? For example, in my examples above, does this seem like it would apply?

I'm just hoping for some general rules/guidelines to follow because right now I have no idea how to tell what a good architecture for a large system looks like.

答:
I thought I'd make a quick comment on your first question:

1) How do you come up with what entities are needed?

The first thing I do for a new project is, either on a white board or big blank piece of paper, write down all the physical and conceptual things about that particular project that I and my team can think of. It's a brainstorm session.

Nouns tend to be objects, verbs tend to be use cases or methods.

Physical: photo (obvious!), display type, system, photo file, file format, user, date....

Conceptual: add, delete, save/store, retrieve, sort, modify, view/display photo....

Make connections between nouns and verbs.  User Adds Photo.  (Well - there's a use case!)

I would also suggest looking at UML and Design Patterns and how they can be used in generic OOD.  (Notice - I didn't mention a language or a database anywhere above.  Don't pick a language and then do your OOD.  Do your OOD in a way that the design can be implemented by any OOL.


问:
Why is polling accepted in web programming?
I am currently working on a Ruby on Rails project which shows a list of images.

A must-have for this project is that it shows new posts in realtime without the need of refreshing the web page. After searching for a while, I've stumbled upon some JavaScript solutions and services such as PubNub; however, none of the provided solutions made sense at all.

In the JavaScript solution (polling) the following happens:

User 1 views the list of photos.

In the background the JavaScript code is polling an endpoint every second to see if there is a new post.

User 2 adds a new photo.

There is a delay of 50 ms before the new cycle is triggered and fetches the new data.

The new content is loaded in the DOM.

This seems odd when translated to a real world example:

User 1 holds a pile of pictures on his/her desk.

He/she walks to the photographer every second and asks if he has a new one.

The photographer makes a new photo.

This second when he/she walks in, she can take the picture and put it on the pile.

In my opinion the solution should be as following:

User 1 holds a pile of pictures on his/her desk.

The photographer takes a new picture.

The photographer walks to the pile and puts it with the rest.

The PubNub solution is basically the same, however this time there is an intern walking between the parties to share the data.

Needless to say, both solutions are very energy consuming as they are triggered even when there is no data to load.

As far as my knowledge goes there is no (logic) explanation why this way of implementation is used in almost every realtime application.

答:
The HTTP protocol is limited in that the client MUST be the one to initiate the request. The server cannot communicate with the client unless responding to a client's request.

So to adjust your real world example, add the following restraint:

User 2 can ONLY respond to User 1's questions with a single sentence reply, after which User 1 must leave. User 2 has no other way of communicating.

With this new restraint, how would you do it other than polling?


答:
Sometimes good enough is good enough.

Of all the possible ways to implement a "real-time" communications process, polling is perhaps the simplest way.  Polling can be used effectively when the polling interval is relatively long (i.e. seconds, minutes or hours rather than instantaneous), and the clock cycles consumed by checking the connection or resource don't really matter.

Title: Why is polling accepted in web programming?

Body:
I am currently working on a Ruby on Rails project which shows a list of images.

A must-have for this project is that it shows new posts in realtime without the need of refreshing the web page. After searching for a while, I've stumbled upon some JavaScript solutions and services such as PubNub; however, none of the provided solutions made sense at all.

In the JavaScript solution (polling) the following happens:

User 1 views the list of photos.

In the background the JavaScript code is polling an endpoint every second to see if there is a new post.

User 2 adds a new photo.

There is a delay of 50 ms before the new cycle is triggered and fetches the new data.

The new content is loaded in the DOM.

This seems odd when translated to a real world example:

User 1 holds a pile of pictures on his/her desk.

He/she walks to the photographer every second and asks if he has a new one.

The photographer makes a new photo.

This second when he/she walks in, she can take the picture and put it on the pile.

In my opinion the solution should be as following:

User 1 holds a pile of pictures on his/her desk.

The photographer takes a new picture.

The photographer walks to the pile and puts it with the rest.

The PubNub solution is basically the same, however this time there is an intern walking between the parties to share the data.

Needless to say, both solutions are very energy consuming as they are triggered even when there is no data to load.

As far as my knowledge goes there is no (logic) explanation why this way of implementation is used in almost every realtime application.


答:
Pushing works well for 1, or a limited number of users.

Now change the scenario with one photographer and 1000 users that all want a copy of the picture. The photographer will have to walk to 1000 piles. Some of them might be in locked office, or spread all over the floor. Or their user on vacation, and not interested in new pictures at the moment.

The photographer would be busy walking all the time and not take new pictures.

Fundamentally: a pull/poll model scales better to lots of unreliable readers with loose realtime requirements (if a picture takes 10 seconds later to arrive on a pile, what's the big deal).

That said, a push model is still better in a lot of situations. If you need low latency (you need that new photo 5s after it's taken), or updates are rare and requests frequent and predictable (keep asking the photographer every 10 seconds when he generates a new picture a day), then pulling is inappropriate. It depends on what you're trying to do. NASDAQ: push. Weather service: pull. Wedding photographer: probably pull. News photo agency: probably push.


答:
Some more info I just checked out.

On x86_64, the MUL opcode has a 10 cycle latency and 1/2 cycle throughput.  MOV, ADD and SHL have a latency of 1 cycle, with 2.5, 2.5, and 1.7 cycle throughput.

A multiplication by 15 would require 3 SHL and 3 ADD ops at minimum and probably a couple of MOVs.

https://gmplib.org/~tege/x86-timing.pdf

Title: When I test out the difference in time between shifting and multiplying in C, there is no difference. Why?

Body:
I have been taught that shifting in binary is much more efficient than multiplying by 2^k. So I wanted to experiment, and I used the following code to test this out:

```<code>#include <time.h>
#include <stdio.h>

int main() {
    clock_t launch = clock();
    int test = 0x01;
    int runs;

    //simple loop that oscillates between int 1 and int 2
    for (runs = 0; runs < 100000000; runs++) {

    // I first compiled + ran it a few times with this:
    test *= 2;

    // then I recompiled + ran it a few times with:
    test <<= 1;

    // set back to 1 each time
    test >>= 1;
    }

    clock_t done = clock();
    double diff = (done - launch);
    printf("%f\n",diff);
}
</code>```

For both versions, the print out was approximately 440000, give or take 10000. There was no (visually, at least) significant difference between the two versions' outputs. So my question is, is there something wrong with my methodology? Should there even be a visual difference? Does this have something to do with the architecture of my computer, the compiler, or something else?


答:
Presuming your app can be built from the command line given a clean checkout and pre-requisites preinstalled you can mechanically do it with something as simple as a cron job or scheduled task. But what you really want here is known as a continuous integration server.

These servers handle a couple of things:

they make it easy to orchestrate the "go build this every day at midnight" or "go build this every time someone checks in" by providing scheduling facilities.

they extend that basic build by providing feedback mechanisms -- such as emailing the whole team when Bob breaks the build.

they can provide long-term reporting on build performance and success over time.

can provide the plumbing to automate packaging and publishing of an application where appropriate.

Or, they are effectively the brains of a modern development and deployment process.

There are two products that are good to start with in this field -- Jenkins which is free and open source and TeamCity which is free for your scale but not open source. Both will get you where you need to go, which one to pick is really a tactical decision based on what you are building stuff in and how much effort you might want to put into configuring the thing -- not that a basic setup with either product is horribly involved if you've ever stood up a and configured a web application. They are anatomically similar so the rest of this answer will apply to both.

These products both have a central server which is what you interact with as well as a concept of build agents or workers where the builds take place. This seems a bit odd until you realize that you could be building a cross-platform product that needs a native windows, osx and linux build.

In terms of where to install it that is really a tactical decision -- they both are very flexible java products that will run on just about anything. It really boils down to avaliability of hardware / software / licensing and security -- some folks really want to keep everything on the LAN. As for the build agent that is also a tactical decision. There is no reason the agent can't be on the same box as your CI server but you could certainly drop it somewhere different if need be. Having it on the same LAN helps unless you want to do some network configuration as they do need to communicate and typically that requires some firewall hole punching.

I probably would not install this on a machine someone was actively using just to guard against someone turning the machine off. Or hosing the machine and breaking your CI process. But mechanically an old desktop will do -- we just retired a ~2005 era HP desktop that was the main build server for every one of our dozen plus QA sites that got built pretty frequently. It's main issue was that we could only put 2gb of RAM in the box so we could not cache a lot of things in ram and it would page out to a slow disk made by the lowest vendor operating well beyond it's expected service life.

tldr: get Jenkins or TeamCity, install on a spare desktop, conquor the world.

Title: Daily builds with SVN for a small team

Body:
I have a general question regarding best practices. I have a small team working on a medium-scale software project, which involves integrating code from different environments, etc. The project is a standalone piece of desktop software.

Based on lessons learned from a similar prior project that went badly, I am trying to implement some better software engineering practices.

I'd like to start by automating daily builds. We use SVN for source control, and all the developers are working in the trunk, including me. My question is rather simple:

Where locally do we do the daily builds? Should I make another folder on my local machine that is the "daily build" folder? Should I set up a virtual machine? Should I suck it up and do it in my development folder?

I understand the revision control paradigms pretty well. I'm mostly looking for how folks implement it in practice.


问:
Duck typing in statically-typed languages
Is it a fair assumption to say that an overloaded constructor for a class can be thought of as a 'duck' for duck typing?  Let's say that ClassA has an overloaded constructor, it would stand to reason that the different constructors are there for a reason -- the object is being used in a manner that indicates all of its properties do not have to be set for the object to perform correctly.

So, I ask, is an overloaded constructor a duck?

答:
It's fair to say that overloaded constructors specify different ways to construct a duck.  That's not duck typing, though.

Consider the following class:

```<code>public class Rectangle
{
    public Rectangle(Point A, Point B)
    {
        // Constructs a rectangle by using points A and B as a diagonal,
        // and filling in the rectangle with the usual lines at right angles.
    }

    public Rectangle(Point A, Length diagonal, Angle angle)
    {
        // Computes Point B using the specified size and diagonal, and then
        // calls the first constructor.
    }

    public Rectangle(Point A, Point B, Point C, Point D)
    {
        // Constructs a rectangle from the four supplied points, and
        // verifies that all angles are 90 degrees.
    }
}
</code>```

Body:
It's fair to say that overloaded constructors specify different ways to construct a duck.  That's not duck typing, though.

Consider the following class:

public class Rectangle
{
    public Rectangle(Point A, Point B)
    {
        // Constructs a rectangle by using points A and B as a diagonal,
        // and filling in the rectangle with the usual lines at right angles.
    }

    public Rectangle(Point A, Length diagonal, Angle angle)
    {
        // Computes Point B using the specified size and diagonal, and then
        // calls the first constructor.
    }

    public Rectangle(Point A, Point B, Point C, Point D)
    {
        // Constructs a rectangle from the four supplied points, and
        // verifies that all angles are 90 degrees.
    }
}


答:
No it isn't.

Objects of a particular class all support exactly the same set of messages no matter what constructor they were created with. Overloading constructors merely means that it isn't necessary to initialize explicitly all the fields that make up an object's state. For instance, an object might have color with a sensible default value, so you can have a constructor with a color value and one without such a value, while a field that is an obligatory foreign key to another entity can't be made up by the class, so it always has to be a constructor argument. But in Java, all class members are fully defined when an object is constructed (in fact, at run-time there is no such thing as an undefined value), so comparing Java objects to those in duck-typed languages isn't helpful.

Title: Duck typing in statically-typed languages

Body:
Is it a fair assumption to say that an overloaded constructor for a class can be thought of as a 'duck' for duck typing?  Let's say that ClassA has an overloaded constructor, it would stand to reason that the different constructors are there for a reason -- the object is being used in a manner that indicates all of its properties do not have to be set for the object to perform correctly.

So, I ask, is an overloaded constructor a duck?


答:
No, It Isn't Duck Typing

I would argue that this is not an acceptable form of duck typing in a static language.

In a language that supports duck typing, one would expect to be able to define a function that accepts an object foo of unspecified type that defines a function (or property) bar.

```<code>def call_bar (foo) {
  foo.bar
}
</code>```

The function doesn't care what type foo is, just that is defines bar. Your system doesn't provide any way for a function to take an object of any type, so long as that type defines the required functions.

So how could we get duck typing in a statically typed language?

1. Interfaces

Well, the typical approach in most languages is to define interfaces. This doesn't get us all the way there, but it gets us close. We can at least define a contract by which we identify any pertinent functions/properties/etc on a type.

A function can then be written so that it accepts inputs by interface, rather than concrete classes. We retain the ability to check the type at compile time, to ensure that the required functions exist on the inputs, while getting the flexibility to ignore the implementation details.

2. Structural Typing

Scala has an interesting approach to this, which offers a much more flexible way of getting duck-typed behavior in a static language. Scala allows you to reference a type in terms of its members, using the following syntax:

```<code>def callBar(foo : { def bar() : Unit }) = {
  foo.bar()
}
</code>```

This will match any types that define the bar function, accepting no inputs and returning void output. You also retain the static typechecking benefits of a static language, as opposed to relying on late-binding to determine whether or not inputs will have the right members.

Body:
No, It Isn't Duck Typing

I would argue that this is not an acceptable form of duck typing in a static language.

In a language that supports duck typing, one would expect to be able to define a function that accepts an object foo of unspecified type that defines a function (or property) bar.

def call_bar (foo) {
  foo.bar
}

The function doesn't care what type foo is, just that is defines bar. Your system doesn't provide any way for a function to take an object of any type, so long as that type defines the required functions.

So how could we get duck typing in a statically typed language?

1. Interfaces

Well, the typical approach in most languages is to define interfaces. This doesn't get us all the way there, but it gets us close. We can at least define a contract by which we identify any pertinent functions/properties/etc on a type.

A function can then be written so that it accepts inputs by interface, rather than concrete classes. We retain the ability to check the type at compile time, to ensure that the required functions exist on the inputs, while getting the flexibility to ignore the implementation details.

2. Structural Typing

Scala has an interesting approach to this, which offers a much more flexible way of getting duck-typed behavior in a static language. Scala allows you to reference a type in terms of its members, using the following syntax:

def callBar(foo : { def bar() : Unit }) = {
  foo.bar()
}

This will match any types that define the bar function, accepting no inputs and returning void output. You also retain the static typechecking benefits of a static language, as opposed to relying on late-binding to determine whether or not inputs will have the right members.


问:
How are mixins or traits better than plain multiple inheritance?
C++ has plain multiple inheritance, many language designs forbid it as dangerous. But some languages like Ruby and PHP use strange syntax to do the same thing and call it mixins or traits. I heard many times that mixins/traits are harder to abuse than plain multiple inheritance.

What specifically makes them less dangerous? Is there something that isn't possible with mixins/traits but possible with C++-style multiple inheritance? Is it possible to run into the diamond problem with them?

This seems as if we were using multiple inheritance but just making excuses that those are mixins/traits so we can use them.

答:
There are a number of problems with multiple inheritance when it is used with full fledged classes, but they all revolve around ambiguity.

The ambiguity shows up in a few different ways:

If you have two base classes with the same field x, and the derived type asks for x, what does it get?

If the two x variables have incongruent types, you could infer it.

If they're the same type, you could try to merge them into the same variable.

You could always expose them as weird fully qualified names.

If you have two base classes with the same function f with identical signatures, and someone calls f, which gets called?

What if the two base classes share another common virtual ancestor (the diamond problem).

What if the function has different, but compatible signatures?

When you construct a class with two base classes, which of the base classes' constructor is called first? When you destroy the object, which is killed?

When you lay out the object in memory, how do you do it consistently?

How do you handle all of these cases with 3 base classes? 10?

And that ignores things like dynamic dispatch, type inference, pattern matching and other things I know less about which become more challenging when the language supports multiple inheritance of full classes.

Traits or Mix-ins (or interfaces, or...) are all constructs which specifically limit a type's capabilities so that there is no ambiguity. They rarely own anything themselves. This allows the composition of types to go smoother because there's not two variables or two functions... there is a variable and a reference; a function and a signature. The compiler knows what to do.

The other common approach taken is to force the user to "build" (or mix in) their type one at a time. Instead of the base classes being equal partners in the new type, you add one type to another - overriding anything that was there (usually with optional syntax to re-name and/or re-expose the overridden bits).

Is there something that isn't possible with mixins/traits but possible with C++-style multiple inheritance?

Depending on the language - it generally becomes troublesome or impossible to merge implementations of functions and storage for variables from multiple base classes and expose them in the derived type.

Is it possible to run into diamond problem with them?

Occasionally less severe variations will pop up based on your language, but usually no. The entire point of traits are to break that sort of ambiguity.


问:
Why a hashtable? Why not just a non-hashed associative array?
I've been learning about using a hashtable to efficiently check for items in a list without looping through the whole thing, but there's one thing that I don't get:

Why hashed keys?

It seems like:

```<code>var wordList = {
   'aa'    : ['aa'],
   'aah'   : ['aah'],
   'ahhed' : ['aahed']
};
</code>```

Would work just as well as:

```<code>var wordList = {
   '/* hashed value of aa*/'    : ['aa'],
   '/* hashed value of aah*/'   : ['aah'],
   '/* hashed value of aahed*/' : ['aahed']
};
</code>```

What's the performance difference between looking up a hashed key and a simple name key?

答:
Because you still need a way to search the associative array.  The hash table is your search mechanism; it gives you O(1) performance for any given key search, by computing an index into the bucket containing your item.

What is your underlying search mechanism, if it's not a hash table?  A Binary Search Tree?  That's good for very large tables, but it's not O(1); it's  O(log n).  If you don't have a search mechanism at all (i.e. you're searching the entire array from top to bottom to find your key), your performance is  O(n).

If your keys are already ordered, you can use a Binary Search without maintaining a tree; that is also O(log n) performance.


答:
I think it would be more helpful for the questioner to have a more differentiated answer, because I see several unexamined assumptions in the questions and in some of the answers or comments.

The resulting relative runtime of shifting and multiplication has nothing to do with C. When I say C, I do not mean the instance of a specific implementation, such as that or that version of GCC, but the language. I do not mean to take this ad absurdum, but to use an extreme example for illustration: you could implement a completely standards compliant C compiler and have multiplication take an hour, while shifting takes milliseconds - or the other way around. I am not aware of any such performance restrictions in C or C++.

You may not care about this technicality in argumentation. Your intention was probably to just test out the relative performance of doing shifts versus multiplications and you chose C, because it is generally perceived as a low level programming language, so one may expect its source code to translate into corresponding instructions more directly. Such questions are very common and I think a good answer should point out that even in C your source code does not translate into instructions as directly as you may think in a given instance. I have given you some possible compilation results below.

This is where comments that question the usefulness of substituting this equivalence in real-world software come in. You can see some in the comments to your question, such as the one from Eric Lippert. It is in line with the reaction you will generally get from more seasoned engineers in response to such optimizations. If you use binary shifts in production code as a blanket means of multiplying and dividing, people will most likely cringe at your code and have some degree of emotional reaction ("I have heard this nonsensical claim made about JavaScript for heaven's sake.") to it that may not make sense to novice programmers, unless they better understand the reasons for those reactions.

Those reasons are primarily a combination of the decreased readability and futility of such optimization, as you may have found out already with comparing their relative performance. However, I do not think that people would have as strong of a reaction if substitution of shift for multiplication was the only example of such optimizations. Questions like yours frequently come up in various forms and in various contexts. I think what more senior engineers actually react to so strongly, at least I have at times, is that there is potential for a much wider range of harm when people employ such micro-optimizations liberally across the code base. If you work at a company like Microsoft on a large code base, you will spend a lot of time reading other engineers' source code, or attempt to locate certain code therein. It may even be your own code that you will be trying to make sense of in a few years' time, particularly at some of the most inopportune times, such as when you have to fix a production outage following a call you received being on pager duty on a Friday night, about to head out for a night of fun with friends … If you spend that much time on reading code, you will appreciate it being as readable as possible. Imagine reading your favorite novel, but the publisher has decided to release a new edition where they use abbrv. all ovr th plc bcs thy thnk it svs spc. That is akin to the reactions other engineers may have to your code, if you sprinkle them with such optimizations. As other answers have pointed out, it is better to clearly state what you mean, which is using the operation in code that is semantically closest to what you are trying to express in idea.

Even in those environments, though, you may find yourself solving an interview question where you are expected to know this or some other equivalence. Knowing them is not bad and a good engineer would be aware of the arithmetic effect of binary shifting. Note that I did not say that this makes a good engineer, but that a good engineer would know, in my opinion. In particular, you may still find some manager, usually towards the end of your interview loop, who will grin broadly at you in anticipation of the delight to reveal this smart engineering "trick" to you in a coding question and prove that he/she, too, used to be or is one of the savvy engineers and not "just" a manager. In those situations, just try to look impressed and thank him/her for the enlightening interview.

Why did you not see a speed difference in C? The most likely answer is that it both resulted in the same assembly code:

```<code>int shift(int i) { return i << 2; }
int multiply(int i) { return i * 2; }
</code>```

Can both compile into

```<code>shift(int):
    lea eax, [0+rdi*4]
    ret
</code>```

On GCC without optimizations, i.e. using the flag "-O0", you may get this:

```<code>shift(int):
    push    rbp
    mov rbp, rsp
    mov DWORD PTR [rbp-4], edi
    mov eax, DWORD PTR [rbp-4]
    sal eax, 2
    pop rbp
    ret
multiply(int):
    push    rbp
    mov rbp, rsp
    mov DWORD PTR [rbp-4], edi
    mov eax, DWORD PTR [rbp-4]
    add eax, eax
    pop rbp
    ret
</code>```

As you can see, passing "-O0" to GCC does not mean that it will not be somewhat smart about what kind of code it produces. In particular, notice that even in this case the compiler avoided the use of a multiply instruction. You can repeat the same experiment with shifts by other numbers and even multiplications by numbers that are not powers of two. Chances are that on your platform you will see a combination of shifts and additions, but no multiplications. It seems like a bit of a coincidence for the compiler to apparently avoid using multiplications in all those cases if multiplications and shifts really had the same cost, does it not? But I do not mean to supply supposition for proof, so let us move on.

You could rerun your test with the above code and see if you notice a speed difference now. Even then you are not testing shift versus multiply, as you can see by the absence of a multiplication, though, but the code that was generated with a certain set of flags by GCC for the C operations of shift and multiply in a particular instance. So, in another test you could edit the assembly code by hand and instead use a "imul" instruction in the code for the "multiply" method.

If you wanted to defeat some of those smarts of the compiler, you could define a more general shift and multiply method and will end up with something like this:

```<code>int shift(int i, int j) { return i << j; }
int multiply(int i, int j) { return i * j; }
</code>```

Which may yield the following assembly code:

```<code>shift(int, int):
    mov eax, edi
    mov ecx, esi
    sal eax, cl
    ret
multiply(int, int):
    mov eax, edi
    imul    eax, esi
    ret
</code>```

Here we finally have, even on the highest optimization level of GCC 4.9, the expression in assembly instructions you may have expected when you initially set out on your test. I think that in itself can be an important lesson in performance optimization. We can see the difference it made to substitute variables for concrete constants in our code, in terms of the smarts that the compiler is able to apply. Micro-optimizations like the shift-multiply substitution are some very low-level optimizations that a compiler can usually easily do by itself. Other optimizations that are much more impactful on performance require an understanding of the intention of the code that is often not accessible by the compiler or can only be guessed at by some heuristic. That is where you as a software engineer come in and it certainly typically does not involve substituting multiplications with shifts. It involves factors such as avoiding a redundant call to a service that produces I/O and can block a process. If you go to your hard disk or, god forbid, to a remote database for some extra data you could have derived from what you already have in memory, the time you spend waiting outweighs the execution of a million instructions. Now, I think we have strayed a bit far from your original question, but I think pointing this out to a questioner, especially if we suppose someone who is just starting to get a grasp on the translation and execution of code, can be extremely important to address not just the question itself but many of its (possibly) underlying assumptions.

So, which one will be faster? I think it is a good approach you chose to actually test out the performance difference. In general, it is easy to be surprised by the runtime performance of some code changes. There are many techniques modern processors employ and the interaction between software can be complex, too. Even if you should get beneficial performance results for a certain change in one situation, I think it is dangerous to conclude that this type of change will always yield performance benefits. I think it is dangerous to run such tests once, say "Okay, now I know which one's faster!" and then indiscriminately apply that same optimization to production code without repeating your measurements.

So what if the shift is faster than the multiplication? There are certainly indications why that would be true. GCC, as you can see above, appears to think (even without optimization) that avoiding direct multiplication in favor of other instructions is a good idea. The Intel 64 and IA-32 Architectures Optimization Reference Manual will give you an idea of the relative cost of CPU instructions. Another resource, more focused on instruction latency and throughput, is http://www.agner.org/optimize/instruction_tables.pdf. Note that they are not a good predicator of absolute runtime, but of performance of instructions relative to each other. In a tight loop, as your test is simulating, the metric of "throughput" should be most relevant. It is the number of cycles that an execution unit will typically be tied up for when executing a given instruction.

So what if the shift is NOT faster than the multiplication? As I said above, modern architectures can be quite complex and things such as branch prediction, caching, pipelining, and parallel execution units can make it hard to predict the relative performance of two logically equivalent pieces of code at times. I really want to emphasize this, because this is where I am not happy with most answers to questions like these and with the camp of people outright saying that it is simply not true (anymore) that shifting is faster than multiplication.

No, as far as I am aware we did not invent some secret engineering sauce in the 1970's or whenever to suddenly annul the cost difference of a multiplication unit and a bit shifter. A general multiplication, in terms of logical gates, and certainly in terms of logical operations, is still more complex than a shift with a barrel shifter in many scenarios, on many architectures. How this translates into overall runtime on a desktop computer may be a bit opaque. I do not know for sure how they are implemented in specific processors, but here is an explanation of a multiplication: Is integer multiplication really same speed as addition on modern CPU

While here is an explanation of a Barrel Shifter. The documents I have referenced in the previous paragraph give another view on the relative cost of operations, by proxy of CPU instructions. The engineers over at Intel frequently seem to get similar questions: intel developer zone forums clock cycles for integer multiplication and addition in core 2 duo processor

Yes, in most real-life scenarios, and almost certainly in JavaScript, attempting to exploit this equivalence for performance's sake is probably a futile undertaking. However, even if we forced the use of multiplication instructions and then saw no difference in run-time, that is more due to the nature of the cost metric we used, to be precise, and not because there is no cost difference. End-to-end runtime is one metric and if it is the only one we care about, all is well. But that does not mean that all cost differences between multiplication and shifting have simply disappeared. And I think it is certainly not a good idea to convey that idea to a questioner, by implication or otherwise, who is obviously just starting to get an idea of the factors involved in the run-time and cost of modern code. Engineering is always about trade-offs. Inquiry into and explanation as to what tradeoffs modern processors have made to exhibit the execution time that we as users end up seeing may yield a more differentiated answer. And I think a more differentiated answer than "this is simply not true anymore" is warranted if we want to see fewer engineers check in micro-optimized code obliterating readability, because it takes a more general understanding of the nature of such "optimizations" to spot its various, diverse incarnations than simply referring to some specific instances as out of date.

Body:
I think it would be more helpful for the questioner to have a more differentiated answer, because I see several unexamined assumptions in the questions and in some of the answers or comments.

The resulting relative runtime of shifting and multiplication has nothing to do with C. When I say C, I do not mean the instance of a specific implementation, such as that or that version of GCC, but the language. I do not mean to take this ad absurdum, but to use an extreme example for illustration: you could implement a completely standards compliant C compiler and have multiplication take an hour, while shifting takes milliseconds - or the other way around. I am not aware of any such performance restrictions in C or C++.

You may not care about this technicality in argumentation. Your intention was probably to just test out the relative performance of doing shifts versus multiplications and you chose C, because it is generally perceived as a low level programming language, so one may expect its source code to translate into corresponding instructions more directly. Such questions are very common and I think a good answer should point out that even in C your source code does not translate into instructions as directly as you may think in a given instance. I have given you some possible compilation results below.

This is where comments that question the usefulness of substituting this equivalence in real-world software come in. You can see some in the comments to your question, such as the one from Eric Lippert. It is in line with the reaction you will generally get from more seasoned engineers in response to such optimizations. If you use binary shifts in production code as a blanket means of multiplying and dividing, people will most likely cringe at your code and have some degree of emotional reaction ("I have heard this nonsensical claim made about JavaScript for heaven's sake.") to it that may not make sense to novice programmers, unless they better understand the reasons for those reactions.

Those reasons are primarily a combination of the decreased readability and futility of such optimization, as you may have found out already with comparing their relative performance. However, I do not think that people would have as strong of a reaction if substitution of shift for multiplication was the only example of such optimizations. Questions like yours frequently come up in various forms and in various contexts. I think what more senior engineers actually react to so strongly, at least I have at times, is that there is potential for a much wider range of harm when people employ such micro-optimizations liberally across the code base. If you work at a company like Microsoft on a large code base, you will spend a lot of time reading other engineers' source code, or attempt to locate certain code therein. It may even be your own code that you will be trying to make sense of in a few years' time, particularly at some of the most inopportune times, such as when you have to fix a production outage following a call you received being on pager duty on a Friday night, about to head out for a night of fun with friends … If you spend that much time on reading code, you will appreciate it being as readable as possible. Imagine reading your favorite novel, but the publisher has decided to release a new edition where they use abbrv. all ovr th plc bcs thy thnk it svs spc. That is akin to the reactions other engineers may have to your code, if you sprinkle them with such optimizations. As other answers have pointed out, it is better to clearly state what you mean, which is using the operation in code that is semantically closest to what you are trying to express in idea.

Even in those environments, though, you may find yourself solving an interview question where you are expected to know this or some other equivalence. Knowing them is not bad and a good engineer would be aware of the arithmetic effect of binary shifting. Note that I did not say that this makes a good engineer, but that a good engineer would know, in my opinion. In particular, you may still find some manager, usually towards the end of your interview loop, who will grin broadly at you in anticipation of the delight to reveal this smart engineering "trick" to you in a coding question and prove that he/she, too, used to be or is one of the savvy engineers and not "just" a manager. In those situations, just try to look impressed and thank him/her for the enlightening interview.

Why did you not see a speed difference in C? The most likely answer is that it both resulted in the same assembly code:

int shift(int i) { return i << 2; }
int multiply(int i) { return i * 2; }

Can both compile into

shift(int):
    lea eax, [0+rdi*4]
    ret

On GCC without optimizations, i.e. using the flag "-O0", you may get this:

shift(int):
    push    rbp
    mov rbp, rsp
    mov DWORD PTR [rbp-4], edi
    mov eax, DWORD PTR [rbp-4]
    sal eax, 2
    pop rbp
    ret
multiply(int):
    push    rbp
    mov rbp, rsp
    mov DWORD PTR [rbp-4], edi
    mov eax, DWORD PTR [rbp-4]
    add eax, eax
    pop rbp
    ret

As you can see, passing "-O0" to GCC does not mean that it will not be somewhat smart about what kind of code it produces. In particular, notice that even in this case the compiler avoided the use of a multiply instruction. You can repeat the same experiment with shifts by other numbers and even multiplications by numbers that are not powers of two. Chances are that on your platform you will see a combination of shifts and additions, but no multiplications. It seems like a bit of a coincidence for the compiler to apparently avoid using multiplications in all those cases if multiplications and shifts really had the same cost, does it not? But I do not mean to supply supposition for proof, so let us move on.

You could rerun your test with the above code and see if you notice a speed difference now. Even then you are not testing shift versus multiply, as you can see by the absence of a multiplication, though, but the code that was generated with a certain set of flags by GCC for the C operations of shift and multiply in a particular instance. So, in another test you could edit the assembly code by hand and instead use a "imul" instruction in the code for the "multiply" method.

If you wanted to defeat some of those smarts of the compiler, you could define a more general shift and multiply method and will end up with something like this:

int shift(int i, int j) { return i << j; }
int multiply(int i, int j) { return i * j; }

Which may yield the following assembly code:

shift(int, int):
    mov eax, edi
    mov ecx, esi
    sal eax, cl
    ret
multiply(int, int):
    mov eax, edi
    imul    eax, esi
    ret

Here we finally have, even on the highest optimization level of GCC 4.9, the expression in assembly instructions you may have expected when you initially set out on your test. I think that in itself can be an important lesson in performance optimization. We can see the difference it made to substitute variables for concrete constants in our code, in terms of the smarts that the compiler is able to apply. Micro-optimizations like the shift-multiply substitution are some very low-level optimizations that a compiler can usually easily do by itself. Other optimizations that are much more impactful on performance require an understanding of the intention of the code that is often not accessible by the compiler or can only be guessed at by some heuristic. That is where you as a software engineer come in and it certainly typically does not involve substituting multiplications with shifts. It involves factors such as avoiding a redundant call to a service that produces I/O and can block a process. If you go to your hard disk or, god forbid, to a remote database for some extra data you could have derived from what you already have in memory, the time you spend waiting outweighs the execution of a million instructions. Now, I think we have strayed a bit far from your original question, but I think pointing this out to a questioner, especially if we suppose someone who is just starting to get a grasp on the translation and execution of code, can be extremely important to address not just the question itself but many of its (possibly) underlying assumptions.

So, which one will be faster? I think it is a good approach you chose to actually test out the performance difference. In general, it is easy to be surprised by the runtime performance of some code changes. There are many techniques modern processors employ and the interaction between software can be complex, too. Even if you should get beneficial performance results for a certain change in one situation, I think it is dangerous to conclude that this type of change will always yield performance benefits. I think it is dangerous to run such tests once, say "Okay, now I know which one's faster!" and then indiscriminately apply that same optimization to production code without repeating your measurements.

So what if the shift is faster than the multiplication? There are certainly indications why that would be true. GCC, as you can see above, appears to think (even without optimization) that avoiding direct multiplication in favor of other instructions is a good idea. The Intel 64 and IA-32 Architectures Optimization Reference Manual will give you an idea of the relative cost of CPU instructions. Another resource, more focused on instruction latency and throughput, is http://www.agner.org/optimize/instruction_tables.pdf. Note that they are not a good predicator of absolute runtime, but of performance of instructions relative to each other. In a tight loop, as your test is simulating, the metric of "throughput" should be most relevant. It is the number of cycles that an execution unit will typically be tied up for when executing a given instruction.

So what if the shift is NOT faster than the multiplication? As I said above, modern architectures can be quite complex and things such as branch prediction, caching, pipelining, and parallel execution units can make it hard to predict the relative performance of two logically equivalent pieces of code at times. I really want to emphasize this, because this is where I am not happy with most answers to questions like these and with the camp of people outright saying that it is simply not true (anymore) that shifting is faster than multiplication.

No, as far as I am aware we did not invent some secret engineering sauce in the 1970's or whenever to suddenly annul the cost difference of a multiplication unit and a bit shifter. A general multiplication, in terms of logical gates, and certainly in terms of logical operations, is still more complex than a shift with a barrel shifter in many scenarios, on many architectures. How this translates into overall runtime on a desktop computer may be a bit opaque. I do not know for sure how they are implemented in specific processors, but here is an explanation of a multiplication: Is integer multiplication really same speed as addition on modern CPU

While here is an explanation of a Barrel Shifter. The documents I have referenced in the previous paragraph give another view on the relative cost of operations, by proxy of CPU instructions. The engineers over at Intel frequently seem to get similar questions: intel developer zone forums clock cycles for integer multiplication and addition in core 2 duo processor

Yes, in most real-life scenarios, and almost certainly in JavaScript, attempting to exploit this equivalence for performance's sake is probably a futile undertaking. However, even if we forced the use of multiplication instructions and then saw no difference in run-time, that is more due to the nature of the cost metric we used, to be precise, and not because there is no cost difference. End-to-end runtime is one metric and if it is the only one we care about, all is well. But that does not mean that all cost differences between multiplication and shifting have simply disappeared. And I think it is certainly not a good idea to convey that idea to a questioner, by implication or otherwise, who is obviously just starting to get an idea of the factors involved in the run-time and cost of modern code. Engineering is always about trade-offs. Inquiry into and explanation as to what tradeoffs modern processors have made to exhibit the execution time that we as users end up seeing may yield a more differentiated answer. And I think a more differentiated answer than "this is simply not true anymore" is warranted if we want to see fewer engineers check in micro-optimized code obliterating readability, because it takes a more general understanding of the nature of such "optimizations" to spot its various, diverse incarnations than simply referring to some specific instances as out of date.


答:
I'm really surprised that only one person has mentioned WebSockets. Support is implemented in basically every major browser.

In fact PubNub uses them. For your application the browser would probably subscribe to a socket that would broadcast whenever a new photo is available.
The socket wouldn't send the photo, mind you, but just a link so the browser could download it asynchronously.

In your example imagine something like:

User(s) lets photographer know that he wants to know about all future photos

Photographer says over loudspeaker that a new photo is available

User asks photographer for photo

This is somewhat like your original example solution. It's more efficient than polling because the client doesn't have to send any data to the server (except maybe heartbeats.)

Also, as others have mentioned, there are other methods that are better than simple polling that work in older browsers (longpolling, et al.)


问:
What popular "best practices" are not always best, and why?
"Best practices" are everywhere in our industry.  A Google search on "coding best practices" turns up nearly 1.5 million results.  The idea seems to bring comfort to many; just follow the instructions, and everything will turn out fine.

When I read about a best practice - for example, I just read through several in Clean Code recently - I get nervous.  Does this mean that I should always use this practice?  Are there conditions attached?  Are there situations where it might not be a good practice?  How can I know for sure until I've learned more about the problem?

Several of the practices mentioned in Clean Code did not sit right with me, but I'm honestly not sure if that's because they're potentially bad, or if that's just my personal bias talking.  I do know that many prominent people in the tech industry seem to think that there are no best practices, so at least my nagging doubts place me in good company.

The number of best practices I've read about are simply too numerous to list here or ask individual questions about, so I would like to phrase this as a general question:

Which coding practices that are popularly labeled as "best practices" can be sub-optimal or even harmful under certain circumstances?  What are those circumstances and why do they make the practice a poor one?

I would prefer to hear about specific examples and experiences.

答:
Databinding

I hate it and love it. (Depends on complexity of the project)


答:
Well, if you need to find something in your associative array, you need to iterate through each of the keys, and find equality. This means that in the worst case, you'll need to iterate through your whole collection to find the good key.

Accessing an array with an index (myArray[0] for example) is instant; it doesn't require any searching, because the runtime of the languages knows exactly where to find this value.

When using a hashtable, you compute the hash code of a given key to find the associated value. The hashcode is an index in the underlying array of the hashtable. This means that finding a key in a hashtable is as fast as accessing an array by index.

An hashtable's code is a bit more complex, but this is the general idea.

Title: Why a hashtable? Why not just a non-hashed associative array?

Body:
I've been learning about using a hashtable to efficiently check for items in a list without looping through the whole thing, but there's one thing that I don't get:

Why hashed keys?

It seems like:

```<code>var wordList = {
   'aa'    : ['aa'],
   'aah'   : ['aah'],
   'ahhed' : ['aahed']
};
</code>```

Would work just as well as:

```<code>var wordList = {
   '/* hashed value of aa*/'    : ['aa'],
   '/* hashed value of aah*/'   : ['aah'],
   '/* hashed value of aahed*/' : ['aahed']
};
</code>```

What's the performance difference between looking up a hashed key and a simple name key?


问:
Why not apply Interface Segregation Principle to "extreme"
Providing that clients would typically consume just one method, though methods would be conceptually related, why not always apply the Interface Segregation Principle to the extreme and have [many] single-method interfaces? Is there an objective rule against this? Not something like "oh it feels wrong" or "but you will have so many types, it's hard to read and manage" but rather something logical and clear. (Still want to name contracts clearly, so functions are not a good fit?).

Example:

```<code>IGeometryManager
{
   Shape CreateTriangle();
   Shape CreateCircle();
   Shape CreateSquare();
   Shape CreateEllipse();
   Shape CreateCurve();
   Shape CreateLine();
   void RemoveAll();
}
</code>```

Result:

```<code>ITriangleCreator
{
   Shape CreateTriangle();
}

ICircleCreator
{
   Shape CreateCircle();
}

ISquareCreator
{
   Shape CreateSquare();
}

IEllipseCreator
{
   Shape CreateEllipse();
}

ICurveCreator
{
   Shape CreateCurve();
}

ILineCreator
{
   Shape CreateLine();
}

IShapeRemover
{
   void RemoveAll();
}
</code>```

This is a relevant blog post, but I am not 100% persuaded by the authors logic: http://blog.ploeh.dk/2014/03/10/solid-the-next-step-is-functional

答:
In most programming languages and frameworks, overly-segregated interfaces make it difficult to aggregate, compose, or wrap objects which share various combinations of abilities.  If many types implement an interface which defines many methods, but also includes a means of asking how well particular instances can promise to implement them, then a single wrapper or aggregating class will be able to wrap or aggregate instances of all such types, and expose to the client whatever combinations of abilities are supported by the wrapped or aggregated instances.

If instead each class only implemented exactly those methods it supported, and was expected to usefully support every method it implemented, then the author of each wrapper class would need to select a fixed set of methods for it to supports.  Any object which couldn't support all those methods couldn't be wrapped, and no method which wasn't in that set could be made available to clients.  If a client with limited need wanted to wrap objects with limited abilities, and a client with greater needs wanted to wrap objects with greater abilities, different wrapper classes would be required for those clients.  Because wrapper classes need to contain explicit logic for each wrapped method, one couldn't use a generic family of wrappers to handle the different use cases; every combination of supported methods would require a completely-separate wrapper class.  If objects support many different combinations of abilities, and clients have many different combinations of requirements, the number of wrappers that are required may become totally unworkable.

While it can be useful to have the type system ensure at compile time that objects which will need to have a certain ability will, in fact, have that ability, there are many situations where trying to validate everything at compile time simply won't work usefully.  If implementations of one interface would frequently be try-cast to another interface, that's a good sign that the members of both interfaces should perhaps be combined into a single interface.


问:
When I test out the difference in time between shifting and multiplying in C, there is no difference. Why?
I have been taught that shifting in binary is much more efficient than multiplying by 2^k. So I wanted to experiment, and I used the following code to test this out:

```<code>#include <time.h>
#include <stdio.h>

int main() {
    clock_t launch = clock();
    int test = 0x01;
    int runs;

    //simple loop that oscillates between int 1 and int 2
    for (runs = 0; runs < 100000000; runs++) {

    // I first compiled + ran it a few times with this:
    test *= 2;

    // then I recompiled + ran it a few times with:
    test <<= 1;

    // set back to 1 each time
    test >>= 1;
    }

    clock_t done = clock();
    double diff = (done - launch);
    printf("%f\n",diff);
}
</code>```

For both versions, the print out was approximately 440000, give or take 10000. There was no (visually, at least) significant difference between the two versions' outputs. So my question is, is there something wrong with my methodology? Should there even be a visual difference? Does this have something to do with the architecture of my computer, the compiler, or something else?

答:
You've got several problems with your test program.

First, you're not actually using the value of test. There is no way, within the C standard, that the value of test matters. The optimizer is this completely free to remove it. Once its removed it, your loop is actually empty. The only visible effect would be to set runs = 100000000, but runs also isn't used. So the optimizer can (and should!) remove the entire loop. Easy fix: also print the computed value. Note that a sufficiently determined optimizer could still optimize away the loop (it relies entirely on constants known at compile time).

Second, you do two operations that cancel each other out. The optimizer is allowed to notice this and cancel them out. Again leaving an empty loop, and removed. This one is downright hard to fix. You can switch to an unsigned int (so overflow isn't undefined behavior), but that of course just results in 0. And simple things (like, say, test += 1) are easy enough for the optimizer to figure out, and it does.

Finally, you assume that test *= 2 is actually going to be compiled to a multiply. That's a very simple optimization; if the bitshift is faster, the optimizer will use it instead. To get around this, you'd have to use something like an implementation-specific assembly inline.

Or, I suppose, just check your microprocessor data sheet to see which is faster.

When I checked the assembly output of compiling your program with gcc -S -O3 using version 4.9, the optimizer actually saw through every simple variation above, and several more. In all cases, it removed the loop (assigning a constant to test), the only thing left was the calls to clock(), the convert/subtract, and the printf.


答:
One advantage of polling is that it limits the harm that can be caused if a message goes missing or the state of something gets glitched.  If X asks Y for its state once every five seconds, then the loss of a request or a reply will merely result in X's information being ten seconds out of date rather than 5.  If Y gets rebooted, X can find out about it the next time Y is able to respond to one of X's messages.  If X gets rebooted, it might never bother asking Y for anything afterward, but whoever is observing the status of X should recognize that it has been rebooted.

If instead of X polling Y, X relied upon Y to inform it whenever its state changed, then if Y's state changed and it sent a message to X, but for whatever reason that message was not received, X might never become aware of the change.  Likewise if Y gets rebooted and never has any reason to send X a message about anything.

In some cases it may be helpful to for X to request that Y autonomously send messages with its status, either periodically or when it changes, and only have X poll if it goes too long without hearing anything from Y.  Such a design may eliminate the need for X to send most of its messages (typically, X should at least occasionally inform Y that it's still interested in receiving messages, and Y should stop sending messages if it goes too long without any indication of interest).  Such a design would, however, require Y to persistently maintain information about X, rather than being able to simply send a reply to whoever polled it and then immediately forget about who that was.  If Y is an embedded system, such a simplification may help reduce memory requirements sufficiently to allow the use of a smaller and cheaper controller.

Polling can have an additional advantage when using a potentially-unreliable communications medium (e.g. UDP or radio): it can largely eliminates the need for link-layer acknowledgments.  If X sends Y a status request Q, Y responds with a status report R, and X hears R, X won't need to hear any sort of link-layer acknowledgment for Q to know that it was received.  Conversely, once Y sends R, it doesn't need to know or care if X received it.  If X sends a status request and gets no response, it can send another.  If Y sends a report and X doesn't hear it, X will send another request.  If each request goes out once and either yields a response or doesn't, neither party needs to know or care whether any particular message was received.  Since sending an acknowledgment may consume almost as much bandwidth as a status request or report, using a round-trip of request-report doesn't cost much more than would an unsolicited report and acknowledgment.  If X sends a few requests without getting replies, it may on some dynamically-routed networks need to enable link-level acknowledgments (and ask in its request that Y do likewise) so that the underlying protocol stack can recognize the delivery problem and search for a new route, but when things are working a request-report model will be more efficient than using link-level acknowledgments.