答:
Edsger Dijkstra made a note about != vs. < in chapter 8 of his "Discipline of Programming", page 56:

Prior to my getting used to these formal developments I would always have used "j < n" as the guard for this repetitive construct, a habit I still have to unlearn, for in case like this, the guard "j != n" is certainly to be preferred. The reason for the preference is twofold. The guard "j != n"allows us to conclude "j = n" upon termination without an appeal to the invariant relation P and thus simplifies the argument about what the whole construct achieves for us compared with the guard "j < n". Much more important, however, is that the guard "j != n" makes termination dependent upon (part of) the invariant relation, viz. "j <= n", and is therefore to be preferred for reasons of robustness. If the addition "j := j + 1" would erroneously increase j too much and would establish "j > n", then the guard "j < n" would give no alarm, while the guard "j != n" would at least prevent proper termination. Even without taking machine malfunctioning into account, this argument seems valid.

I promptly stopped using < in my loop termination conditions after reading this note some 25 years ago.

EDIT This note follows a discussion of a program that finds a maximum of a function f(k) in the range [0..n):

```<code>k, j := 0, 1;
do j != n --> if f(k) >= f(j) --> j := j + 1
              [] f(k) <= f(j) --> k, j := j, j + 1 fi od
</code>```

This unusual notation adopted in his book roughly corresponds to this program:

```<code>int k = 0, j = 1;
while (j != n) {
    if (f(k) <= f(j)) k = j;
    j++;
}
</code>```

Body:
Edsger Dijkstra made a note about != vs. < in chapter 8 of his "Discipline of Programming", page 56:

Prior to my getting used to these formal developments I would always have used "j < n" as the guard for this repetitive construct, a habit I still have to unlearn, for in case like this, the guard "j != n" is certainly to be preferred. The reason for the preference is twofold. The guard "j != n"allows us to conclude "j = n" upon termination without an appeal to the invariant relation P and thus simplifies the argument about what the whole construct achieves for us compared with the guard "j < n". Much more important, however, is that the guard "j != n" makes termination dependent upon (part of) the invariant relation, viz. "j <= n", and is therefore to be preferred for reasons of robustness. If the addition "j := j + 1" would erroneously increase j too much and would establish "j > n", then the guard "j < n" would give no alarm, while the guard "j != n" would at least prevent proper termination. Even without taking machine malfunctioning into account, this argument seems valid.

I promptly stopped using < in my loop termination conditions after reading this note some 25 years ago.

EDIT This note follows a discussion of a program that finds a maximum of a function f(k) in the range [0..n):

k, j := 0, 1;
do j != n --> if f(k) >= f(j) --> j := j + 1
              [] f(k) <= f(j) --> k, j := j, j + 1 fi od

This unusual notation adopted in his book roughly corresponds to this program:

int k = 0, j = 1;
while (j != n) {
    if (f(k) <= f(j)) k = j;
    j++;
}


问:
Is the phrase "never reinvent the wheel" suitable for students?
I find myself constantly running into this expression "don't reinvent the wheel" or "never reinvent the wheel" when I ask some questions on SO.  They tell you to use some frameworks or existing packages.  I know where this attitude is coming from since it's unwise to waste time on something others have already solved.  Or it that so?

As a student,  I find by using some code others wrote to solve my problem I can't learn as much as I'd like to, and I gain less insight.  And sometimes I think that phrase is mainly for working programmers facing deadlines and not for students like me.

Is it that bad to "reinvent the wheel"?  Maybe I'm thinking it wrong? Maybe there is a way I can avoid reinventing the wheel and at the same time learn a lot?

答:
The Hacker Jargon Lexikon has a very good comment on reinventing the wheel:

To design or implement a tool equivalent to an existing one or part of
  one, with the implication that doing so is silly or a waste of time.
  This is often a valid criticism. On the other hand, automobiles don't
  use wooden rollers, and some kinds of wheel have to be reinvented many
  times before you get them right. On the third hand, people reinventing
  the wheel do tend to come up with the moral equivalent of a trapezoid
  with an offset axle.

So it might be good to reinvent the wheel, but make sure that you look at other's solutions before or after doing it.

ContentLicense: CC BY-SA 3.0


问:
Advantages and disadvantages of building a single page web application
I'm nearing the end of a prototyping/proof of concept phase for a side project I'm working on, and trying to decide on some larger scale application design decisions.  The app is a project management system tailored more towards the agile development process.  One of the decisions I need to make is whether or not to go with a traditional multi-page application or a single page application.

Currently my prototype is a traditional multi-page setup, however I have been looking at backbone.js to clean up and apply some structure to my Javascript (jQuery) code.  It seems like while backbone.js can be used in multi-page applications, it shines more with single page applications.  I am trying to come up with a list of advantages and disadvantages of using a single page application design approach.  So far I have:

Advantages

All data has to be available via some sort of API - this is a big advantage for my use case as I want to have an API to my application anyway. Right now about 60-70% of my calls to get/update data are done through a REST API.  Doing a single page application will allow me to better test my REST API since the application itself will use it.  It also means that as the application grows, the API itself will grow since that is what the application uses; no need to maintain the API as an add-on to the application.

More responsive application - since all data loaded after the initial page is kept to a minimum and transmitted in a compact format (like JSON), data requests should generally be faster, and the server will do slightly less processing.

Disadvantages

Duplication of code - for example, model code.  I am going to have to create models both on the server side (PHP in this case) and the client side in Javascript.

Business logic in Javascript - I can't give any concrete examples on why this would be bad but it just doesn't feel right to me having business logic in Javascript that anyone can read.

Javascript memory leaks - since the page never reloads, Javascript memory leaks can happen, and I would not even know where to begin to debug them.

There are also other things that are kind of double edged swords.  For example, with single page applications, the data processed for each request can be a lot less since the application will be asking for the minimum data it needs for the particular request, however it also means that there could be a lot more small request to the server.  I'm not sure if that is a good or bad thing.

What are some of the advantages and disadvantages of single page web applications that I should keep in mind when deciding which way I should go for my project?

答:
There's one all-important client that never runs Javascript: Google crawler (as of 2012). (Bing's doesn't run JS either, I suppose.)

You will need to provide a reasonable non-AJAX version of every page that needs to be indexed, or links to a page that needs to be indexed.

If your site is small, you can provide very basic versions of the few pages just for indexing bots.

If most of the site's content is only for registered users, or need not be indexed for some other reasons, you can create the entire non-indexed space as a one-page app, with your own search, blackjack, etc.

If neither of these, you're probably better off developing a multi-page site from the start, and only providing AJAX updates where it does not change the 'general purpose' of the page.


问:
Is the creation of brand new software generally a major part of most programming jobs?
I have worked in software development for over 10 years now, and it's dawning on me that I rarely get to create anything "new".  I realize that "new" is a vague term, but I would define it as anything from an obvious new large-scale project to a new large feature in an existing project (say something that would require some thought into its design, and that might take 2 weeks or more to complete).  Maybe a rough guideline is something is new if it requires a written spec.  I think most programmers know what I'm talking about - you're in the zone, writing a ton of code at a fast pace.

Anyway, thinking back to what I've done, I'd estimate that less than 10% of my time is spent on "new" work.  There are things like "adapt this existing system to work in this new environment", which certainly requires a lot of planning, but the actual coding and "new stuff" comes down to making tiny changes in many places throughout the code.  Likewise for small feature requests - if I know what to do, these can often be finished in under an hour, and if I don't, it's just a lot of reading code and figuring out what to do (which frustrates me because I learn much better by doing, not by reading).

In general I feel like I am not really creating anything most of the time.  I kind of assumed that this was the case at most places - a new product would come out rather quickly and at that point everyone would be excited and banging out the code at a fast pace, but then once live it moves into maintenance mode, where few of the subsequent changes would be considered "new & creative".

Am I wrong?  Am I accurately describing most programming jobs, or do most programmers feel like they are often creating new things?

答:
I would say it depends on the company you work for.

My first job was an accounting software firm whose major product was an ERP system, competing at about the same level as Great Plains or Peachtree (as in you moved up to it from QuickBooks, or sideways when you got tired of GP's obfuscated schema or whatever you thought was wrong with PT, then you moved up out of the tier altogether into a package like SAP). That job was 99.99% maintenance, defined as fixing bugs and adding "small stuff", without fundamentally changing the way the software worked or what it could do. I left the company when the CEO wanted to do a page-one rewrite of the system, which would have been cool except he insisted on several design features that are clear anti-patterns, such as inner-platform (allowing a high degree of customization of the program by basically giving the customer a dumbed-down VS Designer, and customizing business rules by providing an expression language).

My next job after that was a contract firm that did "turnkey development"; the system the customer spec'ed was built from the ground up, hardware and software, then at the completion of the project it was all turned over to the client who could either maintain it themselves or retain the company's services for a monthly fee. My job was in development of one of these major projects, and so while I worked there pretty much everything I'd done hadn't existed before I started. Even then, development is inherently iterative; you're always adding to what you already have (even if what you have is nothing), and you have to avoid and fix regression problems (new stuff breaking old stuff). And once the project moved into "warranty" status, new functionality was complete and we were expected to fix any defects the customer found during their UATs.

My current job is back to in-house development, for a security company which uses video monitoring and audio feedback to provide alarm signal verification and other "virtual guard" services. This field is growing quickly and still developing; new equipment enters the market all the time, new customers are signed up who want us to do new things, and existing products no longer meet adapting UL and government regs. 99% of this job is "integration"; writing new software that never existed before, to make one new but pre-existing piece of equipment or software work with another probably older pre-existing piece of equipment or software, so that we can do new things with both.


问:
C++ - Best way to have a central data repository
I'm coding in C++. I have a server that will have clients connect to it, and each client gets spun off into its own thread for communication. This server is hosting a game, so there is information that must be shared between all client threads, as well as any other threads I choose to spawn off. This data is like level data, players online, etc, so all threads might possible have to access any of the data at any time. When I was doing this in C#, I just had a static static with all static fields. Is there a superior way to do this? I really don't want to have to deal with passing a reference to a specific object everywhere, but I figure my current implementation goes against OOP etc. Would this be a good case for using a singleton design pattern? Any other ideas are welcomed!</p>

答:
I really don't want to have to deal with passing a reference to a
  specific object everywhere

Why not? Is passing a single reference so much effort? You'll kick yourself tomorrow when you use a global variable just because you were too lazy today to implement it properly.

Just send the reference and get it done.


答:
each client gets spun off into its own thread for communication

Not a fan of Boost.Asio?

there is information that must be shared between all client threads

Sounds like you just want a giant global table that any client instance (whether a thread or an Asio implementation) can read and write.

Title: C++ - Best way to have a central data repository

Body: I'm coding in C++. I have a server that will have clients connect to it, and each client gets spun off into its own thread for communication. This server is hosting a game, so there is information that must be shared between all client threads, as well as any other threads I choose to spawn off. This data is like level data, players online, etc, so all threads might possible have to access any of the data at any time. When I was doing this in C#, I just had a static static with all static fields. Is there a superior way to do this? I really don't want to have to deal with passing a reference to a specific object everywhere, but I figure my current implementation goes against OOP etc. Would this be a good case for using a singleton design pattern? Any other ideas are welcomed!</p>


问:
Algorithm for creating cluster groups on two criteria
I would like to group a population based on two criteria. I will use an analogy to simplify my question.

Let's say I want n number of groups. I want to populate those groups based on person's age and weight, so that all groups contain about the same total age and are evenly distributed by weight (so that there are about same number of heavy and light people in each group).

What kind of algorithm could I use to automate this process? Is there a simple Excel formula or some other method?

UPDATE

Here is the motivation for this statistical analysis. I would like to set up partitioning in a database which will have the best performance. I need to store a lot of data which is grouped by county. I do not know ahead of time, what would be the best number of partitions. Partitions should be uniform, so that they contain about the same number of rows. A partition should hold data rows for one or more counties. Each county will be ranked on the frequency and possibly quantity of updates. Partitions should be built so that frequently updated county data is uniformly distributed.

It does not seem as if there is a simple way to do this. So what kind of algorithm would work for this? I probably would not use VBA for coding, instead most likely I would use perl to write the program for doing the analysis. Are there any ready-made statistical tools that do these type of analysis?

Let me clarify what I mean when I say n number of groups. I will basically pick a number of groups (partitions), plug it into the formula or analysis tool, or custom program. Then I will repeat the process for a different number of groups (partitions) until I find by trial and error, the number of partitions that yields best performance.

Maybe there is a name for this type of analysis? Something that I could try to research via a search engine?

答:
Usually, the term "cluster analysis" refers to building groups of similar objects.

Your intention however seems to build groups of diverse objects, such that each group is a somewhat representative sample of your data and similarly sized, right?
Why would you choose the sum of age to be approximately the same?

Definitely look into sampling strategies. You will much more likely find you answer there than in the clustering domain. Because again, clustering usually tries to minimize variation inside each group.

OwnerDisplayName: Anony-Mousse


问:
Using HashTable without overriding hashcode()
Today I was asked this question during an interview:

What will happen if we do not override the hashcode method for our
  class, then add it to HashTable and then try to get objects?

What could go wrong?

答:
I would only add, that all of these concepts have to with identity and comparison.

There is a contract with hash code:

1.) Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.

2.) If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

3.) It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.

The upshot is that if the hash codes are the same the entries in the table overwrite each other and that could be surprising to some...

Hope this helps.


问:
Which things instantly ring alarm bells when looking at code?
I attended a software craftsmanship event a couple of weeks ago and one of the comments made was "I'm sure we all recognize bad code when we see it" and everyone nodded sagely without further discussion.

This sort of thing always worries me as there's that truism that everyone thinks they're an above average driver. Although I think I can recognize bad code I'd love to learn more about what other people consider to be code smells as it's rarely discussed in detail on people's blogs and only in a handful of books. In particular I think it'd be interesting to hear about anything that's a code smell in one language but not another.

I'll start off with an easy one:

Code in source control that has a high proportion of commented out
  code - why is it there? was it meant
  to be deleted? is it a half finished
  piece of work? maybe it shouldn't have
  been commented out and was only done
  when someone was testing something
  out? Personally I find this sort of
  thing really annoying even if it's just the odd line here and there, but when you see large blocks interspersed with the rest of the code it's totally unacceptable. It's
  also usually an indication that the rest of
  the code is likely to be of dubious
  quality as well.

答: Can anyone think of an example where code should legitimately refer to a file by absolute path?</p>

ContentLicense: CC BY-SA 2.5


问:
Is monkeypatching considered good programming practice?
I've been under impression, that monkeypatching is more in quick and dirty hack category, rather than standard, good programming practice. While I'd used from time to time to fix minor issues with 3rd party libs, I considered it temporary fix and I'd submit proper patch to the 3rd party project.

However, I've seen this technique used as "the normal way" in mainstream projects, for example in Gevent's gevent.monkey module.

Has monkeypatching became mainstream, normal, acceptable programming practice?

See also: "Monkeypatching For Humans" by Jeff Atwood

答:
Patching in general should be a last resort, monkey patching even more so.  The issue is primarily one of maintainability.

A long time ago, my linux kernel had 3 separate patches applied to it, necessary for my video card driver and two proprietary applications I had.  Two of them had conflicting changes, which meant I needed a 4th patch to resolve the differences between them.  Now whenever a security issue was fixed in the upstream kernel, I either had to wait for the vendors of those 3 patches to release an update to the new kernel version, which took from one to six months, or I had to manually maintain the upstream security patches until the other patch vendors caught up.

After a few years, the vendors managed to get included in the upstream kernel source, and I was able to stop the balancing act, but you can see what a mess it was in the mean time.  Don't inflict that on your programmers unless you have to.


问:
How do you make an open source website and profit?
I'm not asking from a business sense exactly, but for example, both reddit and Twitter are completely open source.  It is my understanding that at least the large majority of their profit comes from advertising on their website.  So what exactly is to prevent someone from copying their code and making their own website with some small but effective changes?

I ask this because I have a website, and I want to make money on it through advertising.  I also want the code to be open source, just to be nice, but I don't want this to happen to me.  My site is not (and will probably never ben close to) an institution like Twitter or reddit.  I'm not sure if they're just so big they're not worried about someone copying their site, or if they actually have some protection in spite of being open source.

reddit uses CPAL, and Twitter uses the Apache license -- does this offer the protection they need or is there something else I'm not getting?

答:
There's no "protection" when anyone could take their codebase and put it up on another server.  None.  Zip.  Reddit and Twitter are instead relying on the network effect to make their sites valuable.  (The Wikipedia article even cites Twitter as an example of the network effect.)

The basic idea is that for a service that connects people together, its value is based primarily on the number of users.  (If I'm the only person in the world with a phone, it's useless.  But once everyone has one, that phone is an incredibly valuable tool.)  So yes, they're "just so big they're not worried about someone copying their site," because the site itself isn't what they're about.  Having a site that's that big is.


答:
Even if you'd make some small but effective changes, your alternative twitter probably wouldn't catch on. People wouldn't be able to use their clients on it (as no client I knows allows you to change the domain it uses), their friends won't be on it, etc. You'd be completely detached from everything that makes these sites what they are: their community.

I think (but IANAL) there is nothing legally stopping anyone from creating a new twitter (hell, someone has probably tried at some point), but the chances of it working are just very slim.

Title: How do you make an open source website and profit?

Body:
I'm not asking from a business sense exactly, but for example, both reddit and Twitter are completely open source.  It is my understanding that at least the large majority of their profit comes from advertising on their website.  So what exactly is to prevent someone from copying their code and making their own website with some small but effective changes?

I ask this because I have a website, and I want to make money on it through advertising.  I also want the code to be open source, just to be nice, but I don't want this to happen to me.  My site is not (and will probably never ben close to) an institution like Twitter or reddit.  I'm not sure if they're just so big they're not worried about someone copying their site, or if they actually have some protection in spite of being open source.

reddit uses CPAL, and Twitter uses the Apache license -- does this offer the protection they need or is there something else I'm not getting?


问:
Why is the empty list used as the list terminator in Lisp?
It seems to me that the list terminator in Lisp could be any arbitrary value. For example, the string terminator in C is the null pointer. Is there a philosophical reason why the empty list was chosen to terminate lists?</p>

答:
I will give you the philosophical answer to your philosophical question:

It seems to me that the list terminator in Lisp could be any arbitrary value. [...] Is there a philosophical reason why the empty list was chosen to terminate lists?

The answer to your question is this: the list terminator is an arbitrary value. It is so arbitrary that different Lisp dialects use a different value for it and yet remain conceptually compatible.

Common Lisp uses a symbol object: the symbol nil.  A symbol! What does a symbol have to do with lists? Nothing.

(Except that when we work with mathematical objects with pencil and paper, we use symbols. A circle with a dash through it or {} represent an empty set, etc. So why not use machine symbols similarly?)

Scheme uses an empty list, the object () which is not a symbol.

The Scheme () and the Common Lisp nil are quite different, yet they adequately terminate a list, exactly in line with your observation that it could be any arbitrary value!

So therefore, is there a philosophical reason why the empty list terminates lists? Yes! The reason is that any object which is understood to terminate a list is, by definition, the empty list.  If you use the number 42 as the list terminator, then () means 42.

Mathematically, every list has the empty list as its suffix (just like every set has the empty set as a subset). Since the Lisp list representation is suffix-based (a non-empty list is an reference to an object holding the first element, and the suffix of that list), there has to be something to handle the case when a list has just one element, and its proper suffix is (mathematically) the empty list. Whatever object is installed as the suffix is then understood to be the empty list, and for the sake of consistency and unity, that object better be used as the representation of the stand-alone empty list also, not only as the representation of the empty suffix of the one-element list.

OwnerDisplayName: Skilldrick


答:
Reddit and twitter can open source their codebase as it's not the primary reason they are so popular. Their biggest commodity is their community and their content. If they were to make their community and content freely available to others, then they would be putting themselves at risk in the same way as you're describing.

Wolfram alpha on the other hand is an example of a site that would be at risk if it was fully open source. If a company like google integrated their codebase into it's search, it could be devastating for them.

I guess the answer to your question is how valuable do you think the code is on your site, compared to the benefit it would get from being open sourced.


答:
I've struggled with this concept myself, and here's my best shot at an answer: Your job as a software developer is not to write code; it's to provide some sort of service (whatever that may be).

Most code will move from being a novelty to a ubiquity with time anyway, so I think that's a good attitude even in a proprietary environment . For example, nobody needs to code anything anymore to create a basic webpage for small business or fanclub.

Making a profit off open source software is like making a profit from a bake sale where everybody knows that your recipe for brownies came off the back of the box. People could have made their own brownies, but they didn't or they don't want to or [long list of reasons]. They'll buy yours out of convenience, or [another list of reasons].  Don't try to monetize your recipe. Focus, instead, on providing the service.


答:
There are many forms of open sourcing a website, out there.

You may open source the code, but not the data.

(you may not even own the data to the extent of being able to open source it, btw)

...then people come to you for the unique contents.

Cloning: cloning the site is simple, but then you just get an empty shell.

Open source the data, not the code (stackoverflow model)

...where we users keep coming because the software here is very good at continuosly extorting from other people contents we may want to read.

Cloning such a site is harder, but certainly is possible.

Still, cloners start a race with light years of gap behind the original authors and have to keep up-to-date while providing new competitive features to overrun the original site and compel more people to visit.

It's a race so hard to win, that if someone does, they objectively earned it.

(and it may happen if the original site is lingering in a state of neglect)

In general, it is meant more of a safety net for the community if the site disappears for one reason or the other, than anything else.

Wikipedia it out of the window. (open source everything)

Clones, they will happen.

The original site, still, has an head-start:

on data: there is an active community, generating, updating and revising content

on code: no one understands and can maintain an hefty lump of rotting code like the brain that conceived it in the first place

Another factor: copycat sites are frequently downranked by search engines (google, at least)  sorting algorithms, (after so many wikipedia clones tried to cash-in on Adsense) so cloners may never get the visibility they wanted.


答:
3 main ways of doing this:

Use a global static object, its gets constructed at startup and can be a good pattern as it is very simple. Simple can often = good.

Use a singleton. You now have the object created later, and its still a single object. you fetch this object as needed. This is a "step-up" as you have more control about initialisation of the object compared to the global.

Use an 'Inversion of Control' object. This is basically passing the object into each class in the constructor, so each object has its private member pointer to the object. This is another step-up as it allows much easier access to the 'global', and also allows you to switch the injected object on a class by class basis.

Ultimately it depends, the IoC pattern is very fashionable at the moment, but I tend to prefer the global TBH. It depends as well what data you're putting into it, and if its a read-only or a read-write object.


答:
I'd say it depends very much on  the nature of your role.

I'm part of a small team and as such, have to maintain and support everything I create.

5 years ago most of what I did was "new" - now I'd say maintenance of existing code takes up at least half of my time, with a further 25% being "new" versions of existing systems.

But if you worked solely as a developer with a team to take on maintenance and support after you release your code then technically everything would be "new". If you can find a job where maintaining your own code isn't required, take it!

Title: Is the creation of brand new software generally a major part of most programming jobs?

Body:
I have worked in software development for over 10 years now, and it's dawning on me that I rarely get to create anything "new".  I realize that "new" is a vague term, but I would define it as anything from an obvious new large-scale project to a new large feature in an existing project (say something that would require some thought into its design, and that might take 2 weeks or more to complete).  Maybe a rough guideline is something is new if it requires a written spec.  I think most programmers know what I'm talking about - you're in the zone, writing a ton of code at a fast pace.

Anyway, thinking back to what I've done, I'd estimate that less than 10% of my time is spent on "new" work.  There are things like "adapt this existing system to work in this new environment", which certainly requires a lot of planning, but the actual coding and "new stuff" comes down to making tiny changes in many places throughout the code.  Likewise for small feature requests - if I know what to do, these can often be finished in under an hour, and if I don't, it's just a lot of reading code and figuring out what to do (which frustrates me because I learn much better by doing, not by reading).

In general I feel like I am not really creating anything most of the time.  I kind of assumed that this was the case at most places - a new product would come out rather quickly and at that point everyone would be excited and banging out the code at a fast pace, but then once live it moves into maintenance mode, where few of the subsequent changes would be considered "new & creative".

Am I wrong?  Am I accurately describing most programming jobs, or do most programmers feel like they are often creating new things?


问:
When is a requirement considered complete?
Which elements must a requirement contain that it can be considered complete? Or if this works better - which questions should I ask about a requirement to find out if it is complete. I am not talking about the implementation of the requirement but the requirement itself.

I am asking this from the perspective of an analyst who wants to make sure that his requirements are complete before passing them on to the design team.

答:
I consider a set of functional requirements complete when they can be used to link every system output to one or more system inputs. This is horizontal traceabiliy. Without it you will be missing about 30% of your total requirements. For more inf see http://www.barbarabea.com/?page_id=11

Any requirement that needs child requirements is, and must be, ambiguous. If it were unambiguous, it would not need child requirements. By this criteria, most of the requirements in a large system are ambiguous.

For functional requirements that do not have children, there is a simple test for ambiguity. Full details at http://www.barbarabea.com/?page_id=78

The simplified description of the test is that the requirements must be horizontally traceable and the processing step in each functional requirement must be an algorithm.


答: In addition to the network effect mentioned above, Twitter also earns money from licensing its whole data. I'm not talking about the API, which is used to create 3rd party apps thus increase the network effect. I'm talking about running data analytics algorithms that can mine patterns and trends that is only present in the data as a whole, but not in parts of it. The more data you have, the more its value increases, so you can sell that to businesses. One can for example predict financial market movements, political opinion, sports games results based one what users do on Twitter or reddit... This is what I'm working on right now and we pay a lot for the data...


答:
According to Karl Wiegers in Software Requirements, there are characteristics of each requirement. A high-quality, well-written requirement is:

Complete - it fully describes the functionality

Correct - it accurately describes the functionality

Feasible - the requirement can be implemented

Necessary - the capability documented must be required

Prioritized - an indicator of how essential the requirement is to the system or a particular release

Unambiguous - anyone who reads the requirement should arrive at a single interpretation of it

Verifiable - the system can somehow be tested to confirm that it meets the requirement

Title: When is a requirement considered complete?

Body:
Which elements must a requirement contain that it can be considered complete? Or if this works better - which questions should I ask about a requirement to find out if it is complete. I am not talking about the implementation of the requirement but the requirement itself.

I am asking this from the perspective of an analyst who wants to make sure that his requirements are complete before passing them on to the design team.


问:
How can one best avoid writing bloated GUI code?
I find whenever I work with GUI code, the code tends to bloat faster then other kinds of code. It also seems harder to refactor. Whereas in other kinds of code I can refactor pretty easily -- I find I can decompose a larger class into smaller pieces of functionality -- with most GUI frameworks I'm often bound to a framework that requires my widget/control/whatever class to implement a lot more things more directly in the widget/control/whatever. Sometimes this is due to needing to either (a) inherit off of some base widget/control/thing or (b) need access to protected methods.

I typically also have to, for example, respond to a large variety of inputs via signals/events/whatever from the framework to implement all the modes of interacting with the user. I might need in one GUI widget/control to handle a large variety of input/output that might include:

a right click/context menu

reacting to selections from the context menu -- which may be many

a special way to paint the GUI

react to keyboard input

buttons, checkboxes,

etc etc

... all the while manage the classes under the GUI representing business logic.

A simple straight-forward GUI can have its code grow pretty quickly, even when seperating out buisiness logic and using MVC, I find GUI code is a big magnet for change.

Is there any way to manage GUI code in a sane way and avoid letting it become a broken window? Or is a mass of random event handlers/overridden methods really the best we can do for GUI code?

答:
My answer consists of four parts: structure, simplicity, testing and syntax.

The first three are really hard to do!

Structure means paying a lot of attention to using the least amount of code and the maximum amount of frameworks, libraries etc.

Simplicity means keeping things simple from initial design to actual implementation.  Keeping the navigation simple, using simple plugins, keeping the layout fairly 'plain' will all help here.  They can now be 'sold' to clients/users that can quickly see the advantages of pages that work on pc's, ipad, mobile and other devices.

Testing means including browser-testing tools (webrat and capybara come to mind with my rails work) that catch cross-browser issues up front when better code can be designed to deal with them at the beginning as opposed to the frequent 'patching' of code by different developers as they are 'discovered' by users of different browsers.

Syntax.
It's really helpful to use a code checker / IDE / editor-plugin, etc. for your HTML, CSS, Javascript, etc.  The advantage that browsers have obtained through being able handle ill-formed HTML works against you when different browsers perform differently with it, so a tool that checks your HTML format is essential.  Having well-formed HTML is very helpul in having unbloated HTML as bad code should have more visibility.


问:
Where has Cloud Computing gone?
I have been hearing about this term for close to 5 years now. I have read about services from Microsoft (Azure), but I have never saw it adopted in the mainstream usage. The thing I am trying to understand is this:

What happened to cloud computing? Is the infrastructure at present insufficient to implement this?

Is it still in its infancy?

Is it being used in other forms, like all the services Google seems to provide (plus Plus Google OS, etc)?

If it has failed, then why?

答:
Look to the enterprise.  You will find cloud computing on the consumer side, but it is often not as you think of cloud computing. You hit the nail on the head when you mentioned Google Services, also look at all the Web services business popping up, Evernote, Mint.com, etc.  They are all in the cloud.

If you think of Cloud Computing as an Infrastructure service, then you will be more likely to find that on the enterprise side, with Amazon, Rackspace, and even IBM all offering Infrastructure on Demand services.  I've heard that a lot of startup web companies love to use these services to quickly get their servers up and running and to ease the task of anticipating demand.

To sum up, the cloud isn't dead, and is still growing at a strong pace. That said much like Web 2.0 there are multiple definitions to what Cloud Computing actually is.

Title: Where has Cloud Computing gone?


问:
Are there any OS which are simple enough for learning?
I would really like to understand how an operating  system works behind the scenes. However, I think that the kernel of most open-source OSs out there are too complex for learning purposes, even for a full-time programmer to learn. Are there any "simple" OSs made for learning purposes only out there?</p>

答:
In my university we have learnt NachOS. It's a great open source OS for learning. You can also find many universities exercises on NachOS for learning.

Nachos is instructional software for teaching undergraduate, and
  potentially graduate, level operating systems courses.  The Nachos
  distribution comes with:

An overview paper

Simple baseline code for a working operating system

A simulator for a generic personal computer/workstation    sample assignments

A C++ primer (Nachos is written in an easy-to-learn subset of C++,
   and the primer helps teach C programmers our subset)

The assignments illustrate and explore all areas of modern operating
  systems, including threads and concurrency, multiprogramming,  system
  calls, virtual memory, software-loaded TLB's, file systems,  network
  protocols, remote procedure call, and distributed systems.


答:
I think many of the problems you are experiencing can be traced back to a simple cause. Most developers do not treat GUI code like 'real' code. I have no evidence or statistics here, just my gut feeling.

Maybe they think it is 'just presentation' and not important. 'There is no business logic there', they say, 'why unit test it'? They laugh when you mention object orientation and writing clean code. They do not even TRY to make things better. There is no structure to start with, they just slap some code and let it rot as others add their own touch over time. A beautiful mess, graffiti code.

GUI code has its unique challenges therefore has to be treated differently and with respect. It needs love and developers who want to write it. The ones that will keep it thin and give it good structure and correct patterns.

Title: How can one best avoid writing bloated GUI code?

Body:
I find whenever I work with GUI code, the code tends to bloat faster then other kinds of code. It also seems harder to refactor. Whereas in other kinds of code I can refactor pretty easily -- I find I can decompose a larger class into smaller pieces of functionality -- with most GUI frameworks I'm often bound to a framework that requires my widget/control/whatever class to implement a lot more things more directly in the widget/control/whatever. Sometimes this is due to needing to either (a) inherit off of some base widget/control/thing or (b) need access to protected methods.

I typically also have to, for example, respond to a large variety of inputs via signals/events/whatever from the framework to implement all the modes of interacting with the user. I might need in one GUI widget/control to handle a large variety of input/output that might include:

a right click/context menu

reacting to selections from the context menu -- which may be many

a special way to paint the GUI

react to keyboard input

buttons, checkboxes,

etc etc

... all the while manage the classes under the GUI representing business logic.

A simple straight-forward GUI can have its code grow pretty quickly, even when seperating out buisiness logic and using MVC, I find GUI code is a big magnet for change.

Is there any way to manage GUI code in a sane way and avoid letting it become a broken window? Or is a mass of random event handlers/overridden methods really the best we can do for GUI code?


答:
I agree with the other posters the the value of Redit and Twitter is about network effect, fanbase, community etc.

I would also point out that it wouldn't be much effort to write a Twitter or Reddit like web site from scratch. A basic copy would probably take a couple of man years, reproducing all of the more sophisticated features would probably still be less than 10 man years effort. These figures are trivial to a venture capitalist who thinks there is money to be made. So close sourcing the code only makes it slightly more difficult for a potential competitor.

In addition there is a substantial number of open source projects that do something similar so you would not need to start from scratch to replicate their functionality.


答:
Applications such as Word Processing, Graphics editors, etc. have complex interfaces and their code can't be simple. However, for business applications, the GUI does not have to be so complex but some how it still is.

Some of the keys to simplifying GUI are (most apply to .NET):

Strive for simpler design whenever possible. Avoid fancy behaviors if not called for by the business.

Use a good controls provider.

Don't create custom control functionality in the client code itself. Instead, create user controls that extends the original control in such a way that you can reflect your specific behaviors in the controls rather than in the code of the using form/page.

Use a framework (even a home grown) to handle internationalization, resources management, styles, etc. so that you don't repeat this code in every UI.

Employ a component (or framework) for navigation.

Build standard dialogues for errors, warnings, confirmation, etc.


答:
Legacy systems are the successful ones. They survived the initial development process where 50% of projects fail (even after success has been redefined!). They survived a changing business environment. They probably survived about ten proposals by young naive programmers to re-write the whole thing in Java or whatever was trendy at the time. They were lucky enough that whatever department, company or agency that the software was serving survived the various budget cuts, reorganizations, mergers etc.

Probably less then 5% of the software written will still be running ten years later.

So rather than moan about this see it as a privilege to work on such a Darwinian success story and an opportunity to learn what works in the real world and why.


答:
The thing to remember about GUI code is that it is event-driven, and event-driven code is always going to have the appearance of a mass of randomly organized event handlers. Where it gets really messy is when you try to shoehorn non-event-driven code into the class. Sure, it has the appearance of providing support for the event handlers and you can keep your event handlers nice and small, but all of that extra support code floating around makes your GUI source seem bloated and messy.

So what can you do about this, and how can you make things easier to refactor? Well, I would first change my definition of refactoring from something I do on occasion to something I do continuously as I code. Why? Because you want refactoring to enable you to more easily modify your code, and not the other way around. I'm not simply asking you to change the semantics here, but asking you instead to do a little mental calisthenics in order to see your code differently.

The three refactoring techniques that I find I use most commonly are Rename, Extract Method, and Extract Class. If I never learned a single other refactoring, those three would still enable me to keep my code clean and well structured, and from the content of your question, it sounds to me like you will probably find yourself using the same three refactorings almost constantly in order to keep your GUI code thin and clean.

You can have the best possible separation of GUI and Business logic in the world, and still the GUI code can look like a code mine has been detonated in the middle of it. My advice is that it doesn't hurt to have an extra class or two to help you to manage your GUI properly, and this does not necessarily have to be your View classes if you are applying the MVC pattern - although frequently you'll find the intermediary classes are so similar to your view that you'll often feel an urge to merge them for convenience. My take on this is that it doesn't really hurt to add an additional GUI-specific layer to manage all of the visual logic, however you probably want to weigh up the benefits and costs of doing so.

My advice therefore is:

Do nothing directly behind your GUI except to invoke and define how the GUI will hook into the View (or an intermediary layer).

Don't try to shoe-horn every view related thing into a single class - or even a single class per GUI window - unless it makes sense for you to do so.  Your alternative is to create lots of little and easy to manage classes to manage your GUI logic.

When your methods are starting to look a little larger than a 4-5 lines of code, examine if this is necessary and if it is possible to extract a method or two so that you can keep your methods lean, even if this means a class with many more methods.

If your classes are starting to look really large, start by removing ALL of the duplicated functionality, and then see if you can logically group your methods such that you can extract another class or two.

Think about refactoring every time you write a line of code.  If you get a line of code to work, see if you can refactor it to avoid duplicating functionality, or to make it a little leaner without changing the behaviour.

Accept the inevitable, that you will always feel that one part or another in your system will start to feel a little bloated, especially if you neglect refactoring as you go. Even with a well-factored code base, you can still feel as if there is more that you could do.  This is the reality of writing software, that you will find yourself always feeling that something more could have been done "better", so you need to strike a balance between doing a professional job, and gold-plating.

Accept that the cleaner you try and keep your code, the less bloated your code will seem.


答:
Rather than seeing legacy code as continually cleaning up someone else's mess, look at it as an opportunity to work on a lot of new projects.

Think about it, every new feature added to a system is a small project within itself. You still need to apply the entire SDLC in order to ensure you have completed the job properly.  Sure, you are likely given a specification for the feature, but usually the fine detail has been left up, so it is up to you to analyse the problem as shown, design the best method to apply the change, test it, code it, and then release it back to your version control system, and quite possibly maintain it in the future.

It's been my experience that you don't often get to work in a completely green field, and often when you have been lucky enough to do so, you will be expected to see the project through a good portion of it's maintenance and perhaps even for the lifetime of the product, or for the entire time you are with a given employer.  This is because your intimate experience with a product means that you become a knowledge repository, and it can be seen as costly to move you on to other things.  When you start on an existing product, it is because the employer has recently lost a resource or needs more resources on the project, and they business needs to ensure it doesn't make too great a loss on the investment it has made in its software. That is the reality of being a software engineer.

I've worked in IT for nearly 22 years with the last 15 as a Software Developer, and in that entire time I've only created about 5 new products, with most of my time either maintaining those products long term, or maintaining someone else's product. Each has given me challenges and problems to solve, and each has been treated not as simply a big project that I am merely a part of, but also as a HUGE series of micro-projects to complete.

It's amazing how a little mental calisthenics can totally change your perception and enjoyment of the daily work that you do. ;-)


答:
The cloud was originally invented by companies like Amazon and Google for their own internal use- they needed a way to make things scale, stay available and be resilient because they depend on making their services reliably accessible.

Once those technologies had matured somewhat they started making them available to others and companies like Microsoft saw the possible benefits of this approach and began working on their own service. By now there are a few different services available and they all have their positives and negatives.

It's being used now by the big players. They're not making a fuss about it, just taking advantage of the things it offers. It's very convenient if you want to build a service and be ready for future capacity without having to worry about the hardware underneath it. Takes a few considerations out of the equation in a very helpful way.

I think if anything the term is going to become less popular/buzzwordy because it will just be acknowledged that people are using this technology and it will be nothing special.

Title: Where has Cloud Computing gone?

Body:
I have been hearing about this term for close to 5 years now. I have read about services from Microsoft (Azure), but I have never saw it adopted in the mainstream usage. The thing I am trying to understand is this:

What happened to cloud computing? Is the infrastructure at present insufficient to implement this?

Is it still in its infancy?

Is it being used in other forms, like all the services Google seems to provide (plus Plus Google OS, etc)?

If it has failed, then why?


答:
I would say that it depends on a lot of factors.  Where do you work, what sort of products do you make, how is your team organized, etc.

The four years that I've worked at my company, I would say 70-80% of my time is spent creating something new.  Probably 50-60% of that is spent on large projects that is entirely new code, while the rest of that time is spent on enhancements to current functionality.

Part of that I know is how my company works.  Not everyone in my development team spends this much time building new functionality.  There are a number that focus their time in nothing but bug fixing/hunting.  If it is a brand new piece of functionality or they need help, then it gets kicked over to me to investigate.  In general though, that small team of bug hunters is what allows the larger group of developers to press on without interruption.


答:
There are a couple of other options not mentioned yet:-

Shared memory. Use the POSIX Interprocess Communication and Shared Memory APIs to allocate and control a piece of shared memory. The advantage is that you can now share the data between processes which will scale well within a single machine.

Use a mini server process, which can be accessed via the technology of your choice (RPC, CORBA, plain TCP/IP sockets). This will scale well over multiple machines, but, you need to write a fairly complex API to manage updates etc.

Use a database. Sounds like overkill but this is exactly what database management systems were written for. This scales up to almost Facebook/Amazon size provided you are careful with your SQL, and, you don't need to write much code to implement this.


问:
Converting Fortran 77 code to C#
I'm trying to convert a Fortan77 program to C#. I have a subroutine with about 650 lines of code and horrific GOTO statements all over the place. I'm having a lot of trouble even starting to visualise the flow of the subroutine to figure out what it does.

Is there anybody with experience in this sort of thing who could give me any advice on how to get an overview of this subroutine? Are there some tools available to speed up or facilitate this type of conversion?

答:
A simple way of recoding stuff with lots of gotos is to draw a flowchart and pull the string straight.  Sometimes, F77 programs are just old F66 programs or even worse FII programs.  F66 did not have an if-then-else construct so gotos were necessary.  All you need to do is invert the condition to get an if-then.

F66 did not have a do-while either but F77 does.  It depends on whether the coder was a convert from F66 to F77 (like many today are C to C++ or C++ to C#) where they are using F77 like F66. If you can spot the patterns, in the coding, it is far easier to convert.

Title: Converting Fortran 77 code to C#


问:
When is it acceptable to NOT fix broken windows?
In reference to broken windows, are there times when refactoring is best left for a future activity?

For example, if a project to add some new features to an existing internal system is assigned to a team that has not worked with the system until now, and is given a short timeline in which to work with - can it be ever be justifiable to defer major refactorings to existing code for the sake of making the deadline in this scenario?

答:
If its really broken then it should be fixed.

But is it really broken? Are you sure you are not just equating "not pretty" with broken.

You need to apply a "sunk value" calculation before you re-factor working code because you don't like the style, or, because you think it will cause problems in the future.

For re-factoring code you wrote last week you sunk cost is the time you spent coding it up last week, not really worth bothering about if the code is substantially improved.

Re-factoring code that has been through unit test. Now you don't just need to re-write, you need to re-define and re-run all the testing done so far, this is starting to look expensive.

Re-factoring code that has gone to production. Even more testing to be done, plus a roll out to the users, and, the risk of delivering something that doesn't work as well as the old release. You need to justify this and clear it with the big boss before going ahead.

Re-Factoring code that has bee in production for a while and been through several releases and bug fixes. Unless you know the software is going to stop working don't even go there!


问:
Do Fortran compilers really generate faster code than C compilers?
When I was studying in the university I often heard the idea that Fortran compilers produced faster code than C compilers for an equivalent program.

The key reasoning went like this: a Fortran compiler emits on average 1,1 processor instruction per line of code, while a C compiler emits on average 1,6 processor instruction per line of code - I don't remember the exact numbers but the idea was that C compilers emitted noticeably more machine code and therefore produced slower programs.

How valid is such comparison? Can we say that Fortran compilers produce faster programs than C compilers or vice versa and why does this difference exist?

答:
The statement may have been true in the old days (circa late 70s) when C was in its infancy,  and Fortran was supported by all major manufacturers and were highly optimized. Early Fortrans were based on the IBM architecture so simple stuff like the arithmetic if would certainly have been one statement per assembly instruction.  This is true of the older machines like Data General and Prime, which had 3 way jumps. This doesn't work on modern instruction sets which do not have a 3 way jump.

Lines of code does not equal statements of code.  Earlier versions of Fortran only allowed one statement per line.  Later versions of Fortran can take multiple statements per line.  C can have multiple statements per line.  On the faster production compilers like Intel's IVF (formerly CVF, MS Powerstation) and Intel's C, there really is no difference between the two.  These compilers are highly optimized.


答:
I've been working almost three years as the only developer in a company that used QuickBooks and Excel and nothing else when I started. Now we've got a Windows Forms application, a SharePointsetup, SQL Server + Reports, an Excel add-in and an Outlook add-in.

Just today, I setup for the first time a ticketing system because I lost the ability to manage email requests at a rate that kept users from complaining, so I view this is a sign that I've entered maintenance mode.

My previous jobs have been more like what the others have posted, but I figured I'd throw in my atypical experience just because it goes to show you never know what the next job will bring. I'm exhausted, but the amount I've learned on this job has been worth the work.


答: Go read a book about programming in assembler. You don't have to become profictient at it but it will teach you a lot of the inner workings of a computer.</p>

Title: Are there any OS which are simple enough for learning?

Body: I would really like to understand how an operating  system works behind the scenes. However, I think that the kernel of most open-source OSs out there are too complex for learning purposes, even for a full-time programmer to learn. Are there any "simple" OSs made for learning purposes only out there?</p>


问:
What kind of problems does MapReduce solve?
I have been reading about MapReduce for a while -- but what I can't understand is how someone would make a decision to use (or not use) MapReduce.

I mean, what are the problem patterns that signal that MapReduce could be used.

答:
It's basically problems that are huge, but not hard. Travelling salesman depends crucially on the distance between any given pair of cities, so while it can be broken down into many parts, the partial results cannot be recombined so that the globally optimal solution emerges (well, probably not; if you know a way, please apply for your Fields medal now).

On the other hand, counting frequencies of words in a gigantic corpus is trivially partitionable, and trivially recombinable (you just add up the vectors computed for the segments of the corpus), so map-reduce is the obvious solution.

In practice, more problems tend to be easily recombinable than not, so the decision whether to parallelize a task or not has more to do with how huge the task is, and less with how hard it is.


答:
The MapReduce pattern is taken from the world of functional programming. It is a process for applying something called a catamorphism over a data-structure in parallel. Functional programmers use catamorphisms for pretty much every simple transformation or summarization.

Assuming your data is a tree, the deciding factor is whether you can compute a value for a node using only the data contained in that node and the computed values for its children.

For example you can compute the size of a tree using a catamorphism; you would compute the sum of the computed values for all children plus one.

Title: What kind of problems does MapReduce solve?

Body:
I have been reading about MapReduce for a while -- but what I can't understand is how someone would make a decision to use (or not use) MapReduce.

I mean, what are the problem patterns that signal that MapReduce could be used.


问:
Is it a good practice to use smaller data types for variables to save memory?
When I learned the C++ language for the first time I learned that besides int, float etc, smaller or bigger versions of these data types existed within the language. For example I could call a variable x

```<code>int x;
or
short int x;
</code>```

The main difference being that short int takes 2 bytes of memory while int takes 4 bytes, and short int has a lesser value, but we could also call this to make it even smaller:

```<code>int x;
short int x;
unsigned short int x;
</code>```

which is even more restrictive.

My question here is if it's a good practice to use separate data types according to what values your variable take within the program. Is it a good idea to always declare variables according to these data types?

答:
Most of the time the space cost is negligible and you shouldn't worry about it, however you should worry about the extra information you are giving by declaring a type. For example, if you:

```<code>unsigned int salary;
</code>```

You are giving a useful piece of information to another developer: salary cannot be negative.

The difference between short, int, long is rarely going to cause space problems in your application. You are more likely to accidentally make the false assumption that a number will always fit in some datatype. It's probably safer to always use int unless you are 100% sure your numbers will always be very small. Even then, it is unlikely to save you any noticeable amount of space.

Body:
Most of the time the space cost is negligible and you shouldn't worry about it, however you should worry about the extra information you are giving by declaring a type. For example, if you:

unsigned int salary;

You are giving a useful piece of information to another developer: salary cannot be negative.

The difference between short, int, long is rarely going to cause space problems in your application. You are more likely to accidentally make the false assumption that a number will always fit in some datatype. It's probably safer to always use int unless you are 100% sure your numbers will always be very small. Even then, it is unlikely to save you any noticeable amount of space.


答:
Depending on how the specific operating system works, you generally expect the memory to be allocated unoptimized such that when you call for a byte, or a word or some other small data type to be allocated, the value occupies an entire register all of it's very own. How your compiler or interpreter works to interpret this however is something else, so if you were to compile a program in C# for instance, the value might physically occupy a register for itself, however the value will be boundary checked to ensure you don't try to store a value that will exceed the bounds of the intended datatype.

Performance-wise, and if you are really pedantic about such things, it's likely faster to simply use the datatype that most closely matches the target register size, but then you miss out on all of that lovely syntactic sugar that makes working with variables so easy.

How does this help you? Well, it's really up to you to decide what sort of situation you are coding for.  For nearly every program I have ever written, it's enough to simply trust your compiler to optimize things and to use the datatype that is most useful to you.  If you need high precision, use the larger floating point data types.  If working with only positive values, you can probably use an unsigned integer, but for the most part, simply using the int datatype is enough.

If however you have some very strict data requirements, such as writing a communications protocol, or some sort of encryption algorithm, then using range-checked datatypes can come in very handy, particularly if you are trying to avoid problems relating to data overruns/underruns, or invalid data values.

The only other reason I can think of off the top of my head to use specific datatypes is when you are trying to communicate intent within your code.  If you use a shortint for example, you are telling other developers that you are allowing positive and negative numbers within a very small value range.

Title: Is it a good practice to use smaller data types for variables to save memory?

Body:
When I learned the C++ language for the first time I learned that besides int, float etc, smaller or bigger versions of these data types existed within the language. For example I could call a variable x

```<code>int x;
or
short int x;
</code>```

The main difference being that short int takes 2 bytes of memory while int takes 4 bytes, and short int has a lesser value, but we could also call this to make it even smaller:

```<code>int x;
short int x;
unsigned short int x;
</code>```

which is even more restrictive.

My question here is if it's a good practice to use separate data types according to what values your variable take within the program. Is it a good idea to always declare variables according to these data types?


问:
Sell me on IoC containers, please
I've seen several recommend use of IoC containers in code. The motivation is simple. Take the following dependency injected code:

```<code>class UnitUnderTest
{
    std::auto_ptr<Dependency> d_;
public:
    UnitUnderTest(
        std::auto_ptr<Dependency> d = std::auto_ptr<Dependency>(new ConcreteDependency)
    ) : d_(d)
    {
    }
};

TEST(UnitUnderTest, Example)
{
    std::auto_ptr<Dependency> dep(new MockDependency);
    UnitUnderTest uut(dep);
    //Test here
}
</code>```

Into:

```<code>class UnitUnderTest
{
    std::auto_ptr<Dependency> d_;
public:
    UnitUnderTest()
    {
        d_.reset(static_cast<Dependency *>(IocContainer::Get("Dependency")));
    }
};

TEST(UnitUnderTest, Example)
{
    UnitUnderTest uut;
    //Test here
}

//Config for IOC container normally
<Dependency>ConcreteDependency</Dependency>

//Config for IOC container for testing
<Dependency>MockDependency</Dependency>
</code>```

(The above is hypothetical C++ example of course)

While I agree that this simplifies the interface of the class by removing the dependency constructor parameter, I think the cure is worse than the disease for a couple of reasons. First, and this is a big one for me, this makes your program dependent on an external configuration file. If you need single binary deployment, you simply cannot use these kinds of containers. The second issue is that the API is now weakly and worse, stringly typed. The evidence (in this hypothetical example) is the string argument to the IoC container, and the cast on the result.

So.. are there other benefits of using these kinds of containers or do I just disagree with those recommending the containers?

答:
This great SO answer by Ben Scheirman details some code examples in C#; some advantages of IoC containers (DI) being:

Your dependencies chain can become nested, and it quickly becomes unwieldy to wire them up manually.

Enables use of Aspect oriented programming.

Declarative & nested database transactions.

Declarative & nested Unit of work.

Logging.

Pre/Post conditions (Design by Contract).

Title: Sell me on IoC containers, please


问:
What's the best way to review a code before it's committed to the trunk? (SVN)
What's the best way to review a code before it's committed to the SVN trunk? One idea that I am thinking of is to having the developer to commit his code to a branch and then reviewing his code while merging the branch revisions into the trunk. Is this a good practice? If not, what else could be done to review a code before it's committed to the trunk?</p>

答:
Branches should work OK, based on my experience of using them in pre-commits reviews at prior job.

Note back then, we were using pre-commit reviews only for critical patches to production release candidate code, so there weren't much branches (routine changes were passed through post-commit reviews).

Since you seem to be going to use pre-commit reviews for all the changes, you might need to manage large amount of branches. If you expect developer to make one "reviewable" change per week on average, you'll end up having about 50 branches every year for every developer in team. If you are using smaller chunks of work - like ones taking 1, 2, 3... days - multiply 50 by 2, 3, 5... accordingly.

Below are few other considerations to take into account if you want it best way.

1. handling cases when delayed review blocks code needed for other team members

Establish, monitor and resolve conflicts related to code review deadlines. Per my recollection of pre-commit reviews to routine changes I dealt with in one of the past projects, reasonable deadline is about 3 days and time to start worrying about is when review isn't completed more than 1 day after submission.

For comparison, at post-commit reviews these requirements are much more relaxed (I'm using 2 weeks deadline and start worrying after 1 week) - but since you target pre-commit reviews, this is probably not interesting.

2. merge conflicts when submitting reviewed code

What to do if commit for reviewed code is blocked by conflicting changes committed by someone else while code was waiting for review?

Couple of options to consider are

roll-back to beginning and require developers to re-implement and re-review the change

For that case you might need to address a negative impact on team morale this might (will!) have.

pass the responsibility of merge to other team member ("merge master")

For that case, you will also need to decide whether merges per se should go through pre-commit review or not - and if yes, then what to do in case if that merge in turn meets another conflict.

ignore changes done to reviewed code at the stage of merge

For that case you might need to address a negative impact on team morale related to the fact that code committed differs from one that was reviewed.

invent a way to avoid conflicts

Straightforward approach is to allow only one developer at time to modify particular set of files - although this won't protect you from the kind of changes that don't modify files directly, but impact them through internal API changes. You might also find out that this kind "pessimistic locking" makes system-wide changes and deep refactoring quite troublesome.

For comparison, there would be no issues of that kind in post-commit reviews (since these deal with code that is already merged by definition) - but since you target pre-commit reviews, this is probably not interesting.

3. load developer who is waiting for review

Establish an explicit policy for whether developer who submitted review should switch to new task or do something else (like eg chasing reviewer).

For comparison, post-commit reviews hardly need explicit policy (since it's natural to proceed to next task after you committed code and taking into account that review deadline is a week or two) - but since you target pre-commit reviews, this is probably not interesting.


问:
Worst coding standard you've ever had to follow?
Have you ever had to work to coding standards that:

Greatly decreased your productivity?

Were originally included for good reasons but were kept long after the original concern became irrelevant?

Were in a list so long that it was impossible to remember them all?

Made you think the author was just trying to leave their mark rather than encouraging good coding practice?

You had no idea why they were included?

If so, what is your least favorite rule and why?

Some examples here

答:
This may ruffle a few feathers, but standards that mandate templated block comments at the top of each method always bug the crap out of me.

1) They are always out of date since they are too far from the code that does the actual work to notice when you are updating things. Bad comments are worse than no comments.

2) They often just repeat information that is already contained the source control tool, just less accurate. For example: Last Modified by, list of modification date/reasons.


问:
What's are best Windows 7 gadgets for programmers?
I am looking for a theme with gadgets that will make my life easier as a programmer.

Googling from the desktop is one feature I am looking for.

Integration with SharePoint or other bug trackers are the second.

Any other idea that might make me more productive is a good one.

答:
TFS gadgets:

See http://www.gregcons.com/KateBlog/SidebarGadgetsForTFS.aspx - it's about two years old, so ignore the Vista comments.


答:
Is it parallelisable?

Any parallelisable problem is essentially map and fold; conversely, the map step is inherently parallelisable (and the fold step might be, depending on the structure over which it's folding), so this is a bidirectional property.


问:
Is the creation of brand new software generally a major part of most programming jobs?
I have worked in software development for over 10 years now, and it's dawning on me that I rarely get to create anything "new".  I realize that "new" is a vague term, but I would define it as anything from an obvious new large-scale project to a new large feature in an existing project (say something that would require some thought into its design, and that might take 2 weeks or more to complete).  Maybe a rough guideline is something is new if it requires a written spec.  I think most programmers know what I'm talking about - you're in the zone, writing a ton of code at a fast pace.

Anyway, thinking back to what I've done, I'd estimate that less than 10% of my time is spent on "new" work.  There are things like "adapt this existing system to work in this new environment", which certainly requires a lot of planning, but the actual coding and "new stuff" comes down to making tiny changes in many places throughout the code.  Likewise for small feature requests - if I know what to do, these can often be finished in under an hour, and if I don't, it's just a lot of reading code and figuring out what to do (which frustrates me because I learn much better by doing, not by reading).

In general I feel like I am not really creating anything most of the time.  I kind of assumed that this was the case at most places - a new product would come out rather quickly and at that point everyone would be excited and banging out the code at a fast pace, but then once live it moves into maintenance mode, where few of the subsequent changes would be considered "new & creative".

Am I wrong?  Am I accurately describing most programming jobs, or do most programmers feel like they are often creating new things?

答:
It depends how danger is your job position: ;-)

If you work for a new company that develops a new products with a high risk that the company is going to survive, you probably create some great new products.

If you work for an old company that have a stable position on the market, it is more likely you will code in maintenance mode ;-) .

The creation of new software is always very tempting. The truth it is hard to do this in a right way. Doing maintainable code is not a trivial task.

If you think on these tons of aspects you must ensure to write good code: proper logging, proper monitoring and statistics acquiring, descriptive design that is efficient and helps even unfamiliar people to involve in your project, documenting, automatic testing and test driven developments.

No many people are doing it right so we must maintain their code and polish it to the proper state. ;-)

The good news is if you are in the company long enough, you can have an influence how new code is written :-)


问:
A good way to share knowledge of a new technology with team members when time is short?
We've been having constant requirement changes of having to choose which graphic rendering library to use for our project.

In a team of about 10 members, two of us are exploring the new graphic library. The team lead expects that we learn what's necessary within 2 days and introduce it to the rest of the team (wants the two of us to give a value-add to the other teams by introducing it to them so they won't be lost). We've told him that 2 days is ridiculous, so he asked us to give him our plan. We've already lost a few months in exploring some other graphic libraries, so the project is behind schedule. The other team members are developing algorithms that will make calls to the graphic library. They'll have to write some code using the graphic library too.

In such a situation, what is a good way to share knowledge?

Have brainstorming sessions everyday for an hour where they tell us
their algorithm interfaces and we tell them the graphic library
interfaces which they can use?

Give them a short overview of the skeleton of how their interfaces
would fit in with ours and let them figure out the graphic library
code for themselves?

Any other ways?

答:
Spend the two days working with the new graphic library. Then work with one or at most two of the senior team members to port their algorithms to the new graphic library. After two weeks present a formal seminar of what you have learned from the porting effort to the entire team. Make a wiki.

Here is the rationale:

You need at least two days to figure out what the library is all about and write "Hello World".

You need to start doing some "real" work after two days in order to satisfy your team lead that you are not wasting time. He probably needs to report this up the chain of command so be sympathetic.

You need to start the integration work with senior members of the team so that if you run into problems these credible people can explain to the team leader why you are stuck.

You need to at least two weeks with the senior engineers and their algorithms in order to complete some meaningful programming, but any more than two weeks will make management nervous.

After two days and two weeks you need to hold a seminar for the other team members so that they can get started and management will see that knowledge is being diffused to the entire team, and so that the team does not get too far down the road with code that might require a lot of changes to fit the new graphic API. The team can then use the examples on the wiki that you have developed with the two senior members to start their own work.

Do not start by doing brainstorming - things will just get out of control and it will generate a lot of noise. Do not leave the programmers to figure it out on their own after a short presentation - some will get stuck and then complain, and there will be a lot of duplicated learning going on.


问:
Biggest mistake you've ever made
Similar to the question I read on Server Fault, what is the biggest mistake you've ever made in an IT related position. Some examples from friends:

I needed to do some work on a production site so I decided to copy over the live database to the beta site. Pretty standard, but when I went to the beta site it was still pulling out-of-date info. OOPS! I had copied the beta database over to the live site! Thank god for backups.

And for me, I created a form for an event that was to be held during a specific time range. Participants would fill out the form for a chance to win, and we would send the event organizers a CSV from the database. I went into the database, and found ONLY 1 ENTRY, MINE. Upon investigating, it appears as though I forgot an auto increment key, and because of the server setup there was no way to recover the lost data.

I am aware this question is similar to ones on Stack Overflow but the ones I found seemed to receive generic answers instead of actual stories :)

What is the biggest coding error/mistake ever…

答:
"We need to do a rewrite."

On the otherhand, it was a five year old VB6 app.

Title: Biggest mistake you've ever made


答:
While the task is not at all reasonable - two days to learn a new library??? - the quickest way to transfer the knowledge is to create code templates and examples that the other programmers can use to cough copy-paste to their implementations.

Something like

```<code>// initialize graphic subsystem
MegaDraw.loadDriver(DriverManager.locateDriver(DRIVER_OPENGL2));
// create viewport
Viewport vp = MegaDraw.createViewport(1, null, FOOBAR_DEFAULT);

// draw a line
Point p1 = vp.createPoint(0,0);
Point p2 = vp.createPoint(10,10);
Line l = vp.drawLine(p1,p2);
</code>```

Once a programmer knows which methods to call, it's relatively easy to look up the reference guide for the details.

Title: A good way to share knowledge of a new technology with team members when time is short?

Body:
We've been having constant requirement changes of having to choose which graphic rendering library to use for our project.

In a team of about 10 members, two of us are exploring the new graphic library. The team lead expects that we learn what's necessary within 2 days and introduce it to the rest of the team (wants the two of us to give a value-add to the other teams by introducing it to them so they won't be lost). We've told him that 2 days is ridiculous, so he asked us to give him our plan. We've already lost a few months in exploring some other graphic libraries, so the project is behind schedule. The other team members are developing algorithms that will make calls to the graphic library. They'll have to write some code using the graphic library too.

In such a situation, what is a good way to share knowledge?

Have brainstorming sessions everyday for an hour where they tell us
their algorithm interfaces and we tell them the graphic library
interfaces which they can use?

Give them a short overview of the skeleton of how their interfaces
would fit in with ours and let them figure out the graphic library
code for themselves?

Any other ways?

Body:
While the task is not at all reasonable - two days to learn a new library??? - the quickest way to transfer the knowledge is to create code templates and examples that the other programmers can use to cough copy-paste to their implementations.

Something like

// initialize graphic subsystem
MegaDraw.loadDriver(DriverManager.locateDriver(DRIVER_OPENGL2));
// create viewport
Viewport vp = MegaDraw.createViewport(1, null, FOOBAR_DEFAULT);

// draw a line
Point p1 = vp.createPoint(0,0);
Point p2 = vp.createPoint(10,10);
Line l = vp.drawLine(p1,p2);

Once a programmer knows which methods to call, it's relatively easy to look up the reference guide for the details.


答:
You might want to take a look at the Model View Presenter/Passive View pattern. Ray Ryan gave a good talk on a Google IO about best architecture practices for GWT.

http://www.google.com/events/io/2009/sessions/GoogleWebToolkitBestPractices.html

It is easy to abstract the ideas to other frameworks and languages. The main benefit of MVP (in my opinion) is unit-testability. And you only get that, if your code that is not bloated and not spaghetti (judging by your question, this is what you want). It works by introducing a view logic layer called the presenter. The actual view is decoupled from this via an interface (and thus can easily be mocked in unit tests). Now, since your view logic layer (the presenter) is freed from the internals of the concrete GUI framework, you can organize it like regular code and you are not tied to e.g. Swings inheritance hierarchy. Ideally you could switch GUI implementations in different frameworks as long as they conform to the same interface.


问:
Is there a standard for when you include libraries or not?
I often come across a class which has a single reference to another library and was wondering if its better to include the library or to reference the object by it's full name. Is one better then the other? Is one more of a standard then another?

For example using System.Windows.Messagebox:

Option A:

```<code>using System.Windows;

public class MyClass
{
    SomeMethod()
    {
        MessageBox.Show("Something");
    }
}
</code>```

Option B:

```<code>public class MyClass
{
    SomeMethod()
    {
        System.Windows.MessageBox.Show("Something");
    }
}
</code>```

If B, how many references do you need before you decide to add the entire library?

答:
If it is indeed a single use, I tend to go with option B. However, the moment I notice more than a single use, it's normally better off as option A. Might be just me, but I don't really like polluting the default namespace with potentially a large number of identifiers, only one of which is ever used and only once.

This differs somewhat based on the size of the namespace named in the using directive; a large namespace, such as System.Windows, sees more scrutiny at my keyboard than, say, System.Collections.Generic. It also depends somewhat on the size of the source code file; in a small file, it's easier to have an overview of what adding a using clause might do. (Yes, I know that best would often be to refactor and break up into smaller classes and files, but sometimes it's not practical to do so inside the scope of a small task.)


答: The solution I've found is declarative code. Using just procedural code is a recipe for spaghetti GUI code. Sure, a "special way to paint the widget" is probably going to remain code. But this is code isolated in a class. Event handlers, keyboard shortcuts, window sizes - all that messy stuff is best declared.</p>


答:
Whether you primarily do maintenance or not is at least partially under your control. In my case, most of my work for the past 15+ years has been new development. This is because I seek out jobs that let me do new development. I am not a contractor, and I genenerally don't do web development. I have almost always worked for small employers, and I usually work in niche areas (desktop GUI development, QA tools, developer tools, vertical markets).

I've also seen and experienced first hand that the best programmers on a team typically (though not always) get the best jobs. So, focus on being the best programmer at your company and you'll start to see new development come your way.


问:
Why is naming a table's Primary Key column "Id" considered bad practice?
My t-sql teacher told us that naming our PK column "Id" is considered bad practice without any further explanations.

Why is naming a table PK column "Id" is considered bad practice?

答:
From data.stackexchange.com

BOOM, question answered.

Now go tell your teacher that SO practice bad database design.


问:
What techniques help retain programming knowledge?
How do you remember programming related stuff? Have you had the feeling that you've encountered the error you have before you right now, a few years ago and you could swear you knew the cause then but now you've forgotten it?

Did you work with the xsl's string parsing some time ago but now you can't remember exactly which are the string functions altogether from xsl and you have to start from scratch? Or perhaps you forget about some feature from Apache Commons like "filtering a collection by some predicate" that you surely used in the past.

So how do you do it? I tried having a blog but when I develop apps, I never find the time to update the blog or write about my experiences. Also, using a wiki is a nice thing but then I found it difficult to keep a clean separation between them since many times I needed to change a blog post to add new information about that topic. This made me think that I actually should have put this topic in the wiki instead of the blog.

Do you have any systems that help you remember about your programming experience? What's your setup?

答:
Short answer:

Practise, practise, practise.

Not-So-Short answer:

How do you remember how to walk? How do you remember how to speak? Granted these skills aren't exactly the same and they don't require a, seemingly, encyclopaedic knowledge (for beginners, at least), but you're using the same thing: memory.

While I admit that, for beginners, programming can seem an impossibly large subject when you start to study it, it becomes like any other subject once you've gotten the basics down.

As soon as I figured that out, I started to break things down into smaller and smaller chunks (my own, personal version of abstraction). That way, something that seemed difficult to remember becomes easier (at least with me it does).

Writing things down helps more than you might think (having worked in Education, I know that this can have massive positive effects on retention). Especially if you can put it into your own words - rather than just copying it verbatim. If you can paraphrase or equate it to something you already know, even better.

For example:
In C#, String objects are immutable. This means that whenever I tell my program to change the contents of a string object, what actually happens is the original string is destroyed (technically it's placed on the garbage collector's lowest level). Exactly like when an artist makes a mistake when creating a marble sculpture - it cannot be changed, thus it is destroyed and a new one created.

It's not a great example, but it shows the basics of what I'm getting at.

Quality documentation helps, too. Something that my Programming 101 lecturer once told me stuck with me:

Make your commenting verbose. Not to the point of stupidity, but you need to be able to write comments that a non-programmer could understand. That way, you know that someone else on the project can understand it, perfectly. Imagine that you'd spend months implementing a system but you where involved in some kind of horrible accident on the way to work. Someone else will be assigned your work - especially if it's close to crunch time - and if they can't figure out what your code is doing, then production stops.

Good books are an excellent resource, too. A different tutor once told me that if a book doesn't have an index (and there are lots of them, out there that don't), then it's not worth buying.

Google can be an amazing resource, but be aware of copy-paste coders. Stay away from sites that just give you a block of code with no explanation. I prefer to read a whole article on small blocks of code, that way you go away knowing exactly what the block of code is meant to do, how it does it, and why the programmer wrote it that way.

Hope that helps


答:
Maintenance development is a difficult task, harder in many ways than new development. In my experience employers like to keep a developer doing maintenance, especially if they are good at it. Finding good maintenance developers in legacy technologies is harder than finding someone who can work with the latest tech.

I've worked at a company which was divided into a product team, which was all maintenance, and a project team, which was all new development. There was great developers on both sides, but the maintenance guys were definitely more specialised and used legacy tech.

Could I make a suggestion that you push back and ask for some new development work? And if your employer only does maintenance then maybe you need to move on?


问:
Is the phrase "never reinvent the wheel" suitable for students?
I find myself constantly running into this expression "don't reinvent the wheel" or "never reinvent the wheel" when I ask some questions on SO.  They tell you to use some frameworks or existing packages.  I know where this attitude is coming from since it's unwise to waste time on something others have already solved.  Or it that so?

As a student,  I find by using some code others wrote to solve my problem I can't learn as much as I'd like to, and I gain less insight.  And sometimes I think that phrase is mainly for working programmers facing deadlines and not for students like me.

Is it that bad to "reinvent the wheel"?  Maybe I'm thinking it wrong? Maybe there is a way I can avoid reinventing the wheel and at the same time learn a lot?

答:
Answer A: Reinvent the wheel.  It deepens your understanding of data structures and algorithms and makes it a LOT more likely that you'll write good stuff.  I'm sure that when Guido van Rossum was starting on Python, people told him not to reinvent the wheel.  There were lots of languages already.  Why write google when there was already Yahoo!   How about clang?  Learn it all.  Be a giant.  Don't let the small people limit you.
Answer B: If an instructor tells you what to do, give him what he wants, or just a bit more even if it seems silly.  If you want to ALSO go crazy making an astonishing solution and give him a link to it go ahead.  First, though, fulfill the requirements set forth as given so (s)he's happy.</p>


问:
Real-time Dataflow Programming

Background

Recently, I have been fascinated about the possibilities of dataflow-based programming approaches - in particular, signal/event-based concepts as realized by functional reactive programming, Boost::Dataflow::Signals, and the like.

Sample scenario:

Consider a car that has four speed sensors, one at each of its tires. Let's simplify things and say that these sensors are analog sensors providing the measured speed at that tire. The car further has individual brakes on the four tires (the actuators) that one can program to break more or less strongly.

There is no concrete task, but imagine having to realize things like detecting tires not turning due to aqua-planing, or ABS-support, or or or... In short: you have to evaluate the speed sensor data and control the actuators according to some logic.

From a programming point of view, one could think of realizing this via a signal-network of the following sort:

```<code>timer ------------\
sensor1/2/3/4 -> logic -> brakes1/2/3/4
</code>```

(That is, the timer triggers the logic, which takes the latest analog values of the sensors)

Like this, the timer can be programmed to trigger in fixed intervals (especially important to ensure the real-time constraints).

The advantage of the dataflow-approach here is that the above diagram is directly realized in the code, i.e. you have a logical wiring of signals and just need to provide an implementation that turns your actual hardward sensor's data into a signal (of the corresponding library you are using).

When it comes to real-time requirements, the maximal signal path length can also be computed (or at least more easily derived from the source).

The question

Of course, all of this is just an application idea and I am sure several brilliant people have come up with this before. What I am looking for is the follow-up. Are there any hard problems with this scenario which make it unrealizable in practice? Are there experiences from real-world projects on following such a line of thought? Is there even existing literature on this?

To make things clearer and more objective, I am looking for an answer that either shows an inherent fault in my line of thinking or provides reference to existing work/literature along with evaluations. Bonus points if real-time constraints are taken into account.

答:
This is an old idea, that has popped up an unbelievable number of times over the last several decades.  LabView (I think that's the name) is the best-known current version.

I worked with one such system, called RIPPEN, from Orincon (as I recall), around 1998-1999.  (Orincon was bought by Lockheed-Martin in 2003.  The product appears to be dead and gone now.)  The biggest drawback I noticed was that about 20% of my CPU time went to moving data around between processing blocks.  Considering that I was doing significant numbercrunching (coordinate transformations, from az/el/range to X/Y/Z and then applying a coordinate system rotation: BUNCHES of trig and matrix/vector multiplication, 20% is a LOT of CPU time.

Around this time, I went to a function at my old university, and mentioned the product to an old friend, who was a grad student when I was there and is now a full professor.  His answer was that he'd done a similar thing quite a number of years earlier.

Title: Real-time Dataflow Programming