问:
Is there a difference between merges in svn compared to git or mercurial?
From my understanding SVN is 'Easy to branch. Difficult to merge'. Why is that? Is there a difference how they merge?</p>

答:
The core problem lies in the way these systems represent a versioned directory structure.

Subversion's basic concept around which the whole system revolves is that of a version (or, in svn lingo, "revision"): a snapshot of a file at a certain point. As long as the history is perfectly linear, all is fine, but if you need to merge changes from two independent lines of development, svn has to compare the current versions of both, and then do a three-way comparison between the last shared version and the two head versions. Lines that appear changed in one of the heads, but not the other, can easily be resolved; lines that deviate exactly the same way in both heads are harder, but usually doable; lines that deviate in different ways are what makes svn say "I can't figure this out, human, please resolve this for me."

By contrast, git and mercurial track changesets rather than versions. The entire repository is a tree of changesets, each one depending on a parent, where a parent changeset can have any number of children, and the tree root represent an empty directory. In other words, git/hg says "first I had nothing, then this patch was applied, then that patch, etc.". When you need to merge two lines of development, git/hg not only knows what each head currently looks like, and what the last common version looked like, it also knows how the transition happened, allowing for much smarter merging.

Another thing that makes merging easier in a DVCS is an indirect consequence of separating the concepts of commit and push, and of allowing all sorts of cross-merges between any two clones of the same repository at any time. With svn, people tend to commit large changesets with often unrelated changes, because a commit is also an update on the central repository which affects all other team members; if you commit a broken version, everyone is going to be angry with you. Since most setups involve a networked svn server, committing also involves pumping data over the network, which means committing introduces a considerable delay to the workflow (especially when your working copy is outdated and you have to pull first). With git and mercurial, the commit happens locally, and because both are very efficient at handling local filesystems, it usually finishes instantly. As a result, people (once they get used to it) commit small incremental changes, and then when it works, push a dozen or so commits in one go. Then when merge time comes around, the SCM has much more detailed information to go by, and can do a better job resolving conflicts safely and automatically.

And then there's the nice details that make things even easier:

You can have multiple heads and still commit on either; unlike subversion, you don't need to combine pull, update and merge before committing again - the multiple heads just stay that way until you choose to merge

Directories are not treated specially; instead, the path is just considered one large filename, and all your directories have to be at the same revision at all times. This means you can't do the subversion voodoo where a project's subfolders are at different revisions, but it also means the working copy is less likely to become a huge unmanageable broken mess, and more interestingly, a move isn't represented as a delete-and-add (which would break entirely in svn if it weren't for the retrofit metadata), but simply as a rename; if you move a file, its entire history is preserved; merging can even apply changes to the moved file that were made to a non-moved version of the same file after the move, in another branch

Most of the time, you actually don't even need to branch: instead, you just clone the entire repository. Cloning is cheap, especially if it's done on the same filesystem, and if you decide you want to get rid of the clone, you just delete the directory it lives in and that's that. You don't even need to use hg or git for that.

There are few (if any) restrictions on what you can merge. You can have six clones of the same repository, and merge (or rather, push or pull; an explicit merge is often not required) from A to B, then C to B, then B to D, then C to D, B back to A, D to E, at any time and as often as you like.

You can test a merge by cloning one of the repositories you want to merge, and then pulling into that from the other. If it does what you want, you can push back to the real target, if it doesn't, you throw away the clone and start afresh.


问:
How can I gauge a candidate's ability to learn in an interview?
We are hiring for a small development department within a medium sized company for which software is not the main line of business.  As such, we are attempting to recruit what we have labeled a Senior Programmer.  The goal is to find someone that can design, implement and maintain entire new and existing systems from the database through to the front-end.

Regardless of a candidates claim to experience (read: massively spun CVs), or the results of the technical test, what I really care about is their ability to learn and the speed at which they will pick up technologies or concepts they are not familiar with to fill any gaps they might have in their knowledge.

How can I go about getting an idea as to a candidates ability to (or speed of) learning?

答:
Do a normal interview, but instead of noting all his/her skills, note every question (s)he failed. Give her/him a computer with internet and ask him/her to resolve problems that involve every subject (s)he failed at the interview. Example: if (s)he told you (s)he does't know generics, give her/him a problem that involve them.

Judge the candidates on the results AND time spent.

Give it enough time and don't stop her/him to avoid ceiling effect.

To make it relevant, do it with at least 5 candidates.

ContentLicense: CC BY-SA 3.0


答:
Try to evaluate how big is the knowledge gap between diploma and first job, then between both and next job, and so on.

Then try to evaluate how successful were successive jobs.

Ask questions about how difficult it was each time to climb the learning curve.

Title: How can I gauge a candidate's ability to learn in an interview?

Body:
We are hiring for a small development department within a medium sized company for which software is not the main line of business.  As such, we are attempting to recruit what we have labeled a Senior Programmer.  The goal is to find someone that can design, implement and maintain entire new and existing systems from the database through to the front-end.

Regardless of a candidates claim to experience (read: massively spun CVs), or the results of the technical test, what I really care about is their ability to learn and the speed at which they will pick up technologies or concepts they are not familiar with to fill any gaps they might have in their knowledge.

How can I go about getting an idea as to a candidates ability to (or speed of) learning?


问:
Why is local copy writable by default in SVN, but readonly in Perforce/TFS?
I have some experience with Perforce, SVN, and TFS. For SVN, The source files were by default writable after synchronization. However, they were readonly for Perforce, as well as TFS if memory served me.

Meanwhile, 'checkout' means source sync for SVN but its meaning is quite different for other popular tools.
I'm wondering which is more 'correct' behavior and why these tools behave differently.

Thanks.

答:
There used to be two different ways or paradigms with source control.  These were:

Get latest/checkout (locking for other users)/edit/commit

Checkout (not locking for other users)/edit/merge/commit

The first was used by VSS, whereas svn uses the second by default.

(TFS has evolved from VSS and I believe Perforce used cvs as a starting point)

Using the first paradigm, when getting files from the repository, you haven't said that you want to edit them and the source control marks them as readonly to force you to explicitly 'checkout for edit' the file you want to alter.  VSS had commands to 'get latest' and checkout' - and it was checkout that marked the field as editable (and locked it in the repository by default so other couldn't edit the same file at the same time).

This leads to issues if one developer checks out and locks a particular file and then goes off on leave, etc.  His colleagues cannot edit the file without breaking the lock or hacking into his account.

Subversion uses the 2nd, edit/merge/commit paradigm.  There is no command to 'get latest' without the ability to edit the file - there is only the checkout command.  Several developers can modify a same file a the same time.

This leads to other issues at commit.  If you and I have both edited the same file, and you commit your changes first, I cannot commit my version without first merging in your changes.  There is a risk here that I don't understand the changes you've made and I alter the file so it does what I wanted and breaks the change you had made.

Both paradigms have potential issues, but in my opinion the checkout/edit/merge is better.  If multiple developers are editing the same files at the same time and have difficultly merging the changes, I believe you've got problems with the code structure and the inter-team communication that cannot be solved by source control tool alone.

In order to avoid the issue when one developer has a file locked and cannot be contacted to release the lock, some source control systems allowed locks to be broken or overridden.  Some also allow the repository to be set such that some files are not locked and then have to be merged prior to commit - i.e. using an amalgamated checkout/edit/merge/commit.  Because of their provenance, their 'get latest' command obtains a read-only copy and insists that you 'checkout for edit' in order to get a writable copy, but they then follow the same flow as subversion with the editing and merging before commit.  This is how Perforce works.

In order to mitigate the cannot merge changes issue, Subversion does allow the repository to be setup to require locking for some or all files.  (I’ve used this is the past to ensure MSWord documentation that was a pain to merge could only be updated by one user at a time, and similarly with picture/icons.)


问:
How to improve yourself and grow as a programmer?

Possible Duplicate:

  How do I improve my coding skills?

I'm a 4 yrs experienced programmer with JAVA being the strong point of mine. I know basics of web, C++ android, blackberry programming. Was wondering how should I improve myself.

Does learning new languages help or learning design stuff and learn to become a architect?
How do you guys plan yourself for future? May be learn a language every year? or be in touch the the new technologies?

How do you guys improve yourself as a core programmer?

答:
One thing that has really helped me is doing a pet project (roughly) per year. My general guidelines are:

It should be something useful, even if only to me (an itch to scratch),

It's perfectly ok to re-invent the wheel (as it's a learning experience),

It should involve concepts / technologies I'm unfamiliar with,

Finish it. Actually finish it. No excuses, finish it.

I've already posted a question for this year's project, but sadly I haven't had a chance to start it yet. I've also posted an answer that documents my process as a solo developer, as up until now all my pet projects are solo projects.

And of course, my other extremely obvious way of bettering myself as a programmer is lurking around Programmers SE, and reading everything, without really understanding most of it. But I'm understanding more and more every day, thanks everyone!


答:
You don't necessarily have to learn a new language to be a better developer. I for example are a 99% C# developer. First I was doing only WinForms (desktop) applications. Then I started to learn WPF/Silverlight when they came out. Then found out how cool LINQ is so I made a few smaller projects just to see how to use it. All this time I was studying computer science I was lucky that my mentor was pretty cool and made it possible for me to choose what things I want to do as a project. So I was able to improve myself in web developement while creating some MVC applications. Now I have a cool job where we develop Silverlight apps but are likely to switch to HTML5/Javascript so these are the things that I am tackeling now. Just keep widening your view in any direction you feel confortable. You can never know to much especially in software developement. So just pick yourself something you would like to have (a mobile app shoping list/a web application where you can track your bonsai tree growth and fertilazation/ a desktop application which will help you track your workout progress)

Learn about good practice and try to implement it and over time you will have a  lot more knowladge and (maybe more important) confidence in yourself.

Keep (smart) coding and have fun:)

Title: How to improve yourself and grow as a programmer?

Body:
Possible Duplicate:

  How do I improve my coding skills?

I'm a 4 yrs experienced programmer with JAVA being the strong point of mine. I know basics of web, C++ android, blackberry programming. Was wondering how should I improve myself.

Does learning new languages help or learning design stuff and learn to become a architect?
How do you guys plan yourself for future? May be learn a language every year? or be in touch the the new technologies?

How do you guys improve yourself as a core programmer?


问:
Trimming script size by using array notation for frequently accessed properties
I noticed some redundancy in a script I ran through Google Closure Compiler.

```<code>(function(){function g(a){var k;if(a){if(a.call)a.prototype=j,a.prototype[e]={}}else a=
{};var c=a,b,c=(a=c.call?c:null)?new a(a):c;b=c[e]||{};var f=b.extend;b=b.a;var
d=c.hasOwnProperty("constructor")?c.constructor:b?b:f?g.b(f):new Function;if
(f)b=d.prototype,k=new h(h.prototype=f.prototype),f=k,h.prototype={},d.prototype=f,i
(d.prototype,b);i(d,a);i(d.prototype,c);return d.prototype.constructor=d}function i(a,c)
{for(var b in c)c.hasOwnProperty(b)&&"prototype"!=b&&b!=e&&(a[b]=c[b])}var h=new Function,
e="decl-data",j={extend:function(a){return(this[e].extend=a).prototype},a:function(a)
{return(this[e].a=a).prototype}};g.c=function(a){e=a};return g})().b=function(g){return
function(){g.apply(this,arguments)}};
</code>```

It looks like a big sea of prototype and constructor, doesn't it?

I was was able to get it to about 6/7 of the size of the original by storing  "constructor" and "prototype" strings and using array notation everywhere to access prototypes and constructors. The size savings should grow as the size of the script grows. Here's what it looks like after the change:

```<code>(function(b,h){function i(a){a?a.call&&(a[b]=l,a[b][f]={}):a={};var d=a,c,d=(a=d.call?
d:null)?new a(a):d;c=d[f]||{};var g=c.extend;c=c.a;var e=d.hasOwnProperty(h)?d[h]:c?c:g?i.b
(g):new Function;if(g){c=e[b];var m=b,g=new j(j[b]=g[b]);j[b]={};e[m]=g;k(e[b],c)}k(e,a);k(e
[b],d);return e[b][h]=e}function k(a,d){for(var c in d)d.hasOwnProperty(c)&&c!=b&&c!=f&&(a
[c]=d[c])}var j=new Function,f="decl-data",l={extend:function(a){return(this[f].extend=a)
[b]},a:function(a){return(this[f].a=a)[b]}};i.c=function(a){f=a};return i})
("prototype","constructor").b=function(b){return function(){b.apply(this,arguments)}};
</code>```

Is it worth it to damage readability to save a few bytes? It's hard to know when to stop... hasOwnProperty only appears twice, I might use it once more. So, should I replace .hasOwnProperty with [_has]? Should I just stop here? Or should I put it back the way it was, and not worry about the few extra bytes?

On the other hand, maybe this doesn't damage readability at all, and could just be looked at as convenient shortcuts.

Another alternative would be abstracting the behavior using macros; write .prototype and have it converted to [_p] at build time, of course declaring _p somewhere. But that seems overly complicated for a relatively minor size optimization. Speaking of which, I wonder why closure-compiler doesn't do something like this already?

I'm curious what the community thinks about this.

For reference, the un-minified source before the size optimization:

```<code>var decl = (function(){

var Clone = new Function(), // dummy function for prototypal cloning
    /** dataKey

        The name of the property where declaration objects'
        metadata will be stored. If you want to pass objects to decl
        instead of functions, put the metadata (parent, partial, etc.)
        in this property.
    */
    dataKey = 'decl-data',

    /** proto

        This object is used as a prototype for declaration objects,
        so all properties are available as properties of `this`
        inside the body of each declaration function.

    */
    proto = {

      /** extend

          Perform prototypal inheritance by calling `this.extend(ParentCtor)`
          within your decalration function.

          @param {Function} ctor to extend.

          @return {Object} prototype of parent ctor.
      */
      extend: function (ctor) {
        return (this[dataKey].extend=ctor).prototype;
      },

      /** augment

          Finish a partial declaration.
          TODO: test for bugs, possibly retroactively fix child classes when augmenting parent.

          @param {Function} ctor to augment.

          @return {Object} prototype of partial ctor.
      */
      augment: function (ctor) {
        return (this[dataKey].augment=ctor).prototype;
      }

    };

/** decl

    Create a prototype object and return its constructor.

    @param {Function|Object} declaration
*/
function decl (declaration) {
  if (!declaration) {
    declaration = {};
  }
  else if (declaration.call) {
    declaration.prototype=proto;
    declaration.prototype[dataKey]={};
  }
  return getCtor(declaration);
}

/** setDataKey

    Sets the name of the property where declaration objects'
    metadata will be stored. If you want to pass objects to decl
    instead of functions, put the metadata (parent, partial, etc.)
    in this property.

    @param {String} String value to use for dataKey
*/
decl.setDataKey = function (value) { dataKey=value; };

/** clone

    Create a copy of a simple object.

    @param {Object} obj

    @return {Object} clone of obj.

*/
function clone (object) {
  var r=new Clone(Clone.prototype=object);
  Clone.prototype={};
  return r;
};

/** merge

    Merge src object's properties into target object.

    @param {Object} target object to merge properties into.

    @param {Object} src object to merge properties from.

    @return {Object} target for chaining.

*/
function merge (target, src) {
  for (var k in src) {
    if (src.hasOwnProperty(k) && k!='prototype' && k!=dataKey) {
      target[k] = src[k];
    }
  }
  return target;
};

/** getCtor

    Prepare a constructor to be returned by decl.

    @param {Function|Object} declaration

    @return {Function} constructor.

*/
function getCtor (declaration) {
  var oldProto,
      declFn = declaration.call ? declaration : null,
      declObj = declFn ? new declFn(declFn) : declaration,
      data = declObj[dataKey] || {},
      parent = data.extend, partial = data.augment,
      ctor =  // user-defined ctor
              declObj.hasOwnProperty('constructor') ? declObj.constructor :
              // ctor already defined (partial)
              partial ? partial :
              // generated wrapper for parent ctor
              parent ? decl.wrap(parent) :
              // generated empty function
              new Function();

  // If there's a parent constructor, use a clone of its prototype
  // and copy the properties from the current prototype.
  if (parent) {
    oldProto = ctor.prototype;
    ctor.prototype = clone(parent.prototype);
    merge(ctor.prototype, oldProto);
  }

  // Merge the declaration function's properties into the constructor.
  // This allows adding properties to `this.constructor` in the declaration function
  // without defining a constructor, or before defining one.
  merge(ctor, declFn);

  // Merge the declaration objects's properties into the prototype.
  merge(ctor.prototype, declObj);

  // Have the constructor reference itself in its prototype, and return it.
  return (ctor.prototype.constructor=ctor);
};

return decl;

}());

// This is outside of the main closure so wrapper functions
// will have as short a lookup chain as possible.

/** wrap

    Generate wrapper for parent constructor.

    @param {Function} parent constructor to wrap.

    @return {Function} child constructor.

*/
decl.wrap = function (parent) {
  return function(){ parent.apply(this, arguments); };
};
</code>```

And after:

```<code>var decl = (function(_p, _c){

var Clone = new Function(), // dummy function for prototypal cloning

    /** dataKey

        The name of the property where declaration objects'
        metadata will be stored. If you want to pass objects to decl
        instead of functions, put the metadata (parent, partial, etc.)
        in this property.
    */
    dataKey = 'decl-data',

    /** proto

        This object is used as a prototype for declaration objects,
        so all properties are available as properties of `this`
        inside the body of each declaration function.

    */
    proto = {

      /** extend

          Perform prototypal inheritance by calling `this.extend(ParentCtor)`
          within your decalration function.

          @param {Function} ctor to extend.

          @return {Object} prototype of parent ctor.
      */
      extend: function (ctor) {
        return (this[dataKey].extend=ctor)[_p];
      },

      /** augment

          Finish a partial declaration.
          TODO: test for bugs, possibly retroactively fix child classes when augmenting parent.

          @param {Function} ctor to augment.

          @return {Object} prototype of partial ctor.
      */
      augment: function (ctor) {
        return (this[dataKey].augment=ctor)[_p];
      }

    };

/** decl

    Create a prototype object and return its constructor.

    @param {Function|Object} declaration
*/
function decl (declaration) {
  if (!declaration) {
    declaration = {};
  }
  else if (declaration.call) {
    declaration[_p]=proto;
    declaration[_p][dataKey]={};
  }
  return getCtor(declaration);
}

/** setDataKey

    Sets the name of the property where declaration objects'
    metadata will be stored. If you want to pass objects to decl
    instead of functions, put the metadata (parent, partial, etc.)
    in this property.

    @param {String} String value to use for dataKey
*/
decl.setDataKey = function (value) { dataKey=value; };

/** clone

    Create a copy of a simple object.

    @param {Object} obj

    @return {Object} clone of obj.

*/
function clone (object) {
  var r=new Clone(Clone[_p]=object);
  Clone[_p]={};
  return r;
};

/** merge

    Merge src object's properties into target object.

    @param {Object} target object to merge properties into.

    @param {Object} src object to merge properties from.

    @return {Object} target for chaining.

*/
function merge (target, src) {
  for (var k in src) {
    if (src.hasOwnProperty(k) && k!=_p && k!=dataKey) {
      target[k] = src[k];
    }
  }
  return target;
};

/** getCtor

    Prepare a constructor to be returned by decl.

    @param {Function|Object} declaration

    @return {Function} constructor.

*/
function getCtor (declaration) {
  var oldProto,
      declFn = declaration.call ? declaration : null,
      declObj = declFn ? new declFn(declFn) : declaration,
      data = declObj[dataKey] || {},
      parent = data.extend, partial = data.augment,
      ctor =  // user-defined ctor
              declObj.hasOwnProperty(_c) ? declObj[_c] :
              // ctor already defined (partial)
              partial ? partial :
              // generated wrapper for parent ctor
              parent ? decl.wrap(parent) :
              // generated empty function
              new Function();

  // If there's a parent constructor, use a clone of its prototype
  // and copy the properties from the current prototype.
  if (parent) {
    oldProto = ctor[_p];
    ctor[_p] = clone(parent[_p]);
    merge(ctor[_p], oldProto);
  }

  // Merge the declaration function's properties into the constructor.
  // This allows adding properties to `this.constructor` in the declaration function
  // without defining a constructor, or before defining one.
  merge(ctor, declFn);

  // Merge the declaration objects's properties into the prototype.
  merge(ctor[_p], declObj);

  // Have the constructor reference itself in its prototype, and return it.
  return (ctor[_p][_c]=ctor);
};

return decl;

}('prototype', 'constructor'));

// This is outside of the main closure so wrapper functions
// will have as short a lookup chain as possible.

/** wrap

    Generate wrapper for parent constructor.

    @param {Function} parent constructor to wrap.

    @return {Function} child constructor.

*/
decl.wrap = function (parent) {
  return function(){ parent.apply(this, arguments); };
};
</code>```

答:
I would suspect the shortcuts to be slower, which is probably why the minifier does not apply such transformation. At least google chrome has optimizing byte-code compiler for javascript and might be able to take a shortcut or two when it knows the member name is constant, which it does not when variable is used.

I would definitely not recommend doing this manually, but if you really wanted it, you should do it as part of the minification. Damaging readability is not worth it.


答:
Please see my Stack Overflow answer for a very concrete situation where Mercurial (and Git) merges without problems and where Subversion presents you with a bogus conflict. The situation is a simple refactoring done on a branch where you rename some files.

With regard to tdammers answer, then there is a number of misunderstandings there:

Subversion, Mercurial, and Git all track repository-wide snapshots of the project. Calling them versions, revisions, or changesets makes no difference. They are all logically atomic snapshots of a set of files.

The size of your commits makes no difference when it comes to merging. All three systems merge with the standard three-way merge algorithm and the inputs to that algorithm are

greatest common ancestor version

version on one branch

version on other branch

It doesn't matter how the two branch versions were created. You can have used 1000 small commits since the ancestor version, or you can have used 1 commit. All that matters is the final version of the files. (Yes, this is surprising! Yes, lots of DVCS guides get this horribly wrong.)

He also raises some good points about the differences:

Subversion has some "voodoo" where you can merge from /trunk into, say, /branches/foo. Mercurial and Git does not use this model — branches are instead modeled directly in the history. The history therefore becomes a directed acyclic graph instead of being linear. This a much simpler model than the one used by Subversion and this cuts away a number of corner cases.

You can easily delay a merge or even let someone else handle it. If hg merge gives you a ton of conflicts, then you can ask your coworker to hg pull from you and then he has the exact same state. So he can hg merge and maybe he's better at resolving conflicts than you are.

This is very difficult with Subversion where you're required to update before you can commit. You cannot just ignore the changes on the server and keep committing on your own anonymous branch. In general, Subversion forces you to play around with a dirty working copy when you svn update. This is kind of risky since you haven't stored your changes anywhere safe. Git and Mercurial lets you commit first, and then update and merge as necessary.

The real reason Git and Mercurial are better at merging than Subversion is a matter of implementation. There are rename conflicts that Subversion simply cannot handle even thought it's clear what the correct answer is. Mercurial and Git handles those easily. But there's no reason why Subversion couldn't handle those as well — being centralized is certainly not the reason.

Title: Is there a difference between merges in svn compared to git or mercurial?

Body: From my understanding SVN is 'Easy to branch. Difficult to merge'. Why is that? Is there a difference how they merge?</p>


问:
Defining Rank names for employees
I want to create a list of ranks for the employees in my company. We are an open source integrator that works usually with existing solutions and also building custom solutions.

We don't want to name our employees as normal senior consultant, trainee and we would like give them ranks as forums do to the users.

Does anyone have any suggestion for this?

答: Guild style- apprentice, craftsman, journeyman, master - can be applied to any stream of developer, architect or other technical type and describes things rather nicely, to my mind.</p>

Title: Defining Rank names for employees

ContentLicense: CC BY-SA 2.5


问:
Is Javascript a Functional Programming Language

Is Javascript a functional language? I know it has objects & you can do OOP with it also, but is it also a functional language, can it be used in that way?

You know how OOP became/seems like the next evolution in programming, does that mean that 'Functional Programming' is the next evolution(Note: this is NOT a prompt for opinion BUT a prompt for a factual evidence based answer, & this note is more for the moderators than the contributors ;) ).

I learn best through examples, maybe someone could show performing the same task in a OOP way & then in a Functional Programming way for myself to understand & compare what functional programming does/is.

I don't really completely understand 'Functional Programming' to be honest :P So comparing Javascript to functional programming may be totally incorrect.

To put Functional programming in laymans terms: is it simply the benefit of abstration THROUGH using anonymous functions?

Or is that way too simple? In a simple way, OOP is the benefit of abstraction through objects, but I believe thats being a little too simplistic to describe OOP.

Is this a good example of functional programming?...

Javascript OOP Example:

```<code>// sum some numbers
function Number( v )
{
  this.val = v;
}

Number.prototype.add( /*Number*/ n2 )
{
    this.val += n2.val;
}
</code>```

Functional programming example:

```<code>function forEach(array, action)
{
   for (var i = 0; i < array.length; i++)
       action(array[i]);
}

function add(array)
{
    var i=0;
    forEach(array, function(n)
    {
        i += n;
    });
    return i;
}

var res = add([1,9]);
</code>```

答:
Javascript is prototypal first, with functional capabilities - granted by it's use of functions as first class objects.

This means that you can use functions as data, which has the curious effect of reducing the need for variables that maintain state. If you find that yourself reaching for the var statement, or are using one or more "if" statements, then you're straying from a functional style.

Another notable idiosyncrasy of functional style is that functions should ONLY return the result of their evaluation and have no side effects on the state outside of their scope:

```<code>// oops, this is producing a side effect
function sideEffecter(){//theres no input...
    window.thingy = 'foo';
    // hey, this isn't returning anything!!!
}
</code>```

Functional languages are non-destructive - meaning that they do not mutate the input, but rather return entirely new data based on the input. See this thread:  https://stackoverflow.com/questions/749084/jquery-map-vs-each

Functional languages also feature a lot of methods in common - with names like "map", "fold", "reduce" that process lists/collections. In JS, unlike other languages, we have to handcrank these into existence - see libraries like underscore.js for some examples, although the latest implementation of JS has some of these straight out the box.

The important thing to bear in mind (IMO) is that while JS can utilise some functional patterns, it is not always well equipped to execute then.

Take iterating over an array, for example. You can do this using a functional style or the native loop constructs - and generally speaking the loop is more performant. Take this example - hit it with loops of increasing size and record the execution times in different browsers (i've done this already, but I've lost the benchmarks - sorry!):

```<code>var test = ['foo', 'bar', 'baz'], removeFunc, removeLoop;

//(semi)functional style...
// to be really functional each condition in the ternary would be another function
removeFunc = function(src, trg) {
    return src.length === 0 ?
        src :
            src[0] === trg ?
                src.slice(1) :
                    [src[0]].concat(removeFunc(src.slice(1), trg));
};

//but this is faster
removeLoop = function(src, trg){
    var len = src.length, // using variables to represent state...
        i=0,
        result = [];
    while(i < n){
       if(src[i] !== trg){
          result.push(src[i]);
       }
       i = i+1;
    }
}
</code>```

In addition, if you use a functional construct to hit loops of considerable size and don't utilise some form of ad-hoc stack management you could flood the stack (although, to be fair, you need a BIG list for this to occur...). You've also got to factor in to the mix the variant optimisations in each browser - although if you're working in a Node.js environment this is obviously more of a fixed target.

That's not to say you shouldn't use functional constructs in Javascript - just be aware of the limitations in it's implementation relative to it's environment.

Here are some links that might be of interest to you:

A good chapter on Functional Programming in Javascript from the excellent "Eloquent Javascript"

The Little Schemer

a friend of mine wrote a JS library based on the Little Schemer

A good tutorial on Scheme that might help you better comprehend FP

Body:
Javascript is prototypal first, with functional capabilities - granted by it's use of functions as first class objects.

This means that you can use functions as data, which has the curious effect of reducing the need for variables that maintain state. If you find that yourself reaching for the var statement, or are using one or more "if" statements, then you're straying from a functional style.

Another notable idiosyncrasy of functional style is that functions should ONLY return the result of their evaluation and have no side effects on the state outside of their scope:

// oops, this is producing a side effect
function sideEffecter(){//theres no input...
    window.thingy = 'foo';
    // hey, this isn't returning anything!!!
}

Functional languages are non-destructive - meaning that they do not mutate the input, but rather return entirely new data based on the input. See this thread:  https://stackoverflow.com/questions/749084/jquery-map-vs-each

Functional languages also feature a lot of methods in common - with names like "map", "fold", "reduce" that process lists/collections. In JS, unlike other languages, we have to handcrank these into existence - see libraries like underscore.js for some examples, although the latest implementation of JS has some of these straight out the box.

The important thing to bear in mind (IMO) is that while JS can utilise some functional patterns, it is not always well equipped to execute then.

Take iterating over an array, for example. You can do this using a functional style or the native loop constructs - and generally speaking the loop is more performant. Take this example - hit it with loops of increasing size and record the execution times in different browsers (i've done this already, but I've lost the benchmarks - sorry!):

var test = ['foo', 'bar', 'baz'], removeFunc, removeLoop;

//(semi)functional style...
// to be really functional each condition in the ternary would be another function
removeFunc = function(src, trg) {
    return src.length === 0 ?
        src :
            src[0] === trg ?
                src.slice(1) :
                    [src[0]].concat(removeFunc(src.slice(1), trg));
};

//but this is faster
removeLoop = function(src, trg){
    var len = src.length, // using variables to represent state...
        i=0,
        result = [];
    while(i < n){
       if(src[i] !== trg){
          result.push(src[i]);
       }
       i = i+1;
    }
}

In addition, if you use a functional construct to hit loops of considerable size and don't utilise some form of ad-hoc stack management you could flood the stack (although, to be fair, you need a BIG list for this to occur...). You've also got to factor in to the mix the variant optimisations in each browser - although if you're working in a Node.js environment this is obviously more of a fixed target.

That's not to say you shouldn't use functional constructs in Javascript - just be aware of the limitations in it's implementation relative to it's environment.

Here are some links that might be of interest to you:

A good chapter on Functional Programming in Javascript from the excellent "Eloquent Javascript"

The Little Schemer

a friend of mine wrote a JS library based on the Little Schemer

A good tutorial on Scheme that might help you better comprehend FP


问:
DRY way to write Javadoc on overload methods
I want to write Javadoc in DRY way. But the oracle document about Javadoc says write same thing again in overload method comment. Can't I avoid repetition?</p>

答:
I sprinkle {@inheritDoc} directives here and there in my Javadoc comments when overriding methods from superclasses or implementing interface-defined methods.

This works well for me at least, avoids repetition in the source code, and you can still add specific information to the particular Javadoc comment if there is a need to do so. I don't consider the fact that the Javadoc comment itself is fairly bare to be any issue when all it takes in a decent IDE is to hover over the associated identifier name to get the rendered Javadoc with references and all.


问:
What's a good light-weight source repository for local development?
I'm doing some prototyping locally that I would like to keep in source control (for backup and revert purposes) but I don't necessarily want to publish it as open-source or make available online for others to view.

What source control system would you recommend for local development?  Any setup or walk through for my scenario is greatly appreciated.

I'm looking for:

Easy setup and administration. As this is my local machine, I'm constrained to Window OS and would really like to minimize the amount of environment configuration changes and necessary learning curve. There will only be one user, so I don't want to configure access rights, etc.

Low resource overhead, I want to host locally on my developer machine, so I don't want it sucking up my CPU.  I don't plan on storing massive amounts of data, either.

Familiar. I've used SVN clients before.  Visual Studio integration is a nice-to-have.

Portable. If I have to move it to a external drive or to another machine.

Free. Yes I want it all and don't want to have to pay for it.

答: RocketSVN is a frozen product now. It's no longer being developed. So I use uberSVN and tortoiseSVN. They're both free and pretty easy to use. </p>


问:
What is the relevance of Unit Testing in an "Release early release often" environment?
Over last one year or so, I have driven my team towards the release-early-release-often mode of development (AKA: Rapid Application Development, not Agile). For more information about the manner in which we close the build, see my answer here:
A simple ways to improve the release quality in RAD environment

When we adopted RAD, people were quite independent and they were doing unit testing first; the integrated tests happened much later in the process. It was a natural process for them without much formal enforcement. Now the situation is quite different:

The entire platform is well integrated with established builds/releases working client-side without any hot spots.

New functionality requirements keep coming and we incrementally build them as we go.

The overall dynamics of the system are very important because while independent development groups might be following processes right, major failures have arisen due to complicated, non-obvious circumstances.

Many parts of the system involve new algorithms and research inputs so the challenges (and hence mechanism for testing) are not quite always foreseen correctly, like feature testing in well-defined software.

Recently, I was trying to get better overall picture to see if we need process improvement. When I sat down with my team, many of them balked: "We don't do unit testing anymore!" while others thought we shouldn't start now because it will never be effective.

Are unit tests useful in a relatively mature system? Should we at least need to weigh test scope depending on the maturity of units? Will unit testing slow down the pace of development? Is there a need to evaluate unit testing in a different way?

What are the best practices of testing for a mature platform in a release-early-release-often environment?

答:
Unit tests are not primarily for finding bugs in the first place - they are for assuring that the next release of your system is as stable as the previous release. The shorter your release cycle is, the more important does it get that you can run this tests automatically instead of doing them manually.

Of course, if you have a system with some independent parts, and you were working between two releases only at a small portion of the system, you probably can omit some unit tests which are for other parts of the system. But you should definitely use (and extend) the unit tests for the parts where you are working at.

Another thing is that when a system grows, there will be more and more need for additional integration tests - but that does not mean you will need fewer unit tests.

The real question behind yours may be perhaps a different one. Has it become harder to write unit tests since your system has gotten bigger and bigger? Are your "unit" tests are really units tests, or do they not test things in isolation any more? This may be because they rely on lower-level parts of the system which have stabilized over the time.

These things happen because developers tend to re-use existing libraries and code by directly referencing them. It often has the effect that writing unit tests get harder, because they often have to provide a more complex environment and more test data. If that is your problem, then you should learn about at the key concepts Dependency Injection and Interface Segregation Principle, which may help you to make the code more unit-testable.


答:
This is a tricky situation. You are straying into some seriously ego-driven territory here, particularly with people who identify very strongly with their work. I have seen people get VERY twisted over being a Developer III when somebody else they consider inferior is a Developer IV.

Usually when a system with grades like this is put in place it is because there is a push for some kind of a standardization. It usually appears with a pay scale. Almost always it is a larger organization. In smaller organizations you usually wind up with a title prefix like "Senior" or "Chief" as a way to differentiate. In all cases what you are doing is making a hierarchy visible and using it as a way for people to measure themselves. If this is your goal, then go ahead and put in some kind of a system.

Be aware that you will immediately ruffle feathers when people find out they are not seen by management as the best on the team. Also be prepared for the demands of "When will I make the next grade?" This will come hand in hand with a demand for more compensation. If the compensation winds up tied to the title then people will be able to figure out what you are paying the new hire and this will spawn more issues.

If it's internal, maybe tie it to some kind of objective metric like number of releases authored, bugs resolved, etc. This would feed the need for recognition but not be something you'd have to put on a business card.

In my own experience I just called everyone "Software Developer" and made sure that I communicated with everyone all the time so that I could head off any feelings of ill will, etc. It also cut down somewhat on "that's not my job" comments. The only person who wound up as a "Senior Software Developer" had minor management duties. It was not perfect and had its own issues but overall worked for me. YMMV.

Title: Defining Rank names for employees

Body:
I want to create a list of ranks for the employees in my company. We are an open source integrator that works usually with existing solutions and also building custom solutions.

We don't want to name our employees as normal senior consultant, trainee and we would like give them ranks as forums do to the users.

Does anyone have any suggestion for this?


答:
You should consider looking into test driven development, where the tests are designed first and describe how the new code will work when written.  You then make the tests pass.

In my experience this tend to make leaner and better thought out code, especially for libraries, and it is a runnable part of the specification (meaning that it will always be correct documentation).

That said, existing tests are used to ensure that the code still works as expected.  It can catch code breakage, and allow you to ensure that third  party code still works as expected when upgrading.

Title: What is the relevance of Unit Testing in an "Release early release often" environment?

Body:
Over last one year or so, I have driven my team towards the release-early-release-often mode of development (AKA: Rapid Application Development, not Agile). For more information about the manner in which we close the build, see my answer here:
A simple ways to improve the release quality in RAD environment

When we adopted RAD, people were quite independent and they were doing unit testing first; the integrated tests happened much later in the process. It was a natural process for them without much formal enforcement. Now the situation is quite different:

The entire platform is well integrated with established builds/releases working client-side without any hot spots.

New functionality requirements keep coming and we incrementally build them as we go.

The overall dynamics of the system are very important because while independent development groups might be following processes right, major failures have arisen due to complicated, non-obvious circumstances.

Many parts of the system involve new algorithms and research inputs so the challenges (and hence mechanism for testing) are not quite always foreseen correctly, like feature testing in well-defined software.

Recently, I was trying to get better overall picture to see if we need process improvement. When I sat down with my team, many of them balked: "We don't do unit testing anymore!" while others thought we shouldn't start now because it will never be effective.

Are unit tests useful in a relatively mature system? Should we at least need to weigh test scope depending on the maturity of units? Will unit testing slow down the pace of development? Is there a need to evaluate unit testing in a different way?

What are the best practices of testing for a mature platform in a release-early-release-often environment?


问:
Agile development deployment process. Where do QA and Business Owners test?
I've been reading up a lot lately on various web application deployment processes using SVN or GIT, with a view to redesigning how we currently deploy where I work.

As is the way with many flavours of Agile, it's assumed that anything committed to master or trunk is production ready. Both GitHub and Etsy, http://codeascraft.etsy.com/2010/05/20/quantum-of-deployment/ say that they work on this basis (although Etsy actually have a staging environment).

This process assumes all unit test and CI tests have been run. You run the tests locally and on CI and then commit to trunk. SO, at this point your code is technically sound.

Your code may be technically correct, but user/functional testing may unearth more bugs, particularly when it comes to front end testing.

My question is this. Where do QA and Business owners test the feature changes you have implemented? On your local development machine before you commit to trunk, or on a QA/staging machine?

If you have a staging machine that runs off trunk, and you assume that all code committed to trunk is production ready ... eh .. then at what point is the code signed off and good to go into production from both a technical and business perspective? If you have only one staging machine, many developers and that is where the code is to be QA'd, then how can you deploy from trunk as many developer changes can be waiting for sign off.

I'd be interested to hear how others have approached this?

答:
As a general rule, waiting to commit before the code is perfect is half the time take back the advantages of version control system. (Without much elaboration, i would say that unless one is allowed multiple check-ins to VCS, one has no way to revert my own work!) So as a practice we always ask people to keep check-in (within their branch for SVN or it can be local commits in case of GIT) as much as they want. In fact the more the better.

However, when the point arrives where everything appears to be done and tested - we call it a release and then it is merged with trunk. Essentially, QA can certify the RC by taking a fresh check out on the HEAD of the branch and if he/she Okey's it, the same is merge back with trunk.

So essentially we use the concept of task-branches or private-branches so people are free to make check-ins as much as they need. At the same time, trunk is relatively free from any broken check-ins.

OwnerDisplayName: Bazza


问:
Example of time-saving usage of compile-time meta-programming?
The webpage of Converge states that:

Converge has a macro-like facility that can embed domain specific languages with arbitrary syntaxes into source files.

I am most intrigued by the possibility to create domain specific languages. My understanding of the purpose of such languages, is that they enables the developer to become much more efficient when solving domain specific problems.

So, I went on to read the "about" section. There are two examples of usage here, but none of them describe how the developer could save development-time by utilizing Converge. Can anyone come up with an example or refer me to an example? I am happy to read examples in other languages than Converge.

答:
There are two canonical examples of domain specific languages:

Regular expressions. They are simple language, but language nevertheless and they are compiled to the actual search automaton, so definitely benefit from compiler handling them. Other parsing languages like BNF are similar case.

SQL. While this is normally compiled in the database server and so does not benefit from processing in the compiler this way, there is a huge benefit in support for it from the language if it can automatically bind variables for parameters and results.


问:
How to avoid "DO YOU HAZ TEH CODEZ" situations?
I have a strange situation at work, where a colleague of mine often asks me and other co-workers for working code.

I would like to help him, but this constant request of trivial snippets interrupts my thoughts and sometimes makes it hard to concentrate.

Plus, I have the impression (...) that this requests are generated by lack of competence, more than by laziness. In fact, he often asks things pretending to know the answer, since when I solve the problem he usually says things like "Sure", "Yes, that's what I thought", giving me the impression that my answer isn't worth it.

How can I solve this embarrassing situation?

Should I show more explicitly in front of other colleagues his lack of knowledge (by saying things like: "do it yourself if you can, please") or continue giving him what he wants?

I think that he should aggregate all his questions in one, so that I can give him a portion of my time and he can work all by himself on his things.

There is no hierarchy in the team, I must say we both have a similar seniority of five years, more or less. For the same reason I believe I cannot report to management, since trivial questions are often ignored.

I discussed with other two members and they agree with me: in fact he often ask things cycling through colleagues.

答: That's bizarre - he's just asking you to do his job for him. Unless he has some very clever/subtle way of asking, I think I'd be tempted to just say "no, I don't have time".</p>


问:
General approach to re-factoring a large, very badly written legacy system

Possible Duplicate:

  Techniques to re-factor garbage and maintain sanity?

  What is a good way to refactor a large, terribly written code base by myself?

Really open question here.  I'm not after an answer.. only advice.  Any past experience people have had with re-factoring legacy systems that they could pass on would be amazing.  Here's some information about the software I am to re-factor (you'll cringe!):

Web application

Database driven (MySQL)

PHP4 and PHP5

Most of the code is PHP4

Nearly all the code is procedural

Code that is PHP5 isn't OO.. example: 10,000 line+ file with one class and one function

Global variables used everywhere

No source control was used to write the software (you can see from the comments in the code)

Massive amounts of code repetition

No separation of concerns - user interface and logic is combined everywhere

Application relies on order of database tables

Few code comments

250,000+ lines of code

Application in heavy use

Basically, the software is our core product and I have been hired to do a major re-factor (amongst other things).  It's a massive task and I can't just dive in and fix all the little things.. I need an overall strategy.  I've written some scripts to tidy indentation up, removed commented-out code everywhere and made the project into a repo but now it's time to do the real stuff.

I kind of have a vague idea but not sure how to go about it.  I could somehow leave the current code alone and write some layer of software over it that abstracts away from all the horribleness.  It would be good if the new layer was some sort of MVC architecture.  At the same time I would go into the current code, remove redundancies because otherwise the new layer would be using bad code anyway so the code could slow down even more.

As you can see.. need some clues/hints/tips/advice/experiences!

Thanks very much :).

答:
Test-Driven Reverse Engineering.

Reverse engineer some user epics; not all the stories, but the "big picture" suites of functionality that comprise the system.

Prioritize based on quality, replaceability, value, etc., etc.  This is subjective, but you need to pick a piece to work on.

Write unit tests as best you can that the legacy code will pass.

Write new code for just that.

Now comes the hard part.  Bridges.

You need to deploy the new part and maintain the legacy while you're moving forward.  You'll need to "bridge" data from legacy to new (and new back to legacy).

You'll also have to write a bunch of Apache rewrite rules to redirect requests to the new so that the URL's don't appear to change too much or too disruptively.  Some change is inevitable as your rewrite.  Some change is disruptive to users and requires mod_rewrite or 304 redirects or both.

Once you've got that first epic (set of stories) deployed in production, you need to then rethink your epics and decomposition of what's left in the legacy that's still valuable.  Reprioritize.

Write unit tests for the next epic.  Rewrite the code.  Create and revise the bridges.  Deploy the next chunk.

You'll repeat the "partition, prioritize, test, refactor, deploy" loop until what's left over as legacy is of so little value that you no longer need any bridges.  Then you decommission the old.  Delete the code.  Burn the bridges.  No going back.

ContentLicense: CC BY-SA 4.0


答:
First thing to do is have a frank discussion with the guy in question. Do it one to one instead of in a group or he might feel ganged up on (possibly deservedly so). Ask him why he keeps asking these questions, explain how disruptive this is to your work - see what he has to say.

Depending on what you glean from this conversation, try to see if he can learn by himself. Help him help himself instead of giving him answers. See if pointing him to the right direction would be enough.

If none of the above helps:

You and your colleagues should stop answering his trivial questions.

Answers like:

Sorry, can't help now. I have a deadline.

Why are you asking?

That looks trivial for someone like you.

Basically, if all the team agrees to play along with this, he will have to figure things out by himself.

You say this is being uncooperative - yes, it is. That's the whole point.

You have a team member that is not pulling his weight - he is in fact causing you and your colleagues to be less productive. If he is in a level that these questions are not questions that he should be asking, decline to answer them.

If you feel that this is not a good strategy, you can start an interruptions log. Record every time he asks you a trivial question and how long it took you to get back to your work (that is, into the mindframe you were in before the interruption).

This log will give you an idea of how much time he is costing you. If all of your colleagues do this, you will have a solid idea of how bad the problem is.

What you do with this data is up to you - discuss it with him, explain the issue and try to resolve it or escalate to management.

Title: How to avoid "DO YOU HAZ TEH CODEZ" situations?

Body:
I have a strange situation at work, where a colleague of mine often asks me and other co-workers for working code.

I would like to help him, but this constant request of trivial snippets interrupts my thoughts and sometimes makes it hard to concentrate.

Plus, I have the impression (...) that this requests are generated by lack of competence, more than by laziness. In fact, he often asks things pretending to know the answer, since when I solve the problem he usually says things like "Sure", "Yes, that's what I thought", giving me the impression that my answer isn't worth it.

How can I solve this embarrassing situation?

Should I show more explicitly in front of other colleagues his lack of knowledge (by saying things like: "do it yourself if you can, please") or continue giving him what he wants?

I think that he should aggregate all his questions in one, so that I can give him a portion of my time and he can work all by himself on his things.

There is no hierarchy in the team, I must say we both have a similar seniority of five years, more or less. For the same reason I believe I cannot report to management, since trivial questions are often ignored.

I discussed with other two members and they agree with me: in fact he often ask things cycling through colleagues.


答:
As suggested by Doc Brown and Thorbjørn Ravn Andersen, a Release early release often environment can benefit even more from good unit testing and test driven development than one with long release cycles.

If you have a good Continuous integration system in place and tests which represent the functionality well, you have a good idea at any point in time what is working (because the tests for that functionality are passing) and what hasn't yet been implemented (because there are no tests for that functionality).


答:
A constructive way of approaching this (because you say it feels like this is because of lack of competence), could be as follows:

Try coaching him into the direction of the answer, but try to make him come up with the final answer. This way, he will learn how to come up with trivial things himself, and also he will become more confident about his own competence of coming up with solutions (it might be that he is insecure and needs confirmation of you and/or your colleagues?).

If he asks a similar question multiple times, make it clear that you already explained this, and that he should know this (because in that exact case, you actually KNOW what his knowledge on the matter should be).


答:
Get him to learn some computer science and help to evolve from brainless scripting; probably he's a kind of person who knows stuff (with proven skills) but has no background.

"You know, that you really can get into more of this stuff, but how about improving yourself over this - now..". Spend some money on amazon to get an good used book (Gang of four, Programming in Haskell,.. Just for fun?) thus add some bookmarks about his recent questions.


答: My response would be to say "I'm a little busy right now, can you email me and I'll deal with it later". Chances are some of his questions are legitimate, by forcing him to email you it doesn't interrupt your flow and he is unlikely to bother detailing the problem in an email if its trivial. You then also have a record to show to management if his questions still stay at an unreasonable level.</p>


问:
Are there good techniques or tests for naming types?
An awkward, open question, but it's a problem I'm always bumping against:

Software that's easy to maintain and work with is software designed well. Trying to make a design intuitive means naming your components in such a way that the next developer should be able to infer the function of the component. This is why we don't name our classes "Type1", "Type2", etc.

When you're modelling a real-world concept (e.g. customer) this is generally as simple as naming your type after the real-world concept being modelled. But when you're building abstract things, which are more system-oriented, it's very easy to run out of names which are both easy to read and simple to digest.

It gets worse (for me) when trying to name families of types, with a base-type or interface which describes what the components have to do, but not how they work. This naturally leads to each derived type trying to describe the flavour of the implementation (e.g. IDataConnection and SqlConnection in the .NET Framework), but how do you express something complicated like "works by reflection and looking for a specific set of attributes"?

Then, when you've finally picked a name for the type you think describes what it's trying to do, your colleague asks "WTF does this DomainSecurityMetadataProvider actually do?"

Are there any good techniques for choosing a well-meaning name for a component, or how to build a family of components without getting muddled names?

Are there any simple tests that I can apply to a name to get a better feel for whether the name is "good", and should be more intuitive to others?

答:
Are there any good techniques for choosing a well-meaning name for a component, or how to build a family of components without getting muddled names?

Not really.

One tip, however, is to avoid "passive voice".

"DomainSecurityMetadataProvider" is passive.  There's no verb, it's all nouns and nouns used as adjectives.

"ProvideMetadataForDomainSecurity" is more active.  There's a verb.

Object-oriented programming is all (really) noun-verb.  Noun == object.  Verb == method.  So a class name is generally very "nounish".  To break this habit, and start inserting verbs, is difficult.

Are there any simple tests that I can apply to a name to get a better feel for whether the name is "good", and should be more intuitive to others?

Yes.  You defined an excellent test in your question.  Ask other people.

In the olden days we called this a "design walkthrough".  It was a big, sweaty deal in a waterfall methodology.  Nowadays, with Agile methods, it should be an ordinary collaboration between the author and users of a class.  It doesn't (and shouldn't) take long.  Discussing the design (and the names) before writing the tests (and the code) will reduce the astonishment factor and can prevent WTF's.


答:
Ask him to write his question down so you would be able to answer later when you will be free and speak with your manager to ensure you have quiet working conditions.

Your situation fails The Joel Test's point #8 Do programmers have quiet working conditions?

If a coworker asks you a question, causing a 1 minute interruption, but this knocks you out of the zone badly enough that it takes you half an hour to get productive again, your overall productivity is in serious trouble.


答:
My base test is if you can describe the variable's function using only words from the variable:

e.g. if DomainSecurityMetadataProvider either "Provides
  Domain Security Metadata" or "Provides Metadata relating to Domain
  Security", it's good.

However, there are nuances that vary from person to person:

e.g. For me, original_team_code is the code for the
  original team, whereas for someone else it might be the original code
  for the team. My personal favourite one of these was
  "UnsafeLegacyMutex", which I couldn't help but read as "This is a
  Legacy Mutex which is Unsafe", rather than "This is a Mutex for
  ThreadUnsafe Legacy Code".

So my extended test is to write the variable down on a board/wiki/chat, and have people guess what it means.

Title: Are there good techniques or tests for naming types?

Body:
An awkward, open question, but it's a problem I'm always bumping against:

Software that's easy to maintain and work with is software designed well. Trying to make a design intuitive means naming your components in such a way that the next developer should be able to infer the function of the component. This is why we don't name our classes "Type1", "Type2", etc.

When you're modelling a real-world concept (e.g. customer) this is generally as simple as naming your type after the real-world concept being modelled. But when you're building abstract things, which are more system-oriented, it's very easy to run out of names which are both easy to read and simple to digest.

It gets worse (for me) when trying to name families of types, with a base-type or interface which describes what the components have to do, but not how they work. This naturally leads to each derived type trying to describe the flavour of the implementation (e.g. IDataConnection and SqlConnection in the .NET Framework), but how do you express something complicated like "works by reflection and looking for a specific set of attributes"?

Then, when you've finally picked a name for the type you think describes what it's trying to do, your colleague asks "WTF does this DomainSecurityMetadataProvider actually do?"

Are there any good techniques for choosing a well-meaning name for a component, or how to build a family of components without getting muddled names?

Are there any simple tests that I can apply to a name to get a better feel for whether the name is "good", and should be more intuitive to others?


答:
One thing I'd be very firm on is that Names should NEVER be allowed to be incorrect. Best example, during some re-factoring, a lot of code changed, and a few variables started referring to something other than what their names suggested.

Pretty soon, one programmer was spending ages and using some very expensive database calls trying to get hold of certain pieces of data which had been extracted and stored already. I renamed everything and suddenly we could remove a ton of overcomplicated and buggy logic.


答:
Have you considered having an adult conversation with this person? Let them know their constant questions are a productivity killer, and ask why he feels he has to constantly ask you seemingly simple questions. Maybe he is a bit incompetent. You can choose to let him fail, or you can choose to help him succeed.

Ideally, let him know you are wiling to help if he's truly stuck, but that you expect him to give you the respect you deserve and do a little independent research first. Continually giving him answers to simple questions helps no one. Encouraging him to learn and grow helps the whole team.

Yes, it will be an uncomfortable conversation, but it will be less uncomfortable than a few more months of silent resentment.


答:
For naming, there are six techniques that were proven to work for me:

spend a lot of time on inventing names

use code reviews

don't hesitate to rename

spend a lot of time on inventing names

use code reviews

don't hesitate to rename

PS. In case if your API is going to be public, above applies before that - because, you know,

"Public APIs, like diamonds, are forever. You have one chance to get it right so give it your best..." (Joshua Bloch, How to Design a Good API and Why it Matters)


答:
Send him the link to Stack Overflow.

If it really is laziness then it shouldn't be your responsibility to backfill his willingness to complete work.  If it is a lack of ability then let him cargo cult on his own dime and not yours.  You have a professional responsibility to your employer to do your best work and you can't allow others to compromise you.  Working cooperatively and helping colleagues is professional and expected behaviour.  Letting deadweight keep you from doing your job (without contributing something back) is something you need to avoid and it's what your manager gets the big bucks to fix.


答:
Then, when you've finally picked a name for the type you think describes what it's trying to do, your colleague asks "WTF does this DomainSecurityMetadataProvider actually do?"

What kind of name do you expect for a complex and domain specific class?  This is about as good as it's going to get without making your class name a sentence (which will have everyone thinking you've given too much responsibility to a single class)

I would consider dropping provider from the name.  If it specifically mentions Metadata, everyone already knows you're using reflection.  You could make it one word more concise (or possibly change to another word--it's more of a consumer than a provider from what you've written)


答: Ask him to post the question this site and see what response he gets, it's helped a lot of programmers ;)  Put a copy of the CLR via C# on his desk and let him to check in there.</p>


答: Hopefully cases where you have to think so hard about the names are rare. When those cases arise, just write a paragraph explaining what the class does. Contrary to in-function comments or function level comment, the primary purpose of a class rarely changes so the risk of comments getting out of date is relatively small. So you have the luxury of writing a couple of paragraphs or even draw ASCII to explain what the class does.</p>


答:
As someone who has employed these kinds of people before, let me tell you that becoming aware of this problem is a really good deed. What I wanted my people to do in these circumstances was:

Start saying no. This is difficult because these people are very good at what they do, which is getting other people to help them. Very good. [see note 1]

If you are up for it, have a grownup conversation where you identify the behaviour and say you aren't going to participate any more. This is optional. You don't need to tell a coworker he can't take $20 bills from your wallet at will.

Tell your boss. Lord, I wish people had told me earlier.

You know what will happen if this coworker is fired? This is the shocking thing. NOTHING BAD. If the team was producing x units of work a week before, they will continue to produce x units of work a week afterwards. The time this person is consuming, and the disruption they are causing in your work flow, can really only be noticed afterwards. You will get more done when this behaviour stops. You will be happier, too. And your company will have more money.

note 1: Once I had an employee who was having a bad day in a bad week. A, I said, I need a list of all your outstanding stuff and where it stands before you go home today. I will look it over tonight and we will make a plan tomorrow morning. There was an hour left in the day. After I left A's office (to drive home, we did not work the same hours), in swanned B and bullied A into "helping" with B's project (which was not even important to the company, it was a training project to make B better at a particular tech by adding something to our website) for - you guessed it - one hour. Then A went home. I don't object to that, a hard stop is a hard stop. But wowee was I mad at B the next day. The skill level it takes to get smart people to drop everything for you is not something to underestimate. You can resolve to say no, you can tell your personal B to stop doing this to you, but in my experience, it won't work.

I wish I could tell you how to make the person stop doing it. In my experience you cannot. But you can make them stop doing it to you. Sometimes these people, after being let go from a place they were doing this, end up working somewhere there is no-one to leech from and not liking it there, or working at a job they actually know how to do. But while they have a job they don't know how to do, and the ability to make other people do it for them, that is the strategy they will use.


答:
I'd ask him to put all his questions into a big pile, and then sit down and do some pair programming with him during a longer stretch of time.

It does sound like he doesn't know how to program, but that may just be your frustration. Pair programming will teach him how to program (assuming he is teachable, not everyone has the knack of the programz).


问:
How is Python used in the real world?
I'm looking to get a job as a Python programmer. I know the basics of the language and have created a few games with it using pygame. I've also started to experiment with Django.

However, looking at the job market, it doesn't seem very many Python jobs are web-related. On the desktop side of things, it doesn't seem like very many companies use the popular GUI libraries like pyQt or wxPython.

How are companies actually using Python? What areas should one focus on to land a job as a Python programmer?

答:
It is worth pointing out this page on python success stories over at python.org. It has

41 real-life Python success stories, classified by application domain.

Title: How is Python used in the real world?


问:
How do you name your private variables in C#?
What is the best practice, most commonly accepted naming conventions for private variables in C#?

private int myInteger;

private int MyInteger;

private int mMyInteger;

private int _myInteger;

private int _MyInteger;

Mysterious other option

Which do you use and why?  (My company is fairly new to C# and I would like to pick the most "industry accepted" method to try and get into our coding standard.)

答:
Use camelCasing for private variables like myInteger

Consider a preceding _ if the variable is a backup for a property to reduce confusions-

Variable _myProperty for property MyProperty


问:
Were the first assemblers written in machine code?
I am reading the book The Elements of Computing Systems: Building a Modern Computer from First Principles, which contains projects encompassing the build of a computer from boolean gates all the way to high level applications (in that order).  The current project I'm working on is writing an assembler using a high level language of my choice, to translate from Hack assembly code to Hack machine code (Hack is the name of the hardware platform built in the previous chapters).  Although the hardware has all been built in a simulator, I have tried to pretend that I am really constructing each level using only the tools available to me at that point in the real process.

That said, it got me thinking.  Using a high level language to write my assembler is certainly convenient, but for the very first assembler ever written (i.e. in history), wouldn't it need to be written in machine code, since that's all that existed at the time?

And a correlated question... how about today?  If a brand new CPU architecture comes out, with a brand new instruction set, and a brand new assembly syntax, how would the assembler be constructed?  I'm assuming you could still use an existing high level language to generate binaries for the assembler program, since if you know the syntax of both the assembly and machine languages for your new platform, then the task of writing the assembler is really just a text analysis task and is not inherently related to that platform (i.e. needing to be written in that platform's machine language)... which is the very reason I am able to "cheat" while writing my Hack assembler in 2012, and use some preexisting high level language to help me out.

答:
An anecdote:

When I learned assembly language, on the Apple ][, There was a program included in the ROM called the micro-assembler. It did immediate translation of assembly instruction to bytes, as you entered them. This means there were no labels -- if you want to jump or load, you had to calculate the offsets yourself. It was much easier than looking up the instruction layouts and entering hex values though.

No doubt, real assemblers were first written using the micro-assembler, or some other not quite complete environment.


答: Python is true general purpose language. Your question is kind of like asking, what area should you focus on if you want C++ job or Java job. There is no one answer, spectrum is extremely wide. If you want to find banking job related to Python, you'll find one, if you want to find embedded programming in Python, you'll find it, if you want be game developer using Python you'll find that too.

Title: How is Python used in the real world?

Body:
I'm looking to get a job as a Python programmer. I know the basics of the language and have created a few games with it using pygame. I've also started to experiment with Django.

However, looking at the job market, it doesn't seem very many Python jobs are web-related. On the desktop side of things, it doesn't seem like very many companies use the popular GUI libraries like pyQt or wxPython.

How are companies actually using Python? What areas should one focus on to land a job as a Python programmer?


问:
How to correctly chain overloaded functions?
Assuming you have functions which take an increasing number of optional parameters (and a pseudo language which does not allow optional parameters and an arbitrary number of parameters) like this:

```<code>function doStuff(Param a)
function doStuff(Param a, Param b)
function doStuff(Param a, Param b, Param c)
</code>```

What is a good way to unify them to a single call? I can imagine two designs:

Fall through everything:

```<code>function doStuff(Param a)
    doStuff(a, defaultB)

function doStuff(Param a, Param b)
    doStuff(a, b, defaultC)

function doStuff(Param a, Param b, Param c)
    // magic goes here
</code>```

The Upside: Not much code duplication, easy changing of a single default parameter.

The Downside: Many function calls, might render Stacktraces harder to read or useless.

Or directly call the 'last' function:

```<code>function doStuff(Param a)
    doStuff(a, defaultB, defaultC)

function doStuff(Param a, Param b)
    doStuff(a, b, defaultC)

function doStuff(Param a, Param b, Param c)
    // magic goes here
</code>```

The Upside: Not many function calls, not worries if a new function is added into the chain.

The Downside: Much code duplication, especially the default values.

What did I not think of?

答:
The first is just two extra lines in a stacktrace which isn't so much.
In Java the I've never found stacktraces hard to read because of similar method names.

Anyway, using too much parameters could be a bad code smell: How many parameters are too many?

OwnerDisplayName: Bobby

OwnerDisplayName: palacsint


答:
As a former manager I cannot begin to tell you how much time I spent on a  weekly basis as a "grown up" baby sitter. All of the egos, conflicts, insults, and occasional work related issues. Never any problem with code reviews.

I only wish that real work places even began to resemble those in Joel's book(s).

Collectively, sit down in a conference room with all staff that are pestered by this individual. Let this person know that the interruptions are a distraction from your work, and interfere with your ability to work in "the zone".

Inform the manager, if possible.

Ask that all questions be addressed via email to eliminate the work interference and so you can begin to keep a log of both the frequency of interruption and low level of experience demonstrated.

Within a short period of time the group collectively should have either sent a message which put this person off from bothering everyone, or you'll have collected enough email trails to demonstrate to even an inexperienced manager the hiring mistake that was made.

A lesson I learned early as a manager was to hire the best employees I could find, try to see  how each person worked within the team and how the team gelled.

Another early lesson was to get rid of bad employees promptly.


答:
I would get assistance from management, have a chat about this with them, and then arrange a time to sit down as a group with this developer to deal with the situation.

Alternatively, it is sometimes necessary to be somewhat politic about these things and show the person's behaviour up clearly in front of the rest of the team (and management, if possible), without being rude or confrontational, but by gently questioning why they are doing this. I had to deal with a similar situation, not long ago. In that case, I said to the developer in question, when asked once again for assistance, "If you know what you are doing, as you claim to, then why do you consistently ask questions? And when I answer them, why argue? If you'd like me to help you in future, then just let me do so." The same person was let go by the tech director, a couple of days later (he had been latently aware of problems already).

We were both contractors, FYI, so there was little internal loyalty to either of us, from the TD's point of view. Sometimes, things just need to be brought out into the open.


答:
Since you're on the same team, be a good team player by showing him how to be one, too.  Exposing him to management could draw ire from some of your colleagues, and it's karmically bad, in my opinion.

Chances are, management already knows about your colleague, so why step out of line by "showing" them that he was a bad hire?
In the long run, helping this fellow out a little bit now could pay off for you in the long run in ways you might never even imagine.

Sorry you've found yourself in such a tough spot.


问:
"Comments are a code smell"
A coworker of mine believes that any use of in-code comments (ie, not javadoc style method or class comments) is a code smell.  What do you think?

答:
Only if the comment describes what the code is doing.

If I wanted to know what was happening in a method or block, I would read the code. I would hope, anyway, that any developers working on a given project were at least familiar enough with the development language to read what is written and understand what it is doing.

In some cases of extreme optimization, you might be using techniques that makes it difficult for someone to follow what your code is doing. In these cases, comments can and should be used to not only explain why you have such optimizations, but what the code is doing. A good rule of thumb would be to have someone else (or multiple other people) familiar with the implementation language and project look at your code - if they can't understand both the why and the how, then you should comment both the why and the how.

However, what's not clear in the code is why you have done something. If you take an approach that might not be obvious to others, you should have a comment that explains why you made the decisions that you did. I would suspect that you might not even realize that a comment is needed until after something like a code review, where people want to know why you did X instead of Y - you can capture your answer in the code for everyone else who looks at it in the future.

The most important thing, though, is to change your comments when you change your code. If you change an algorithm, be sure to update the comments with why you went with algorithm X over Y. Stale comments are an even bigger code smell.

Title: "Comments are a code smell"


问:
Why should we NOT do frequent deployment in PROD or to test server?
I was instructed by my project manager that frequent deployment in PROD or to test server should be avoided. But I don't understand why? We roll our testing copy to PROD on every sprint end but suddenly client would ask a simple change to the existing application which would require a re-deployment. When every thing was well tested and QA approved. why should we avoid frequent deployment?

How it was done universally?

答: if your re-deployement require downtime, then client may be unhappy about that. Also it depends on the frequency whether its daily weekly or monthly. My last project has a regular outage window at 2nd sat of every month with client's approval. You may check for any accepted outage window with your client.</p>


问:
Is there a way to handle nested Collections more elegantly?
My question is rather a design question. In my program I got to a data structure that looks something like this:

```<code>private ConcurrentHashMap<A, ConcurrentHashMap<B, ConcurrentHashMap<Integer, C>>> services  = new ConcurrentHashMap<A, ConcurrentHashMap<B, ConcurrentHashMap<Integer, C>>>();
</code>```

Is there a way to handle such a data structure more elegantly?
Thanks!

edit: A, B and C are business classes. An A instance "can have" (as association) many Bs and a B "can have" many mappings Integer-C.

答:
Create a class Triple with fields for A,B,Integer, override hashCode() and equals(), and use Map<Triple,C> instead of Map<A,Map<B,Map<Integer,C>>>

In this approach - you put all elements in one map, with a larger possible range of keys.

OwnerDisplayName: ovdsrn

OwnerDisplayName: amit


答:
[I come from C# background, but the answer should apply]

[It doesn't much matter but I assume the last item is ConcurrentHashMap<C,Integer>]

You have a function f of type A --> (B --> (C --> int))
If it is really what you need, I don't have a ready answer. But perhaps, having a function f of type (A x B x C) --> int would be enough for your purposes.

The difference between two cases is, the first one is lazier, more functional, arguably more elegant and it is possible to have a "partially applied" function around. For example, you have an a (of type A) element, you apply a to f and have a function g of type (B --> (C --> int)) to pass around, send to methods, whatever. However it is a little cumbersome and a little more code to properly initialize the function.

The second is more eager and less elegant, but may be easier to code and understand. All you need to do is to have a generic class Triple, override Equals() and GetHashCode() so that it will have value semantics, (two instances are to be considered equal if they have equal elements) and declare the ConcurrentHashMap is from Triple to Integer. The most obvious cost to pay is you need to have the A, B, C elements ready all at once to create an instance of Triple and perform the lookup.

Edit: If the last item is really ConcurrentHashMap<C,Integer>, then your generic class will have A, B and Integer fields, and the mapping will be from Triple to C

Title: Is there a way to handle nested Collections more elegantly?

Body:
My question is rather a design question. In my program I got to a data structure that looks something like this:

```<code>private ConcurrentHashMap<A, ConcurrentHashMap<B, ConcurrentHashMap<Integer, C>>> services  = new ConcurrentHashMap<A, ConcurrentHashMap<B, ConcurrentHashMap<Integer, C>>>();
</code>```

Is there a way to handle such a data structure more elegantly?
Thanks!

edit: A, B and C are business classes. An A instance "can have" (as association) many Bs and a B "can have" many mappings Integer-C.

Body:
[I come from C# background, but the answer should apply]

[It doesn't much matter but I assume the last item is ConcurrentHashMap<C,Integer>]

You have a function f of type A --> (B --> (C --> int))
If it is really what you need, I don't have a ready answer. But perhaps, having a function f of type (A x B x C) --> int would be enough for your purposes.

The difference between two cases is, the first one is lazier, more functional, arguably more elegant and it is possible to have a "partially applied" function around. For example, you have an a (of type A) element, you apply a to f and have a function g of type (B --> (C --> int)) to pass around, send to methods, whatever. However it is a little cumbersome and a little more code to properly initialize the function.

The second is more eager and less elegant, but may be easier to code and understand. All you need to do is to have a generic class Triple<A,B,C>, override Equals() and GetHashCode() so that it will have value semantics, (two instances are to be considered equal if they have equal elements) and declare the ConcurrentHashMap is from Triple to Integer. The most obvious cost to pay is you need to have the A, B, C elements ready all at once to create an instance of Triple and perform the lookup.

Edit: If the last item is really ConcurrentHashMap<C,Integer>, then your generic class will have A, B and Integer fields, and the mapping will be from Triple<A,B,Integer> to C

OwnerDisplayName: Ali


问:
Is there a design pattern for modelling job execution flow?
In my application I have a set of jobs to execute:

Each job goes through the states "not started", "started", "completed", "failed" etc.

Each job has a set of pre-conditions and post-conditions.

Job cannot start until the preconditions are satisfied and should be marked as failed if it doesn't satisfy the post conditions.

For example let's say the job imports a text file into the database. Pre-condition would be to check if the source file exists and post-condition would be to check if data exists in database. On top of these pre and post-conditions, sometimes job is also dependent on other jobs to finish. It is easy to create a jobs table and have a dependency table for jobs, but is it actually possible to make these pre and post validation checks to be configurable in database (so that no code changes need to be made if these conditions change or new conditions are added)?

Even if it is possible somehow, is it a good idea to do so? There is a requirement to make this model generic so that other applications can also make use of it even if the validation checks to be performed are entirely different for other applications.

答:
but is it actually possible to make these pre and post validation checks to be configurable in database (so that no code changes need to be made if these conditions change or new conditions are added)?

Yes. It's trivially possible.  There are lots of techniques.

Invent your own domain-specific language for this. And write your own interpreter.

Use BPEL.

Use any dynamic language (Python, Ruby, Lua, etc.) and put code in the database.

is it a good idea to do so?

No.

Code is best represented as code.

The pre-condition checks are often best left as code.  Ant, Maven and Scons all provide ways of doing this in code.

There is a requirement to make this model generic so that other applications can also make use of it even if the validation checks to be performed are entirely different for other applications.

Read up on Ant, Maven and Scons for approaches that work nicely.

Also, there are many commercial products that do this.

Finally, you should be able to Google "open source batch schedulers" and find even more solutions to this well-understood and already-solved problem.

You don't really need to solve this again.


答:
You could theoretically make a precondition and post condition table that linked to jobs, but the implementation would be extremely complex. I would first determine the frequency of changes to job dependencies and based on that make a decision whether its worth it to create such a system.  If you find changes are likely to happen weekly that is a completely different scenario than yearly.

Also a requirement to make something generic is one that is easy to say, but much harder to implement and can be unrealistic for a lot of applications. are there currently applications that exist that are intended to be able to use this job manager? are the applications intended to use this generic solution similar enough that a generic solution can actually solve the needs of all applications? It is worth it if you have doubts to examine if a generic solution is actually what is needed or if its is even possible, then tell your manager that I know that this project required a generic solution, but that will take X months longer than than this solution, or we can't create a generic solution that would be acceptable because the target applications are too different.

Title: Is there a design pattern for modelling job execution flow?

Body:
In my application I have a set of jobs to execute:

Each job goes through the states "not started", "started", "completed", "failed" etc.

Each job has a set of pre-conditions and post-conditions.

Job cannot start until the preconditions are satisfied and should be marked as failed if it doesn't satisfy the post conditions.

For example let's say the job imports a text file into the database. Pre-condition would be to check if the source file exists and post-condition would be to check if data exists in database. On top of these pre and post-conditions, sometimes job is also dependent on other jobs to finish. It is easy to create a jobs table and have a dependency table for jobs, but is it actually possible to make these pre and post validation checks to be configurable in database (so that no code changes need to be made if these conditions change or new conditions are added)?

Even if it is possible somehow, is it a good idea to do so? There is a requirement to make this model generic so that other applications can also make use of it even if the validation checks to be performed are entirely different for other applications.