答:
At the risk of sounding tautological, if you want an active branch with bug fixes and feature upgrades, choose the branch with the most recent activity, bug fixes, and feature upgrades.  The revision history is available to you.  It might be time consuming to check it for 15 branches, but it's not unreasonable.

Once you've determined who is the most active maintainer, you can see if he's willing to make it official, and talk to the others to see if they agree.  If they're not making wildly divergent changes, it shouldn't be difficult to find common ground.

Title: How do distributed version-control systems deal with fragmentation?

Body:
Here is the scenario:

X is the author of a software. X releases v1.0 on an open source license on Github and moves on. People interested in the software fork and improve the software. Now there are 15 different flavours of the software. Few also try to send a pull request back, however since X no longer works on the software, the pull request is just sitting idle on his project page.

As a new user wanting to use the most active and stable release of the software, how does he learn which out of the 15 he should clone and use? He certainly would like to use the more active branch, since it may have more bug fixes and features upgrades.

I see that the model works for bigger open-source projects, because the author of the software is usually well-known in the community. As a result, the user base inadvertently knows which branch to clone from. However, how does one solve a problem for a software, where the author, maintainer and several contributors all are practically unknown in the open-source community?


问:
What are the worst false economies in software development?
What are the worst false economies (that is ways of saving money that ultimately cost more than they save) prevalent in the software industry and how do you combat them?</p>

答:
All below can be bad when used or not used inappropriately

external vs inhouse software

ISO 9001 compliance (economy - a mitigation of a MSS loss risk if product quality drops)

development/QA outsourcing

development/build/release/support procedures

ContentLicense: CC BY-SA 2.5


问:
What's the formal name of this diagram?

I'd also want to know how can I draw them.

答:
Just a hint for LaTeX-Users:

The rail-package allows the generation of such rail-diagramms with (La)TeX.

You may check TeX.SX for an example.

ContentLicense: CC BY-SA 3.0

Title: What's the formal name of this diagram?


问:
Is it possible to reach absolute zero bug state for large scale software?
I am talking about 20-30+ millions lines of code, software at the scale and complexity of Autodesk Maya for example.

If you freeze the development as long as it needs to be, can you actually fix all the bugs until there is simply not a single bug, if such a thing could be verified by computers? What are the arguments for and against the existence of a bug-free system?

Because there is some notion that every fix you make creates more bugs, but I don't think that's true.

By bugs I meant from the simplest typos in the UI, to more serious preventative bugs that has no workaround. For example a particular scripting function calculates normals incorrectly. Also even when there are workarounds, the problem still has to be fixed. So you could say you can do this particular thing manually instead of using the provided function but that function still has to be fixed.

答:
According to this article, the on-board software for the Space Shuttle came very close -- the last three versions of the 420,000 line program had just one error each.  The software was maintained by a group of 260 men and women.  A large number of these people were verifiers, whose sole purpose was to find errors.

The upgrade of the software to permit the shuttle to navigate with Global Positioning Satellites impacted just 1.5% of the program, or 6,366 lines of code. The specs for that one change ran 2,500 pages. The specs for the overall program filled 30 volumes and ran 40,000 pages, or an average of ten lines of code per page of the spec.

Budget was not a problem -- at $35 milli0n per year, they could afford to do things right.


问:
What is the best way to understand code in a project with null documentation?
It is our first game and we are a start-up. We had a programmer who suddenly is seeming to be a dead weight. Though we knew him personally we thought that he was as motivated as we are and hence I never looked for a code review or documentation. Now it seems that he is slacking a lot and we want him out.

Now during a conversation he said that he would not document the code so as we could be dependent on him. I looked at the code and there is no documentation.

The code is all over the place. What would be the best way to understand his code?

Details of the code:

Written in C# and targeting a mobile platform using Unity3D.

The game play mechanic and camera is scripts are the main and they have no documentation.

Too much of Send/Broadcast messages so I am not able to see the references through Mono.

Again hefty use of strings in either invoking methods or passing parameters

Update function everywhere which could have been reduced to coroutines.

Naming is poor and inconsistet

Absolutely no pooling with usage of destroy and instantiation. I am expecting memory leaks.

What protocols should I adopt to understand the code and work on top it?

答:
What I would do is sit down at the keyboard, invent a problem, and try to solve it -- that is, pick some part of the app and try to modify it. It doesn't really matter much what you try to change -- the act of digging deep into the code to make the change will force you to confront all of the bad coding practices as you try to understand them.

Dedicate lots of uninterrupted time to this task because you'll need to get a little flow going. You'll probably have to juggle lots of things in your head until you understand it all. Don't take the problem lightly -- it will take lots of concentration. Accept it as a professional challenge, and dive in head first.

I had a similar problem once, a long, long time ago. It was some gnarly database code written in fortran, by someone who I think only knew fortran-66. It had some nasty bugs that had eluded several people. I dove in, and I kept a log. I wrote out my thoughts as they happened -- "oh, variable FOO is both a local in this spot and a global in that spot", "this class is never used", "this is sometimes called with three args, sometimes four, and the fourth is never used", etc. This really helped as I slowly discovered the madness within.

It took me a few days, but I finally nailed it.

And talk to a lawyer. It sounds like you're being blackmailed.


答:
Sounds a lot like a project I've been working on for a while.  When I was hired for the job I currently work at, I was given a folder on the desktop of an old machine and told that it was probably the most recent version of the code for a website.  No documentation, code copy and pasted everywhere, some of the business logic in code, some of it in stored procs in multiple databases, etc.  On top of that, the person I was replacing was the only person at the company who had touched that code so no one could really help me.

I'm still working on bringing that code up to some measurable level of sanity but this is what worked for me.

Play around with the project:  I just took a tour through our site (thankfully we had a beta environment I could do this on without fear of corrupting data, etc).  I clicked around, tried using different features etc.  I also looked at the code a bit while I did this so I could get an idea of what was where and how it worked.

Fix a small bug: I started out with some small bugs and tried to fix them.  It took a while to actually fix them, but I got more familiar with the system as I went.  After a while it became easier and easier to find things and to understand the code.  It's still not a pleasant task to work on the code, but it has gotten easier.

Keep at it: It's not an easy thing to work on code with no help, but it does get easier.

TL/DR: Get a test environment and start messing around fixing bugs and playing with your app.  Don't give up, it will get easier.

Title: What is the best way to understand code in a project with null documentation?

Body:
It is our first game and we are a start-up. We had a programmer who suddenly is seeming to be a dead weight. Though we knew him personally we thought that he was as motivated as we are and hence I never looked for a code review or documentation. Now it seems that he is slacking a lot and we want him out.

Now during a conversation he said that he would not document the code so as we could be dependent on him. I looked at the code and there is no documentation.

The code is all over the place. What would be the best way to understand his code?

Details of the code:

Written in C# and targeting a mobile platform using Unity3D.

The game play mechanic and camera is scripts are the main and they have no documentation.

Too much of Send/Broadcast messages so I am not able to see the references through Mono.

Again hefty use of strings in either invoking methods or passing parameters

Update function everywhere which could have been reduced to coroutines.

Naming is poor and inconsistet

Absolutely no pooling with usage of destroy and instantiation. I am expecting memory leaks.

What protocols should I adopt to understand the code and work on top it?


答:
Throw it out and start over.

It's impossible to write code that other people can't follow that you yourself can follow.  Or that is even good.  The code sounds not worth maintaining based on your few lines of description.

Sounds like the kind of person who would leave logic bombs.  Do you want to defuse them?

Sounds like you're about to greatly underestimate the cost of maintaining software.

Fire the employee ASAP.  He's already voiced that he thinks the best way to grow in the firm is to contribute as much negative value as possible.  He is working at negative value currently.


答:
What you need are Characterization Tests.

A characterization test is a test that characterizes the actual behavior of a piece of code. THere's no "Well, it should do this" or "I think it does that." The tests document the actual current behavior of the system. (Feathers, Working Effectively with Legacy Code, 186)

You can use characterization tests to develop documentation for the code after-the-fact. This is not the preferred way of doing it, of course; it is better to write tests before writing code. But when you are dealing with a legacy codebase (and according to Feathers a legacy codebase doesn't have to be old—a brand new codebase has the same characteristics as an ancient one if it does not have tests) characterization tests are a great boon.

Feathers says (186):

Here is a little algorithm for writing characterization tests:

Use a piece of code in a test harness.

Write an assertion that you know will fail.

Let the failure tell you what the behavior is.

Change the test so that it expects the behavior that the code produces.

Repeat

Note that these tests are different that regular TDD tests in that they are not intended to describe what the codebase should do. They only describe what it does—which is exactly what you are wanting to determine.

If, of course, you find that it does something wrong, you now have tests that allow you to change this behavior with TDD. You change the test to expect what you actually want, and then fix the code until it does that.

Feathers has quite a detailed treatment of how to write such tests. He also discusses in other parts of his book how to get the code into a test harness in the first place (and thus he assumes it in step #1 above) but that goes beyond the scope of this question.


问:
How much redundancy/robustness should complex software implement?
The focus of this question: Some software performs "extra work" in order to increase the chance of a "eventually successful/satisfactory" outcome, despite one or more internal errors in the software, which requires a longer execution time when those errors happen. All these happen without the user's knowledge if the outcome was successful.

Definition of complex software:

Contains code written by (contributed from) more than 10 developers over its lifetime, and not written in the same time frame

Depends on more than 10 external libraries, each with caveats

A typical software task (for generating a result wanted by the user) requires 10 or more input parameters, where most of them have default values but are configurable if the user needs control.

Most importantly, software that has the appropriate complexity relative to the task being performed, i.e. not unnecessarily complicated.

Edited: What is complex? Please see There is a big difference between Complex and Complicated. (direct link)

Definition of Redundancy/Robustness within this question:
(Added Robustness based on comments)

If a software task failed when the current set of parameters was used, try different parameters.

Obviously, there must be inside knowledge that those "different" parameters use a different code path, possibly resulting in a different (hopefully better) outcome.

Sometimes these different code path are chosen based on observations of the external libraries.

At the end, if the actual task performed is slightly different from the user's specification, the user will receive a report detailing the discrepancy.

Finally, like the 10-plus configurable parameters, the redundancy and reporting are also configurable.

Example of such software:

Database Migration

Business database

Source control database, etc.

Batch converting between a Word document and an OpenOffice document, PowerPoint and OpenOffice Draw, etc.

Automatic translation of an entire website

Automatic analysis of software package, such as Doxygen, but where the analysis needs to be more dependable (i.e. not just a documentation tool)

Network communication, where packets may be lost and a number of retries are expected

This question was originally inspired from How do you deal with intentionally bad code?
 but is now focused on just one of the causes of software bloat. This question does not address any other causes of software bloat, such as addition of new features.

Possibly related:

How to deal with complex codes in (huge) projects

How do people manage to write and maintain extremely complex and hard to read code?

答:
Complex software typically is redundant as you probably know, but obviously not because that's the best way to do it but because developers tend to "tack on" existing code rather than attempt to understand in great detail how the software works.

However, if you asked me how much redundancy should be acceptable, I would say none whatsoever.  Redundancy is one of many side effects of complexity, the archnemesis of simplicity.  Arguably, simplicity should take a back seat if time is of greater importance, though I stress that those who argue that time is of the essence are rarely those who actually take care in developing software.  It's usually your project manager egging you to just get the job done as soon as possible so you can get back to more pressing issues, however it's your duty as a programmer to know when the job is done.  I think the job isn't done until you've successfully integrated it into the program as it was meant to be.  Perhaps the program is complicated, but at least your modification fits the pattern making it somewhat easy to understand by a programmer used to seeing similar code.

However it should be said that in doing so, you may have to produce redundant code.  If the project is already highly redundant, it may actually be more simple to continue the pattern assuming of course your boss doesn't have a couple weeks to kill allowing you to restructure the entire project.

Edit:  In light of the rephrasing of the question, I'll add a bit about robustness.  In my opinion, parameter checking should be done only if A) you accept a very specific format such as a date value as a string or B) various parameters potentially might conflict with each other or are mutually exclusive.

With A), the requirements that parameters match a specific format is usually critical to the necessity of the method (such as a conversion to a date from a string).  Technically it could still happen in your program without it being a necessity but I would strongly encourage you to eliminate these possibilities and accept only parameters that you know represent the type of data you're looking for (Accept a date rather than a string if the point isn't to convert for example.  If conversion must also be done, use a utility method to convert the string before passing it to the method).

As for B), mutually exclusive parameters represent a bad structure.  There ought to be two classes, one which handles one case and another which handles it in another way.  All common operations can be done in a single base class to avoid redundancy.

In situations in which the number of parameters to a method get to be 10+, I begin to consider a property file which contains all these parameters which are most likely not going to change often.  If they do change, you can save the default in the property file and add a "setPropertyName()" method which lets you override the default at runtime.


问:
How do I avoid writing lots of pass-through functions in a wrapper?
I have a class, which wraps another class of a common base type. Because the base type interface is quite large this involves writing a lot of pass-through functions. I am looking for a way to avoid this.

Let's make an example:

```<code>      Car
     /   \
Volvo     VolvoWithTrailer
</code>```

Now I have to implement each and every function in the car interface for VolvoWithTrailer and call the appropriate function on the wrapped Volvo object except maybe GetMaxSpeed() which will return something lower.
Basically I will have many functions like

```<code>int VolvoWithTrailer::GetNumSeats() {
  return mVolvo.GetNumSeats()
}
</code>```

An obvious way to solve this would be to make VolvoWithTrailer a subclass of Volvo

```<code>    Car
     |
   Volvo
     |
VolvoWithTrailer
</code>```

but that seems to violate the principle of favoring composition over inheritance.

How else could I avoid writing all those wrappers (the language is C++)?
Or - if that is your position - why should I just write them/just use inheritance?
Is there any template magic that could help with this?

答:
Because the base type interface is quite large this involves writing a lot of pass-through functions.

And there's your problem.

Interfaces should handle one responsibility only. Keeping them thin and focused limits the amount of passthrough work you might need to do in case of a decorator, proxy or other wrapper (in addition to making the class simpiler to use, test, maintain and extend).


问:
How do you keep logins organized between multiple developers?
I've worked at several places with 2-10 developers and each place has struggled in the area of tracking if the company has an account on a given web site or service.  We're always left wondering...

What's the username

What's the password (Obviously you don't want to store this, I'm not looking for something that does)

What's the account number

Who created this

When was it created

What email is our account registered under

What do you guys use to track this kind of thing between multiple developers?  I've setup at least a dozen accounts for the company I currently work for and I don't have any documentation to show the next guy what's been done.

Ideally I'm looking for a web solution that will be locked down within our VPN.

答:
http://en.wikipedia.org/wiki/MindTouch

We use Mindtouch but any sort wiki solution would do the trick. You could also set up a lastpass account to which the whole team has access and store all the per account info in secure notes. You could leave out the passwords if you don't trust that and change the account password when a team member moves on.

We use Mindtouch for a lot of things but a subpage dedicated to webservice accounts is one obvious application.


答:
If they're accounts that the business relies on or pays for, there should be someone who's designated as responsible for managing that account. This is important not just for keeping track of whatever information is in the account, but also for making sure that it gets renewed when that's necessary. Ideally, the same person is responsible for managing all the accounts in this category.

If they're not accounts that the business relies on or pays for, it shouldn't much matter if you lose access to it when someone leaves.

I've setup at least a dozen accounts for the company I currently work
  for and I don't have any documentation to show the next guy what's
  been done.

Why don't you? Even a simple text file, spreadsheet, or internal web page would be a good start -- you don't need an elaborate database to manage the few scraps of information needed for each account. Forget about the next guy -- if the company relies on it, you should have it organized so that you can keep track of it.

Title: How do you keep logins organized between multiple developers?

Body:
I've worked at several places with 2-10 developers and each place has struggled in the area of tracking if the company has an account on a given web site or service.  We're always left wondering...

What's the username

What's the password (Obviously you don't want to store this, I'm not looking for something that does)

What's the account number

Who created this

When was it created

What email is our account registered under

What do you guys use to track this kind of thing between multiple developers?  I've setup at least a dozen accounts for the company I currently work for and I don't have any documentation to show the next guy what's been done.

Ideally I'm looking for a web solution that will be locked down within our VPN.


答:
Our admins use KeePass to keep track of accounts on 3rd party sites and server passwords.

KeePass is a Windows app which stores user names and passwords (and optionally a lot of additional info) in an encrypted database. You just need one master password to open the database and view the content.

EDIT:

I just read that you're looking for a web-based solution.

As I said before, KeePass is a desktop app (not web-based), but there is also a portable version (available on the download page).

I'm using this at home to share a single KeePass installation across all my machines: the portable version is on my NAS drive, and from each machine I start KeePass directly from the NAS.

Note: This works for me. I'm the only user and I never used KeePass from more than one machine at once. And I don't know what happens when you try it!

You could try it - if it works, maybe putting the portable version on a network share and just linking that from your intranet is an option for you.


问:
Protocol for closing a socket connection
I'm rolling my own application protocol on top of TCP.  I'm using Linux and C.  I'm wondering whether there is an advisable sequence to closing a socket connection.

The client will always initiate the close by sending a specially-formed string; say, "CLOSE".  I'd like to receive some kind of acknowledgement from the server that it has seen my CLOSE request, so perhaps it needs to send back a special string like "CLOSE_OK".

I've also seen both the close() and shutdown() system calls, but am not sure how to use them. For instance, should the client, after receiving "CLOSE_OK", do a shutdown(OUTPUT) and then wait to receive a zero-length string?  And should the server, after sending "CLOSE_OK", issue close() and then consider the socket to be dead?

I'm hoping there's a "best practice" on this subject that I haven't found yet...

Thanks,
Chap

答:
If you need to handshake at the application layer (for instance, in order to get a confirmation from the other end that some persistent data has been committed), do that using your CLOSE and CLOSE_OK protocol messages. Indeed you need to do this at the application layer (see the end-to-end principle). But after both ends of the socket are already in agreement that the connection, don't waste any time or effort gracefully closing one direction of communication, verifying that that happened, and then gracefully closing the other end. Just close() the socket from both ends. Depending on the timing, the TCP FIN and ACK sequences may or may not occur sequentially or cross each other on the wire, but your application shouldn't care about that. In any case, just closeing will be the fastest thing you can do.

shutdown is useful in cases where you really do need to signal that communication has finished in one direction but the other direction is still needed. It can be used, for example, by a client that is talking to a server that will not send any reply until it gets all of the data from the client, complete with an EOF at the end. shutdown(SHUT_WR) makes that EOF happen without having to close the whole socket (bidirectionally).


问:
Good approaches for packaging PHP web applications for Debian
Many PHP web applications follow this model for installation and upgrade:

Un-tar a source tar ball.

Point Apache at the source.

Navigate a web browser to the home page.

Go through several web pages of set-up (e.g., checks for existence of libraries, asks for database connection information, creates or updates database schema, etc.).

User renames an install/ directory to something else so that application knows it has been installed.

I don't see any (simple) way to create a Debian package out of this without making the user installing the package go through many of the above manual steps. Note that I am not a developer on the application so I am not in a position to make direct change to how the application installation works.

What is the typical approach to packaging such an application?

答:
I have created several PHP web applications that I distribute (internally) through Debian packages. Doing so has been straightforward thanks to scripts (simplified here) to automate the process:

create_package.sh:

```<code># create a clean debian package directory
rm -rf debian
mkdir -p debian/DEBIAN
mkdir -p debian/var/www/myapp

# populate the debian directory
cp control    debian/DEBIAN
cp myapp.php  debian/var/www/myapp
cp index.html debian/var/www/myapp

# finish through fakeroot so we can adjust ownerships without needing to be root
fakeroot ./finish_package.sh debian .
</code>```

finish_package.sh:

```<code># $1 is the debian directory, $2 is the output directory

# adjust ownerships
chown -R root:root $1
chown -R nobody:nobody $1/var/www/myapp

# finally build the package
dpkg-deb --build $1 $2
</code>```

control:

```<code>Package: myapp
Version: 1.2.3
Maintainer: Your Name <yourname@email.com>
Architecture: all
Depends: apache2, php5
Description: The myapp web application.
</code>```

All this is fairly easy to do, and works well for the internal package distribution that I do. I am not sure it is sufficient for global distribution, but it might be similar to what the Ubuntu and Debian people do when they take source packages (probably distributed as tarballs with install scripts) and create .deb packages for them.

I think this can address your five points smoothly:

The Debian package automatically decompresses into the proper place on the target system when it is installed.

You can have the Debian package configure Apache automatically. Some packages like MySQL and Apache have "conf.d" directories in /etc into which you can drop configuration files. This is the ideal. Your packaging script can create a debian/etc/apache2/conf.d directory and copy a configuration file in there. It will be installed on the target system, and you can restart Apache in a script called postinst that you place in debian/DEBIAN.

This is probably unavoidable if custom information must be entered, though many prefer systems that can run "out of the box" with no configuration required.

Library existence can be guaranteed by including the appropriate package dependencies in the control file. Database connection information can be either installed as a default, or asked of the administrator on the configuration pages. Once entered, the configuration pages should invoke idempotent database migration scripts to update the database schema. Several web frameworks (like Django) make this easy.

The code behind the configuration pages should mark the system as configured, not the administrator.

An approach I sometimes use is to separate installation of configuration from installation of the app by making them separate packages. I can then have several different configuration packages (release, development, etc.) that I can install at will. This decoupling is also advantageous because configuration and app can evolve separately, without clobbering each other when reinstalled.

Body:
I have created several PHP web applications that I distribute (internally) through Debian packages. Doing so has been straightforward thanks to scripts (simplified here) to automate the process:

create_package.sh:

# create a clean debian package directory
rm -rf debian
mkdir -p debian/DEBIAN
mkdir -p debian/var/www/myapp

# populate the debian directory
cp control    debian/DEBIAN
cp myapp.php  debian/var/www/myapp
cp index.html debian/var/www/myapp

# finish through fakeroot so we can adjust ownerships without needing to be root
fakeroot ./finish_package.sh debian .

finish_package.sh:

# $1 is the debian directory, $2 is the output directory

# adjust ownerships
chown -R root:root $1
chown -R nobody:nobody $1/var/www/myapp

# finally build the package
dpkg-deb --build $1 $2

control:

Package: myapp
Version: 1.2.3
Maintainer: Your Name <yourname@email.com>
Architecture: all
Depends: apache2, php5
Description: The myapp web application.

All this is fairly easy to do, and works well for the internal package distribution that I do. I am not sure it is sufficient for global distribution, but it might be similar to what the Ubuntu and Debian people do when they take source packages (probably distributed as tarballs with install scripts) and create .deb packages for them.

I think this can address your five points smoothly:

The Debian package automatically decompresses into the proper place on the target system when it is installed.

You can have the Debian package configure Apache automatically. Some packages like MySQL and Apache have "conf.d" directories in /etc into which you can drop configuration files. This is the ideal. Your packaging script can create a debian/etc/apache2/conf.d directory and copy a configuration file in there. It will be installed on the target system, and you can restart Apache in a script called postinst that you place in debian/DEBIAN.

This is probably unavoidable if custom information must be entered, though many prefer systems that can run "out of the box" with no configuration required.

Library existence can be guaranteed by including the appropriate package dependencies in the control file. Database connection information can be either installed as a default, or asked of the administrator on the configuration pages. Once entered, the configuration pages should invoke idempotent database migration scripts to update the database schema. Several web frameworks (like Django) make this easy.

The code behind the configuration pages should mark the system as configured, not the administrator.

An approach I sometimes use is to separate installation of configuration from installation of the app by making them separate packages. I can then have several different configuration packages (release, development, etc.) that I can install at will. This decoupling is also advantageous because configuration and app can evolve separately, without clobbering each other when reinstalled.


问:
How do I Integrate a Former Team Member into the Current Team
Is it possible to re-integrate a former team member into a software project?

We have a  product with a looming customer deadline and we don't have enough hours to get it done!  We have a former employee who left on excellent terms and wants to come back.  They are familiar with the codebase and architecture (which has not changed significantly since they left).

Can we use this situation to avoid Brooks Law?

It seems like an ideal situation, team member up to speed with processes, tools, etc. What do we need to be careful of?  Are there any dragons in the water?  Or should we expect smooth sailing?

答:
Yes, it is possible to do this smoothly. There are several factors that could affect how smoothly it goes, however.

Is the returning employee just coming in as a temporary contractor? If so, it should be smooth. If not, territoriality issues could surface unless territories are made clear at time of rehire.

Is the returning employee becoming a manager or just a contributor? If just a contributor, again, it should be smooth, especially if the employee has his/her own area to focus in, or is playing the role of a mentor. If a manager, then he/she might be dissatisfied with the people supervised, which could create resentment in both directions (up and down). If the former employee hired those people, then it is probably less of an issue.

Will the employee be compensated better than before? If not, there might be resentment unless the employee has been somehow humbled by the outside world and is returning home.

This happens all the time, and generally goes well. I wouldn't worry about it too much. And @RobertHarvey makes an excellent point that if the existing team approves of the move, then so much the better.


问:
Data replication patterns / algorithms
I have a series of systems that need to be distributed to a variable number of nodes (at least two, but more likely 8 - 10). For performance reasons, any one piece of state needs to be maintained in memory and replicated to at least two nodes although as demand increases this may be replicated to more nodes as dictated by the manager. Unfortunately, we cannot buy commercial data grids which are already very good at this.

The question: Assuming the state is immutable, what are some patterns and/or algorithms I can use to facilitate this process? I've supplied a sample to facilitate the discussion, but I'm not tied to this. Really!... I'm wide open on picking a new direction to meet these requirements. If you could point me to pictures or code samples that would be much appreciated.

As it stands, one of the nodes will self-promote and will orchestrate who should replicate and when (i.e. the manager).

Other assumptions:

List item

Systems will communicate via TCP/IP and Multicast

No databases

No file transfer... just byte arrays

All components are currently C#, and I can change almost anything

Eventual consistency will be fine

Note: I realize this sample does not handle fail cases. At this point I thought it would over-complicate things

答:
Paxos is an algorithm that can be used for active-active replication between multiple nodes. In the (patented) version we use, it has been enhanced to work well in a WAN environment.

Implementation is observed to be non-trivial, but appears to meet the described criteria.

Title: Data replication patterns / algorithms


问:
Is Clojure's syntax really simpler than Scala's?
Argument which is always made in favour of Clojure is that.

The syntax is simpler and there is only one way of expressing code with no complicated rules.

However Scala has loads of different types of syntax and constructs as compared to Clojure.

But from last one week while trying to learn Clojure, I have noticed that the list of inbuilt macros are endless, Even though we write them with the same parenthesis syntax we need to learn how each works.

So in what sense is Clojure's syntax simpler ?
For LISPers it might be but for people from a different background learning different constructs in Scala seems simpler.

So from a neutral point of view, which syntax is simpler and readable?

答:
Macros aren't syntax.

Arguing ecosystem or basic library complexity is a completely different discussion.


问:
Check First vs Exception Handling?
I'm working through the book "Head First Python" (it's my language to learn this year) and I got to a section where they argue about two code techniques:

Checking First vs Exception handling.

Here is a sample of the Python code:

```<code># Checking First
for eachLine in open("../../data/sketch.txt"):
    if eachLine.find(":") != -1:
        (role, lineSpoken) = eachLine.split(":",1)
        print("role=%(role)s lineSpoken=%(lineSpoken)s" % locals())

# Exception handling
for eachLine in open("../../data/sketch.txt"):
    try:
        (role, lineSpoken) = eachLine.split(":",1)
        print("role=%(role)s lineSpoken=%(lineSpoken)s" % locals())
    except:
        pass
</code>```

The first example deals directly with a problem in the .split function.  The second one just lets the exception handler deal with it (and ignores the problem).

They argue in the book to use exception handling instead of checking first.  The argument is that the exception code will catch all errors, where checking first will only catch the things you think about (and you miss the corner cases).  I have been taught to check first, so my intial instinct was to do that, but their idea is interesting.  I had never thought of using the exception handling to deal with cases.

Which of the two is the generally considered the better practice?

答:
The book's main argument is that the exception version of the code is better because it will catch anything that you might have overlooked if you tried to write your own error checking.

I think this statement is true only in very specific circumstances - where you don't care if the output is correct.

There is no doubt that raising exceptions is a sound and safe practice. You should do so whenever you feel there's something in the current state of the program that you (as a developer) cannot, or don't want to, deal with.

Your example, however, is about catching exceptions. If you catch an exception, you're not protecting yourself from scenarios you might have overlooked. You are doing precisely the opposite: you assume that you haven't overlooked any scenario that might have caused this type of exception, and therefore you're confident that it's alright to catch it (and thus prevent it from causing the program to exit, as any uncaught exception would).

Using the exception approach, if you see ValueError exception, you skip a line. Using the traditional non-exception approach, you count the number of returned values from split, and if it's less than 2, you skip a line. Should you feel more secure with the exception approach, since you may have forgotten some other "error" situations in your traditional error check, and except ValueError would catch them for you?

This depends on the nature of your program.

If you're writing, for example, a web browser or a video player, a problem with inputs should not cause it to crash with an uncaught exception. It's far better to output something remotely sensible (even if, strictly speaking, incorrect) than to quit.

If you're writing an application where correctness matters (such as business or engineering software), this would be a terrible approach. If you forgot about some scenario that raises ValueError, the worst thing you can do is to silently ignore this unknown scenario and simply skip the line. That's how very subtle and costly bugs end up in software.

You might think that the only way you can see ValueError in this code, is if split returned only one value (instead of two). But what if your print statement later starts using an expression that raises ValueError under some conditions? This will cause you to skip some lines not because they miss :, but because print fails on them. This is an example of a subtle bug I was referring to earlier - you would not notice anything, just lose some lines.

My recommendation is to avoid catching (but not raising!) exceptions in the code where producing incorrect output is worse than exiting. The only time I'd catch an exception in such code is when I have a truly trivial expression, so I can easily reason what may cause each of the possible exception types.

As to the performance impact of using exceptions, it is trivial (in Python) unless exceptions are encountered frequently.

If you do use exceptions to handle routinely occurring conditions, you may in some cases pay a huge performance cost. For example, suppose you remotely execute some command. You could check that your command text passes at least the minimum validation (e.g., syntax). Or you could wait for an exception to be raised (which happens only after the remote server parses your command and finds a problem with it). Obviously, the former is orders of magnitude faster. Another simple example: you can check whether a number is zero ~10 times faster than trying to execute the division and then catching ZeroDivisionError exception.

These considerations only matter if you frequently send malformed command strings to remote servers or receive zero-valued arguments which you use for division.

Note: I assume you would use except ValueError instead of the just except; as others pointed out, and as the book itself says in a few pages, you should never use bare except.

Another note: the proper non-exception approach is to count the number of values returned by split, rather than search for :. The latter is far too slow, since it repeats the work done by split and may nearly double the execution time.

ContentLicense: CC BY-SA 4.0

Title: Check First vs Exception Handling?


答:
My opinion is that you should write whatever you need to write to make the long-term stability and maintainability of the program better. What's the point in avoiding writing 20 lines of code today, if every time you touch something that uses this code or come back to maintain this Class, it costs you an extra 5 minutes or more because you didn't put in the time today?

So the question then becomes "what do you need to write?" I don't think you provide enough information to be able to give a definitive answer, so I'll just list some things that I would think about in making a decision:

1. Do you need to have the Trailer object by itself, now or in the forseeable future?

If so, you have a pretty good argument for making the wrapper around both composited objects, since you already are going to have to wrap one or the other. Might as well be consistent.

2. Is any of the three types (Car, Trailer, CarWithTrailer) in an area of the code that developers go into frequently or look likelly to become so?

If so, be very careful, because the ramifications of choosing the wrong thing can be very costly amortized over every time the code is touched. If not, it may not make any difference what you decide. Just pick a direction and go with it.

3. What's easiest to understand?

Does one approach jump out at you that someone coming behind you would immediately "get" what you're trying to do? Do your teammates have particular biases that might make one approach harder for them to maintain? If all things are equal, pick the solution that imposes the lowest cognitive load.

4. Are there any additional advantages to using one approach over another?

One thing that jumps out at me is that the wrapper idea has a distinct advantage if you write it that your CarWithTrailerWrapper can wrap any car and any trailer into a CarWithTrailer. Then, you wind up writing all your pass-through methods, but you only write them once, rather than once for each Car Class.

This makes your initial investment in writing the pass-through methods much cheaper as you add more Cars and Trailers. It also helps reduce the temptation to couple things too directly to the Volvo or VolvoWithTrailer, while reducing the consequences of coupling to the CarWithTrailerWrapper, since you can do way more with just that one implementation.

Maybe there are distinct advantages you'd get for free by using the extension method, but I don't see them.

OK, so it looks like I've talked myself round to going ahead and filling in the pass-through methods, for non-trivial applications.

I'm not a C++ programmer, so I have no idea what code generation tools are available to you. The IDE I use can generate methods from an Interface, and I can add code templates that would make writing pass-throughs pretty painless. If you don't have access to an IDE that does this, you can actually get pretty far letting Excel write code for you.

Title: How do I avoid writing lots of pass-through functions in a wrapper?

Body:
I have a class, which wraps another class of a common base type. Because the base type interface is quite large this involves writing a lot of pass-through functions. I am looking for a way to avoid this.

Let's make an example:

```<code>      Car
     /   \
Volvo     VolvoWithTrailer
</code>```

Now I have to implement each and every function in the car interface for VolvoWithTrailer and call the appropriate function on the wrapped Volvo object except maybe GetMaxSpeed() which will return something lower.
Basically I will have many functions like

```<code>int VolvoWithTrailer::GetNumSeats() {
  return mVolvo.GetNumSeats()
}
</code>```

An obvious way to solve this would be to make VolvoWithTrailer a subclass of Volvo

```<code>    Car
     |
   Volvo
     |
VolvoWithTrailer
</code>```

but that seems to violate the principle of favoring composition over inheritance.

How else could I avoid writing all those wrappers (the language is C++)?
Or - if that is your position - why should I just write them/just use inheritance?
Is there any template magic that could help with this?


问:
Why is C so high in TIOBE index of popularity, while C++ is just under here too, but not as popular?
I can't get my head around this. If C is so much used, but C is not C++, can someone explain to me the most important reasons that makes C more used than C++ ? Where is all this C code written for ?

Is this about the industrial sector which heavily rely on imperative programming but can't support the cost of implementing or tuning C++ compilers ? Are there that many kernel hackers ?

Is tiobe relevant ? I never stumbled into any article or post commenting or explaining how singular tiobe's ranking is, and what it actually says about what the industry likes, and what it can tell about what the industry actually uses, to pinpoint the industry real needs. It's hard to explain.

I just find it odd many companies want C#, php, java jobs, and not C or C++ jobs (just relating my unemployment and my interviews here) even if those C/C++ jobs are crap. I would take those instead. Or does this mean language hype plays a strong role here ?

答:
The TIOBE index relies on search engine hits - see http://www.tiobe.com/index.php/content/paperinfo/tpci/tpci_definition.htm

This means that (for an example, in theory) you can have a language that everyone is talking about that has a lot of hits and gets a high rating even though nobody uses it, and you can have a language that lots of people are using but there aren't many web pages/hits so it gets a low rating. It doesn't even take into account what the web pages contain (for example, imagine a million web pages saying a certain language is aweful, that all increase the language's TIOBE index).

In theory, weighting factors would need to be applied to get usage from web hits/TIOBE index. For example, for complex language like C++ (where everyone using it is likely to have one or more reference books) usage is likely to be higher than what the TIOBE index indicates; and for languages primarily used for web development (where most of the documentation is typically online and its users are more likely to create web pages) usage is likely to be lower than what the TIOBE index indicates.

Of course it's virtually impossible to accurately determine appropriate weightings for each language; and therefore the TIOBE index can only be considered a crude approximation of usage at best.


答:
Most prevalent I suspect is managers simply not providing developers with the tools they need to do their job efficiently.

Basically, point 9 on the Joel Test.

Title: What are the worst false economies in software development?

Body: What are the worst false economies (that is ways of saving money that ultimately cost more than they save) prevalent in the software industry and how do you combat them?</p>


问:
Why do we write our specs in different files from our source?
The D Programming Language supports writing unit tests inline with source.  There's a Ruby gem called test_inline that lets you write specs in the same file as your code.

Why is it generally conventional to keep source code in a completely separate directory from test code?

答:
First of all, specifications and tests are not always the same. Especially, the links you mention are really just unit tests, i.e. they are way below the level of typical specifications.

Here are some rebukes for your devil's advocate:

Reduces effort spent switching between files when editing specs:
You gotta be kidding, right? We might as well use variable names a,b and c, because it reduces effort spent on typing. We have way more time-consuming tasks in software development than switching between files. This is not really an argument in our case, because even explaining it takes longer than what you save in a year when you apply it.

Easy to organize and put specs next to tested implementation: You know, some IDEs allow you to open the corresponding unit test file from within your application's source file. Additionally, unit tests are positioned next to the tested sources, only that next to means within the same module. Once you run integration tests, which are cross-cutting over modules, you cannot co-locate them with any one of the sources anyways. So again, this is not a real argument.

Easy to encourage using unit specs in same file and integration specs in another file: That's a strange reasoning here. You want to have unit tests in the same file, because it encourages you to have them in the same file? Circular reasoning isn't very popular (esp. not with line managers if you get what I mean ;) )

Using specs and source together may increase sensitivity about lines written: This is in fact something we want to avoid. The whole point of test-driven development is to write the tests without even having any source code, and one reason to do so is because we want to test on a different level. We do not want to be fooled by the actual production code into writing tests tailored towards it. The tests should work for any code, and knowledge about that specific code may only load to a bad test.

In summary, a lot of people value the separation of test and production code. After all, the seperation means you do not ship test code. On the other hand, as your last argument shows, mixing the tests together with the code may cause more harm than good, and none of your arguments are convincing enough for me to even consider this idea.

Edit: Although you removed the arguments of the devil's advocate, their counter-reasoning still gives reasons on why we don't want to do that:

You have little to no trouble finding a unit test for a class.

Integration tests cannot be included with a source due to their nature (or at least it doesn't make much sense to add them to one module, when they really test multiple modules).

TDD means you should think about the design of your classes. Actual source code of that class is just a distraction to that and it makes sense to avoid this via the splitting.

Additionally, there are a few more arguments:

Separation from production code: Test code by its very nature tries to break things and that makes it something that most people prefer not to give to a customer. In addition, if you do not include test code, you end up with a smaller bundle for delivery (not really significant though).

Single Responsibility Principle: If you include the test code within the class, you break the SRP, because the class C is now responsible for X in addition to being responsible for testing that class C is doing X correctly.

Version Control / History: Changes made to production code are important, and you want to be able to quickly see in the history of your version control system who did what. If you mangle this up with commits that only affected test code, you have a lot more noise.


问:
How is Nothing a subtype of every other type in Scala
I am taking Martin Odersky's coursera course on functional programming with scala, and for now I have learned two things that together don't make sense:

Scala doesn't support multiple inheritance

Nothing is a subtype of every other type

These two statements cannot live together, so how exactly is this done? and what exactly is the meaning of "subtype of every other type"

Edit 1

In the Scala API, Nothing is defined as abstract final class Nothing extends Any... so how can it extend other classes?

答:
When he says that Scala doesn't support multiple inheritance, then he refers to inheriting a method implementation multiple times. Of course, you can implement multiple interfaces/traits in a class, and they can even define the same method, but you do not get a conflict between the different implementations due to trait linearization.

In general, if you have a class C1 with a method f() and a class C2 also with a method f(), then multiple inheritance means you can somehow inherit both implementations of f(). This can lead to various problems, which Scala resolves by only letting you inherit from a single class and in case of multiple traits by selecting one implementation based on the order of the traits.

As for Nothing things are really simple, because nothing has no attributes or methods defined. So you cannot have any inheritance conflicts. But I assume that most of your surprise comes from a different understanding of multiple inheritance.

Once you understand that trait linearization effectively eliminates any ambiguity of the inheritance, and that we do not refer to inheriting from multiple traits as multiple inheritance due to that, then you should be fine.

As to how this is realized: the compiler is eventually responsible for this. See the Scala language specification section 3.5.2 conformance, which amongst other properties includes:

```<code>For every type constructor T (with any number of type parameters), scala.Nothing <: T <: scala.Any.
</code>```

Or in other words, if you want to implement a compiler correctly, it has to handle Nothing as a subtype of everything by specification. For obvious reasons, Nothing is not defined to extend from all classes loaded into the system, but the relevance of defining Nothing as subtype is limited to all places, where subtyping is relevant.

An important point here is that there exists no instance of type Nothing, hence, its treatment is strictly limited to type-checking, which is all in the realm of the compiler.

Body:
When he says that Scala doesn't support multiple inheritance, then he refers to inheriting a method implementation multiple times. Of course, you can implement multiple interfaces/traits in a class, and they can even define the same method, but you do not get a conflict between the different implementations due to trait linearization.

In general, if you have a class C1 with a method f() and a class C2 also with a method f(), then multiple inheritance means you can somehow inherit both implementations of f(). This can lead to various problems, which Scala resolves by only letting you inherit from a single class and in case of multiple traits by selecting one implementation based on the order of the traits.

As for Nothing things are really simple, because nothing has no attributes or methods defined. So you cannot have any inheritance conflicts. But I assume that most of your surprise comes from a different understanding of multiple inheritance.

Once you understand that trait linearization effectively eliminates any ambiguity of the inheritance, and that we do not refer to inheriting from multiple traits as multiple inheritance due to that, then you should be fine.

As to how this is realized: the compiler is eventually responsible for this. See the Scala language specification section 3.5.2 conformance, which amongst other properties includes:

For every type constructor T (with any number of type parameters), scala.Nothing <: T <: scala.Any.

Or in other words, if you want to implement a compiler correctly, it has to handle Nothing as a subtype of everything by specification. For obvious reasons, Nothing is not defined to extend from all classes loaded into the system, but the relevance of defining Nothing as subtype is limited to all places, where subtyping is relevant.

An important point here is that there exists no instance of type Nothing, hence, its treatment is strictly limited to type-checking, which is all in the realm of the compiler.


答: Hiring 2 cheap developers instead of 1 really great. (for the same price)


答:
"If C is not so much used" -- I would be interested to see if anyone could back this up.

All of the following are written in pure C:-

the Linux kernel.

the git repository.

MySql, PostgreSQL, SQLite open source databases.

Oracle, DB2, Informix, SYBASE proprietary databases.

Large chunks of the Windows OS.

The Apache Web Server, the ngnix web server.

The Perl, Python, PHP, Lua language reference implementations.

All in all I would say there are more C programs which are executed more often than any other language.

Title: Why is C so high in TIOBE index of popularity, while C++ is just under here too, but not as popular?

Body:
I can't get my head around this. If C is so much used, but C is not C++, can someone explain to me the most important reasons that makes C more used than C++ ? Where is all this C code written for ?

Is this about the industrial sector which heavily rely on imperative programming but can't support the cost of implementing or tuning C++ compilers ? Are there that many kernel hackers ?

Is tiobe relevant ? I never stumbled into any article or post commenting or explaining how singular tiobe's ranking is, and what it actually says about what the industry likes, and what it can tell about what the industry actually uses, to pinpoint the industry real needs. It's hard to explain.

I just find it odd many companies want C#, php, java jobs, and not C or C++ jobs (just relating my unemployment and my interviews here) even if those C/C++ jobs are crap. I would take those instead. Or does this mean language hype plays a strong role here ?


问:
What is the best way to prove that in-code documentation is greater than extensive external documentation?
What is the best way to prove to my boss that in code documentation is greater than extensive external documents containing documentation and screenshots of code/ui?

We have a group in the company running SAP code.  Their documentation process involves hours of laborious documentation and screenshots of the code and the interface (before and after).

They want us (C# developers) to follow the same rubric as they do.  I want to argue that using comments in the code, and a great, self documenting language such as C# is fulfilling the need for documentation the same as, or greater than the other team's document method.

Is there any published research by big companies that say external documentation is out dated and that in code comments are more efficient? (or something similar to this point)

This has nothing to do with users.  This is NOT user training documentation. Only internal use.

This has nothing to do with Design Documents or Architectural Documents.  It's comparing screenshots of code, before and after a change, and screenshots of forms, before and after the change, and putting them into a document with extensive documentation, opposed to simply having great incode documentation.

Would you really want to have to screenshot your code before and after every single baby change and then write a document explaining the change in great depth? when no one will ever use these documents as reference material in the future?

答:
It all depends on the purpose of documentation.

Two GENERAL cases:

Documenting the inner working of a piece of code, down in the gory bits and algorithms - the things that are not important to an outside world because they are hidden under an abstraction or behind an API - is probably best done in the code. Because outside the code nobody else knows or cares.

Things that go further - API's, general design principles, interface definitions, messages that get exchanged, and so on - are a different matter. These should be defined in painful detail in external documents. And only changed later - with the blessing of god.

By APIs I don't mean the stuff that appears in a C header file, or some class definition (though the lines are getting blurry). That can usually be handled fine in the source.

There will be degrees in between that require thought.

Perhaps a few examples would help:

The algorithm you use to calculate days between dates should be documented in the code.

The multi-processor message passing system you defined with failover redundancy and process porting at run-time should be documented in documents.

The plugin architecture for your new driverless vehicle control system (you know, the one that allows you to add a new flight module at run time without rebooting), where the plugins are developed by an outside company - well, documentation in source alone would be very problematic, use a document with words in that describes interactions, dependancies, time ordering, gotchas, exceptions, limitations, and so on. With diagrams. All in one place.

You get the idea - there are degrees to these things, and reasons for going either way. Make an intelligent and well-considered decision.


问:
Open Source, Copyright and Trivial Bugfixes
Say a developer has developed a library for their closed-sourced commercial application. Since they want to give back to the open source community, they publish this library under, say, the GPL, but continue to use it in their own application. Since they hold the copyright, that's fine.

Now, a user of the GPL version finds a bug, fixes it and submits a patch to the original developer. As I understand it, to use this bugfix in their closed-source application, the developer needs to have permission from the submitter. If the submitter refuses, the developer has to find another way to fix the bug in the closed-source version.

But what if the bugfix itself is really trivial? Like properly initializing a variable or checking for a null pointer? Something that any half-competent programmer can find and fix in a matter of minutes, given an error description? Is the patch for this still protected by copyright? Or can the original developer implement the identical fix in their closed-source application without consent of the submitter?

Note: This really is a hypothetical scenario, not one of those "my 'friend' has this problem" questions

答:
Caveat: I am not a lawyer!

Updated: Trivial bugfixes are likely not subject to copyright. See Michael Shaw's answer, which I believe to be more accurate than what I originally said, for more information.

However, even given that, this situation is less than ideal:

This may be fairly clear for your contrived example, which posits a change that is trivial, as opposed to adding significant functionality.  However, in real life it is going to be a judgment call as to when that is the case. You will be left in a copyright gray area.

Ideally, you want to just incorporate the updated file in your program; you don't want to add your own code, even if it is trivial.  It just duplicates work unnecessarily.

Now there will be two versions of the file: yours and the open-source one.  This just makes a mess if you want to later release updated versions of your code to the community.

Conclusion: The Gnu Public License specifically restricts use of the code in closed-source programs.  Thus, releasing your code under the GPL amounts to deliberately creating a fork of your code that can't be incorporated back into the original program.  This doesn't make a lot of sense.

You would be better served by releasing your code under a more permissive license, such as one of the BSD licenses or the Artistic License.  These licenses allow the code to be included in closed-source software without additional permission.  Usually any further development by the community will occur under the same license you used, so you will be able to incorporate any changes that are made (minor or significant) into your software.

Technically, someone could decide to update your code and then release it under the GPL, but they would have to actively make that choice.  It wouldn't be the default position.  And in doing so, they would be cutting off their release from any updates you make, so it probably wouldn't be beneficial for them (given that it is your software, you will likely be doing more development on it than anyone else).


答:
Subtyping and inheritance are two different things! Nothing doesn't extend everything, it's a subtype, it only extends Any.

The specification[§3.5.2] has a special case governing the subtyping-relationship of Nothing:

§3.5.2 Conformance

[...]

For every value type

  T , scala.Nothing <: T <:scala.Any

For every type constructor T (with any number of type parameters)

  scala.Nothing <: T <: scala.Any

[...]

Where <: basically means "is a subtype of".

As for how this is done: We don't know, it's compiler magic and an implementation detail.

Quite often a language does things you as a programmer can't. As a counterpart to Nothing: Everything in Scala inherits from Any, everything except Any. Why doesn't Any inherit from something? You can't do that. Why can Scala do that? Well, because Scala set the rules, not you. Nothing being a subtype of everything is just an other instance of this.

Title: How is Nothing a subtype of every other type in Scala

Body:
I am taking Martin Odersky's coursera course on functional programming with scala, and for now I have learned two things that together don't make sense:

Scala doesn't support multiple inheritance

Nothing is a subtype of every other type

These two statements cannot live together, so how exactly is this done? and what exactly is the meaning of "subtype of every other type"

Edit 1

In the Scala API, Nothing is defined as abstract final class Nothing extends Any... so how can it extend other classes?


问:
Forward declaration vs include

Reduce the number of #include files in header files. It will reduce build times. Instead, put include files in source code files and use forward declarations in header files.

I read the quote above here: http://www.yolinux.com/TUTORIALS/LinuxTutorialC++CodingStyle.html.

So, it says if a class (class A) in a header file does not need to use the actual definition of some class (class B). At that time we can use a forward declaration instead of including the particular (class B) header file.

Question: If the class (class A) in the header doesn't use the actual definition of a particular class (class B), Then how can forward declaration help to reduce the compile time?

答:
A forward declaration is much faster to parse than a whole header file that itself may include even more header files.

Also, if you change something in the header file for class B, everything including that header will have to be recompiled. With a forward declaration, that may only be the source file where A's implementation is residing in. But if A's header actually included B's header, everything including a.hpp will be recompiled also, even if it doesn't use anything of B.

Title: Forward declaration vs include


问:
What are the worst false economies in software development?
What are the worst false economies (that is ways of saving money that ultimately cost more than they save) prevalent in the software industry and how do you combat them?</p>

答:
Technical Debt

ie "Just do it quickly, we'll refactor later". Firstly because I have yet to see someone engaging in this behaviour actually refactor later. Secondly because doing things the quick way, instead of the good way makes it harder to add future features or resolve future bugs so you end up losing time in the long run.

Sadly, many still think it saves developer cycles to have them do something fast. I guess it's possible, but I have yet to see it in practice.


答:
because then A.hpp doesn't need to #include B.hpp

so A.hpp becomes

```<code>class B;//or however forward decl works for classes

class A
{
    B* bInstance_;
//...
}
</code>```

so when A.hpp is included then B.hpp is not implicitly included and all files which depend only on A.hpp don't need to be recompiled each time b.hpp changes

Title: Forward declaration vs include

Body:
Reduce the number of #include files in header files. It will reduce build times. Instead, put include files in source code files and use forward declarations in header files.

I read the quote above here: http://www.yolinux.com/TUTORIALS/LinuxTutorialC++CodingStyle.html.

So, it says if a class (class A) in a header file does not need to use the actual definition of some class (class B). At that time we can use a forward declaration instead of including the particular (class B) header file.

Question: If the class (class A) in the header doesn't use the actual definition of a particular class (class B), Then how can forward declaration help to reduce the compile time?

Body:
because then A.hpp doesn't need to #include B.hpp

so A.hpp becomes

class B;//or however forward decl works for classes

class A
{
    B* bInstance_;
//...
}

so when A.hpp is included then B.hpp is not implicitly included and all files which depend only on A.hpp don't need to be recompiled each time b.hpp changes


答:
The compiler does not care if class A uses class B.  It only knows that when class A is compiled and it has no prior declaration of class B (forward declaration or otherwise), it panics and marks it as an error.

What is important here is that the compiler knows you didn't try to compile a program after your cat walked on your keyboard and created some random letters which may or may not be interpreted as a class.

When it sees an include, to be able to use any information contained within, it must open the file and parse it (regardless of whether or not it actually needs to do so).  If that file then includes other files, those too must be opened and parsed, etc.  If this can be avoided, it is generally a good idea to use a forward declaration instead.

Edit:  The exception to this rule being precompiled headers.  In this case, all headers are compiled and saved for future compilations.  If the headers don't change, the compiler can smartly use the precompiled headers from previous compilations and thus cutting down compile times, but it only works well if you don't often need to change headers.

Title: Forward declaration vs include


问:
Does a team of developers need a manager?
Background:

I'm currently part of a team of four: 1 manager, 1 senior developer and 2 developers. We do a range of bespoke in-house systems / projects (e.g. 6-8 weeks) for an organisation of around 3500 staff, as well as all the maintenance and support required from the systems that have been created before. There is not enough of us to do all the work that is potentially coming our way - we're understaffed. Management acknowledge this, but budget restraints limit our ability to recruit additional members to the team (even if we make the salary back in savings).

The Change

This leaves us where we are now. Our manager is due to leave his role for pastures new, leaving a vacancy in the team. Management are using this opportunity to restructure our team which would see the team manager role replaced by another developer and another senior developer. Their logic being that we need more developers, so here's a way of funding it (one of the roles is partially funded from another vacant post).

The team would have no direct line manager and the roles and responsibilities would be divided up between the seniors and the (relatively new to post) service manager (a non-technical role with little-to-no development knowledge/experience whose focus is shared amongst a number of other teams and individuals) - who would be our next actual manager up the food chain.

I guess the final question is:

Is it possible to run a development team without an manager? Have you had experience of this? And what things could go wrong / could be of benefit to us?

I'd ideally like to "see the light" and the benefits of doing things this way, or come up with some points for argument against it.

答:
I reckon Flat teams are always a problem unless you put one guy in charge to herd a group of same/similar grade engineers.

As mentioned by S.Robins, IF all the team-members are well disciplined then putting a manager can be a needless bottleneck here. A few of the small companies I have worked in have man-power constraints (due to budget constraints among other reasons) and hence they tend to put a group of few freshers / juniors into a flat team with one guy a rung above them managing them.

If the "1-level-higher" manager is not able to manage people, this will backfire. Freshers / juniors starting out their careers are going to hugely competitive - try to establish themselves firmly as early as possible in the team and someone needs to rein in people at times so that their competitiveness doesn't hurt co-operation.

The issue with having a flat team is that with the project scaling you will inevitably have to let one or two guys do a bit more, take a bit more responsibility. At this point you will have to create a well defined hierarchy and definitely put in place a proper Manager to take calls and manage people because very often when there are promotions from within the same group there is always an unhappy bunch.

The other bad idea I see in many smaller Cos is to just put the most senior guy in terms of designation or experience as the manager. Or the most technically adept guy in the group gets promoted to the role of a manager.I have never seen this work out.

I feel any team of more than 4 people will definitely need a Manager early in their time-line if the project has good scaling. Ideally a technical person with man management skills, good communication should be put in charge of certain decisions.


问:
Simple questions to test understanding of Dependency Inversion Principle
I am preparing a short (1-2 hour) presentation about DIP to several (~5) junior developers (1-3 yr xp) in the office. At the end of the presentation I want to know whether they understood what I was presenting, what are some possible questions that I ask in order to figure out their understanding? Maybe something that can be answered and explained by them in 3 minutes or less?</p>

答:
You could concentrate your comprehension questions on the practical consequences of DIP principle.

DIP is about minimizing dependencies from implementations in order to achieve some quality goal, so you could possibly give two small designs, one with client's class dependency on an interface and one with direct dependency to the implementation.

Let your audience explain the advantages of using DIP with respect to different qualities, e.g. testability or maintainability.


答:
With regard to patterns, I often find myself in the situation that I don't fully understand and much less appreciate the pattern until I can explain why it is a better solution than a different pattern/style in a given situation.

Therefore, I would present examples that precisely don't use dependency injection and let the audience point out concrete difficulties that these code snippets have (with regard to modularity, testability), etc.

As a concrete example, show code of the kind:

```<code>def sendMessage(msg):
  if len(msg) > 160:
    raise MessageTooLongException('message is longer than 160 chars')
  with TweetService() as tweetService: # needed to send the message
    tweetService.tweet(msg, API_KEY)
</code>```

A good answer should point out that it is impossible to unit test this method without relying on Twitter's services:

Obviously, if Twitter is down, your unit test would fail because the tweet method raises an exception even though your code is fine. If we were using DI, we could provide a mock TweetService object which allows to check whether the tweet call was made and the object disposed of correctly.

Providing negative examples has the advantage that it trains your audience to recognize such code as they write it and helps them to notice the benefits of DI in these situations right ahead.

Title: Simple questions to test understanding of Dependency Inversion Principle

Body: I am preparing a short (1-2 hour) presentation about DIP to several (~5) junior developers (1-3 yr xp) in the office. At the end of the presentation I want to know whether they understood what I was presenting, what are some possible questions that I ask in order to figure out their understanding? Maybe something that can be answered and explained by them in 3 minutes or less?</p>

Body:
With regard to patterns, I often find myself in the situation that I don't fully understand and much less appreciate the pattern until I can explain why it is a better solution than a different pattern/style in a given situation.

Therefore, I would present examples that precisely don't use dependency injection and let the audience point out concrete difficulties that these code snippets have (with regard to modularity, testability), etc.

As a concrete example, show code of the kind:

def sendMessage(msg):
  if len(msg) > 160:
    raise MessageTooLongException('message is longer than 160 chars')
  with TweetService() as tweetService: # needed to send the message
    tweetService.tweet(msg, API_KEY)

A good answer should point out that it is impossible to unit test this method without relying on Twitter's services:

Obviously, if Twitter is down, your unit test would fail because the tweet method raises an exception even though your code is fine. If we were using DI, we could provide a mock TweetService object which allows to check whether the tweet call was made and the object disposed of correctly.

Providing negative examples has the advantage that it trains your audience to recognize such code as they write it and helps them to notice the benefits of DI in these situations right ahead.


问:
Generating random math expression
I have this idea running around in my head, to generate and evaluate random mathematical expressions. So, I decided to give it a shot and elaborate an algorithm, before coding it to test it.

Example:

Here are some example expressions I want to generate randomly:

```<code>4 + 2                           [easy]
3 * 6 - 7 + 2                   [medium]
6 * 2 + (5 - 3) * 3 - 8         [hard]
(3 + 4) + 7 * 2 - 1 - 9         [hard]
5 - 2 + 4 * (8 - (5 + 1)) + 9   [harder]
(8 - 1 + 3) * 6 - ((3 + 7) * 2) [harder]
</code>```

The easy and medium ones are pretty straight-forward. Random ints separated by random operators, nothing crazy here. But I'm having some trouble getting started with something that could create one of the hard and harder examples. I'm not even sure a single algorithm could give me the last two.

What I am considering:

I can't say I tried those ideas, because I didn't really want to waste much time going in a direction that had no chance of working in the first place. But still, I thought of a couple solutions:

Using trees

Using regular expressions

Using a crazy "for-type" loop (surely the worst)

What I'm looking for:

I'd like to know which way you believe is the best to go, between the solutions I considered, and your own ideas.

If you see a good way to start, I'd appreciate a lead in the right direction, e.g. with the beginning of the algorithm, or a general structure of it.

Also note that I will have to evaluate those expressions. This can be done either after the expression is generated, or during its creation. If you take that in consideration in your answer, that's great.

I'm not looking for anything language-related, but for the record, I'm thinking of implementing it in Objective-C, as that's the language I'm most working with recently.

Those examples did not include the : operator, as I only want to manipulate ints, and this operator adds many verifications. If your answer gives a solution handling this one, that's great.

If my question needs any clarification, please ask in the comments. Thanks for your help.

答:
first of all I'd actually generate the expression in postfix notation, you can easily convert to infix or evaluate after generating your random expression, but doing it in postfix  means you don't need to worry about parenthesis or precedence.

I'd also keep a running total of the number of terms available to the next operator in your expression (assuming you want to avoid generating expressions that are malformed) i.e. somthing like this:

```<code>string postfixExpression =""
int termsCount = 0;
while(weWantMoreTerms)
{
    if (termsCount>= 2)
    {
         var next = RandomNumberOrOperator();
         postfixExpression.Append(next);
         if(IsNumber(next)) { termsCount++;}
         else { termsCount--;}
    }
    else
    {
       postfixExpression.Append(RandomNumber);
       termsCount++;
     }
}
</code>```

obviously this is pseudo code so is not tested/may contain mistakes and you probably wouldn't use a string but a stack of some discriminated union like type

Title: Generating random math expression

Body:
first of all I'd actually generate the expression in postfix notation, you can easily convert to infix or evaluate after generating your random expression, but doing it in postfix  means you don't need to worry about parenthesis or precedence.

I'd also keep a running total of the number of terms available to the next operator in your expression (assuming you want to avoid generating expressions that are malformed) i.e. somthing like this:

string postfixExpression =""
int termsCount = 0;
while(weWantMoreTerms)
{
    if (termsCount>= 2)
    {
         var next = RandomNumberOrOperator();
         postfixExpression.Append(next);
         if(IsNumber(next)) { termsCount++;}
         else { termsCount--;}
    }
    else
    {
       postfixExpression.Append(RandomNumber);
       termsCount++;
     }
}

obviously this is pseudo code so is not tested/may contain mistakes and you probably wouldn't use a string but a stack of some discriminated union like type


答:
The parentheses in the "hard" expression represent order of evaluation.  Rather than trying to generate the displayed form directly, just come up with a list of operators in random order, and derive the display form of the expression from that.

Numbers: 1 3 3 9 7 2

Operators: + * /  + *

Result: ((1 + 3) * 3 / 9 + 7) * 2

Deriving the display form is a relatively simple recursive algorithm.

Update: here is an algorithm in Perl to generate the display form. Because + and * are distributive, it randomizes the order of the terms for those operators.  That helps keep the parentheses from all building up on one side.

```<code>use warnings;
use strict;

sub build_expression
{
    my ($num,$op) = @_;

    #Start with the final term.
    my $last_num = pop @$num;
    my $last_op = pop @$op;

    #Base case: return the number if there is just a number
    return $last_num unless defined $last_op;

    #Recursively call for the expression minus the final term.
    my $rest = build_expression($num,$op);

    #Add parentheses if there is a bare + or - and this term is * or /
    $rest = "($rest)" if ($rest =~ /[+-][^)]+$|^[^)]+[+-]/ and $last_op !~ /[+-]/);

    #Return the two components in a random order for + or *.
    return $last_op =~ m|[-/]| || rand(2) >= 1 ?
        "$rest $last_op $last_num" : "$last_num $last_op $rest";
}

my @numbers   = qw/1 3 4 3 9 7 2 1 10/;
my @operators = qw|+ + * / + * * +|;

print build_expression([@numbers],[@operators]) , "\n";
</code>```

Title: Generating random math expression

Body:
I have this idea running around in my head, to generate and evaluate random mathematical expressions. So, I decided to give it a shot and elaborate an algorithm, before coding it to test it.

Example:

Here are some example expressions I want to generate randomly:

```<code>4 + 2                           [easy]
3 * 6 - 7 + 2                   [medium]
6 * 2 + (5 - 3) * 3 - 8         [hard]
(3 + 4) + 7 * 2 - 1 - 9         [hard]
5 - 2 + 4 * (8 - (5 + 1)) + 9   [harder]
(8 - 1 + 3) * 6 - ((3 + 7) * 2) [harder]
</code>```

The easy and medium ones are pretty straight-forward. Random ints separated by random operators, nothing crazy here. But I'm having some trouble getting started with something that could create one of the hard and harder examples. I'm not even sure a single algorithm could give me the last two.

What I am considering:

I can't say I tried those ideas, because I didn't really want to waste much time going in a direction that had no chance of working in the first place. But still, I thought of a couple solutions:

Using trees

Using regular expressions

Using a crazy "for-type" loop (surely the worst)

What I'm looking for:

I'd like to know which way you believe is the best to go, between the solutions I considered, and your own ideas.

If you see a good way to start, I'd appreciate a lead in the right direction, e.g. with the beginning of the algorithm, or a general structure of it.

Also note that I will have to evaluate those expressions. This can be done either after the expression is generated, or during its creation. If you take that in consideration in your answer, that's great.

I'm not looking for anything language-related, but for the record, I'm thinking of implementing it in Objective-C, as that's the language I'm most working with recently.

Those examples did not include the : operator, as I only want to manipulate ints, and this operator adds many verifications. If your answer gives a solution handling this one, that's great.

If my question needs any clarification, please ask in the comments. Thanks for your help.

Body:
The parentheses in the "hard" expression represent order of evaluation.  Rather than trying to generate the displayed form directly, just come up with a list of operators in random order, and derive the display form of the expression from that.

Numbers: 1 3 3 9 7 2

Operators: + * /  + *

Result: ((1 + 3) * 3 / 9 + 7) * 2

Deriving the display form is a relatively simple recursive algorithm.

Update: here is an algorithm in Perl to generate the display form. Because + and * are distributive, it randomizes the order of the terms for those operators.  That helps keep the parentheses from all building up on one side.

use warnings;
use strict;

sub build_expression
{
    my ($num,$op) = @_;

    #Start with the final term.
    my $last_num = pop @$num;
    my $last_op = pop @$op;

    #Base case: return the number if there is just a number
    return $last_num unless defined $last_op;

    #Recursively call for the expression minus the final term.
    my $rest = build_expression($num,$op);

    #Add parentheses if there is a bare + or - and this term is * or /
    $rest = "($rest)" if ($rest =~ /[+-][^)]+$|^[^)]+[+-]/ and $last_op !~ /[+-]/);

    #Return the two components in a random order for + or *.
    return $last_op =~ m|[-/]| || rand(2) >= 1 ?
        "$rest $last_op $last_num" : "$last_num $last_op $rest";
}

my @numbers   = qw/1 3 4 3 9 7 2 1 10/;
my @operators = qw|+ + * / + * * +|;

print build_expression([@numbers],[@operators]) , "\n";


答: I would use trees. They can give you great control on the generation of the expressions. E.g. you can limit the depth per branch and width of each level separately. Tree based generation also gives the answer already during the generation, which is useful if you want to ensure that also the result (and subresults) are hard enough and/or not too hard to solve. Especially if you add division operator at some point, you can generate expressions that evaluate to whole numbers.</p>

Title: Generating random math expression


答:
My example would be the complete opposite of NimChimpsky's example, namely:

Trying to develop in-house something that can be bought off-the-shelf.

Normally this comes about due to a failure to actually check the market-place to see if something already exists that will solve the problem. This can be compounded by developers who like to "dive in" coding before doing any research and by project managers who fail to factor in that time = money.

One of the most common examples I've seen in my field, web development, are companies trying to develop and in-house CMS system. These invariably start off small, but soon get bloated and out-of-control as features are bolted on, whilst all the time there are plenty of free products and frameworks out-there that would be much better suited.


答:
Here's a theoretic interpretation of your problem.

You are looking to randomly generate words (algebraic expression) from a given language (the infinite set of all syntactically correct algebraic expressions). Here's a formal description of a simplified algebraic grammar supporting only addition and multiplication:

```<code>E -> I
E -> (E '+' E)
E -> (E '*' E)
</code>```

Here, E is an expression (i.e., a word of your language) and I is a terminal symbol (i.e., it's not expanded any further) representing an integer. The above definition for E has three production rules. Based on this definition, we can randomly build a valid arithmetic as follows:

Start with E as the single symbol of the output word.

Choose uniformly at random one of the non-terminal symbols.

Choose uniformly at random one of the production rules for that symbol, and apply it.

Repeat steps 2 - 4 until only terminal symbols are left.

Replace all terminal symbols I by random integers.

Here's an example of the application of this algorithms:

```<code>E
(E + E)
(E + (E * E))
(E + (I * E))
((E + E) + (I * E))
((I + E) + (I * E))
((I + E) + (I * I))
((I + (E * E)) + (I * I))
((I + (E * I)) + (I * I))
((I + (I * I)) + (I * I))
((2 + (5 * 1)) + (7 * 4))
</code>```

I assume you would choose to represent an expression with an interface Expression which is implemented by classes IntExpression, AddExpression and MultiplyExpression. The latter two then would have a leftExpression and rightExpression. All Expression subclasses are required to implement an evaluate method, which works recursively on the tree structure defined by these objects and effectively implements the composite pattern.

Note that for the above grammar and algorithm, the probability of expanding an expression E into a terminal symbol I is only p = 1/3, while the probability to expand an expression into two further expressions is 1-p = 2/3. Therefore, the expected number of integers in a formula produced by the above algorithm is actually infinite. The expected length of an expression is subject to the recurrence relation

```<code>l(0) = 1
l(n) = p * l(n-1) + (1-p) * (l(n-1) + 1)
     = l(n-1) + (1-p)
</code>```

where l(n) denotes the expected length of the arithmetic expression after n applications of production rules. I therefore suggest that you assign a rather high probability p to the rule E -> I such that you end up with a fairly small expression with high probability.

EDIT: If you're worried that the above grammar produces too many parenthesis, look at Sebastian Negraszus' answer, whose grammar avoids this problem very elegantly.

Title: Generating random math expression

Body:
Here's a theoretic interpretation of your problem.

You are looking to randomly generate words (algebraic expression) from a given language (the infinite set of all syntactically correct algebraic expressions). Here's a formal description of a simplified algebraic grammar supporting only addition and multiplication:

E -> I
E -> (E '+' E)
E -> (E '*' E)

Here, E is an expression (i.e., a word of your language) and I is a terminal symbol (i.e., it's not expanded any further) representing an integer. The above definition for E has three production rules. Based on this definition, we can randomly build a valid arithmetic as follows:

Start with E as the single symbol of the output word.

Choose uniformly at random one of the non-terminal symbols.

Choose uniformly at random one of the production rules for that symbol, and apply it.

Repeat steps 2 - 4 until only terminal symbols are left.

Replace all terminal symbols I by random integers.

Here's an example of the application of this algorithms:

E
(E + E)
(E + (E * E))
(E + (I * E))
((E + E) + (I * E))
((I + E) + (I * E))
((I + E) + (I * I))
((I + (E * E)) + (I * I))
((I + (E * I)) + (I * I))
((I + (I * I)) + (I * I))
((2 + (5 * 1)) + (7 * 4))

I assume you would choose to represent an expression with an interface Expression which is implemented by classes IntExpression, AddExpression and MultiplyExpression. The latter two then would have a leftExpression and rightExpression. All Expression subclasses are required to implement an evaluate method, which works recursively on the tree structure defined by these objects and effectively implements the composite pattern.

Note that for the above grammar and algorithm, the probability of expanding an expression E into a terminal symbol I is only p = 1/3, while the probability to expand an expression into two further expressions is 1-p = 2/3. Therefore, the expected number of integers in a formula produced by the above algorithm is actually infinite. The expected length of an expression is subject to the recurrence relation

l(0) = 1
l(n) = p * l(n-1) + (1-p) * (l(n-1) + 1)
     = l(n-1) + (1-p)

where l(n) denotes the expected length of the arithmetic expression after n applications of production rules. I therefore suggest that you assign a rather high probability p to the rule E -> I such that you end up with a fairly small expression with high probability.

EDIT: If you're worried that the above grammar produces too many parenthesis, look at Sebastian Negraszus' answer, whose grammar avoids this problem very elegantly.