问:
What's wrong with comments that explain complex code?
A lot of people claim that "comments should explain 'why', but not 'how'". Others say that "code should be self-documenting" and comments should be scarce. Robert C. Martin claims that (rephrased to my own words) often "comments are apologies for badly written code".

My question is the following:

What's wrong with explaining a complex algorithm or a long and convoluted piece of code with a descriptive comment?

This way, instead of other developers (including yourself) having to read the entire algorithm line by line to figure out what it does, they can just read the friendly descriptive comment you wrote in plain English.

English is 'designed' to be easily understood by humans. Java, Ruby or Perl, however, have been designed to balance human-readability and computer-readability, thus compromising the human-readability of the text. A human can understand a piece of English much faster that he/she can understand a piece of code with the same meaning (as long as the operation isn't trivial).

So after writing a complex piece of code written in a partly human-readable programming language, why not add a descriptive and concise comment explaining the operation of the code in friendly and understandable English?

Some will say "code shouldn't be hard to understand", "make functions small", "use descriptive names", "don't write spaghetti code".

But we all know that's not enough. These are mere guidelines - important and useful ones - but they do not change the fact that some algorithms are complex. And therefore are hard to understand when reading them line by line.

Is it really that bad to explain a complex algorithm with a few lines of comments about it's general operation? What's wrong with explaining complicated code with a comment?

答:
The need for comments is inversely proportional to the abstraction level of the code.

For example, Assembly Language is, for most practical purposes, unintelligible without comments. Here's an excerpt from a small program that calculates and prints terms of the Fibonacci series:

main:
; initializes the two numbers and the counter.  Note that this assumes
; that the counter and num1 and num2 areas are contiguous!
;
    mov ax,'00'                     ; initialize to all ASCII zeroes
    mov di,counter                  ; including the counter
    mov cx,digits+cntDigits/2       ; two bytes at a time
    cld                             ; initialize from low to high memory
    rep stosw                       ; write the data
    inc ax                          ; make sure ASCII zero is in al
    mov [num1 + digits - 1],al      ; last digit is one
    mov [num2 + digits - 1],al      ;
    mov [counter + cntDigits - 1],al

    jmp .bottom         ; done with initialization, so begin

.top
    ; add num1 to num2
    mov di,num1+digits-1
    mov si,num2+digits-1
    mov cx,digits       ;
    call    AddNumbers  ; num2 += num1
    mov bp,num2         ;
    call    PrintLine   ;
    dec dword [term]    ; decrement loop counter
    jz  .done           ;

    ; add num2 to num1
    mov di,num2+digits-1
    mov si,num1+digits-1
    mov cx,digits       ;
    call    AddNumbers  ; num1 += num2
.bottom
    mov bp,num1         ;
    call    PrintLine   ;
    dec dword [term]    ; decrement loop counter
    jnz .top            ;
.done
    call    CRLF        ; finish off with CRLF
    mov ax,4c00h        ; terminate
    int 21h             ;
```

<p>Even with comments, it can be quite complicated to grok. </p>

<p>Modern Example: Regexes are often very low abstraction constructs (lower case letters, number 0, 1, 2, new lines, etc). They probably need comments in the form of samples (Bob Martin, IIRC, does acknowledge this). Here is a regex that (I think) should match HTTP(S) and FTP URLs:</p>

<pre class="lang-regex prettyprint-override"><code>^(((ht|f)tp(s?))\://)?(www.|[a-zA-Z].)[a-zA-Z0-9\-\.]+\.(com|edu|gov|m
+il|net|org|biz|info|name|museum|us|ca|uk)(\:[0-9]+)*(/($|[a-zA-Z0-9\.
+\,\;\?\'\\\+&%\$#\=~_\-]+))*$
</code>```

As the languages progress up the abstraction hierarchy, the programmer is able to use evocative abstractions (variable name, function names, class names, module names, interfaces, callbacks, etc) to provide built-in documentation. To neglect to take advantage of this, and use comments to paper over it is lazy, a disservice to and disrespectful of the maintainer.

I am thinking of Numerical Recipes in C translated mostly verbatim to Numerical Recipes in C++, which I infer began as Numerical Recipes (in FORTAN), with all the variables a, aa, b, c, cc, etc maintained through each version. The algorithms may have been correct, but they did not take advantage of the abstractions the languages provided. And they p*** me off. Sample from a Dr. Dobbs article - Fast Fourier Transform:

void four1(double* data, unsigned long nn)
{
    unsigned long n, mmax, m, j, istep, i;
    double wtemp, wr, wpr, wpi, wi, theta;
    double tempr, tempi;

    // reverse-binary reindexing
    n = nn<<1;
    j=1;
    for (i=1; i<n; i+=2) {
        if (j>i) {
            swap(data[j-1], data[i-1]);
            swap(data[j], data[i]);
        }
        m = nn;
        while (m>=2 && j>m) {
            j -= m;
            m >>= 1;
        }
        j += m;
    };

    // here begins the Danielson-Lanczos section
    mmax=2;
    while (n>mmax) {
        istep = mmax<<1;
        theta = -(2*M_PI/mmax);
        wtemp = sin(0.5*theta);
        wpr = -2.0*wtemp*wtemp;
        wpi = sin(theta);
        wr = 1.0;
        wi = 0.0;
        for (m=1; m < mmax; m += 2) {
            for (i=m; i <= n; i += istep) {
                j=i+mmax;
                tempr = wr*data[j-1] - wi*data[j];
                tempi = wr * data[j] + wi*data[j-1];

                data[j-1] = data[i-1] - tempr;
                data[j] = data[i] - tempi;
                data[i-1] += tempr;
                data[i] += tempi;
            }
            wtemp=wr;
            wr += wr*wpr - wi*wpi;
            wi += wi*wpr + wtemp*wpi;
        }
        mmax=istep;
    }
}
```

As a special case about abstraction, every language has idioms / canonical code snippets  for certain common tasks (deleting a dynamic linked list in C), and regardless of how they look, they shouldn't be documented. Programmers should learn these idioms, as they are unofficially part of the language.

So the take away: Non-idiomatic code built from low-level building blocks that can't be avoided needs comments. And this is necessary WAAAAY less than it happens.

Body:
The need for comments is inversely proportional to the abstraction level of the code.

For example, Assembly Language is, for most practical purposes, unintelligible without comments. Here's an excerpt from a small program that calculates and prints terms of the Fibonacci series:

main:
; initializes the two numbers and the counter.  Note that this assumes
; that the counter and num1 and num2 areas are contiguous!
;
    mov ax,'00'                     ; initialize to all ASCII zeroes
    mov di,counter                  ; including the counter
    mov cx,digits+cntDigits/2       ; two bytes at a time
    cld                             ; initialize from low to high memory
    rep stosw                       ; write the data
    inc ax                          ; make sure ASCII zero is in al
    mov [num1 + digits - 1],al      ; last digit is one
    mov [num2 + digits - 1],al      ;
    mov [counter + cntDigits - 1],al

    jmp .bottom         ; done with initialization, so begin

.top
    ; add num1 to num2
    mov di,num1+digits-1
    mov si,num2+digits-1
    mov cx,digits       ;
    call    AddNumbers  ; num2 += num1
    mov bp,num2         ;
    call    PrintLine   ;
    dec dword [term]    ; decrement loop counter
    jz  .done           ;

    ; add num2 to num1
    mov di,num2+digits-1
    mov si,num1+digits-1
    mov cx,digits       ;
    call    AddNumbers  ; num1 += num2
.bottom
    mov bp,num1         ;
    call    PrintLine   ;
    dec dword [term]    ; decrement loop counter
    jnz .top            ;
.done
    call    CRLF        ; finish off with CRLF
    mov ax,4c00h        ; terminate
    int 21h             ;

Even with comments, it can be quite complicated to grok.

Modern Example: Regexes are often very low abstraction constructs (lower case letters, number 0, 1, 2, new lines, etc). They probably need comments in the form of samples (Bob Martin, IIRC, does acknowledge this). Here is a regex that (I think) should match HTTP(S) and FTP URLs:

^(((ht|f)tp(s?))\://)?(www.|[a-zA-Z].)[a-zA-Z0-9\-\.]+\.(com|edu|gov|m
+il|net|org|biz|info|name|museum|us|ca|uk)(\:[0-9]+)*(/($|[a-zA-Z0-9\.
+\,\;\?\'\\\+&amp;%\$#\=~_\-]+))*$

As the languages progress up the abstraction hierarchy, the programmer is able to use evocative abstractions (variable name, function names, class names, module names, interfaces, callbacks, etc) to provide built-in documentation. To neglect to take advantage of this, and use comments to paper over it is lazy, a disservice to and disrespectful of the maintainer.

I am thinking of Numerical Recipes in C translated mostly verbatim to Numerical Recipes in C++, which I infer began as Numerical Recipes (in FORTAN), with all the variables a, aa, b, c, cc, etc maintained through each version. The algorithms may have been correct, but they did not take advantage of the abstractions the languages provided. And they p*** me off. Sample from a Dr. Dobbs article - Fast Fourier Transform:

void four1(double* data, unsigned long nn)
{
    unsigned long n, mmax, m, j, istep, i;
    double wtemp, wr, wpr, wpi, wi, theta;
    double tempr, tempi;

    // reverse-binary reindexing
    n = nn<<1;
    j=1;
    for (i=1; i<n; i+=2) {
        if (j>i) {
            swap(data[j-1], data[i-1]);
            swap(data[j], data[i]);
        }
        m = nn;
        while (m>=2 && j>m) {
            j -= m;
            m >>= 1;
        }
        j += m;
    };

    // here begins the Danielson-Lanczos section
    mmax=2;
    while (n>mmax) {
        istep = mmax<<1;
        theta = -(2*M_PI/mmax);
        wtemp = sin(0.5*theta);
        wpr = -2.0*wtemp*wtemp;
        wpi = sin(theta);
        wr = 1.0;
        wi = 0.0;
        for (m=1; m < mmax; m += 2) {
            for (i=m; i <= n; i += istep) {
                j=i+mmax;
                tempr = wr*data[j-1] - wi*data[j];
                tempi = wr * data[j] + wi*data[j-1];

                data[j-1] = data[i-1] - tempr;
                data[j] = data[i] - tempi;
                data[i-1] += tempr;
                data[i] += tempi;
            }
            wtemp=wr;
            wr += wr*wpr - wi*wpi;
            wi += wi*wpr + wtemp*wpi;
        }
        mmax=istep;
    }
}

As a special case about abstraction, every language has idioms / canonical code snippets  for certain common tasks (deleting a dynamic linked list in C), and regardless of how they look, they shouldn't be documented. Programmers should learn these idioms, as they are unofficially part of the language.

So the take away: Non-idiomatic code built from low-level building blocks that can't be avoided needs comments. And this is necessary WAAAAY less than it happens.


问:
In Node.js, are non-blocking constructs usually preferable to blocking ones?
Is the following a statement of best practices in Node.js with regard to web applications? If not, how could it be improved?

The statement

The lifecycle of any web app has at least two phases: a setup phase, and a ready phase (when the application is ready to respond to requests.)

In the ready phase,

IO operations (disk access, database calls, etc.) should always be asynchronous/non-blocking.

Even operations that occur purely in memory should be asynchronous, when possible. This is especially true when the operations involve iteration, and especially^2 true when the upper limit on the number of iterations is unknown.

Synchronous/blocking operations should never be performed in response to a request.

In my opinion, the question of whether or not something is part of the best practices for developing in a certain programming language can be answered decisively based on experience and objective criteria.

答:
I respond not by experience, but because of what I have read a lot of time in blogs of node js competent developpers : Yes these are good rules since it seems all whom have passed performance test agree that blocking calls are the main cause of performance dropping.

There is an exemple but i've read a least twelve agreeing with when looking for information about node js.

ContentLicense: CC BY-SA 3.0


答:
The answer as someone who has written a significant amount of node.js code at a professional level is yes. As a JavaScript implementation there is no notion of a thread in Node.js. All IO operations are therefore asynchronous. While many of the common node lower level api's do provide an xxxSync variant using them is not preferred and can cause noticeable performance problems, even under very low load, and development conditions.

With regard to your comment about in memory operations. No in memory operations are truly asynchronous. While it is common to reuse the callback pattern when implementing long lived functions this is more a convention than anything else. In order for a function to be asynchronous it must release it's hold on the processor. In standard languages a system call blocks, meaning that although the process is no longer in charge of the processor, and the process itself is in wait state, other parts of the same program cannot be executed. In node asynchronous callbacks perform the same task that threads do in most languages by allowing the program to proceed although one of it's operations is in wait state.

Long story short, always use async when possible but understand the difference between using the callback pattern and using an actual async operation while they often look identical in the code they are drastically different. Misunderstanding the difference can cause some real headaches for people new to the language.

Title: In Node.js, are non-blocking constructs usually preferable to blocking ones?

Body:
Is the following a statement of best practices in Node.js with regard to web applications? If not, how could it be improved?

The statement

The lifecycle of any web app has at least two phases: a setup phase, and a ready phase (when the application is ready to respond to requests.)

In the ready phase,

IO operations (disk access, database calls, etc.) should always be asynchronous/non-blocking.

Even operations that occur purely in memory should be asynchronous, when possible. This is especially true when the operations involve iteration, and especially^2 true when the upper limit on the number of iterations is unknown.

Synchronous/blocking operations should never be performed in response to a request.

In my opinion, the question of whether or not something is part of the best practices for developing in a certain programming language can be answered decisively based on experience and objective criteria.


问:
Is doing Parent.call from the child object a right way to implement Inheritance in JavaScript?
I came across this piece of code. It didn't look that right to me. Is this the right way to implement super in JavaScript? If not, what is the right way?

```<code>function Person(name){
  this.name = name;
}

function Student(name){
  Person.call(this, name);
}

Student.prototype = new Person();
var a = new Student('test');
var b = new Student('test2');
</code>```

答:
This works and is the right way depending on whether or not the browser supports Object.create:

```<code>Student.prototype = Object.create(Person.prototype);
</code>```

The Object.create method sets up prototypal inheritance without executing the constructor function Person when "inheriting."

Body:
This works and is the right way depending on whether or not the browser supports Object.create:

Student.prototype = Object.create(Person.prototype);

The Object.create method sets up prototypal inheritance without executing the constructor function Person when "inheriting."


问:
Should putting html tags into localization files be avoided?
We are localizing all parts of our website to many languages. We use XML localization files. I think this scenario is so common, and even there should be a standard solution to this, but still I couldn't find any good advice, and every developer here has different opinion about it, so I'm asking you.

Suggest the following example:

If you have question, please ask our Customer support or write an email to Jane Doe  our specialist.

Or a long, formatted text:

```<code> <p>A very long, marketing blah-blah. A very long, marketing blah-blah. A very long, marketing blah-blah concluding in a list:</p>
 <ul>
   <li>1</li>
   <li>2</li>
   <li>3</li>
</ul>
</code>```

1) Would you put html tags into the localization XML file?

My concern is the View is separated into 2 files: your page and your localization file. People will forget to check the localization file. Also, there's logic and style embedded in html as well (see target="_blank", or the fact that the above mentioned list is unordered...)

2) Or splitting it to smaller parts?

<msg id="IfYouHaveQuestion">If you have question, please ask our</msg>

<msg id="CustomerSupport">Customer support</msg>

<msg id="OrWrite">or write an email to</msg>
...

Now, View can contain all the markup and style. It's easy to change it, flexible.

But.

There's absolutely no guarantee that the word order will be the same in all languages. Also, this would make the translator's work a nightmare, making it a puzzle.

3) Or introduce BB-style markdown?

<msg id="HaveQuestion">If you have question, please ask our [link url="{customersupportlink}" title="{{CustomerSupportTitle}}">Customer support[/link] or write an email ...</msg>

But probably this is over-complicating the issue, and also we have to write our own parser for this (though, I think it wouldn't be so hard). And probably does not solve the long, formatted text problem.

4) ??? (Your golden solution here) :)

答:
Generally speaking you should avoid placing these HTML tags in your localised strings. It violates the DRY principle and there is at least one good reason to adhere to it here: Imagine you have not only got - let's say - English and French, but also a plethora of other languages. Now you find one HTML tag to cause problems. You will have to change all of your localisation files - for virtually no reason. If you went with the DRY principle from the beginning you will only have to change one single file at best. Unfortunately the same applies to other markups.

Regarding your problem of the word order this is of course a bit more complex. I still think you should explode the strings as much as possible, but I also think that there is a huge gain in labels of localisation strings which are more or less self explanatory. Therefor you maybe should ditch DRY and consistency to some extent and introduce HTML tags in l13n strings when it is only avoidable with a great effort and the markup is unlikely to change. Otherwise use plain strings.

Another thought: The method I described above only holds if you can absolutely trust your resources. If there is only the slightest chance that someone may inject malicious code via your l13n resources. Use another markup you validate before inserted (ok, should work with HTML either, but I believe it's easier with a more restricted markup) or - if your project allows - a formatter like textile.

ContentLicense: CC BY-SA 4.0


问:
Is using Git Stash as a workflow an antipattern?
I've recently been looking at how me and my team uses Git and how our workflows work. We currently use a feature-branch workflow which seems to work well.

I've also seen some individuals on our team use workflow based on git stash. The workflow goes something like this:

Work on a main branch (like master)

Make commits as you go

If you need to get changes or switch branches, push your uncommitted changes onto the stash

Once your updating is done, pop the changes off the stash.

I should mention that this workflow is used instead of a feature branch workflow. Instead of taking a branch and working on it, developers here only ever work on a single branch and push/pop off the stack as they see fit.

I actually don't think this is a great workflow, and branching would be more appropriate than using git stash in this way. I can see the value of git stash as an emergency operation, but not for using it in a daily, regular workflow.

Would using git stash regularly be considered an anti-pattern? If so, what are some specific problems that could arise? If not, what are the benefits?

答:
From the Git SCM Book:

Often, when you’ve been working on part of your project, things are in a messy state and you want to switch branches for a bit to work on something else. The problem is, you don’t want to do a commit of half-done work just so you can get back to this point later. The answer to this issue is the git stash command.

Stashing takes the dirty state of your working directory — that is, your modified tracked files and staged changes — and saves it on a stack of unfinished changes that you can reapply at any time.

Given this description, I would say this is an Anti Pattern. An overly simplified explanation of Git Stash would be that it is the "Cut and Paste" of source control. You take a bunch of changed files, "stash" them away in a holding pen outside of Git's normal branching workflow, and then reapply those changes to a different branch at a later date.

Going back a little further, committing to master is the anti pattern here. Use branches. That's what they were designed for.

It really boils down to this:

You can hammer a screw into the wall and it will hold up a picture, but using a screwdriver is what you should do. Don't use a hammer when the screwdriver is sitting right beside you.

About Committing "Broken" Code

While the following is opinion, I have come to this opinion from experience.

Commit early, and commit often. Commit as much broken code as you want. View your local commit history as "save points" while you hack away at something. Once you've done a logical piece of work, make a commit. Sure it might break everything, but that doesn't matter as long as you don't push those commits. Before pushing, rebase and squash your commits.

Create new branch

Hack hack hack

Commit broken code

Polish the code and make it work

Commit working code

Rebase and Squash

Test

Push when tests are passing

For the OP, this Linux kernal message thread might be of interest, because it kind of sounds like some members of the OP's team is using Git in a similar manner.

@RibaldEddie said in a comment below:

First of all, a stash is not outside of a "branching workflow" since under the hood a stash is just another branch.

(at the risk of incurring the wrath of many people)

Linus said:

With "git stash", you can have multiple different stashed things too, but
  they don't queue up on each other - they are just random independent
  patches that you've stashed away because they were inconvenient at some
  point.

What I think @RibaldEddie is trying to say is that you can use git stash in a feature branch workflow -- and this is true. It's not the use of git stash that is the problem. It is the combination of committing to master and using git stash. This is an anti pattern.

Clarifying git rebase

From @RibaldEddie's comment:

Rebasing is much more like copy-pasting and even worse modifies committed history.

(Emphasis mine)

Modifying commit history is not a bad thing, as long as it is local commit history. If you rebase commits that you've already pushed, you'll essentially orphan anyone else using your branch. This is bad.

Now, say you've made several commits during the course of a day. Some commits were good. Some... not so good. The git rebase command in conjunction with squashing your commits is a good way to clean up your local commit history. It's nice to merge in one commit to public branches because it keeps the commit history of your team's shared branches clean. After rebasing, you'll want to test again, but if tests pass then you can push one clean commit instead of several dirty ones.

There is another interesting Linux Kernel thread on clean commit history.

Again, from Linus:

I want clean history, but that really means (a) clean and (b) history.

People can (and probably should) rebase their private trees (their own work). That's a cleanup. But never other peoples code. That's a "destroy history"

So the history part is fairly easy. There's only one major rule, and one
  minor clarification:

You must never EVER destroy other peoples history. You must not rebase
  commits other people did. Basically, if it doesn't have your sign-off
  on it, it's off limits: you can't rebase it, because it's not yours.

Notice that this really is about other peoples history, not about
  other peoples code. If they sent stuff to you as an emailed patch,
  and you applied it with "git am -s", then it's their code, but it's
  your history.

So you can go wild on the "git rebase" thing on it, even though you
  didn't write the code, as long as the commit itself is your private
  one.

Minor clarification to the rule: once you've published your history in
  some public site, other people may be using it, and so now it's clearly
  not your private history any more.

So the minor clarification really is that it's not just about "your
  commit", it's also about it being private to your tree, and you haven't
  pushed it out and announced it yet.

...

Now the "clean" part is a bit more subtle, although the first rules are
  pretty obvious and easy:

Keep your own history readable

Some people do this by just working things out in their head first, and
  not making mistakes. but that's very rare, and for the rest of us, we
  use "git rebase" etc while we work on our problems.

So "git rebase" is not wrong. But it's right only if it's YOUR VERY OWN
  PRIVATE git tree.

Don't expose your crap.

This means: if you're still in the "git rebase" phase, you don't push
  it out. If it's not ready, you send patches around, or use private git
  trees (just as a "patch series replacement") that you don't tell the
  public at large about.

(emphasis mine)

Conclusion

In the end, the OP has some developers doing this:

```<code>git checkout master
(edit files)
git commit -am "..."
(edit files)
git stash
git pull
git stash (pop|apply)
</code>```

There are two problems here:

Developers are committing to master. Lock this down immediately. Really, this is the biggest problem.

Developers are constantly using git stash and git pull on master when they should be using feature branches.

There is nothing wrong with using git stash -- especially before a pull -- but using git stash in this manner is an anti pattern when there are better workflows in Git.

Their use of git stash a red herring. It is not the problem. Committing to master is the problem.

Body:
From the Git SCM Book:

Often, when you’ve been working on part of your project, things are in a messy state and you want to switch branches for a bit to work on something else. The problem is, you don’t want to do a commit of half-done work just so you can get back to this point later. The answer to this issue is the git stash command.

Stashing takes the dirty state of your working directory — that is, your modified tracked files and staged changes — and saves it on a stack of unfinished changes that you can reapply at any time.

Given this description, I would say this is an Anti Pattern. An overly simplified explanation of Git Stash would be that it is the "Cut and Paste" of source control. You take a bunch of changed files, "stash" them away in a holding pen outside of Git's normal branching workflow, and then reapply those changes to a different branch at a later date.

Going back a little further, committing to master is the anti pattern here. Use branches. That's what they were designed for.

It really boils down to this:

You can hammer a screw into the wall and it will hold up a picture, but using a screwdriver is what you should do. Don't use a hammer when the screwdriver is sitting right beside you.

About Committing "Broken" Code

While the following is opinion, I have come to this opinion from experience.

Commit early, and commit often. Commit as much broken code as you want. View your local commit history as "save points" while you hack away at something. Once you've done a logical piece of work, make a commit. Sure it might break everything, but that doesn't matter as long as you don't push those commits. Before pushing, rebase and squash your commits.

Create new branch

Hack hack hack

Commit broken code

Polish the code and make it work

Commit working code

Rebase and Squash

Test

Push when tests are passing

For the OP, this Linux kernal message thread might be of interest, because it kind of sounds like some members of the OP's team is using Git in a similar manner.

@RibaldEddie said in a comment below:

First of all, a stash is not outside of a "branching workflow" since under the hood a stash is just another branch.

(at the risk of incurring the wrath of many people)

Linus said:

With "git stash", you can have multiple different stashed things too, but
  they don't queue up on each other - they are just random independent
  patches that you've stashed away because they were inconvenient at some
  point.

What I think @RibaldEddie is trying to say is that you can use git stash in a feature branch workflow -- and this is true. It's not the use of git stash that is the problem. It is the combination of committing to master and using git stash. This is an anti pattern.

Clarifying git rebase

From @RibaldEddie's comment:

Rebasing is much more like copy-pasting and even worse modifies committed history.

(Emphasis mine)

Modifying commit history is not a bad thing, as long as it is local commit history. If you rebase commits that you've already pushed, you'll essentially orphan anyone else using your branch. This is bad.

Now, say you've made several commits during the course of a day. Some commits were good. Some... not so good. The git rebase command in conjunction with squashing your commits is a good way to clean up your local commit history. It's nice to merge in one commit to public branches because it keeps the commit history of your team's shared branches clean. After rebasing, you'll want to test again, but if tests pass then you can push one clean commit instead of several dirty ones.

There is another interesting Linux Kernel thread on clean commit history.

Again, from Linus:

I want clean history, but that really means (a) clean and (b) history.

People can (and probably should) rebase their private trees (their own work). That's a cleanup. But never other peoples code. That's a "destroy history"

So the history part is fairly easy. There's only one major rule, and one
  minor clarification:

You must never EVER destroy other peoples history. You must not rebase
  commits other people did. Basically, if it doesn't have your sign-off
  on it, it's off limits: you can't rebase it, because it's not yours.

Notice that this really is about other peoples history, not about
  other peoples code. If they sent stuff to you as an emailed patch,
  and you applied it with "git am -s", then it's their code, but it's
  your history.

So you can go wild on the "git rebase" thing on it, even though you
  didn't write the code, as long as the commit itself is your private
  one.

Minor clarification to the rule: once you've published your history in
  some public site, other people may be using it, and so now it's clearly
  not your private history any more.

So the minor clarification really is that it's not just about "your
  commit", it's also about it being private to your tree, and you haven't
  pushed it out and announced it yet.

...

Now the "clean" part is a bit more subtle, although the first rules are
  pretty obvious and easy:

Keep your own history readable

Some people do this by just working things out in their head first, and
  not making mistakes. but that's very rare, and for the rest of us, we
  use "git rebase" etc while we work on our problems.

So "git rebase" is not wrong. But it's right only if it's YOUR VERY OWN
  PRIVATE git tree.

Don't expose your crap.

This means: if you're still in the "git rebase" phase, you don't push
  it out. If it's not ready, you send patches around, or use private git
  trees (just as a "patch series replacement") that you don't tell the
  public at large about.

(emphasis mine)

Conclusion

In the end, the OP has some developers doing this:

git checkout master
(edit files)
git commit -am "..."
(edit files)
git stash
git pull
git stash (pop|apply)

There are two problems here:

Developers are committing to master. Lock this down immediately. Really, this is the biggest problem.

Developers are constantly using git stash and git pull on master when they should be using feature branches.

There is nothing wrong with using git stash -- especially before a pull -- but using git stash in this manner is an anti pattern when there are better workflows in Git.

Their use of git stash a red herring. It is not the problem. Committing to master is the problem.


问:
Is MongoDB appropriate for systems that will be likely to change?
I've been using MongoDb (mainly with Meteor) and for me, it has been a great way to mock up prototypes and proof of concepts quickly.

I'm just wondering, after building the initial product, if your product is likely to grow and change, is it a good idea to stick with mongoDb?

Cause it seems like with MongoDb, you need to know a lot about how you're going to use the data upfront. From my experience only, I seemed to constantly be trying to decide whether a datatype should be a document in its own right or a sub-document.

Making it a document gives it flexibility, but if you have all your datatypes as documents, well then you pretty much just have an SQL database with foreign keys that have no foreign key constaints.

Making it a subdocument makes things perform better whilst being convenient - you don't need to join tables (which you seem to have to do manually) - but the problem seems to be if you need to query that datatype outside the context of the parent, it's very hard.

So for example, if I'm building a website with chatrooms, I might have two datatypes - chatrooms and textEntries.

Chatroom will be its own document. But textEntries can either be a document in its own right or a subdocument within Chatroom.

If I make TextEntries a document, then I would need to manually keep track of the relationship between chatroom and textEntries which defeats the purpose of using mongoDB at all.

If I make TextEntries a subdocument, this will make things easier but what if later on, I have a new requirement where I want to search across all TextEntries in all chatrooms for a particular word?

With a prototype, I know exactly what I'm building so these decisions tend to be based on just getting the product working. But longer term, I wouldn't know how or in what way I'm going to want to query the data so in light of that, would I be better off just moving to an SQL database?

答:
My general answer is that use any databases that you think would improve your service.

You wrote:

I'm just wondering, after building the initial product, if your product is likely to grow and change, is it a good idea to stick with mongoDb?

Yes, especially if the schema is going to change, MongoDB is easier to maintain in this case. In a way, it is one of the reasons why a lot of people actually prefer it. One can say it is one of its main use-case.

Cause it seems like with MongoDb, you need to know a lot about how you're going to use the data upfront. From my experience only, I seemed to constantly be trying to decide whether a datatype should be a document in its own right or a sub-document.

On the contrary, a lot of people prefer to just dump the documents in, and worry about it later. Obviously I am exaggerating, but it has its merits when you have clients who change their minds too often, or the project advances in a sporadic fashion due to entering uncharted waters. Obviously it makes it hard to use indices efficiently, but would be helpful when changing parts of your logic and you wouldn't have to migrate your data.

Making it a document gives it flexibility, but if you have all your datatypes as documents, well then you pretty much just have an SQL database with foreign keys that have no foreign key constaints.

Making it a subdocument makes things perform better whilst being convenient - you don't need to join tables (which you seem to have to do manually) - but the problem seems to be if you need to query that datatype outside the context of the parent, it's very hard.

So for example, if I'm building a website with chatrooms, I might have two datatypes - chatrooms and textEntries.

Chatroom will be its own document. But textEntries can either be a document in its own right or a subdocument within Chatroom.

You are very correct. You could experiment by denormalizing your data, or fetch your data in 2 steps like in below (using a imperative logic for demo). This will be quite fast, most likely faster than a sql solution. (make sure to index the queried fields)

```<code>var user = db.user.query({_id: user_id});
var chatrooms_id = user.current.chatrooms_id;
var messages = db.textEntries({
  chatrooms_id: chatrooms_id,
  created_at: { $gt: since_last_checked }
});
</code>```

If I make TextEntries a document, then I would need to manually keep track of the relationship between chatroom and textEntries which defeats the purpose of using mongoDB at all.

You also have to make sure you don't surpass the 16 MB document limit, if you decide to jam a lot of data into on document. For that reason, storing all those textEntries within a chatroom document is overkill and would not work with large rooms. If you missed this link on data modelling examples in the documentation, it would help to have a look.

If I make TextEntries a subdocument, this will make things easier but what if later on, I have a new requirement where I want to search across all TextEntries in all chatrooms for a particular word?

I would just use ElasticSearch for that. I am unsure if a sql solution would be much faster than Mongodb anyway. Their full-text search systems are generally not very performant, compared to a dedicated solution like ES, Sphinx, Lucene, Solr, just pick your favorite.

With a prototype, I know exactly what I'm building so these decisions tend to be based on just getting the product working. But longer term, I wouldn't know how or in what way I'm going to want to query the data so in light of that, would I be better off just moving to an SQL database?

I would use all three: sql, nosql, text-search engines. Further, I would also add in-memory, columnar and graph databases to this, if your needs require them. Why limit yourself? It is not one or the other, it is which ones will get me where I want to go the fastest within the time I have.

For example, you could use MongoDB for client-facing writes, as it is faster to write. You could sync those results to a sql db, and do analytics and certain queries on that. You could keep last 15 minutes of text entries in Redis, so you would not even hit the disk for most cases.

Body:
My general answer is that use any databases that you think would improve your service.

You wrote:

I'm just wondering, after building the initial product, if your product is likely to grow and change, is it a good idea to stick with mongoDb?

Yes, especially if the schema is going to change, MongoDB is easier to maintain in this case. In a way, it is one of the reasons why a lot of people actually prefer it. One can say it is one of its main use-case.

Cause it seems like with MongoDb, you need to know a lot about how you're going to use the data upfront. From my experience only, I seemed to constantly be trying to decide whether a datatype should be a document in its own right or a sub-document.

On the contrary, a lot of people prefer to just dump the documents in, and worry about it later. Obviously I am exaggerating, but it has its merits when you have clients who change their minds too often, or the project advances in a sporadic fashion due to entering uncharted waters. Obviously it makes it hard to use indices efficiently, but would be helpful when changing parts of your logic and you wouldn't have to migrate your data.

Making it a document gives it flexibility, but if you have all your datatypes as documents, well then you pretty much just have an SQL database with foreign keys that have no foreign key constaints.

Making it a subdocument makes things perform better whilst being convenient - you don't need to join tables (which you seem to have to do manually) - but the problem seems to be if you need to query that datatype outside the context of the parent, it's very hard.

So for example, if I'm building a website with chatrooms, I might have two datatypes - chatrooms and textEntries.

Chatroom will be its own document. But textEntries can either be a document in its own right or a subdocument within Chatroom.

You are very correct. You could experiment by denormalizing your data, or fetch your data in 2 steps like in below (using a imperative logic for demo). This will be quite fast, most likely faster than a sql solution. (make sure to index the queried fields)

var user = db.user.query({_id: user_id});
var chatrooms_id = user.current.chatrooms_id;
var messages = db.textEntries({
  chatrooms_id: chatrooms_id,
  created_at: { $gt: since_last_checked }
});

If I make TextEntries a document, then I would need to manually keep track of the relationship between chatroom and textEntries which defeats the purpose of using mongoDB at all.

You also have to make sure you don't surpass the 16 MB document limit, if you decide to jam a lot of data into on document. For that reason, storing all those textEntries within a chatroom document is overkill and would not work with large rooms. If you missed this link on data modelling examples in the documentation, it would help to have a look.

If I make TextEntries a subdocument, this will make things easier but what if later on, I have a new requirement where I want to search across all TextEntries in all chatrooms for a particular word?

I would just use ElasticSearch for that. I am unsure if a sql solution would be much faster than Mongodb anyway. Their full-text search systems are generally not very performant, compared to a dedicated solution like ES, Sphinx, Lucene, Solr, just pick your favorite.

With a prototype, I know exactly what I'm building so these decisions tend to be based on just getting the product working. But longer term, I wouldn't know how or in what way I'm going to want to query the data so in light of that, would I be better off just moving to an SQL database?

I would use all three: sql, nosql, text-search engines. Further, I would also add in-memory, columnar and graph databases to this, if your needs require them. Why limit yourself? It is not one or the other, it is which ones will get me where I want to go the fastest within the time I have.

For example, you could use MongoDB for client-facing writes, as it is faster to write. You could sync those results to a sql db, and do analytics and certain queries on that. You could keep last 15 minutes of text entries in Redis, so you would not even hit the disk for most cases.


问:
What if any languages treat undisposed resources as an error?
I've seen lots of code like the following example. It's in Python, but the same mistake is made in all languages with managed resources:

```<code>f = open('foo.txt', 'rb')
for line in f: print line
</code>```

That's it. The error is that close(f) wasn't called so the file handle is kept open until some indeterministic time in the future when the runtimes memory management decides to reclaim memory.

Python has with and c# has using to help make resource cleanup easier, but let's disregard those features for a minute. Given that:

It's a programming error not to explicitly close open files.

The runtime can detect that an open file has not been closed.

Why then doesn't the runtime throw an error instead of being "helpful" and closing the file for the programmer? That would be the fail fast and fail early strategy. Is there a technical reason why it can't? Is there any languages that does it? Has the idea been considered before (I've googled but not found anything)?

Here is how you almost implement the feature in Python:

```<code>class mustclose:
    def __init__(self, f):
        self.f = f
    def __del__(self):
        if not self.f.closed:
            raise Exception("You forgot to close() me!")
k = mustclose(open('foo.txt', 'wb'))
#k.f.close()
</code>```

Two problems: It requires wrappers, Python doesn't like to throw exceptions from destructors.

(Read this https://stackoverflow.com/questions/2807241/what-does-the-expression-fail-early-mean-and-when-would-you-want-to-do-so SO question for background on why failing fast is often desirable)

答:
When a process is terminated, all of the allocated memory gets automatically released back to the operating system, and any open file handles are closed.  That's your safety valve.

The problem, of course, is that the operating system (and your compiler, for that matter) doesn't actually know that your example code is an error.  You have to state, by your intent when you write your code, when and where that file handle gets disposed.  You might have a reason for holding the file handle open.

The using statement and the IDisposable interface in C# are specifically designed to clean up unmanaged resources like file handles.

```<code>// FileStream inherits from IDisposable, and implements the Dispose() method.
using (FileStream fs = File.Create(path))
{
    fs.Write(...);
}
// The File Stream is automatically closed here, because the Dispose() method on the
// IDisposable interface is automatically called when the "using" block goes out of scope.
</code>```

In a managed environment, memory is typically disposed automatically when garbage collection occurs.  Implementing using and IDisposable insures that file handles and other unmanaged resources get properly disposed before the memory is released. You can also state your specific intent by calling Close() explicitly on your files before the enclosing object goes out of scope.

In some situations, such as repositories that return an IQueryable, it can be a hindrance to put a code block in a using statement, because the connection to the database can actually close before the query is executed.

In short, the OS and the compiler can't read your mind.

Body:
When a process is terminated, all of the allocated memory gets automatically released back to the operating system, and any open file handles are closed.  That's your safety valve.

The problem, of course, is that the operating system (and your compiler, for that matter) doesn't actually know that your example code is an error.  You have to state, by your intent when you write your code, when and where that file handle gets disposed.  You might have a reason for holding the file handle open.

The using statement and the IDisposable interface in C# are specifically designed to clean up unmanaged resources like file handles.

// FileStream inherits from IDisposable, and implements the Dispose() method.
using (FileStream fs = File.Create(path))
{
    fs.Write(...);
}
// The File Stream is automatically closed here, because the Dispose() method on the
// IDisposable interface is automatically called when the "using" block goes out of scope.

In a managed environment, memory is typically disposed automatically when garbage collection occurs.  Implementing using and IDisposable insures that file handles and other unmanaged resources get properly disposed before the memory is released. You can also state your specific intent by calling Close() explicitly on your files before the enclosing object goes out of scope.

In some situations, such as repositories that return an IQueryable, it can be a hindrance to put a code block in a using statement, because the connection to the database can actually close before the query is executed.

In short, the OS and the compiler can't read your mind.


答:
The destructor is called after the object goes out of scope.

If f is global, then that means at program exit.

Someone could use that resource f again, and the compiler / runtime is not generally in a position to know for sure that that cannot happen in any particular case.

Its good practice to scope variables as tightly as possible, and avoid globals.  But these dynamic languages are also used as scripting languages, and scoping can be verbose and detract form readability too.

You can typically have thousands of handles open, and all are closed automatically by the OS on process exit (graceful or otherwise) anyway, so programmers are very rarely bitten by unnecessarily-long-lived resources.

Title: What if any languages treat undisposed resources as an error?

Body:
I've seen lots of code like the following example. It's in Python, but the same mistake is made in all languages with managed resources:

```<code>f = open('foo.txt', 'rb')
for line in f: print line
</code>```

That's it. The error is that close(f) wasn't called so the file handle is kept open until some indeterministic time in the future when the runtimes memory management decides to reclaim memory.

Python has with and c# has using to help make resource cleanup easier, but let's disregard those features for a minute. Given that:

It's a programming error not to explicitly close open files.

The runtime can detect that an open file has not been closed.

Why then doesn't the runtime throw an error instead of being "helpful" and closing the file for the programmer? That would be the fail fast and fail early strategy. Is there a technical reason why it can't? Is there any languages that does it? Has the idea been considered before (I've googled but not found anything)?

Here is how you almost implement the feature in Python:

```<code>class mustclose:
    def __init__(self, f):
        self.f = f
    def __del__(self):
        if not self.f.closed:
            raise Exception("You forgot to close() me!")
k = mustclose(open('foo.txt', 'wb'))
#k.f.close()
</code>```

Two problems: It requires wrappers, Python doesn't like to throw exceptions from destructors.

(Read this https://stackoverflow.com/questions/2807241/what-does-the-expression-fail-early-mean-and-when-would-you-want-to-do-so SO question for background on why failing fast is often desirable)


答:
While it has almost certainly been considered, it has been discarded because, in the general case, it is impossible to do.

What happens if f is not a local variable, or is returned from the function?

At that point, you have an equivalent to the Halting Problem. There is no way (in the general case) for static analysis to prove one way or another if the file is closed somewhere else in your program (or worse, in someone calling this code in a library).


答:
The runtime can detect that an open file has not been closed.

The only time the runtime can unambiguously determine that an open file should have been closed is upon process shutdown, particularly with event driven frameworks that may reuse open file handles in callbacks, etc. Unless the handle has been scoped (and you said ignore C# using {} and Java Try-With-Resources runtime hints), the runtime CANNOT determine if an error has occurred.

Since the runtime is disposing of the whole process, for system stability purposes, its only real recourse is to close all open stream and release the associated resources.


问:
The Definition of "Strong Type Systems"
I saw Martin Odersky's "The Trouble with Types" presenstaion. He divided programing-languages in two dimensions in the "Type Systems Landscape" chart; A "Static/Dynamic" dimension and A "Strong/Weak" one.

I searched to find a definition for "strong/weak type systems" and its difference from "static/dynamic" type-systems that can explain why Python/Ruby have a "strong type system"? I've found something on Wikipedia, but it hasn't satisfied me.

Now I want to know what's the "strong/weak"? and How Python has a strong type system (like as scala)? Is it about inheritance / composable / primitive types in a language or not? If 'no', What's the the concept and measurement-unit for these features (inheritance / compose / primitive / container / ...) in the type-systems?

答:
A strong type system is a type system that has a compile-time restriction or run-time feature that you find attractive.

A weak type system is a type system which lacks that restriction or feature.

Seriously, that's it.  You read the Wikipedia page, so you know that there are at least eleven different mutually incompatible meanings of "strongly typed".  The term is useless unless clarified; no two people discussing a type system need have the same definition in their heads of "strongly typed".

The sensible thing to do is therefore to avoid using "strong" and "weak" entirely; when you talk about a feature of a type system, simply describe the feature rather than characterizing it as "strong" or "weak". If you mean "I like languages where the compiler assigns static types to expressions and searches for type errors" then say that. If you mean "I like languages where every object has one or more associated data types and can describe those types reflectively at runtime" then say that. Don't say "strong" because someone will think you mean "statically typed" and someone will think you mean "has run-time reflection", and those two things have pretty much nothing to do with each other.

Keep in mind also that many people use "strong" to mean that a particular type system restriction is impossible to ignore, and some use "strong" to mean the opposite: that a restriction is encouraged but can be avoided. For example, someone who believes that a type system is "strong" if type errors are impossible at runtime would characterize C# as "weakly" typed, because C# allows the developer to insert type conversions that will fail at runtime. (example: short x = (short)(object)(123.ToString());)  Someone who believes that a type system is "strong" if it encourages writing programs where the compiler finds many but not all type errors at compile time would characterize C# as strongly typed for the same reason.  If the same feature of the type system can be reasonably characterized as both "strong" and "weak" then we know that the terms are useless and should be avoided.

Title: The Definition of "Strong Type Systems"


问:
Algorithms for making image mosaics - is there a quicker way than this?
I've been playing with making image mosaics.  My script takes a large number of images, scales them down to thumbnail size and then uses them as tiles to approximate a target image.

The approach is actually quite pleasing:

I compute the mean square error for every thumb in every tile position.

At first I just used a greedy placement: put the thumb with the least error on the tile it best fits, and then the next and so on.

The problem with greedy is that it leaves you eventually placing the most different thumbs on the least popular tiles, whether they match closely or not.  I show examples here:
http://williamedwardscoder.tumblr.com/post/84505278488/making-image-mosaics

So I then do random swaps until the script is interrupted.  The results are quite OK.

A random swap of two tiles is not always an improvement, but sometimes a rotation of three or more tiles results in a global improvement i.e. A <-> B may not improve, but A -> B -> C -> A1 may..

For this reason, after picking two random tiles and discovering they do not improve, I pick a bunch of tiles to evaluate if they can be the third tile in such a rotation.  I do not explore if any set of four tiles can be profitably rotated, and so on; that'd be super-expensive real soon.

But this takes time.. A lot of time!

Is there a better and faster approach?

Bounty Update

I tested out various Python implementations and bindings of the Hungarian Method.

By far the fastest was the pure-Python https://github.com/xtof-durr/makeSimple/blob/master/Munkres/kuhnMunkres.py

My hunch is that this approximates the optimal answer; when run on a test image, all other libraries agreed on the result but this kuhnMunkres.py, whilst being orders of magnitude faster, only got very very very close to the score the other implementations agreed on.

Speed is very data-dependent; Mona Lisa rushed through kuhnMunkres.py in 13 minutes, but the Scarlet Chested Parakeet took 16 minutes.

Results were much the same as random swaps and rotations for the Parakeet:

(kuhnMunkres.py on the left, random swaps on the right; original image for comparision)

However, for the Mona Lisa image I tested with, the results were noticeably improved and she actually had her defined 'smile' shining through:

(kuhnMunkres.py on the left, random swaps on the right)

答:
If the last tiles are your problem, you should try to place them early on, somehow ;)

One approach would be to look at the tile that is the furthest away from the top x% of its matches (intuitively I'd go with 33%) and place that on its best match. That's the best match it can get anyway.

Furthermore you could choose not to use the best match for the worst tile, but the one where it introduces the least error compared to the best match for that slot, so that you don't completely throw away your best matches for the sake of "damage control".

Another thing to bare in mind is that in the end you are producing an image to be processed by an eye. So what you really want is to use some edge detection to determine which positions on your image are most important. Similarly, what happens at the very periphery of the image is of little value to the quality of the effect. Superpose these two weights and include them in your distance calculation. Any jitter you get should thus gravitate toward the border and away from edges, thus disturbing a lot less.

Also with the edge detection in place, you may want to place the first y% greedily (maybe until you drop below a certain threshold of "edginess" in the tiles left), so that the "hot spots" are dealt with really nicely, and then switch to "damage control" for the rest.


答:
In a nutshell, the strength of a type system is how likely you are to get a type mismatch error when you try to do things in the language.  Strongly typed languages have lots of ways to get a type mismatch error:  wrong type passed into or out of a function, wrong type assigned to a variable, wrong type on one side or the other of an operator.  Strongly typed languages let you create your own types with similar restrictions.  Weakly typed languages try to avoid type mismatch errors.  That doesn't mean variables in weakly typed languages don't have types, just that the language doesn't help the programmer automatically check and enforce those types.

Strong typing is a continuum, not an absolute.  Even strongly typed languages carve out exceptions.  Java does type coercion between numeric types and from most types to a String, for example.  Some language features like type inference or implicits give a superficial appearance of weaker typing, but are still very strong behind the scenes. There is no bright dividing line, but usually it's relatively easy to compare two languages with each other.  You might call C++ strongly typed compared to JavaScript, but not compared to Haskell, for example.

The term is often mistakenly used to mean how expressive a type system is, but that's a separate metric.  It's also often mistaken with static typing, which is  a measure of how much the types are checked at compile time versus runtime.

Title: The Definition of "Strong Type Systems"

Body:
I saw Martin Odersky's "The Trouble with Types" presenstaion. He divided programing-languages in two dimensions in the "Type Systems Landscape" chart; A "Static/Dynamic" dimension and A "Strong/Weak" one.

I searched to find a definition for "strong/weak type systems" and its difference from "static/dynamic" type-systems that can explain why Python/Ruby have a "strong type system"? I've found something on Wikipedia, but it hasn't satisfied me.

Now I want to know what's the "strong/weak"? and How Python has a strong type system (like as scala)? Is it about inheritance / composable / primitive types in a language or not? If 'no', What's the the concept and measurement-unit for these features (inheritance / compose / primitive / container / ...) in the type-systems?


答:
What would happen if a language threw run-time errors e.g. on leaked file handles? Coders would hate it with a flaming passion, and it would go nowhere.

The point of resource management is to aid you in producing a valuable program with less effort. "Valuable" doesn't mean "perfect": a program that leaks a file handle is bad, but often it is nowhere near as bad as a program that deliberately blows up instead of wasting some resources, which might or might not cause problem for your use case.

If the only goal worth aiming at was perfection, them sure, every compiler, run-time and OS should be as ruthless as possible in detecting and terminating processes that commit errors, since they are by definition worthless. Arguably it would be a better world if customers didn't accept anything short of perfection and ruthlessly sued the pants of any vendor who sold them an application with a resource leak in it, but let's be quite clear: this is not such  a world.

That is only the business side of things; others have pointed out that it's not easy to decide whether a handle has truly been leaked or not. Languages with fully automatic garbage collection are in theory capable of adding any desired behaviour to the 'dispose' hook; for instance, Java initially assumed that you would clean up resources in a class's finalize method. This is now widely considered a deplorable mistake, as it turns out having things happen in unpredictable order causes more problems than it solves, particularly if they have effects on the external environment (and not just the strictly process-private memory pool). Ultimately it just wasn't worth making the garbage collection process deterministic just to allow this pattern of resource management, when the language already has finally (and now scoped resources) to achieve the same thing.


答:
In Java 7 and later, resources that implement AutoCloseable will cause the compiler to emit a warning when a resource is not managed with try-with-resources.

Combined with garbage collection, this goes a long way toward ensuring that resources are freed at some point.

As Robert Harvey mentioned, the operating system also disposes of a process's entire memory space and frees dangling resources. However, this does not necessarily ensure that resources are properly closed (e.g. sending a "goodbye" message on a socket to a remote host to free remote resources). This also relies on the process being shut down. A long-running process might leak resources such as remote connections, file handles, etc.

Java 7's try-with-resources comes as close as close as I have seen toward guaranteeing that even non-local resources are freed during program execution, assuming that developers heed the compiler warnings.


答:
Runtime errors are not a tool to discipline programmers. they are an ultima ratio to deal with unexpected errors which, if not handled, would leave an unstable state. Which is not the case with open file handles. In the grand scheme of things, it doesn't matter when they get closed.

Should the compiler issue a warning, if it finds unmanaged resources going out of scope without dispose? Probably. But it is still the programmers decision whether it is acceptable to let the GC handle finalisation at an arbitrary time, or whether those handles need to be closed now.


问:
What is a good design pattern for generating an Excel (xlsx) file in code?
See my Update at the bottom for more.

I occasionally have projects where I have to output some data as an Excel file (xlsx format).  The process is usually:

User clicks some buttons in my application

My code runs a DB query and processes the results somehow

My code generates an *.xlsx file using either the Excel com interop libraries or some third-party library (e.g., Aspose.Cells)

I can easily find code examples for how to do this online, but I am looking for a more robust way to do this.  I'd like my code to follow some design principles to ensure that my code is maintainable and easily understandable.

Here is what my initial attempt to generate an xlsx file looked like:

```<code>var wb = new Workbook();
var ws = wb.Worksheets[0];
ws.Cells[0, 0].Value = "Header";
ws.Cells[1, 0].Value = "Row 1";
ws.Cells[2, 0].Value = "Row 2";
ws.Cells[3, 0].Value = "Row 3";
wb.Save(path);
</code>```

Pros: Not much.  It works, so that's good.

Cons:

Cell references are hardcoded, so I have magic numbers littered throughout my code.

It's difficult to add or remove columns and rows without updating many cell references.

I need to learn some third-party library.  Some libraries are used like other libraries, but there can still be problems.  I had a problem where the com interop libraries use 1-based cell referencing whereas Aspose.Cells uses 0-based cell referencing.

Here is one solution that addresses some of the cons I listed above.  I wanted to treat a table of data as its own object that can be moved around and changed without digging into cell manipulation and disturbing other cell references.  Here is some pseudocode:

```<code>var headers = new Block(new string[] { "Col 1", "Col 2", "Col 3" });
var body = new Block(new string[,]
    {
        { "Row 1", "Row 1", "Row 1" },
        { "Row 2", "Row 2", "Row 2" },
        { "Row 3", "Row 3", "Row 3" }
    });

body.PutBelow(headers);
</code>```

As a part of this solution, I'll have some BlockEngine object that takes a container of Blocks and performs the cell manipulations required to output the data as an *.xlsx file.  A Block object can have formatting attached to it.

Pros:

This removes most of the magic numbers that my initial code had.

This hides a lot of cell manipulation code, although cell manipulation is still required in the BlockEngine object that I mentioned.

It's much easier to add and remove rows without effecting other parts of the spreadsheet.

Cons:

It's still difficult to add or remove columns.  If I wanted to swap the position of columns two and three, I'd have to directly swap the cell contents.  In this case that'd be eight edits, and thus eight opportunities to make a mistake.

If I have any formatting in place for those two columns, I have to update that as well.

This solution doesn't support horizontal block placement; I can only place one block below another.  Sure I could have tableRight.PutToRightOf(tableLeft), but that would cause problems if tableRight and tableLeft had different numbers of rows.  To place tables, the engine would have to be aware of every other table.  This seems unnecessarily complicated to me.

I still need to learn third-party code, though through a layer of abstraction via Block objects and a BlockEngine the code will be less tightly-coupled to the third-party library than my initial attempt.  If I wanted to support lots of different formatting options in a loosely-coupled way, I'd probably have to write a lot of code; my BlockEngine would be a huge mess.

Here is a solution that takes a different route.  Here's the process:

I take my report data and generate an xml file in some format that I choose.

I then use an xsl transformation to convert the xml file to an Excel 2003 XML Spreadsheet file.

From there I simply convert the xml Spreadsheet to an xlsx file using a third party library.

I found this page that describes a similar process and includes code examples.

Pros:

This solution requires almost no cell manipulation.  You instead use xsl/xpath to do your manipulations.  In order to swap two columns in a table, you move the whole columns in the xsl file unlike my other solutions which would require cell-swapping.

While you still need a third-party library that can convert an Excel 2003 XML Spreadsheet to an xlsx file, that's about all you'll need the library for.  The amount of code you need to write that would call into the third-party library is tiny.

I think this solution is the easiest to understand and requires the least amount of code.

The code that creates the data in my own xml format will be simple.

The xsl file will be complicated only because the Excel 2003 XML Spreadsheet is complicated.  However it's easy to check the output of the xsl file: just open the output in Excel and check for error messages.

It's easy to generate sample Excel 2003 XML Spreadsheet files: just create a spreadsheet that looks like your desired xlsx file, and then save it as an Excel 2003 XML Spreadsheet.

Cons:

Excel 2003 XML Spreadsheets don't support certain features.  You can't autofit column widths for instance.  You can't include images in headers or footers.  If you're going to export the resultant xlsx file to pdf, you can't set pdf bookmarks.  (I hacked together a fix for this using cell comments.).  You have to do this using your third-party library.

Requires a library that supports Excel 2003 XML Spreadsheets.

Uses an 11-year old MS Office file format.

Note: I realize that xlsx files are actually zip files containing xml files, but the xml formatting seems too complicated for my purposes.

Finally, I've looked into solutions involving SSRS, but it seems too bloated for my purposes.

Back to my initial question, what is a good design-pattern for generating Excel files in code?.  I can think of a few solutions, but none seem to stick out as ideal.  Each has drawbacks.

Update: So I tried both my BlockEngine solution and my XML Spreadsheet solution for generating similar XLSX files.  Here are my opinions of them:

The BlockEngine solution:

This simply requires too much code considering the alternatives.

I found it too easy to overwrite one block with another if I had an offset wrong.

I originally stated that formatting could be attached at the block level.  I found this to be not much better than doing the formatting separately from the block content.  I can't think of a good way to combine the content and the formatting.  Nor can I find a good way to keep them separate.  It's just a mess.

The XML Spreadsheet solution:

I'm going with this solution for now.

It bears repeating that this solution requires much less code.  I'm effectively replacing the BlockEngine with Excel itself.  I still do need a hack for features like bookmarks and page breaks.

The XML Spreadsheet format is finicky, but it's easy to make a small change and compare the results to an existing file in your favorite Diff program.  And once you figure out some idiosyncrasy, you can put it in place and forget about it from there.

I'm still concerned that this solution relies on an older Excel file format.

The XSLT file I created is easy to work with.  Dealing with formatting is much simpler here than it is with the BlockEngine solution.

答:
If you really want something that works well for you, then I suggest you get used to the idea of "unnecessarily complex"... that's the nature of dealing with Microsoft Office file formats.

I (sort of) like your idea of "blocks"... I would make sub-classed block objects, like Table, with Columns and Rows independent of the notion of cells. Then use your block engine to convert these to XSLS files.

I've used the OpenXML SDK successfully in the past, but don't try to read the documentation and start from scratch. Instead, create an exact copy in Excel of what you want, save it, and inspect it using the provided Document Reflector tool. It will give you the C# code you need to create the document, which you can then learn from and modify.


问:
Why aren't we building and using parallel processors *meant* for general computation?
We all know GPUs are much faster than CPUs for a wide range of applications. When someone asks why we are not just programming for GPUs at all, one of the most common answers is that GPUs are not good for everything - i.e., they fail to do some things that CPUs do easily. Well, no wonder: after all, they are not meant to be used for general computations. GPUs are strongly tied to games and graphical applications, not only having specialized functions for those, but often being advertised for them.

My question is: why, then, aren't we building and using processors that are actually designed for parallel programs?

答:
We already do; that's what multi-core processors are for.

Part of highly-optimizing for speed is specialization.  When you build processors that specialize in one thing, you can optimize for that one thing, and ignore optimizing for anything else.

Optimization can have conflicting goals.  That's the reason we have many different kinds of data structures; each is optimized for a specific task.  If you could write a data structure that was fully optimized for any task, then we'd all be using only that data structure, and nothing else.


答:
Because general computation is hard to parallelize into the SIMD model that is the driving force behind GPU design. Graphics has the bonus of having each vertex of the rendered mesh being able to be looked at in isolation and execute the same operations on it to figure out it's position on the screen and with each resulting pixel on screen is the same. Those are the basis for the vertex and fragment shader in openGL.

General computation is harder to get kernelized computation units that are worth it to parallelize in this way.

Having said that supercomputers are heavily parallelized with each core being a full CPU (using the more flexible MIMD model) and efficient communication between each core.

Efficient parallelization is an open research area with several books written about them.

Title: Why aren't we building and using parallel processors *meant* for general computation?

Body:
We all know GPUs are much faster than CPUs for a wide range of applications. When someone asks why we are not just programming for GPUs at all, one of the most common answers is that GPUs are not good for everything - i.e., they fail to do some things that CPUs do easily. Well, no wonder: after all, they are not meant to be used for general computations. GPUs are strongly tied to games and graphical applications, not only having specialized functions for those, but often being advertised for them.

My question is: why, then, aren't we building and using processors that are actually designed for parallel programs?


问:
What is the legality of making a mobile app version of an existing card or board game?
I see that the market is full of mobile apps based on card/board games. For example, do a search for "Taboo" and there are many results which are not published by Hasbro Inc. Is this legal?

The top "Taboo" result says in the description that they are not associated with Hasbro--does this absolve them of infringement issues?

I can think of a few games that I could make mobile versions of that could be successful, but I'm wary of publishing (and monetizing) a game based on another, especially if it has the same name.

Note: I noticed this useful thread, which hints that it is legal to create such games, but that the original owner may fight to have similar games removed and might win. If I develop such a game and have to pull it down, would I be able to resubmit it after making some changes?

答:
There are several different things protecting board games - not all of them may be in place.

First, there's the copyright on the artwork of the game and the wording of the rules. Copyright is automatic - this is always protected.

Next, there is the trade mark on the name of the game.  These are registered and will typically be done for all professionally made board and card games.  The nature of the trademark requires companies to enforce it, lest they become the next xerox or kleenex (note the lower case use of those words).

Lastly, there's the patent.  Patents cover the gameplay itself.  For example, Khet is protected by patent 7,264,242 and won $1.6M in damages when a big name toy company violated the patent.

Lots of games aren't patented.  It is something to look at and check into to make sure the game isn't patented first.

You may also find old patents of games (such as 726,023 from 1903 known as Blue and Gray) where the patent has long since expired and reimplement it without worry of patent violations. Note that there are lots of games that have been patented but never produced and just trawling around the patent archives and looking at who cites what you may find an existing game that has had its patent expired which you could then reimplement.

Further reading:  MythBusting: Game Design and Copyright, Trademarks, and Patents (US Law) at Board Game Geek.


问:
How does semantic versioning apply to programs without API?
In http://semver.org/ — which in my perception seems to be the most widely used convention in versioning — it is recommended to increase the major version number when a change that breaks/modify the API is introduced.

There are two related scenarios that I don't see how to apply this guideline though:

What if my code doesn't offer any API? How should I version my code?

What if my code starts offering an API in a late stage of its development?

答:
Semver is mostly concerned about versioning libraries and packages in a manner that avoids dependency hell, in it's various incarnations. However, the idea behind Semver can be extended to all kinds of programs – any piece of code has some kind of user interface, or it is pretty useless.

A programming library or web service has an API.

Consumer software might have a GUI.

Command line programs have a set of switches and options.

Configuration files are also an user interface.

Using the example of consumer software, such as a word processor:

Increment the patch number when you ship a bug fix, e.g.: “fixed bug where application always crashes at 00:00 PM on Tuesdays”.

Increment the minor version number when adding a new feature, e.g.: “added support for underlined text”.

Increment the major version when you significantly overhaul the user interface, or rewrite all internals. E.g.: “Toolbars use too much screen estate. The UI is now provided through touch gestures only” – such a change would break existing workflows.

However, many problems which Semver tries to solve do not exist outside of the area of dependency management. In consumer applications, the version is not only a version, but also a marketing asset.

Firefox and Chrome release new versions comparatively frequently, and increment their major version number at each release. This results in ridiculously high version numbers (both are currently in their 30s). A browser with a higher version number must simply be better than a browser with a lower version number, right?

The major version number of Apple's operating system OS X has become part of the name (X is 10 in Roman numerals), making the minor version number the effective major version number.

The Ubuntu operating system uses a year.month.patchlevel versioning scheme. This makes it easy to remember how old your OS is, but makes it much more difficult to figure out which versions are compatible, and how long support for each version lasts.

The Linux kernel bumped the version number from 2.6.39 to 3.0.0, because the 39 was getting a bit large, and to commemorate Linux' 20th anniversary.

Donald Knuth's legendary TeX typesetting system uses a version number that, as of version 3, converges to π by adding another digit at each release: 3.14159265…. This signifies how the system is getting closer to perfection. Similarly, the Metafont system converges to e: 2.7182818….

So, many applications are not well served by Semver. Pick a versioning scheme that's good for your users (regardless of whether these users are fellow programmers or consumers), and keep it consistent.


问:
Alternatives for Agile Scrum
We started following the Agile Scrum methodology and we have completed about 10 sprints.

One observation I had is that not all in the team are taking up the responsibilities of completing the tasks and user stories by themselves and everytime they have to be instructed or allotted with some tasks. Also the estimate they are giving are not very agile.

There is always a need for someone to look after all the user stories, their completion status, tasks that are yet to be done etc and allot them to team members who are not occupied.

I also feel that we would be able to deliver faster if we had one person who would create tasks and assign them to people along with deadlines to complete them (project manager role).

And this is what I feel is missing in Agile Scrum.

Given that the team is not taking up tasks and not risking to take up tight estimates, what are the alternates that we can look for? Or, are there any provisions in Agile Scrum to fasten things?

答:
At the risk of sounding a bit cheeky, one alternative is to actually use scrum. You're using something like scrum but isn't actually scrum.

If you have team members that aren't engaged, it sounds like you need an agile coach to get you past the learning phase.

Title: Alternatives for Agile Scrum


问:
How do developers deal with "where to start" problem in a context of overwhelming difficulties caused by too much heterogeneous information?
A friend of mine, a beginner PHP programmer, needs to link the product his company develops with a third-party product (a set of web services). He received the "relevant" documentation (a few hundred of pages of unreadable stuff) from this third-party, have read the PHP documentation related to SOAP client, have read about SOAP and WSDL, but doesn't have a slightest idea where to start. Instead of a step-by-step tutorial, he has lots of overly verbose documentation.

I suggested him to use prototyping:

Imagine the most basic scenario where the third-party web services can be used,

Select the relevant documentation,

Build (from scratch) the simplest PHP script which will play this scenario,

Once the prototype works, integrate the functionality into the existing product,

Refactor,

Expand the existing product with additional features.

While this may help pushing this person to the right direction, I feel that my suggestion is only partially helpful. I imagine myself six years ago knowing nothing about WSDL and SOAP and having to search inside hundreds of pages of documentation: I would be already discouraged at steps 2 and 3.

Experienced developers have a bunch of patterns, practices and processes which help solving basic problems frequently encountered in software development:

The technical aspects of a feature are uncertain? Use prototyping.

The application "feels unresponsive"? Use profiling to find bottlenecks.

The requirements are subject to frequent change? Use Agile.

Programmers need to be sure their code doesn't contain omissions? Use code reviews.

The successive versions of a product are not deployed fast enough? Use DevOps.

While those patterns and practices help developers solving purely technical/organizational issues (such as "I know how to implement Web Sockets in Java, Python and Node.js, but now I need to do it in Haskell."), the same patterns and practices are not helpful for less experienced programmers who need to solve more substantial and less technical problems (such as "I believe Web Sockets are a sort of HTTP but it happens the other way, something like that; now lead developer asked me to implement that in my app, but I'm not sure why do we need it.")

Inviting the programmer to spend three years in college or twelve months reading programming-related books is not always an option: some people need to work to pay their bills, need to finish the project for the next deadline, and are not paid to read books.

So what are other options?

答:
The series of steps that you suggested sounds very reasonable. Most courses of action will come down to starting with the smallest unit of interaction between PHP and the external library and implementing it, learning from that, extending the scope, implementing, learning, eventually refactor, repeat. I.e. working bottom up to connect the external library to the product that he is working on. In principle there might also be a way to approach this top down but this would probably require your friend to know more of the rough building blocks that he will need, which is the problem in the first case, therefore this is out.

The fact might be that your friend is just simply tasked with something that he cannot solve even given a reasonable amount of time, just because he currently does not have enough overall experience/knowhow/skill (however you might want to label it). Besides the general guideline that you gave him more specific work might help him over the hump. Be that from you or from colleagues. That would mean talking the specific problem through with someone else that has enough general software engineering know how to coax a path to a solution out of him (that could even be you), or with somebody that has enough specific knowledge (i.e. PHP, SOAP and WSDL) that can give him direct advice and guidelines to move him along.

This is not a bad thing, just a part of growing in your chosen profession. I have seen a lot of documentation morphed into just long lists of 'HowTo' from which you can copy and paste. I think there is a skill to comprehending, abstracting and concluding with incomplete knowledge about new systems that you encounter (a skill that grows with every system that you encounter). The HowTo style of documentation does not promote that skill. It sounds like your friend is crossing the threshold where he graduates from using 'HowTo' like documentation and it might be a painful process, but if he makes it he will come out a better developer and engineer.


答:
In general

Break every problem down into N problems that if solved will also solve the larger problem, wherein N is the number of things you can wrap your head around at once.

The "break down" can consist of:

learning about the problem space at a high level

defining or clarifying the "solved" conditions

stating the steps or actions of the larger problem.

Apply recursively until each problem is trivial.

In particular

Your friend needs to avoid thinking about SOAP, XML, JSON, and all the other technical details until the problem has been reduced to problems of which one or more is solved by those details. At that point, one or more of the sub-problems will be, X requests data Y from Z using Z's API. If Z doesn't have an API or your friend doesn't know how to use the given API, he needs to learn that particular problem space, googling or asking other pros.

Title: How do developers deal with "where to start" problem in a context of overwhelming difficulties caused by too much heterogeneous information?

Body:
A friend of mine, a beginner PHP programmer, needs to link the product his company develops with a third-party product (a set of web services). He received the "relevant" documentation (a few hundred of pages of unreadable stuff) from this third-party, have read the PHP documentation related to SOAP client, have read about SOAP and WSDL, but doesn't have a slightest idea where to start. Instead of a step-by-step tutorial, he has lots of overly verbose documentation.

I suggested him to use prototyping:

Imagine the most basic scenario where the third-party web services can be used,

Select the relevant documentation,

Build (from scratch) the simplest PHP script which will play this scenario,

Once the prototype works, integrate the functionality into the existing product,

Refactor,

Expand the existing product with additional features.

While this may help pushing this person to the right direction, I feel that my suggestion is only partially helpful. I imagine myself six years ago knowing nothing about WSDL and SOAP and having to search inside hundreds of pages of documentation: I would be already discouraged at steps 2 and 3.

Experienced developers have a bunch of patterns, practices and processes which help solving basic problems frequently encountered in software development:

The technical aspects of a feature are uncertain? Use prototyping.

The application "feels unresponsive"? Use profiling to find bottlenecks.

The requirements are subject to frequent change? Use Agile.

Programmers need to be sure their code doesn't contain omissions? Use code reviews.

The successive versions of a product are not deployed fast enough? Use DevOps.

While those patterns and practices help developers solving purely technical/organizational issues (such as "I know how to implement Web Sockets in Java, Python and Node.js, but now I need to do it in Haskell."), the same patterns and practices are not helpful for less experienced programmers who need to solve more substantial and less technical problems (such as "I believe Web Sockets are a sort of HTTP but it happens the other way, something like that; now lead developer asked me to implement that in my app, but I'm not sure why do we need it.")

Inviting the programmer to spend three years in college or twelve months reading programming-related books is not always an option: some people need to work to pay their bills, need to finish the project for the next deadline, and are not paid to read books.

So what are other options?


问:
Large internal features on kanban
This days I'm reading some tutorials/advices about Kanban process and Agile methodologies, but I have two big questions about this Kanban methodology.

What I understood is user stories are about adding bussiness value, like a feature which our customers can use. The main problem is we have a lot of features that looks trivial (simple form that manages synonyms for solr, for example) but are hard to implement and may take several days/weeks to complete, due to scaling/coordination details on our cluster (refreshing the synonyms using zk and reloading from database, for exmaple).

How do you break down this user story into smaller ones since Kanban specificies every user story has to be independent? Can I break it down into user stories about implementation details? (implement coordination algorithm, implement X storage service, etc)

And my last question is about architectural changes/refactoring. Since it doesn't add any business value (invisible to our customers) how do you reflect this tasks in this methodology?

答:
I don't know anything specific to Kanban, but in agile in general, the culture is that you must be able to demonstrate new features working to your customer at the end of every iteration. This demonstration usually has to be complete, in the sense that it must have the UI, business logic and persistence processes working (which is often called a vertical slice).

However, in a case like yours where a "trivial" feature demands too much technical effort, your team may ask if your customer agrees to seeing only a partial demonstration by the end of an iteration. For instance, only the UI and business logic working, but without any persistence (since that is your bottleneck). If the customer agrees, then you can break the persistence into another story.

If your customer may not agree, you can try to break the story into even smaller pieces. Though in your case, breaking the story may not help. If it is a simple CRUD, you can break the C, R, U and D operations into individual stories, but you will still have your "weeks" of technical effort on the persistence layer when developing the first of these stories.

So, in the end, if your customer does not agree to the "partial vertical slices" idea, and if you can't break the story into smaller pieces, or breaking them doesn't help you, then you have one very likely outcome: You won't be able to deliver the feature in one iteration.

If this happens, and if your team is counting story points done per iteration (velocity), then what you have is an iteration with zero velocity. This is usually a sign that something in the team has to change. Which brings me to the answer to your last question (about refactoring):

From my (very limited and out of context) perspective, it looks like your team may be facing problems with leaving techcnical debt behind. The fact that you're using a persistence mechanisms that hinders your velocity may not be directly related to technical debt, it may really be necessary for the specific business your team is developing; however, if that is not the case, your team must be able to switch to another persistence mechanism as soon as the one you're currently using creates more problems than it solves.

For instance, you may use a NoSQL database if you want to reduce the effort of changing the "schema" (since NoSQL doesn't have any) or having to perform huge migrations (because you won't need to). But doing this switch may be labeled as "impossible" if your system is a mess. If your architecture is too coupled to the database you're currently using, the only way to switch is to refactor your system to be decoupled from the persistence mechanism.

So about how to fit refactoring within your methodology, I believe this topic is already covered by this other question, so I better not repeat myself here.

Title: Large internal features on kanban


问:
Knowing who is the user in every request (every action, every view, every time)
I have many model classes that are mapped from/to tables using EF.  Two of them are User and UserCookie, which are stored in tables Users and UserCookies.

```<code>public class User
{
    public long UserId { get; set; }
    public string Fullname { get; set; }
    public string Email { get; set; }

    (...)
}

public class UserCookie
{
    public long UserCookieId { get; set; }
    public long? UserId { get; set; }
    public virtual User User { get; set; }
    public string CookieValue { get; set; }
}
</code>```

Every controller in my ASP.NET MVC application is a child (inherits) of MyController, which is like this:

```<code>public class MyController : Controller
{
    protected MyDbContext dbContext;
    protected UserCookie userCookie;
    protected User currentUser;
    protected string cookieValue;

    public MyController() : base()
    {
        this.dbContext = new MyDbContext();
        this.cookieValue = "";
        this.currentUser = null;
        this.userCookie = null;
    }

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        base.OnActionExecuting(filterContext);

        HttpCookie cookie = Request.Cookies["LoginCookie"];

        if (cookie != null)
        {
            this.cookieValue = cookie.Value;
            this.userCookie = db.UserCookies.SingleOrDefault(c => c.CookieValue.Equals(cookieValue));

            if (userCookie != null)
                this.currentUser = userCookie.User;
        }
    }

    protected override ViewResult View(string viewName, string masterName, object model)
    {
        ViewBag.CurrentUser = currentUser;
        ViewBag.UserCookie = userCookie;
        ViewBag.CookieValue = cookieValue;

        return base.View(viewName, masterName, model);
    }
}
</code>```

When the user sign in successfully, I create a cookie in him with a random value, like this:

```<code>   public ActionResult Login(...)
   {
        (...)

        HttpCookie cookie = new HttpCookie("LoginCookie");
        cookie.Value = Guid.NewGuid().ToString();
        Response.Cookies.Add(cookie);

        userCookie.User = user;
        userCookie.CookieValue = cookie.Value;
        db.UserCookies.Add(userCookie);

        db.SaveChanges();
</code>```

The problem with all this that I've shown is that I'm doing a request to the database in every HTTP request (that is, in every call to one of my actions).

I'm also not happy with the table UserCookies because it has to be cleaned and is not intuitive. Also the generated Guid is not safe.

I know how wrong is all this, but... I can't figure out an elegant way of achieving the same benefits.

The main benefit of this is that I have access to currentUser in every action, so I can do stuff like this easily:

```<code>    if (!currentUser.Privileges.Any(p => p.Privilege == PrivilegesEnum.Blah))
    {
         (...)
    }
</code>```

I also have access to currentUser in all of my views.

Questions:

What is the most common way of achieving this in real professional software?

If I wanted to use cache (like Redis), do I have to change a lot of stuff in the presented scenario?

If I do use cache, should I store just the userId instead of the entire User object?

答:
You should never trust a plain text cookie as a source of record for user details as they are easily modifiable.  Doing so will leave you exposed to spoofing type of vulnerabilities.  You can protect against this by using encryption or signing, but I'd leave the details of that to a library if you can as implementation details of doing so can be tricky.

Typically what is done is only a user identifier is sent to the database, like a primary key or a unique guid.  Rather than generating a new guid every time just add a field to the user table in the database.  Send this in a signed cookie or throw it in a session server (Redis works well for this).  If you need the user details for rendering, just throw the user object in your cache and look it up by this identifier.

Basically what you have implemented above is a light weight implementation of ASP.NET's DB Session Server.

The other option is using some sort of Single Sign On system with XML claims, but it is likely overkill for what you want.