答: Good tools for checking website speed and identifying slow areas are YSlow and PageSpeed. Neither integrate with the IDE but they give you good feedback.</p>

Title: How to test the render speed of my solution in a web browser?

Body:
Ok, I need to test the speed of my solution in a web browser, but I have some problems, there are 2 versions of the web solution, the original one that is on server A and the "fixed" version that is on server B.

I have VS2010 Ultimate, so I can make a web and load test on solution B, but I can't load the A solution on my IDE.

I was trying to use fiddle2 and jmeter, but they only gave me the times of the request and response of the browsers with the server, I also want the time it takes to the browser to render the whole page.

Maybe I'm misusing some of this tools...

I don't know if this could be usefull but:

Solution A is on VB 6.0

Solution B is on VB.Net

Thanks in advance!


问:
How can a non-technical person learn to write a spec for small projects?
How can a non-technical person learn to write specs for small projects?

A friend of mine is trying to outsource some development on a statistics project.

In particular, he does a lot of work in excel, and wants to outsource the creation of scripts to do what he now does by hand.

However, my friend is extremely non-technical. He is poor at writing technical specs.

When he does write a spec, it is written the way you would describe doing something in excel (go to this cell and then copy the value to that cell). It is also overly verbose, and does examples several times. I'm not sure if he properly describes corner cases.

The first project he outsourced was a failure. I think he overdescribed some details, but underdescribed corner cases. That and/or the coder he hired didn't think through the corner cases and ask appropriate questions. I'm not sure. I got on IM with him and it took me half an hour to dig out a description that should have taken five minutes or less to describe. I wrote the scripts for him at the end, but didn't examine why his process with the coder failed.

He has asked me for help. However, I refuse to get involved, because taking his spec and translating it into clear requirements is 10x more work than executing on a clearly written spec.

What is the right way for him to learn? Are there resources he could use? Are there ways he can learn from small, low-pressure practice projects with coders?

Most of his scripts are statistical and data processing oriented. e.g. take this column and run an average over it. Remove these rows under these conditions. So the challenge is different than spec'ing a web app.

答:
Most of his scripts are statistical and data processing oriented. e.g. take this column and run an average over it. Remove these rows under these conditions. So the challenge is different than spec'ing a web app.

It is different - it seems a lot simpler than specifying a web app. It's a logical process. This is the easy stuff.

Your friend very simply needs to write down the steps that he takes when he performs this process. He can do it however he wants but the key things to focus on are accuracy, conciseness, and clarity. There's no reason that it can't be done purely in text like a manuscript; it would benefit from some logical division of components or tasks, and would probably work well as a flowchart or diagram.

Now your friend should find a competent analyst/developer and engage their services piece by piece. He needs to lay out his expectations - daily or at least multiple times per week your friend should meet with the developer and see a hands on demonstration of progress. Your friend will pay the developer for his time during these demonstrations, but it will be worth it to ensure that the project is being run to specification. Any changes to the specification - i.e. things that your friend omitted - need to be negotiated and probably added to the quoted price.

Note that I said 'competent' - this is not the same as 'average', because there are plenty of 'average' developers who aren't competent. If your friend just gets the cheapest coder around, or just finds someone online, he should expect problems. Not to suggest that people who find work online are no good, but you wouldn't employ someone without a recommendation.

Your friend must simply find the right person. In any software project there is a need for analysts, programmers, system adminstrators, testers, and project managers. The more of these roles your friend wants to 'outsource', the more skilled the provider will be and the more your friend should expect to pay.

ContentLicense: CC BY-SA 3.0


答:
the coder he hired didn't... ask appropriate questions

That's a recipe for disaster. That, and also the expectation that coder will ask. Coders like to code, not to communicate, expecting them to break their habits without an incentive is pretty unrealistic.

If your friend wants to get job done, they better establish a process involving continuous communication with coder - and it's your friend who has to play an active role in that, not the coder. "Show me what is done every Monday and set up two hours to discuss this on every Tuesday", stuff like that.

For an introduction, supply them some lightweight overviews of iterative and Agile development methodologies (Wikipedia articles will do), so that they get a feeling on how it should be like.

To help them understand past failure, supply them some lightweight overviews of Waterfall / Big Design Up Front (those that include criticism - again, Wikipedia articles will do) - these typically do a pretty good job explaining how it is typically difficult to specify things right up front.

In my experience, most reliable way to get software work as desired with non-technical customers was to permanently communicate and iterate feature descriptions, not trying to specify it to death in one shot.

Title: How can a non-technical person learn to write a spec for small projects?

Body:
How can a non-technical person learn to write specs for small projects?

A friend of mine is trying to outsource some development on a statistics project.

In particular, he does a lot of work in excel, and wants to outsource the creation of scripts to do what he now does by hand.

However, my friend is extremely non-technical. He is poor at writing technical specs.

When he does write a spec, it is written the way you would describe doing something in excel (go to this cell and then copy the value to that cell). It is also overly verbose, and does examples several times. I'm not sure if he properly describes corner cases.

The first project he outsourced was a failure. I think he overdescribed some details, but underdescribed corner cases. That and/or the coder he hired didn't think through the corner cases and ask appropriate questions. I'm not sure. I got on IM with him and it took me half an hour to dig out a description that should have taken five minutes or less to describe. I wrote the scripts for him at the end, but didn't examine why his process with the coder failed.

He has asked me for help. However, I refuse to get involved, because taking his spec and translating it into clear requirements is 10x more work than executing on a clearly written spec.

What is the right way for him to learn? Are there resources he could use? Are there ways he can learn from small, low-pressure practice projects with coders?

Most of his scripts are statistical and data processing oriented. e.g. take this column and run an average over it. Remove these rows under these conditions. So the challenge is different than spec'ing a web app.


问:
In centralized version control, is it always good to update often?
Assuming that:

Your team is using centralized version control.

You are working on a larger feature which will take several days to complete, and you won't be able to commit before that because it would break the build.

Your team members commit something every day that might change some of files you're working on.

Since this is centralized version control,
you will have to update your local checkout at some point:
at least once right before committing the new feature.

If you update only once right before your commit, then there might be a lot of conflicts due to the many other changes by your teammates, which could be a world of pain to resolve all at once.

Or, you could update often, and even if there are a few conflicts to resolve day by day, it should be easier to do, little by little.

Would you stay it's always a good idea to update often?

答:
I actually find it more convenient to use a distributed version control locally. That is, I use git as subversion client. This has the advantages that:

The local changes are saved before updating, so if I make mistake in the merge, I can always go back and do it again.

When doing bigger changes, I can save the parts that are finished. That makes it easier to review the remaining changes in progress.

When I fix a bug during some bigger work, I can commit just that fix, temporarily commit the rest and "dcommit" the fix to subversion while keeping the other work in progress local.


答:
The 3rd bullet point in the question is simply wrong:

You are working on a new feature which will surely take several days
  to complete, and you won't be able to commit before that because it
  would break the build.

If you know you are going to be working on something you cannot commit for some time, that is the textbook example for using branches.

Do not put yourself in the situation where you have a lot of pending changes. If you know you will not be able to commit in your project's main branch for some time, then work on another branch. And there, commit often.

If you are already in the situation described in the question, then switch to a branch right now, commit your changes and continue working in that branch.

Normally in CVCS it is a good idea to update often. But if you are working on a branch then the question of "update often or not" becomes "merge often or not". And the answer is yes anyway. Just make sure to commit all pending changes (in the branch) before merging from another branch, to your option to roll back the merge safely if you have to.

Title: In centralized version control, is it always good to update often?

Body:
Assuming that:

Your team is using centralized version control.

You are working on a larger feature which will take several days to complete, and you won't be able to commit before that because it would break the build.

Your team members commit something every day that might change some of files you're working on.

Since this is centralized version control,
you will have to update your local checkout at some point:
at least once right before committing the new feature.

If you update only once right before your commit, then there might be a lot of conflicts due to the many other changes by your teammates, which could be a world of pain to resolve all at once.

Or, you could update often, and even if there are a few conflicts to resolve day by day, it should be easier to do, little by little.

Would you stay it's always a good idea to update often?


问:
Most appropriate OSS license for infrastructure code
I'm looking into potentially releasing some infrastructure code (related to automated builds and deployments) as OSS and I'm curious about how the various OSS licenses effect it.

Specifically, LGPL prevents the code itself (part/whole) being modified into a commercial product (which is what I'm after), but allows it to be "linked to" in the creation of commercial products (also ok).

How does the "linked to" clause relate to infrastructure code, which is not deployed with the product itself? Would the application still be required to provide "appropriate legal notices" (which I'm not fussed over)?

Would I be better off looking at the Eclipse Public License?

答:
I assume your code is something roughly comparable to the make tool.

Since your code is not distributed with the final product, just use the GPL if you do not want to have your code turned into a proprietary product (or a part thereof). Using the GPL for your tool does not affect the license of the program built with your tool in any way. You could also choose the LGPL, but that would allow your code to become part of a proprietary product (although that part would still be free as in speech).

Disclaimer: IANAL


答:
Yes, it is a good idea to update often. You update often to avoid difficult merge conflicts and this is the basics of Software Configuration Management (SCM) knowledge with the problem of divergent changes.

This is regardless if it is centralized or distributed; the longer time you diverge from an upstream source (meaning if it is a trunk, branch, or other repository in the DVCS case) the higher the chance of merge conflicts. Yes, nasty surprises from your team may come when updating, but postponing the nasty surprise is even worser (the longer you wait, the less people remember why a set of changes were made).

For updating to work this also means that you and other programmers working on code should never knowingly commit or push upstream code that breaks the build. This is usually why programmers branch (or diverge from upstream in SCM terms), to shield your team members and other stakeholders from having broken code if such a situation inevitably should arise.

The mantra you can use to remember is this: "update, update, update, commit". Always make sure your changes works with others before committing. This is also to make sure checking out code for the first time works as well.


问:
Two HTML elements with same id attribute: How bad is it really?
Just browsing the google maps source code. In their header, they have 2 divs with id="search" one contains the other, and also has jstrack="1" attribute. There is a form separating them like so:

```<code><div id="search" jstrack="1">
    <form action="/maps" id="...rest isn't important">
        ...
        <div id="search">...
</code>```

Since this is google, I'm assuming it's not a mistake.

So how bad can it really be to violate this rule? As long as you are careful in your css and dom selection, why not reuse id's like classes? Does anyone do this on purpose, and if so, why?

答:
How bad is it really?

It makes me cry

It's invalid

Many javascript libraries will not work as expected

It makes your code confusing

Experience says that getElementById in major browsers will return the first matched element in the document. But this may not always be the case in the future.

When jQuery is given an id eg #foo, it uses getElementById and mimics that behaviour. If you have to work around this (that's sad), you can use $("*#foo") which will convince jQuery to use getElementsByTagName and return a list of all matched elements.

I often have to write code for other sites, and I have to work around this. In a just world, I would not have to redesign functions to start off by checking if an ID is unique. IDs should always be unique. The world is cruel and that's why I cry.


问:
Should I continue my self-taught coding practice or learn how to do coding professionally?
Lately I've been getting professional work, hanging out with other programmers, and making friends in the industry. The only thing is I'm 100% self-taught. It's caused my style to extremely deviate from the style of those that are properly trained. It's the techniques and organization of my code that's different.

It's a mixture of several things I do. I tend to blend several programming paradigms together. Like Functional and OO. I lean to the Functional side more than OO, but I see the use of OO when something would make more sense as an abstract entity. Like a game object. Next I also go the simple route when doing something. When in contrast, it seems like sometimes the code I see from professional programmers is complicated for the sake of it! I use lots of closures. And lastly, I'm not the best commenter. I find it easier just to read through my code than reading the comment. And most cases I just end up reading the code even if there are comments. Plus I've been told that, because of how simply I write my code, it's very easy to read it.

I hear professionally trained programmers go on and on about things like unit tests. Something I've never used before so I haven't even the faintest idea of what they are or how they work. Lots and lots of underscores "_", which aren't really my taste. Most of the techniques I use are straight from me, or a few books I've read. Don't know anything about MVC, I've heard a lot about it though with things like backbone.js. I think it's a way to organize an application. It just confuses me though because by now I've made my own organizational structures.

It's a bit of a pain. I can't use template applications at all when learning something new like with Ubuntu's Quickly. I have trouble understanding code that I can tell is from someone trained. Complete OO programming really leaves a bad taste in my mouth, yet that seems to be what EVERYONE else is strictly using.

It's left me not that confident in the look of my code, or wondering whether I'll cause sparks when joining a company or maybe contributing to open source projects. In fact I'm rather scared of the fact that people will eventually be checking out my code. Is this just something normal any programmer goes through or should I really look to change up my techniques?

答:
I completely relate to this question.  I have the exactly the same feelings and a very similar background (but not exactly same).  I am supposed to be trained professionally (or rather academically) so I am supposed to know about OO programming etc.  Programming wasn't my major topic but I hvae done it.  I learnt OO in some of my courses and didn't understand reason d'etre at all.  Infact, the only time I understood OO was when I did commercial work and was coerced into it by two great mentors.

I am sure my professor was equally brilliant but you see the real benefit in practice in a commercial environment vs functional programming but you don't have a chance to see it in a course which is designed to run and teach and end within a few months.  I haven't had the chance to work on MVC based structure but I am sure it will be the same i.e. I woiuld be able to pick up the concepts working from a book but I will understand its benefit when I see it in use in a commercial environment.  And I totally agree with you, why use OO and MVC and any other complex structure if you can solve a problem through a simpler way.  My advice is to not be shy of work because it will expose you to situation different and allow you to understand the same things in a different light.

Sure I learnt syntax and concepts in my academic background but it is in commercial world where I started to learn to program.


问:
How to manage 2 DAO methods in a single transaction?
In an interview someone asked me : How do we manage 2 transactional/dao methods in a single transaction. Desired capabilities:

If anyone of them fails we need to rollback both methods.

Both of the methods can be called separately attached with a single transaction.

The management should be on DAO layer, not on service layer.

I think : the question relates to spring transaction management.

答:
First of all, transaction management should be done on service layer, not on DAO layer as that would create a lot of performance overhead (to deal with appropriate transaction isolation level and propagation at each different method). Also, the scope of a unit of work comes from the service layer instead of the data access layer: imagine performing a business process that needs to deal with 2 or more DAOs.

There is a lot of discussion in the Internet that points in that direction as here, here and here.

Anyway, since it's an interview let's accept the question as is. From my point of view, you would be using the @Transactional annotation (or the XML configuration) in both methods and with a transaction propagation with REQUIRED value. That way, when any of those methods is invoked and if no previous transaction exist, a new transaction will be created:

```<code>@Transactional
class MyDAO {

   @Transactional(propagation = REQUIRED)
   public void foo() {
   }

   @Transactional(propagation = REQUIRED)
   public void bar() {
   }

}
</code>```

Body:
First of all, transaction management should be done on service layer, not on DAO layer as that would create a lot of performance overhead (to deal with appropriate transaction isolation level and propagation at each different method). Also, the scope of a unit of work comes from the service layer instead of the data access layer: imagine performing a business process that needs to deal with 2 or more DAOs.

There is a lot of discussion in the Internet that points in that direction as here, here and here.

Anyway, since it's an interview let's accept the question as is. From my point of view, you would be using the @Transactional annotation (or the XML configuration) in both methods and with a transaction propagation with REQUIRED value. That way, when any of those methods is invoked and if no previous transaction exist, a new transaction will be created:

@Transactional
class MyDAO {

   @Transactional(propagation = REQUIRED)
   public void foo() {
   }

   @Transactional(propagation = REQUIRED)
   public void bar() {
   }

}


问:
Is Ubuntu workable as a laptop for an IT consultant?
I work as a consultant programmer, typically in large businesses. I use a Windows Laptop, and many of my colleagues use a Mac.

My personal preference would be to run Ubuntu if I could have complete control over my development environment. But I will have occasional need for Microsoft specific products, especially IE.

My colleagues that use a Mac often run Windows on a virtual machine for these situations.

My question is: Is Ubuntu a workable solution for the laptop of an enterprise programmer? For example, is it as easy to run Windows on a VM on Ubuntu as it is on a Mac? Has anyone out there tried this? Is there any particular reason why Ubuntu would not serve as well as a Mac for development in this environment?

Note that I am not doing .NET development, so I am typically dealing with Java that is going to be run on an Apache server and used by clients running Windows.

答:
Ubuntu is a very suitable to run virtual Windows. VirtualBox and VMWare works very well under Ubuntu and ofcourse you can always switch to Kubuntu if you want your Ubuntu to look more like  Windows but stay Linux.

It runs faster than Windows, saves battery time and does not limit you like a Mac. It is great to have a Linux and especially Ubuntu laptop if you want to work with multiple environments. Everything you need is free and you have the full control.

But you can install and run Windows on a Mac too. I use my Mac like that. You can also install Ubuntu and Windows side by side with dualbooting, but if you want to do that way, make sure that you install Windows first.


问:
How do you explain to an "agile" team that they still need to plan the software they write?
This week at work I got agiled yet again. Having gone through the standard agile, TDD, shared ownership, ad hoc development methodology of never planning anything beyond a few user stories on a piece of card, verbally chewing the cud over the technicallities of a 3rd party integration ad nauseam without ever doing any real thinking or due dilligence and architecturally coupling all production code to the first test that comes into anyone's head for the past few months we reach the end of a release cycle and lo and behold the main externally visible feature that we have been developing is too slow to use, buggy, becoming labyrinthinly complex and completely inflexible.

During this process "spikes" were done but never documented and not a single architectural design was ever produced (there was no FS, so what the hell eh, if you don't know what you are developing, how can you plan or research it?) - the project passed from pair to pair, each of whom only ever focused on a single user story at a time and well the result was inevitable.

To resolve this I went off the radar, went (the dreaded) waterfall, planned, coded and basically didn't swap off the pair and tried as much as I could to work alone - focusing on solid architecture and specifications rather than unit tests which will come later once everything is pinned down. The code is now much better and is actually totally usable, flexible and fast. Certain people seem to have really resented me doing this and have gone out of their way to sabotage my efforts (possibly unconsciously) because it goes against the holy process of agile.

So how do you, as a developer, explain to the team that it is not "un-agile" to plan their work, and how do you fit planning into the agile process? (I'm not talking about the IPM; I'm talking about sitting down with a problem and sketching out an end-to-end design that says how a problem should be solved in sufficient detail that anyone who works on the problem knows what architecture and patterns they should be using and where the new code should integrate into existing code)

答:
One way to get them to work may be to make a T-Map that covers all of your sprint back-log

Each team has a thread, each sprint is a period. It all ties together (which is where your team seem to fall over). Pin this up somewhere, and get magnets to represent the pairs/subteams. They can even 'race'. But everyone knows where they and the other teams are. Put dependancies up on here if there are any.

The point here is you convey the total process but also break it down into sprints. Even if only the first sprint is put on there, and the other periods are blank this should be an excellent roadmap to finishing the project.


答:
Sorry to be the one to break this to you, but it's not a non-technical person's job to learn how to write formal specifications.  It's the developer's job to interview the non-technical person, try to distil what the person says to you about what they're after, determine what it is that the client really wants (as opposed to what it is they think they want, which isn't always the same thing), build a relatively informal requirements document (one that is well-structured but which tries to avoid jargon that the client won't understand) and review that document with the client.

Once the client is happy with the informal requirements document, you can use that as a basis for drafting a more formal requirements specification that starts going into more technical detail about what's needed.

This whole process is known as "requirements capture" and it forms the first step in the software engineering process.  Actually writing the software is only a relatively small part of software engineering, a fact that sadly a lot of software developers forget.  Another thing they seem to forget is that there is a strong need to communicate with the client and keep a dialogue in place with them during the entire process to ensure that things stay on track.

As for communicating with non-technical people, it's vitally important you try to avoid using the jargon of computers and software development when talking to them.  If they use jargon terms from their own field then it's important to understand what these terms mean so you might want to draw up a project glossary to get formal definitions for these terms.  You're working for them after all, so it's important to understand where they're coming from.

instead of jargon, you should try using non-intimidating ways of communicating with your client, documents written in plain English are a help, but a lot of people in the software business are used to writing for computers rather than humans and so may find this difficult.  Additionally, clients don't like reading through big piles of paper, no matter how plain their language is, so you might want to resort to visual aids.  Diagrams, wireframes and storyboards are useful tools here.

But in short, the core point is it's not your client's job to learn your language, it's yours to learn their language.


问:
What does it mean by atomic commit for a versioning system?
One of the reasons why programmers prefer SVN over CVS is the former allows atomic commits ? What does this mean ? </p>

答:
It means that all changes to all files are committed in a single transaction, so either all succeed or none.

This means that you are less likely to get partial edits checked in to the repository which cause builds to fail. You can still get people forgetting to check in all the relevant files, but that's a process issue rather than a problem with the versioning system.


答:
It means that when you do a commit to the version control system either everything you want to commit goes in, OR nothing does.

In CVS, when you try to commit it's possible for the commit to succeed on several files, then fail on several others (because they've changed). This leaves the repository in an unfortunate state because half of your commit isn't there, and it's likely that you've left things in a state where they won't compile or worse. Now you've got to hurry up and integrate whatever changes so that you can commit the other files before someone else needs to update and gets your broken set of changes.

In SVN this won't happen - SVN will either commit everything you've changed, or it will fail the whole changeset. Thus, you'll never leave the repository in a broken state due to commit issues.

Title: What does it mean by atomic commit for a versioning system?

Body: One of the reasons why programmers prefer SVN over CVS is the former allows atomic commits ? What does this mean ? </p>


答:
This is explained eg in Bye-bye CVS. I've been Subverted article written by Andy Lester:

If I try to commit in Subversion, but one of the files has a conflict, or is out-of-date, none of the files commits. In CVS, you’ve got a half-commited set of files that you have to fix RIGHT NOW.

The fact that CVS forces programmer to fix the merge immediately is as counter-productive as it gets. Compared to that, an option to delay / cancel / carefully merge changes is a substantial benefit.

Other benefits of SVN over CVS explained in above article are:

Local versions of everything you do

  If you want to cvs diff, you have to be able to connect to your repository. No net connection, no
  diffing. Subversion stores local pristine copies of what you’re
  working on, so svn diff will work just fine. Want to start over? svn
  revert works unconnected, too.

Symbolic names of revisions

  HEAD is the name of the tip of the trunk in CVS, but I’ve always wanted to be able to say “-r-1″ like I
  could way back when in PVCS days. With CVS, I have to do a cvs log on
  what I’m editing, and then subtract one. That’s no fun. With
  Subversion, I can say svn diff -r PREV.

Real status reporting

  In CVS, the only way you can see if something on the server is newer is to cvs update and hope that
  whatever comes down doesn’t cause any conflicts. With the svn status
  command, I get real status, so I can see if there are conflicts BEFORE
  I do an update.

Helpful handling of merge conflicts

  In CVS, if there are conflicts, you get conflict markers in your file. In Subversion, you
  get conflict markers, PLUS a copy of your original, pre-conflict file,
  PLUS the version that came down from the server, PLUS the version that
  you were originally editing. Then, you must explicitly svn resolve
  filename.txt to tell Subversion that you’ve fixed the problem. No more
  accidentally commiting back into CVS with conflict markers still
  there.


答:
Ignoring spring and frameworks in my answer..... just the basic idea of using function parameters. I'm sure the concept could apply within [insert framework here].

You would need to handle the commit/rollback outside of the 2 DAO methods. The 2 methods would need to take the transaction/connection as input.

psuedo code:

```<code>bool method1(Tran t) { /* stuff */}
bool method2(Tran t) { /* stuff */ }

callingMethod() {
     Tran t = null;
     try {
         t = new Conn().open().startTran();
         if(method1(t) && method2(t))
             t.commit();
         else
             t.rollBaack();
     }
     catch(ex) {  t.rollBack();  }
     finally {  t.closeConn();  }
}
</code>```

Title: How to manage 2 DAO methods in a single transaction?

Body:
In an interview someone asked me : How do we manage 2 transactional/dao methods in a single transaction. Desired capabilities:

If anyone of them fails we need to rollback both methods.

Both of the methods can be called separately attached with a single transaction.

The management should be on DAO layer, not on service layer.

I think : the question relates to spring transaction management.

Body:
Ignoring spring and frameworks in my answer..... just the basic idea of using function parameters. I'm sure the concept could apply within [insert framework here].

You would need to handle the commit/rollback outside of the 2 DAO methods. The 2 methods would need to take the transaction/connection as input.

psuedo code:

bool method1(Tran t) { /* stuff */}
bool method2(Tran t) { /* stuff */ }

callingMethod() {
     Tran t = null;
     try {
         t = new Conn().open().startTran();
         if(method1(t) && method2(t))
             t.commit();
         else
             t.rollBaack();
     }
     catch(ex) {  t.rollBack();  }
     finally {  t.closeConn();  }
}


问:
Do people in non-English-speaking countries code in English?
I've heard it said (by coworkers) that everyone "codes in English" regardless of where they're from. I find that difficult to believe, however I wouldn't be surprised if, for most programming languages, the supported character set is relatively narrow.

Have you ever worked in a country where English is not the primary language?

If so, what did their code look like?

答:
I'm from Bangalore, India. Programmers are from various states with different languages.

We code in English, document in English, comment in English, naming convention is in English. English is our common language while talking in office.

ContentLicense: CC BY-SA 2.5


问:
What does cheap copying/branching mean for a versioning system like SVN?
One of the advantages of SVN over CVS as given here is cheap copying and branching. What does "cheap copying and branching" mean in SVN parlance? How is it different from CVS copying and branching?

答:
If I read it right "cheap copying and branching" is the same as "lazy copying and branching".

In these schemes the file isn't actually copied until it becomes different from the parent file. The system creates a placeholder for the file but when you read the contents it goes back to the main trunk for the contents.

This has the main advantage of saving disk space on your server. If you did a full copy of the trunk then you would double the amount of disk space you need on your server. By only actually copying the files that have changed you drastically reduce this requirement. A typical branch will only actually modify a handful or a few hundred files at most.

Another significant advantage is that as the files aren't copied until needed the creation of the branch is a very quick operation. This encourages branching as it's now seen as a cheap/quick operation rather than an expensive/slow one. (Thanks to Andres F. and Murph for pointing that out)


问:
Critique of the IO monad being viewed as a state monad operating on the world
The IO monad in Haskell is often explained as a state monad where the state is the world. So a value of type IO a monad is viewed as something like worldState -> (a, worldState).

Some time ago I read an article (or a blog/mailing list post) that criticized this view and gave several reasons why it's not correct. But I cannot remember neither the article nor the reasons. Anybody knows?

Edit: The article seems lost, so let's start gathering various arguments here.
I'm starting a bounty to make things more interesting.

Edit: The article I was looking for is Tackling the awkward squad: monadic input/output, concurrency, exceptions, and foreign-language calls in Haskell by Simon Peyton Jones. (Thanks to TacTics's answer.)

答: Here's a trivial answer: any change to the state monad's state is due to any actions ran in the monad. If indeed the “WorldState -> (a, WorldState)” explanation claims the same property, with WorldState being a pure value that only the IO monad changes, it's wrong. Time changes, the content of files, the state of handles, etc. can change independently of what happens in the IO monad. That's the point of the IO monad. The fact that GHC passes around a RealWorld value (or w/e it was) underneath is to guarantee things are ran in order, as far as I know, if that (may just be something to put in the ST value).</p>


问:
Configuration data: single-row table vs. name-value-pair table
Let's say you write an application that can be configured by the user. For storing this "configuration data" into a database, two patterns are commonly used.

The single-row table

```<code>  CompanyName  |  StartFullScreen  |  RefreshSeconds  |  ...
---------------+-------------------+------------------+--------
  ACME Inc.    |        true       |       20         |  ...
</code>```

The name-value-pair table

```<code>  ConfigOption   |   Value
-----------------+-------------
 CompanyName     | ACME Inc.
 StartFullScreen | true (or 1, or Y, ...)
 RefreshSeconds  | 20
 ...             | ...
</code>```

I've seen both options in the wild, and both have obvious advantages and disadvantages, for example:

The single-row tables limits the number of configuration options you can have (since the number of columns in a row is usually limited). Every additional configuration option requires a DB schema change.

In a name-value-pair table everything is "stringly typed" (you have to encode/decode your Boolean/Date/etc. parameters).

(many more)

Is there some consensus within the development community about which option is preferable?

答:
I'd generally go with option 2 BUT I'd have multiple columns to enforce data type

```<code>ConfigOption   |   textValue    |   DateValue   |   NumericValue
</code>```

Option 1 Has the additional Benefit that you can very easily "Swap" entire Configurations by adding an Active Column.

Body:
I'd generally go with option 2 BUT I'd have multiple columns to enforce data type

ConfigOption   |   textValue    |   DateValue   |   NumericValue

Option 1 Has the additional Benefit that you can very easily "Swap" entire Configurations by adding an Active Column.


答:
I personally prefer the single-row tables for most things.  While it's true that it is less flexible, unless you are expecting dynamic behavior, it's perfectly acceptable to add extra columns later if you need to.  In a way, it's the equivalent of using a dictionary/map to hold name-value pairs vs having class members when programming.  Granted, it's not a perfect metaphor, but many of the advantages and disadvantages are paralleled when you think about it.  </p>

<p>So would you use a dictionary/map over class members?  Probably not unless you had reason to think the amount of data to be represented is entirely adaptable, much like having a name-value pair table.  </p>

Title: Configuration data: single-row table vs. name-value-pair table

Body:
Let's say you write an application that can be configured by the user. For storing this "configuration data" into a database, two patterns are commonly used.

The single-row table

```<code>  CompanyName  |  StartFullScreen  |  RefreshSeconds  |  ...
---------------+-------------------+------------------+--------
  ACME Inc.    |        true       |       20         |  ...
</code>```

The name-value-pair table

```<code>  ConfigOption   |   Value
-----------------+-------------
 CompanyName     | ACME Inc.
 StartFullScreen | true (or 1, or Y, ...)
 RefreshSeconds  | 20
 ...             | ...
</code>```

I've seen both options in the wild, and both have obvious advantages and disadvantages, for example:

The single-row tables limits the number of configuration options you can have (since the number of columns in a row is usually limited). Every additional configuration option requires a DB schema change.

In a name-value-pair table everything is "stringly typed" (you have to encode/decode your Boolean/Date/etc. parameters).

(many more)

Is there some consensus within the development community about which option is preferable?

Body:
I personally prefer the single-row tables for most things.  While it's true that it is less flexible, unless you are expecting dynamic behavior, it's perfectly acceptable to add extra columns later if you need to.  In a way, it's the equivalent of using a dictionary/map to hold name-value pairs vs having class members when programming.  Granted, it's not a perfect metaphor, but many of the advantages and disadvantages are paralleled when you think about it.

So would you use a dictionary/map over class members?  Probably not unless you had reason to think the amount of data to be represented is entirely adaptable, much like having a name-value pair table.


问:
How to learn to make better estimates?
I suck at estimates. When someone asks me how long something will take, I don't even dare to make a guess since I will be completely off the mark. Usually I'm way too optimistic, and should probably multiply my guess with some large X factor...

How can I learn to make better estimates? It's not taught at my uni, and even though we have deadlines for all laborations I never think about how long something will actually take. Which I should. For everyone's sake (especially mine).

答:
For openers, read "Software Engineering Economics", by Barry Boehm, and "Controlling Software Projects", by Tom DeMarco.  After you have read and digested those two, read "Software Cost Estimation With COCOMO 2", by Barry Boehm.

For what I have to say next, it will help you a LOT to have taken a probability and statistics class, even a basic cookbook one.

No estimate is perfect.  There is some probability of coming in early, and some probability of coming in late.  Boehm's original detailed COCOMO model gave predictions that turned out to be within 30% of the actual result, better than 60% of the time.  That was a lot better than what was common when he wrote and published the book.

When you take your best guess (and that's all an estimate is), you are including those probabilities.  If you pull the estimate in, you are increasing the probability that you will come in late.  If you increase the estimate, you are increasing the probability that you will come in early or finish on time.  How much you pull it in or let it out controls how the probability changes, and must necessarily depend on the penalties for being early or late.  (Insert horror stories here - and there've been a LOT of them over the years!)

DeMarco addresses this to some extent.  He also points out that there is an "impossibility region": some schedules are just too tight to be made, no matter what kind of heroics are attempted.

Title: How to learn to make better estimates?


问:
How do I get from a highly manual process of development and deploy to continuous integration?
We have a development process which is completely manual. No unit tests, interface tests are manual, and merging and integration are as well. How could we go from this state to implementing continuous integration with full (or at least close to full) automation of build and test? We have a pretty intense development cycle, and are not currently using agile, so switching to agile with CI in one move would be a very complicated and expensive investment. How can we take it slowly, and still moving constantly towards a CI environment?</p>

答:
I suggest using Jenkins which allows you to add build scripts but also commit hooks that run on each commit. You don't need to configure your entire build on one day but you can make small steps each day.

For example, you can enhance your build script whenever you have time and you can integrate more build reports or unit testing as you go along. In the beginning Jenkins will create an automatic build on each commit and the build will be done within a second because you have not yet specified any work. This assures you that the system is working and you can then start working towards the build system that you want.


答: What I understand for cheap process in terms of create a branch of a tag in SVN in when you execute the command(svn tag or branch), the command itselft ins't creating a new physical folders with the content of all your project, all the system do it's replicate the structure base of the snapshot of you trunk which is pretty different than copy and paste all the files in the new folder, bring the consequence that the application that the process it's faster.</p>

Title: What does cheap copying/branching mean for a versioning system like SVN?

Body: One of the advantages of SVN over CVS as given here is cheap copying and branching. What does "cheap copying and branching" mean in SVN parlance? How is it different from CVS copying and branching?


答:
The approach I'd take depends on your current needs. Since you're making a process change, it sounds like there's a problem that you're trying to solve. What problem(s) you are trying to solve will change the approach that you take. Eventually, to achieve a good continuous integration environment, you'd want to address all of these issues.

Can you build easily? Your build should be executed by a single command to something like a Makefile or an Ant script or a Maven script, depending on your language and target platform. Simply executing this script should do a complete rebuild and execute any tests that you have. If you don't have this, creating one would quickly make the manual process less painful.

Is your build slow? If your build is slow, I'd look at either starting a regular (nightly?) build or improving your build time as the first step. If you check in to an integration or alpha branch at least once a day, a nightly build would be sufficient. Every night, your build starts and your quality assurance team has a fresh build to work on every morning without downtime in the day waiting for the build to be kicked off manually. If you don't check in every day, it would probably be better to check to see if there are updates before building. The other option would be to improve build performance so that manual builds take less time to execute. When you move to automation, it will allow you to see the results of the build/test cycle faster.

Is your quality poor? If you have poor quality (unstable software, defects detected after shipping), focus on improving and automating your tests first. Create unit tests that can be automatically run (once you automate your build process) and give instantaneous feedback to developers. Also work on automating integration and acceptance tests as much as possible so they can be executed and provide feedback to the developers and quality assurance teams.

There are probably other questions that you can ask, depending on your individual situation. But take it slow. Implement one aspect of a continuous integration culture at a time - automated builds, automated tests, fast builds, instantaneous feedback, visible results of build/test cycles, and automated deployment - starting with the ones that will add the most value to your team.

Title: How do I get from a highly manual process of development and deploy to continuous integration?

Body: We have a development process which is completely manual. No unit tests, interface tests are manual, and merging and integration are as well. How could we go from this state to implementing continuous integration with full (or at least close to full) automation of build and test? We have a pretty intense development cycle, and are not currently using agile, so switching to agile with CI in one move would be a very complicated and expensive investment. How can we take it slowly, and still moving constantly towards a CI environment?</p>


答:
SVN "cheap copies and branches" is explained in the manual ( http://svnbook.red-bean.com/en/1.1/ch04s02.html ). Relevant section:

Cheap Copies

Subversion's repository has a special design. When you copy a directory, you don't need to worry about the repository growing huge—Subversion doesn't actually duplicate any data. Instead, it creates a new directory entry that points to an existing tree. If you're a Unix user, this is the same concept as a hard-link. From there, the copy is said to be “lazy”. That is, if you commit a change to one file within the copied directory, then only that file changes—the rest of the files continue to exist as links to the original files in the original directory.

This is why you'll often hear Subversion users talk about “cheap copies”. It doesn't matter how large the directory is—it takes a very tiny, constant amount of time to make a copy of it. In fact, this feature is the basis of how commits work in Subversion: each revision is a “cheap copy” of the previous revision, with a few items lazily changed within. (To read more about this, visit Subversion's website and read about the “bubble up” method in Subversion's design documents.)

Of course, these internal mechanics of copying and sharing data are hidden from the user, who simply sees copies of trees. The main point here is that copies are cheap, both in time and space. Make branches as often as you want.

Note that this isn't how CVS works. Copies in CVS are "expensive", both in the time it takes to create the branch, and the disk space it takes up.


问:
Selling your services when you use uncommon technologies
I took a look in Stack Overflow most popular profiles, and then I did the same in several other sites, and then I took a look in job postings in several boards, mostly out of curiosity, because I noticed this:

If you work with Java, .NET or other managed languages, or you work with stuff that is popular for web development (Ruby, JavaScript, etc...) you can get lots of points on Stack Overflow, find lots of jobs and clients, find forums, friends, colleagues, etc...

But how a programmer of uncommon languages (Lua, pure C, Lisp, D, ADA, Haskell, etc...) find information, sell his services, and so on?

EDIT: This also applies to fields:

You work with web, corporate software, database, etc... it is great...

You dislike those previous 3, no one ever will hire your services...

答:
You have to look for the jobs, and you have to be prepared to live somewhere that there are those jobs. If you do ADA expect to live in a state with a biog aerospace/defense industry - not on a beach in the Caribbean.

There are fewer jobs for specialized roles - but there are also fewer candidates competing for them.

Finally you need to publicize yourself, write blogs, write articles, speak at conferences.


答:
It seems that your understanding is that the way of selling our services is based on StackOverflow's reputation. From my point of view, SO's reputation doesn't say how good you are at specific technologies, it says how good are your contributions to the community (and, further on, how keen you are to contribute and help others to find solutions).

There are thousands (maybe millions) of really good and experienced developers out there with low reputation in StackOverflow and that doesn't mean they aren't good developers (or that they aren't able to sell their services). I agree that sometimes you find some recruiters that when see a high reputation in SO think you are pretty good at some technologies... but well, it's quite difficult to find good recruiters anyway.

Even non-common technologies have their demand, there are several things that you should do to make recruiters of those specific technologies interested in you:

Research the kind of business that may be interested in your technologies, their actual needs and try to come up with some sort of solutions.

Have some actual work (libraries, researches, etc) published somewhere either as code or as blog posts (or even both).

Make your own network: Look for people that work in the same areas, collaborate with them, grow your network with them.

Publicize: Your work must be know, it's not enough tu publish it, you must reach your potential clients.

Don't sell smoke: Be honest, do work that actually solves problems, try to be innovative and never, never stop learning.

Title: Selling your services when you use uncommon technologies

Body:
I took a look in Stack Overflow most popular profiles, and then I did the same in several other sites, and then I took a look in job postings in several boards, mostly out of curiosity, because I noticed this:

If you work with Java, .NET or other managed languages, or you work with stuff that is popular for web development (Ruby, JavaScript, etc...) you can get lots of points on Stack Overflow, find lots of jobs and clients, find forums, friends, colleagues, etc...

But how a programmer of uncommon languages (Lua, pure C, Lisp, D, ADA, Haskell, etc...) find information, sell his services, and so on?

EDIT: This also applies to fields:

You work with web, corporate software, database, etc... it is great...

You dislike those previous 3, no one ever will hire your services...


问:
Is Operator Overloading supported in C
When I read about the LCC (Windows) compiler, I found out it has the implementation for operator overloading.

However, after a bit of Googling, I've confirmed that operator overloading isn't supported in standard C, although someone's comment mentioned LCC is ANSI-compliant.

Is LCC really standard C or is it just like objective-c, a C variant with object-oriented features?

答:
Many compilers claim to be compliant to some standard or another, and then enable their own private extensions by default. As long as you disable enough extensions, you can typically get a compiler into a mode that's "compliant" to some standard.

The only C functionality that's remotely close to overloading is limited type-generic macros of <tgmath.h> in C99 and generic selection expressions in C11 as outlined on this site.

Title: Is Operator Overloading supported in C


答: No, it's an extension. You're allowed to have extensions as long as they don't conflict with the standard.</p>

Title: Is Operator Overloading supported in C

Body:
When I read about the LCC (Windows) compiler, I found out it has the implementation for operator overloading.

However, after a bit of Googling, I've confirmed that operator overloading isn't supported in standard C, although someone's comment mentioned LCC is ANSI-compliant.

Is LCC really standard C or is it just like objective-c, a C variant with object-oriented features?


答: C11 does not support operator overloading. Compilers may implement their own vendor-specific functionalities but those are not part of the C standard and as such they aren't standard compliant.</p>

Title: Is Operator Overloading supported in C


答:
It is common for compilers to support a superset of a standard and describe themselves as compliant.

As long as they handle code which conforms to the standard as the standard says they should then they are conforming.  Many compilers have a command line flag which can be turned on to treat code more strictly, rejecting code which makes use of non-standard features.  I'd imagine LCC will have such a flag.

Title: Is Operator Overloading supported in C


问:
What are bit operators good for?
Programming languages often come with various bit operators (e.g. bitwise left- and right shift, bitwise AND, OR, XOR...). These don't get used though very much, or at least such has my experience been. They are sometimes used in programming challenges or interview questions, or the solution migh require them, e.g.:

Without using any equality operator, create a function which returns true when two values are equal

Without using a third variable, swap the value of two variables

These then again, probably have few real world uses. I guess that they should be faster because they directly manipulate memory on a low level.

Why are such found in most programming languages? Any real world use cases?

答:
Not sure if this usage has been noted yet:

I see OR quite a lot when working with the illumos (openSolaris) source code to reduce multiple return values to 0 or 1, e.g.

```<code>int ret = 0;
ret |= some_function(arg, &arg2); // returns 0 or 1
ret |= some_other_function(arg, &arg2); // returns 0 or 1
return ret;
</code>```

Title: What are bit operators good for?

Body:
Not sure if this usage has been noted yet:

I see OR quite a lot when working with the illumos (openSolaris) source code to reduce multiple return values to 0 or 1, e.g.

int ret = 0;
ret |= some_function(arg, &arg2); // returns 0 or 1
ret |= some_other_function(arg, &arg2); // returns 0 or 1
return ret;


答:
I wrote a blog post on the topic of how to model IO as a form of asymmetric coroutine communicating with the runtime system for your language. (It is admittedly the third part of a series)

http://comonad.com/reader/2011/free-monads-for-less-3/

That post covers a bit of why it is awkward to reason about the semantics of 'world-passing'.

Title: Critique of the IO monad being viewed as a state monad operating on the world

Body:
The IO monad in Haskell is often explained as a state monad where the state is the world. So a value of type IO a monad is viewed as something like worldState -> (a, worldState).

Some time ago I read an article (or a blog/mailing list post) that criticized this view and gave several reasons why it's not correct. But I cannot remember neither the article nor the reasons. Anybody knows?

Edit: The article seems lost, so let's start gathering various arguments here.
I'm starting a bounty to make things more interesting.

Edit: The article I was looking for is Tackling the awkward squad: monadic input/output, concurrency, exceptions, and foreign-language calls in Haskell by Simon Peyton Jones. (Thanks to TacTics's answer.)


答:
Pick one easy goal, get success and then set another goal. IMHO your first goal should be a nightly build. A long time ago we had deployment problems because of sloppy checkins, bad version numbering, unknown dependencies etc and a nightly build solved a lot of those problems. It gave us a single reliable output for testers, installers, deployment etc. Everyone could be confident that version x.y.z was the latest successful build. No more testing old builds.

Creating a nightly build may create some people problems, you will need a strong sponsor to help you. I hit lots of objections such as 'but that's not how I like to work'. Of course, but the end users don't like the bugs in your work. A good sponsor will assist you with objections.

Creating a automated build will uncover other issues like dependency problems. When you start turning over rocks be prepared to be surprised by what you find underneath. Part of the pain of getting to automation/nightly builds/CI is getting everyone onto the same dependencies/libraries. I wish we had maven back then.

Develop a pitch for an automated build process. Try to find bug reports from the deployers or end users that could have been prevented.


问:
Suggestions needed on an architecture for a multiple clients and customisable web application
Our product is a web based course managemant system. We have 10+ clients and in future we may get more clients. (Asp.net,SQL Server)

Currently if one of our customers need extra functionality or customised business logic, we will change the db schema and code to meet the needs.

(we only have one branch code base and one database schema)

To make the change wont affect each others route, we use a client flag, which defined in a web config file, thus those extra fields and biz logic only applied to a particular customer's system.

```<code>if(ClientId = 'ABC')
{
   //DO ABC Stuff
}
else
{
   //Normal Route
}
</code>```

One of our senior colleagues said, in this way, small company like us can save resources on supporting multiple resources.

But what I feel is, this strategy makes our code and database even harder to maintain.

Anyone there crossed similar situation? How do you handle that?

答:
Create a company table in the database.  Every user gets associated with a company.  Here is some pseudo-SQL for company-customizations for displaying dates, time-zone, fiscal offset, and contact-person:

```<code>table user:
id
company_id
... other fields ...
foreign key (company_id)

table company:
id
date_format
time_zone
fiscal_offset
contact_person
... other customization fields ...
</code>```

You probably need to query the user and company for most screens in order to test for customizations.  Pulling a single record from the database for a screen should take no more than 5ms.

I understand that you don't want to introduce complexity, but having company-specific code for each client littered through your application is already complexity.  Better to incorporate this officially into your database model, than to wake up one day with 100 one-off company customizations littered throughout the code.  At least this puts them all in one place, and by looking at these settings on the company-edit screen, your testers can easily see what they need to think about when testing for different companies.

Body:
Create a company table in the database.  Every user gets associated with a company.  Here is some pseudo-SQL for company-customizations for displaying dates, time-zone, fiscal offset, and contact-person:

table user:
id
company_id
... other fields ...
foreign key (company_id)

table company:
id
date_format
time_zone
fiscal_offset
contact_person
... other customization fields ...

You probably need to query the user and company for most screens in order to test for customizations.  Pulling a single record from the database for a screen should take no more than 5ms.

I understand that you don't want to introduce complexity, but having company-specific code for each client littered through your application is already complexity.  Better to incorporate this officially into your database model, than to wake up one day with 100 one-off company customizations littered throughout the code.  At least this puts them all in one place, and by looking at these settings on the company-edit screen, your testers can easily see what they need to think about when testing for different companies.


答:
See Tackling the Awkward Squad.

The big reason is RealWorld state models of the IO monad don't work well with concurrency. SPJ in this readable classic favors using an operational semantics to understand it.


问:
Has "Not everyone can be a programmer" been studied?
An old adage that many programmers stick to is "It takes a certain type of mind to learn programming, and not everyone can do it."

Now I'm sure that we all have our own trove of anecdotal evidence, but has this been studied scientifically?

答:
Yes, there's a pretty famous paper online designed to more or less determine "Who is cut out to be a programmer."

A cognitive study of early learning of programming - Prof Richard Bornat, Dr. Ray Adams

All teachers of programming find that their results display a 'double
hump'. It is as if there are two populations: those who can [program],
and those who cannot [program], each with its own independent bell
curve.

Almost all research into programming teaching and learning have
concentrated on teaching: change the language, change the application
area, use an IDE and work on motivation. None of it works, and the
double hump persists.

We have a test which picks out the population
that can program, before the course begins. We can pick apart the
double hump. You probably don't believe this, but you will after you
hear the talk. We don't know exactly how/why it works, but we have
some good theories.

Here's a blog post by Jeff Atwood that interprets the results and puts some things into context.

Despite the enormous changes which have taken place since electronic
computing was invented in the 1950s, some things remain stubbornly the
same. In particular, most people can't learn to program: between 30%
and 60% of every university computer science department's intake fail
the first programming course.

Experienced teachers are weary but never
oblivious of this fact; brighteyed beginners who believe that the old
ones must have been doing it wrong learn the truth from bitter
experience; and so it has been for almost two generations, ever since
the subject began in the 1960s.


答:
The main complaint about RealWorld state models is that, as TacTics says, world-passing doesn't necessarily work with concurrency. But Wouter Swierstra and Thorsten Altenkirch showed how to reason about concurrency as "world-passing" effect, with a fixed-but-arbitrary sequence of interleaving threads in their paper "Beauty in the Beast: A Functional Sematics for the Awkward Squad": http://www.staff.science.uu.nl/~swier004/Publications/BeautyInTheBeast.pdf

The code corresponding to this is on Hackage as IOSpec: http://hackage.haskell.org/package/IOSpec

I think Wouter's thesis goes into more detail: http://www.staff.science.uu.nl/~swier004/Publications/Thesis.pdf


问:
Figuring a max repetitive sub-tree in an object tree
I am trying to solve a problem of finding a max repetitive sub-tree in an object tree.

By the object tree I mean a tree where each leaf and node has a name.
Each leaf has a type and a value of that type associated with that leaf.
Each node has a set of leaves / nodes in certain order.

Given an object tree that - we know - has a repetitive sub-tree in it.

By repetitive I mean 2 or more sub-trees that are similar in everything (names/types/order of sub-elements) but the values of leaves. No nodes/leaves can be shared between sub-trees.

Problem is to identify these sub-trees of the max height.

I know that the exhaustive search can do the trick. I am rather looking for more efficient approach.

答:
You could trade off some storage for computation:

On insert check for similarity with parent and if found, copy "similar tree counter" from parent and increment for child. What you do with that is up to you. Either leave it in a tree or a keep a map somewhere indexed on the head of each sub-tree.

At minimum you're only doing n-1 comparisons, not counting whatever accounting you choose to do to keep track of the sub-trees.


问:
What Does It Usually Mean for a Feature to be "Supported"?
I'm currently working some testing for a particular area of an application. I had to write some automated tests for a particular feature but due to the circumstances, this was not easy to do. When I asked one of the other testers about it, he mentioned that the same features exist in a sister application our company produces but isn't documented anywhere (end-user documentation or otherwise). He also said that the feature doesn't typically get tested at all in the sister application and isn't usually tested in the application I work on. Apparently this feature isn't heavily used but removing it would require a fair bit of work so the benefit-cost ratio doesn't work out.

All of this has left me with some questions. Other than "The documentation says so" or "We told the client it is", what usually makes a feature "supported" versus an unsupported feature?

答:
what usually makes a feature "supported" versus an unsupported feature?

Commitment by the developer. If some program happens to be able to import XML but the developer doesn't plan to support that feature going forward, users should expect it to break at any moment, or not to work at all. On the other hand, if the developer says that the feature is supported, users can expect that feature to be tested and to work properly. If the feature doesn't work, users can rightly complain that the software doesn't do what the developer says it does.


问:
Interfaces on an abstract class
My coworker and I have different opinions on the relationship between base classes and interfaces.  I'm of the belief that a class should not implement an interface unless that class can be used when an implementation of the interface is required.  In other words, I like to see code like this:

```<code>interface IFooWorker { void Work(); }

abstract class BaseWorker {
    ... base class behaviors ...
    public abstract void Work() { }
    protected string CleanData(string data) { ... }
}

class DbWorker : BaseWorker, IFooWorker {
    public void Work() {
        Repository.AddCleanData(base.CleanData(UI.GetDirtyData()));
    }
}
</code>```

The DbWorker is what gets the IFooWorker interface, because it is an instantiatable implementation of the interface.  It completely fulfills the contract.  My coworker prefers the nearly identical:

```<code>interface IFooWorker { void Work(); }

abstract class BaseWorker : IFooWorker {
    ... base class behaviors ...
    public abstract void Work() { }
    protected string CleanData(string data) { ... }
}

class DbWorker : BaseWorker {
    public void Work() {
        Repository.AddCleanData(base.CleanData(UI.GetDirtyData()));
    }
}
</code>```

Where the base class gets the interface, and by virtue of this all inheritors of the base class are of that interface as well.  This bugs me but I can't come up with concrete reasons why, outside of "the base class cannot stand on its own as an implementation of the interface".

What are the pros & cons of his method vs. mine, and why should one be used over another?

答:
I'd have to agree with your coworker.

In both examples you give, BaseWorker defines the abstract method Work(), which means that all subclasses are capable of meeting IFooWorker's contract.  In this case, I think BaseWorker should implement the interface, and that implementation would be inherited by its subclasses.  This will save you from having to explicitly indicate that each subclass is indeed an IFooWorker (the DRY principle).

If you weren't defining Work() as a method of BaseWorker, or if IFooWorker had other methods that subclasses of BaseWorker wouldn't want or need, then (obviously) you'd have to indicate which subclasses actually implement IFooWorker.

Title: Interfaces on an abstract class


答:
Supported can mean anything from, we have full ISOxxxx accreditation for that fully tested feature which all our customers are using - through to - we think an intern worked on that a couple of years ago.

Unsupported can mean anything from, we haven't yet received full ISOxxxx accreditation for that fully tested feature which all our customers are using - through to - we think an intern worked on that a couple of years ago.

Title: What Does It Usually Mean for a Feature to be "Supported"?

Body:
I'm currently working some testing for a particular area of an application. I had to write some automated tests for a particular feature but due to the circumstances, this was not easy to do. When I asked one of the other testers about it, he mentioned that the same features exist in a sister application our company produces but isn't documented anywhere (end-user documentation or otherwise). He also said that the feature doesn't typically get tested at all in the sister application and isn't usually tested in the application I work on. Apparently this feature isn't heavily used but removing it would require a fair bit of work so the benefit-cost ratio doesn't work out.

All of this has left me with some questions. Other than "The documentation says so" or "We told the client it is", what usually makes a feature "supported" versus an unsupported feature?


答: I usually take "supported" literally:  It means the responsible party (programmer/group/company) intends to support users of the feature when they encounter problems with it.  Support can be in the form of direct help, debugging, releasing bug fixes, providing documentation, etc.  On the other hand, "Unsupported" tends to mean 'it may work, but don't complain to us if something goes wrong.'</p>


问:
How to write reusable code in node.js
I am trying to understand how to design node.js applications, but it seems there is something I can't grasp about asynchronous programming.

Let's say my application needs to access a database. In a synchronous environment I would implement a data access class with a read() method, returning an associative array.

In node.js, because code is executed asynchronously, this method can't return a value, so, after execution, it will have to "do" something as a side effect. It will then contain some code which does something else than just reading data.

Let's suppose I want to call this method multiple times, each time with a different success callback. Since the callback is included in the method itself, I can't find a clean way to do this without either duplicating the method or specifying all possible callbacks in a long switch statement.

What is the proper way to handle this problem? Am I approaching it the wrong way?

答:
Since you can pass functions as parameters, it is common to pass a "callback" function to these sorts of functions.  So, for example, you may have a "read" function that looks like this:

```<code>function getUser(userId, callback) {
  var mydbAPI = something;
  var myQuery = somethingElse;

  mydbAPI.getUser(myQuery, function(data) {
    //parse data a little here:
    myParsedData = ...;

    callback(myParsedData);
  });
}
</code>```

You can then call the read method like this:

```<code>getUser(userId, function(parsedData) {
  //...do something with parsedData
});
</code>```

Title: How to write reusable code in node.js

Body:
Since you can pass functions as parameters, it is common to pass a "callback" function to these sorts of functions.  So, for example, you may have a "read" function that looks like this:

function getUser(userId, callback) {
  var mydbAPI = something;
  var myQuery = somethingElse;

  mydbAPI.getUser(myQuery, function(data) {
    //parse data a little here:
    myParsedData = ...;

    callback(myParsedData);
  });
}

You can then call the read method like this:

getUser(userId, function(parsedData) {
  //...do something with parsedData
});


问:
Plug-in based software design
I'm a software developer who is willing to improve his software design skills. I think software should not only work but have a solid and elegant design too to be reusable and extensive to later purposes.

Now I'm in search of some help figuring out good practices for specific problems.
Actually, I'm trying to find out how to design a piece of software that would be extensible via plug-ins.

The questions I have are the following:

Should plug-ins be able to access each others functionality? This would bring dependencies I guess.

What should the main application offer to the plug-ins if I want to let's say develop a multimedia software which would play videos and music but which could later on get functionality added over plug-ins that would let's say be able to read video status (time, bps, ...) and display it. Would this mean that the player itself would have to be part of the main program and offer services to plug-ins to get such information or would there be a way to develop the player as a plug-in also but offer in some way the possibility to other plug-ins to interact with it?

As you see, my questions are mainly for learning purposes as I strive to improve my software development skills.

I hope to find help here and apologize if something is wrong with my question.

答:
Pretty much any software that "wants" to be extended over time, by multiple contributors who are not closely linked or coordinating, can benefit from a plug-in architecture of some sort. Common examples are operating systems, CAD and GIS tools, drawing and image manipulation tools, text editors and word processors, IDEs, web browsers, web content management systems, and programming language and frameworks. Plugins are the mainstay of extensible systems.

Plug-in architectures typically use duck typing. The architect defines a common set of methods (e.g. open, close, play, stop, seek, etc.), which each plugin then implements (either entirely or in part). Some methods are mandatory, while others may be optional, or useful only in specific cases.

When the main program initially runs, it checks one or more "plugin areas" (such as known ./plugins directories) for the existence of plugins. Those found are loaded into the program.

Often plugins must exist at the time the main program runs. The Unix kernel and the Apache web server typically operate this way; they must be restarted to "see" and use new plugins. Plugins may be more dynamic however; here the main program periodically re-checks for newly-added or changed plugins (for example by comparing a stored plugins-last-loaded timestamp with the "last modified" timestamp for a plugins directory). The main program would then (re-)load plugins--either all of them, in the simple/naive case, or just the new/changed ones, if it's more sophisticated.

There is often a "registration" requirement, with each plugin not just being code, but also including some metadata that communicates how the plugin integrates into the whole. A music player plugin, for example, might be required to state what kind(s) of files it can play, what processor architecture(s) it can run on, what resources it needs (e.g. how much memory it needs to be allocated), and other attributes required for the main program to decide which plugin to use to play which file.

The mechanisms for plugin registration, loading, and interaction with the main program is quite language- and framework-specific. Because there's a lot of "orchestration" going on, with some functions handled by the main program and some by its plugins (of which there might be quite a few), setting up a program for extensibility requires care and consideration, and an architectural view of the program as "a system" rather than "a single piece of code."

Most large-scale projects will have already chosen a plugin framework, or designed their own. There are also a number of generic plugin frameworks designed to simplify making your program into an extensible system.

(Answer to Question 1) While plug-ins can use each other's functionality, they typically would do so through the pre-defined methods/APIs the architect laid out. The use of such "duck typing" helps avoid super-interdependency, and means that it's not necessarily clear whether a given feature is provided by "core" code or a plugin. Indeed, having adopted a plug-in strategy, many developers implement even "core" features as plugins--just ones that are shipped with the main program. While having spaghetti tangles of plugins isn't ideal, it's not uncommon to see some plug-ins requiring the existence of other plug-ins.

(Answer to Question 2) As an architect, the main thing you offer plugins is an architecture--e.g. a set of methods via which they are setup, registered, and invoked, and a design and set of requirements in which the plugins will operate. The main program, while running, usually exposes many if not all of its internal data structures and methods to plugins. This is obviously a security exposure. A number of sandboxing techniques can be (and
increasingly are being) used, but most often, plugins are "trusted" code, operating as
if they are part of the main program.

For further reading:

Wikipedia's plug-in page is worth studying.

A good walkthrough of how you might make an editor extensible using the Yapsy plugin framework.

Explanation of a bare-bones plug-in system for Python

Title: Plug-in based software design


答:
I hate to be the one to break it to you, but the things individuals value rarely align with the things society values.  People succeed in business not by selling what they want to sell, but by selling what other people want to buy.  Otherwise, we'd all be making six figures selling professional couch potato services.  If work wasn't work they would call it something else.

Part of your issue is you're putting the cart before the horse by worrying about the technology instead of the problem.  Customer's don't care what language you use as long as their problem gets solved.  Self-employed people have a lot of flexibility along those lines, but it comes with instability.  If you want more stability, you have to deal with more restrictions.  That's just how it is.  Find the least objectionable thing someone will agree to pay you to do, and do it.


问:
What's the next level of abstraction?
Since programming languages initially only used lines of code executed sequentially, and it evolved into including functions which were one of the first levels of abstraction, and then classes and objects were created to abstract it even further; what is the next level of abstraction?

What's even more abstract than classes or is there any yet?

答:
For many, the purest form of code abstraction in the current era of binary programming is the "higher-order function". Basically, the function itself is treated as data, and functions of functions are defined, much as you would see them in mathematical equations with operators defining the result of their operands and a predetermined order of operations defining the "nesting" of these operations. Math has very very few "imperative commands" in its structure; the two examples I can think of are "let x have some value or be any value conforming to some constraint", and "piecewise functions" in which the input determines the expression needed to produce the output. These constructs are easily representable as their own functions; the "function" x always returns 1, and "overloads" of functions are defined in terms of what is passed to them (which unlike object-oriented overloads can be defined based on values input) allowing "piecewise" evaluation of a named group of functions, even in terms of themselves. As such, the program does away with the notion of imperatives at the low level, and instead focuses on "evaluating itself" given input data.

These higher-order functions form the backbone of "functional languages"; what a program does is defined in terms of "pure functions" (one or more inputs, one or more outputs, no side effects or "hidden state"), which are nested into each other and evaluated as necessary. In such cases, most "imperative logic" is abstracted away; the runtime handles the actual calling of functions, and any conditions in which one or the other overload of a function may need to be called. In such a program, the code isn't thought of as "doing" something, it's thought of as "being" something, and what exactly it is is determined as the program runs given initial input.

Higher-order functions are now a staple of many imperative languages as well; .NET's lambda statements basically allow for "anonymous" functional input into another "function" (implemented imperatively but theoretically it doesn't have to be), thus allowing for highly-customizable "chaining" of very general-purpose "functions" to achieve the desired result.

Another abstraction commonly seen in the latest round of programming languages is dynamic variable typing based on the concept of "duck-typing"; if it looks like a duck, swims like a duck, flies like a duck and quacks like a duck, you can call it a duck. Doesn't matter if it's actually a mallard or a canvasback. It MIGHT matter if it's actually a goose or a swan, but then again it might not matter if all you care about is that it swims and flies, and kinda looks like a duck. This is considered the ultimate in object inheritance; you don't care what it is, except to give it a name; what's more important is what it does. In such languages there are basically only two types; the "atom", a single element of information (one "value"; a number, character, function, whatever), and the "tuple", composed of an atom and a "pointer" to everything else in the tuple. Exactly how these types are implemented in binary by the runtime is irrelevant; using these, you can achieve the functionality of virtually every type you can think of, from simple value types to strings to collections (which, since values can be of different "types", allows for "complex types" aka "objects").

Title: What's the next level of abstraction?


问:
Questions to ask before someone leaves
Apart from the obvious questions relating to specific project work someone is working on are there any questions I should be asking a fellow dev who is leaving the company?

So far I am thinking about;

Locations of things on the server he uses that not maybe everyone does.

Credentials he has set up that we wouldn't have needed.

Client details he has not yet saved into our CRM system.

答:
Whatever you ask him, record it.  You will eventually need every little detail and you cannot remember it all even when writing it down.

Video conference, screen capture, you name it.

And then tell him to show you it all....

Title: Questions to ask before someone leaves


答:
You can hash your sub-trees:  for each node, generate a hash value based on the values of interest (i.e., excluding leaf values) and the hash values of its children, in order.

Use this hash to insert your nodes into an appropriately-sized hash table, and check collisions to determine which are actually repetitive, and which are accidental.

Title: Figuring a max repetitive sub-tree in an object tree

Body:
I am trying to solve a problem of finding a max repetitive sub-tree in an object tree.

By the object tree I mean a tree where each leaf and node has a name.
Each leaf has a type and a value of that type associated with that leaf.
Each node has a set of leaves / nodes in certain order.

Given an object tree that - we know - has a repetitive sub-tree in it.

By repetitive I mean 2 or more sub-trees that are similar in everything (names/types/order of sub-elements) but the values of leaves. No nodes/leaves can be shared between sub-trees.

Problem is to identify these sub-trees of the max height.

I know that the exhaustive search can do the trick. I am rather looking for more efficient approach.


问:
LGPL License in commercial application
I have searched around but I don't seem to be able to get a clear answer on my questions that I understand.
I want to use the Xuggler library in my application, which is licensed either GPL or LGPL depending on whether I compile it myself. I don't intend to edit the library

If I compile it myself and thus get a LGPL version of the library, can I use it in a commercial application without having to distribute the source code of my application?
Furthermore, do I have to give my application the LGPL license as well?
What other problems might using this library give me?

答:
In simple terms, as I understand things (I'm not a lawyer, but the licenses aren't that hard to read):

LGPL - You can use and distribute the library with your application, with the stipulation that you have to mention the GPL and LGPL and the library in your notices, and that you have to make the LIBRARY source available to anyone that you sell or give the application to. This includes building the library into your program. Note that if you change the library, you'll need to make that modified source code available.

GPL - you pretty much can only use a GPL library in a GPL program. If you distribute a GPL program, you pretty much have to distribute the source (including any modification you made).

Title: LGPL License in commercial application


答:
Another study, Investigating the viability of mental models held by novice programmers:

This paper describes an investigation into the viability of mental models used by novice programmers at the end of a first year Java programming course. The qualitative findings identify the range of mental models of value and reference assignment held by the participants. The quantitative analysis reveals that approximately one third of students held non-viable mental models of value assignment and only 17% of students held a viable mental model of reference assignment. Further, in terms of a comparison between the participants' mental models and their performance in in-course assessments and final examination, it was found that students with viable mental models performed significantly better than those with non-viable models. These findings are used to propose a more "constructivist" approach to teaching programming based on the integration of "cognitive conflict" and program visualisation.

Also, see later research from the same authors of the Sheep vs Goats study (which was never actually published, to be clear). Their last and most recent study on this topic from 2009 is Meta-analysis of the effect of consistency on success in early learning of programming (pdf).

A test was designed that apparently examined a student's knowledge of assignment and sequence before a first course in programming but in fact was designed to capture their reasoning strategies. An experiment found two distinct populations of students: one could build and consistently apply a mental model of program execution; the other appeared either unable to build a model or to apply one consistently. The first group performed very much better in their end-of-course examination than the second in terms of success or failure. The test does not very accurately predict levels of performance, but by combining the result of six replications of the experiment, five in UK and one in Australia, we show that consistency does have a strong effect on success in early learning to program -- but background programming experience, on the other hand, has little or no effect.

Title: Has "Not everyone can be a programmer" been studied?

Body:
An old adage that many programmers stick to is "It takes a certain type of mind to learn programming, and not everyone can do it."

Now I'm sure that we all have our own trove of anecdotal evidence, but has this been studied scientifically?


答:
I think you have some misconceptions about the history of computing.

The first abstraction (in 1936) was, in fact, Alonzo Church's Lambda Calculus, which is the foundation for the concept of high-order functions and all of the functional languages that followed. It directly inspired Lisp (the second oldest high-level programming language, created in 1959), which in turn inspired everything from ML to Haskell and Clojure.

The second abstraction was procedural programming. It came out of the von Neumann computer architectures where sequential programs were written, one instruction at a time. FORTRAN (the oldest high-level programming language, 1958) was the first high-level language to come out of the procedural paradigm.

The third abstraction was probably actually declarative programming, first exemplified by Absys (1967), and then later Prolog (1972). It is the foundation of logic programming, where expressions are evaluated by matching a series of declarations or rules, rather than executing a series of instructions.

The fourth abstraction then was object-oriented programming, which made its first appearance in Lisp programs in the 60's, but was later exemplified by Smalltalk in 1972. (Though there seems to be some debate as to whether the message-passing style of Smalltalk is the One True object-oriented abstraction. I'm not going to touch that.)

All other abstractions, especially on the traditional von Neumann computer architecture, are variations on those four themes. I'm not convinced that there is another abstraction beyond those four that is not merely a variation or a combination of them.

But an abstraction is, in essence, merely a way to model and describe an algorithm. You can describe algorithms as a series of discrete steps, as a set of rules which must be obeyed, as a set of mathematical functions, or as interacting objects. It's very hard to conceive of any other way to describe or model algorithms, and even if there is, I'm not convinced of its utility.

There is, however, the quantum computing model. In quantum computing, new abstractions are necessary to model quantum algorithms. Being a neophyte in this area, I can't comment on it.

Title: What's the next level of abstraction?

Body:
Since programming languages initially only used lines of code executed sequentially, and it evolved into including functions which were one of the first levels of abstraction, and then classes and objects were created to abstract it even further; what is the next level of abstraction?

What's even more abstract than classes or is there any yet?


答:
If I understand you correctly, your "ascending abstractions" can be thought of as increasingly large encapsulations of logic, mostly related to code reuse.

From specific instructions executed one after the other, we move to functions/subroutines, which encapsulate, or abstract, a logical grouping of instructions into a single element.  Then we have objects, or modules, which encapsulate subroutines relating to a certain logical entity or category, so I can group all string operations under the String class, or all common math operations under the Math module (or static class, in languages such as C#).

So if that's our progression, what comes next? Well, I don't think you have a clear-cut next step. As others have answered, your progression applies only to imperative/procedural programming styles, and other paradigms don't share your concepts of abstraction. But if I there's something that can logically extend your metaphor, it's services.

A service is similar to a class in the sense that it's an entity that exposes functionality, but it implies a much stricter separation of concerns than the back-and-forth with objects you instantiated yourself. They expose a limited set of operations, hide the internal logic, and are not even necessarily running on the same machine.

Again, there is a fine distinction. In most cases, you will use an object that acts as a proxy to a service, and the two will be very similar, but as an architecture, the two are distinct.

Title: What's the next level of abstraction?


答:
Anyone can be a programmer. Consider how easily people grasp spreadsheets. Consider how readily Alan Kay introduces children to programming by means of experiment and exploration in a programmable environment.

People may study success in college-level courses and conclude "some people aren't fit to learn programming". However, such a conclusion severely oversteps the bounds of the observed evidence. How much failure could instead be attributed to how the programming is taught (too abstract?), or which style of programming is taught (too imperative?), or the programming environment (compilation, no immediate feedback?).

It is well understood that people grasp abstractions most readily after they've already worked with multiple concrete instances - i.e. that we cannot learn something until we almost already know it. Starting with the abstract, therefore, is an entirely foolish way to teach programming. Many people who stumble over premisconceived "mental models" would thrive if taught in a more concrete environment with real-time feedback (e.g. as in the Kahn Academy for CS) then encouraged to climb the ladder of abstraction when they are ready for it. Learnable Programming is a recent essay by Bret Victor draws attention to unnecessary environmental challenges programmers face in learning.

In some cases, it is the students that fail their classes. Intellectual laziness and willful ignorance will exist in any large group of humans. Smart folk are no exception, as anyone who has argued with a brilliant crank can attest. But, especially for programming and maths, it is often the classes that are failing the students.


答:
Disclaimer

IANAL.  Assuming LGPL 2.  God help you with version 3.

Answer

You do not need to license your code that uses the library as GPL or LGPL, but you need to permit modification of the combined work (meaning your code and the library together) as well as reverse-engineering for debugging such modifications.  You still have to honor the other aspects of the LGPL for the library which uses it (not for your code that uses the library).

Justification

Section 6 of the LGPL v. 2.0 says,

you may also compile or link a 'work that uses the Library' with the
Library to produce a work containing portions of the Library, and
distribute that work under terms of your choice, provided that the
terms permit modification of the work for the customer's own use and
reverse engineering for debugging such modifications.

I believe that when they say, "modification of the work" they mean the combined "work that uses the library" which means you have to permit modification of the combined work as well as reverse-engineering for debugging such modifications.

Additional Thoughts

The company I work for specifically does not want to permit modification or reverse engineering of their proprietary code, so we do not distribute any LGPL code with our application.  Neither will we distribute any GPL code unless it specifies the Classpath/Linking Exception.

The GPL 2 with the Classpath/Linking Exception is similar to the LGPL, except it does not impose those restrictions on a combined work.  The last section of that Wikipedia article backs me up on this.

In my mind, the GPL 2 with the Classpath/Linking Exception has roughly the same intention as the Apache 2 license, but the Apache license is much clearer about it.  I believe that the GPL 3 is worded to prevent the Classpath/Linking Exception.

Title: LGPL License in commercial application

Body:
I have searched around but I don't seem to be able to get a clear answer on my questions that I understand.
I want to use the Xuggler library in my application, which is licensed either GPL or LGPL depending on whether I compile it myself. I don't intend to edit the library

If I compile it myself and thus get a LGPL version of the library, can I use it in a commercial application without having to distribute the source code of my application?
Furthermore, do I have to give my application the LGPL license as well?
What other problems might using this library give me?