问:
What's a good algorithm for a random, uneven distribution of a fixed amount of a resource?

Problem

I have X, a positive integer, of some resource, R.

There are N potential targets.

I want to distribute all of R to the N targets in some "interesting" way.

"Interesting" means:

Some targets may not get any R.

It should rarely be near even (with a majority of target getting near X/N of the resource).

There should be at least a small chance of one target getting all of R.

Bad solutions

The naive approach would be to pick a random target and give one R to it and repeat X times.  This would result in too even of an approach.

The next idea is to pick a random number between 1 and X and give it to a random target.  This results in too large of a number (at least X/2 on average) being given to one target.

Question

This algorithm will be used frequently and I want the distribution to be interesting and uneven so that the surprise doesn't wear off for users.

Is there a good algorithm for something in between these two approaches, that fits the definition of interesting above?

答:
Combine the two approaches. Hand out a random amount of the resource to a random user, then repeat. At each step, pick a portion of the remaining resource (1/x, with x a floating point number between 2 and 10), and hand it to any of the players (including a player who has already received some of the resource). When the remaining resource left to hand out gets low enough (say, under 1/2N left) just hand it out without further subdividing.

This allows for the chance of almost all of the resource going to the same player (1/2 handed out twice to one player), it being evenly divided, and a fractal-like distribution in between. Most of the time there will be significant imbalances in the resource available to each user. You can play with the cutoff point and the range of subdivision (2..10, 1..20, 3..5) to see how it varies the distribution of resources until you find a result that pleases you.

Further, the subdivision parameters could themselves be flexible... from A..B, and A and B are randomly chosen. If both are low (1.2 to 2.5) then a very small number of users will get most of the resources. If both are high (8.1 to 11.0) then the distribution will be quite even. This also allows for tuning the granularity of resource distribution as a setup option.


问:
Is it safe to install TortoiseSVN on production servers?
Small shop, few production servers, no test or development servers, all Win2k3 WEB based.

There is a need to keep versioned files on one of the machines. Is TortoiseSVN safe against exploitability, does it need extra hardening? Any known license problems, incompatibilities?

答:
If you are using SVN to deploy stuff then sure, why not? I can't count the amount of times being able to svn switch to the previous version of the app has saved our tails. It also opened up angles of letting people setup the push to production without access -- they commit, ops runs svn update.

Security-wise, it doesn't run anything that should be remotely exploitable and if you've got local exploit issues on the server then you probably need to rethink your security policy. The biggest issue if these are web apps is that the .svn folders on windows could potentially be read depending on server setup. Default IIS is fine -- it doesn't pass unknown extensions. But if you are, say, running tomcat as a web server, it will let people HTTP GET your svn-revprops and potentially bits of your source code, without some tuning. This is fixed by svn 1.7 as there are no longer .svn folders in every folder as 1.7 uses a central sqllite DB. So if you make the root folder higher than the webroot you are golden.

Or, if it helps you enough to be worth deploying to production than go for it understanding some caveats around file structures.

ContentLicense: CC BY-SA 3.0


问:
How should I log time spent on multiple tasks?
In Joel's blog on evidence based scheduling he suggests making estimates based on the smallest unit of work and logging extra work back to the original task.

The problem I'm now experiencing is that I'll have create object A with subtask method A which creates object B and test all of the above.

I create tasks for each of these that seems to be resulting in ok-ish estimates (need practice), but when I go to log work I find that I worked on 4 tasks at once because I tweak method A and find a bug in the test and refactor object B all while coding it.

How should I go about logging this work? should I say I spent, for example, 2 hours on each of the 4 tasks I worked on in the 8 hour day?

答:
I'm not intimately familiar with evidenced-based scheduling, but it sounds like your tasks are too small. You should try to make your tasks more encompassing. Although one of the examples from Joel's post is "write a subroutine foo", I think that's way too small. I find I work better if a task is a visible, deliverable thing, and my subtasks are the pieces of it. As an example, a task might be to correct a defect in an output file, and this defect is entered in the defect tracking system. My subtasks might be to review the code (especially if I'm not familiar with it), write test cases to confirm the defect (and help ensure that it's fixed), apply the fix, update the documentation, and run any smoke tests to ensure that I didn't introduce any other defects in the system before I push the changes up.

I'd also recommend focusing on one task at a time. If you find something else to do, pause, write it down (or enter the defect in the bug tracker or add a //TODO comment or...), and resume what you were doing. When you have finished your current task, prioritize the newly found tasks, make sure they are tracked per your team's process, and make sure they are done by the best people to do the job.


问:
CI tests to enforce specific development rules - good practice?
The following is all purely hypothetical and any particular portion of it may or may not accurately describe real persons or situations, whether living, dead or just pretending.

Let's say I'm a senior dev or architect in charge of a dev team working on a project. This project includes a security library for user authentication/authorization of the application under development. The library must be available for developers to edit; however, I wish to "trust but verify" that coders are not doing things that could compromise the security of the finished system, and because this isn't my only responsibility I want it to be done in an automated way.

As one example, let's say I have an interface that represents a user which has been authenticated by the system's security library. The interface exposes basic user info and a list of things the user is authorized to do (so that the client app doesn't have to keep asking the server "can I do this?"), all in an immutable fashion of course. There is only one implementation of this interface in production code, and for the purposes of this post we can say that all appropriate measures have been taken to ensure that this implementation can only be used by the one part of our code that needs to be able to create concretions of the interface.

The coders have been instructed that this interface and its implementation are sacrosanct and any changes must go through me. However, those are just words; the security library's source is open for editing by necessity. Any of my devs could decide that this secured, private, hash-checked implementation needs to be public so that they could do X, or alternately they could create their own implementation of this public interface in a different library, exposing the hashing algorithm that provides the secure checksum, in order to do Y. I may not be made aware of these changes so that I can beat the developer over the head for it. An attacker could then find these little nuggets in an unobfuscated library of the compiled product, and exploit it to provide fake users and/or falsely-elevated administrative permissions, bypassing the entire security system.

This possibility keeps me awake for a couple of nights, and then I create an automated test that reflectively checks the codebase for types deriving from the interface, and fails if it finds any that are not exactly what and where I expect them to be. I compile this test into a project under a separate folder of the VCS that only I have rights to commit to, have CI compile it as an external library of the main project, and set it up to run as part of the CI test suite for user commits. Now, I have an automated test under my complete control that will tell me (and everyone else) if the number of implementations increases without my involvement, or an implementation that I did know about has anything new added or has its modifiers or those of its members changed. I can then investigate further, and regain the opportunity to beat developers over the head as necessary.

Is this considered "reasonable" to want to do in situations like this? Am I going to be seen in a negative light for going behind my devs' backs to ensure they aren't doing something they shouldn't?

答:
What you want is completely reasonable.  Our CI build process, besides compiling the code, runs StyleCop, FxCop and NCover and runs unit tests.  The result has been much higher quality code, code which is more readable and maintainable.  You could also do some other automated things, like C# code contracts static analysis.

A nice side effect is that during our code reviews we can focus on things that really matter instead of styling / best practices.


问:
What to answer to a customer who asks which one of two equivalent technologies must be used?
As a freelancer, I am often asked by my customers what they must choose between similar elements, neither of which being better than another. Examples:

“Do I need my e-commerce website be in PHP or ASP.NET?”

“Do I need to host this ordinary web service in Cloud or use an ordinary hosting service?”

“Which one is better for my new website: MySQL or Oracle?”

etc.

There is maybe at most 1% of cases where the choice is relevant, and there is a real, objective reason to use one over another, based on the precise metrics and studies. In all other cases, it doesn't matter at all. It is totally, completely irrelevant, either because there are no implications¹, or because those implications are too small to be taken in account², or, finally, because it's impossible to predict those implications³.

If you know one thing and not another one, the answer to those questions is easy:

“You can either write the application in C# or Java, both being probably equivalent in your case. Note that I'm a C# developer, so if you choose Java, I would not be able to work on your project and you would need to find another freelancer.”

When you know both technologies, you can't answer that.

In this case, how to explain to the customer that the question he asks is subject to flamewar and has no real consequences on his project?

In other words, how to explain that you've chosen to use one technology rather than an equivalent one for the reasons related to human resources, without giving the impression to be unprofessional or to not care about the project?

¹ Example: Is MySQL better (worse?), performance-wise, compared to Oracle, for a personal website which will be accessed by, oh, let's be optimistic, two people per day?

² Example: for a given project, I was asked to asset if Windows Azure hosting would be cheaper than the hosting of the same application on a well-known ASP.NET hosting provider. The cost revealed to be exactly the same.

³ Example: your customer have an idea of a future application (the idea itself being extremely vague). There is no business plan, no requirements, nothing at all. Just an idea. You are asked if Java is better than C# for this app. What do you answer?

答:
There are rare cases where one technology is clearly inferior to another - "Should I develop my website in Python or Cobol?", but mostly it's a question of horses for courses.

There is a methodology I use for deciding which technology suits a client:-

What do they use currently?  More of the same is usually better than something new.

Does the current technology have any constraints which will be exceeded by the new project? For example, they use SQLite, but they now expect 100 users to make concurrent updates.

If the current technolgy is not suitable, then choose between the most popular open-source and the commercial market leader.

Is the market leader significantly better than the open-source offering, and, are there differences significant to the current project?

Having gone for open source or commercial, take a good like at the two nearest competing offerings and see if they are a closer fit.

Most of the time the choice stops at step two. If the client uses Acme Widgets, have people experienced in using Acme Widgets, have a set of standards, change control and management procedures built up around Acme Widgets and Acme Widgets can do the job then Acme Widgets is the way to go -- even if Ezee DohDahs is technicaly better for this task!


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

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

I'll start off with an easy one:

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

答:
When grading a student's program, I can sometimes tell in a "blink"-style moment. These are the instant clues:

Poor or inconsistent formatting

More than two blank lines in a row

Nonstandard or inconsistent naming conventions

Repeated code, the more verbatim the repeats, the stronger the warning

What should be a simple piece of code is overly complicated (for example, checking the arguments passed to main in a convoluted way)

Rarely are my first impressions incorrect, and these warning bells are right about 95% of the time. For one exception, a student new to the language was using a style from a different programming language. Digging in and re-reading their style in the idiom of the other language removed the alarm bells for me, and the student then got full credit. But such exceptions are rare.

When considering more advanced code, these are my other warnings:

The presence of many Java classes that are only "structs" to hold data. It doesn't matter if the fields are public or private and use getters/setters, it's still not likely part of a well thought-out design.

Classes that have poor names, such as just being a namespace and there's no real cohesion in the code

Reference to design patterns that aren't even used in the code

Empty exception handlers without explanation

When I pull up the code in Eclipse, hundreds of yellow "warnings" line the code, mostly due to unused imports or variables

In terms of style, I generally don't like to see:

Javadoc comments that only echo the code

These are only clues to bad code. Sometimes what may seem like bad code really isn't, because you don't know the programmer's intentions. For instance, there may be a good reason that something seems overly complex-- there may have been another consideration at play.

ContentLicense: CC BY-SA 2.5


问:
Why would you use data structures (ie Binary Trees, Linked Lists) in your jobs/side projects?
It seems to me that, for everyday use, more primitive data structures like arrays get the job done just as well as a binary tree would.  My question is how common is to use these structures when writing code for projects at work or projects that you pursue in your free time?

I understand the better insertion time/deletion time/sorting time for certain structures but would that really matter that much if you were working with a relatively small amount of data?

答:
Very honestly, I have to disagree.  I spend a lot of my free time writing C. I've done a number of interpreters lately. Although I do use arrays in some circumstances, I almost always use linked lists, binary trees, hash tables or other structures.

I have two reasons:

No size limits. No matter how much you think you know at first,
you'll always hit a size limit.

More natural algorithms fall out of things like linked lists and
binary trees. You can recurse on them, or you can iterate, but they
just work better.


答:
I use trees/maps and lists literally every day. Actually I rarely use arrays at all, for their inflexibility: arrays are harder to work with!

Which specific implementation of a list (ArrayList, LinkedList,..) or map (HashMap, TreeMap,..) I use depends solely on the task on hand, and takes some common sense and educated guessing.

Title: Why would you use data structures (ie Binary Trees, Linked Lists) in your jobs/side projects?

Body:
It seems to me that, for everyday use, more primitive data structures like arrays get the job done just as well as a binary tree would.  My question is how common is to use these structures when writing code for projects at work or projects that you pursue in your free time?

I understand the better insertion time/deletion time/sorting time for certain structures but would that really matter that much if you were working with a relatively small amount of data?


答: If I'm using Python, I use mainly: dictionaries (no surprise), lists, tuples. I admit that I regard lists as arrays so long as they can be indexed as one.</p>


答:
So many useful data structures are in convenient-to-use libraries these days that I use the best data structure for the job regardless, which very often is trees, linked lists, tries, or whatever.  Of course, this is expected at work.  But why would I want to make my life harder just because it's a hobby project?  I don't do hobby programming so that I can have fun typing out a[x+1] = a[x] + a[x-1] a bunch of times; I do it to solve problems.  Appropriate use of data structures is a big part of how to make this happen.

If you're asking how often do I write a custom data structure...well..not very often in any context, since so many powerful ones are available in libraries.  But the rule is the same: if a novel data structure is "best" (taking into account how long it will take me to write and debug the code for it), then I use it.


答:
Each language has its own set of 'built in' data structures that developers make use of more than others. In C its arrays, but in C#, Python and Ruby its probably Lists and Dictionaries. It depends on what you get 'for free' with a language and its base library.

I'm developing mainly in C# and use the generic (strongly typed) List all the time along with the generic Dictionary. It frees you from having to worry about the data structure implementation and you can just concentrate on your algorithm. In C I think you'd spend a lot more time implementing these types of things and so you may be happy sticking to lower level structures like arrays.

But implementing your own custom data structures does have a role too - I recently needed to setup a QuadTree type in C# for partitioning 2D space - that was the best solution for what was needed.


答:
/* Fuck this error */
```

<p>Typically found inside a nonsense <code>try..catch</code> block, it tends to grab my attention. Just about as well as <code>/* Not sure what this does, but removing it breaks the build */</code>.</p>

<p>A couple more things:</p>

<ul>
<li>Multiple nested complex <code>if</code> statements</li>
<li>Try-catch blocks that are used to determine a logic flow on a regular basis</li>
<li>Functions with generic names <code>process</code>, <code>data</code>, <code>change</code>, <code>rework</code>, <code>modify</code></li>
<li>Six or seven different bracing styles in 100 lines</li>
</ul>

<p>One I just found:</p>

<pre class="lang-perl prettyprint-override"><code>/* Stupid database */
$conn = null;
while(!$conn) {
    $conn = mysql_connect("localhost", "root", "[pass removed]");
}
/* Finally! */
echo("Connected successfully.");
</code>```

Right, because having to brute force your MySQL connections is the right way do things. Turns out the database was having issues with the number of connections so they kept timing out. Instead of debugging this, they simply attempted again and again until it worked.

Title: Which things instantly ring alarm bells when looking at code?

Body:
I attended a software craftsmanship event a couple of weeks ago and one of the comments made was "I'm sure we all recognize bad code when we see it" and everyone nodded sagely without further discussion.

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

I'll start off with an easy one:

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

Body:
/* Fuck this error */

Typically found inside a nonsense try..catch block, it tends to grab my attention. Just about as well as /* Not sure what this does, but removing it breaks the build */.

A couple more things:

Multiple nested complex if statements

Try-catch blocks that are used to determine a logic flow on a regular basis

Functions with generic names process, data, change, rework, modify

Six or seven different bracing styles in 100 lines

One I just found:

/* Stupid database */
$conn = null;
while(!$conn) {
    $conn = mysql_connect("localhost", "root", "[pass removed]");
}
/* Finally! */
echo("Connected successfully.");

Right, because having to brute force your MySQL connections is the right way do things. Turns out the database was having issues with the number of connections so they kept timing out. Instead of debugging this, they simply attempted again and again until it worked.


答:
I used to work with both C++ and C#. I use Lists, Maps, Vectors almost everyday. Most of the people are not really bothered about taking it in a perspective of data structure but just as a way to meet their target.

I use arrays very rarely, mostly when working with Windows APIs etc. where we need to give fixed length array. But on the other hand, I am not used to replace arrays with the dynamically growing data structures like vector. I feel it's tricky and on top of complexity it spoils the readability.

It also depends what kind of platform you're working on. When I have worked in embedded Linux project, I was mostly stuck with fixed size arrays where none of these C++ data structures or implementations can be used.


问:
Separating model from UI
I have a Swing application with a custom TreeModel that can refer to domain instances. I'm wondering what changes I could make if I consider moving to a web interface later on. Would a pluggable model be considered as good design? What would you do?</p>

答: A pluggable model, using MVC (at a larger system level than what Swing defines MVC as), or a facade pattern would all work</p>

Title: Separating model from UI


答:
Effective C++ says that std::vector (a resizeable array) should be the default choice for a container. Bjarne Stroustrup presented an "invisible graph" [vanished from the slides] on the Going Native conference where he compared theoretically better data structure (linked list) with a vector.  Vector won for his tested size range as cache misses caused by following list elements killed performance totally.

At work we develop various data-transformation algorithms where performance is important, and ~75% of all data structures are vectors.  Next in line come sorted vectors, which are efficiently searchable with binary search (std::lower_bound and std::upper_bound). Next come hashes and trees (when the algorithm needs efficient online insert/update/delete [i.e., when a sorted vector can't be constructed from scratch]), after them comes std::dequeue (a combination of list and sequential allocation) meagerly used less than a dozen times. Singly/doubly linked list? < 5 (I'd even dare say zero) occurrences in a large C++ project.


答:
I wonder if it is not the fault of the way you are organizing your tasks. As I read it you are creating tasks at the level of code. ie a task for Class A, and perhaps subtasks for method B,C.

Try setting your tasks at a higher level of abstraction ( ie UseCase / functional behaviour / Use story level ). If it requires you to change 4 areas of code to achieve one outcome, that is one task. Also it will save you having to "refactor" your tasks when you change your technical approach.

Depending on your SDLC approach you need to ensure that these task levels are correctly size (   generally the more agile your approach the smaller the size ought to be )

Title: How should I log time spent on multiple tasks?

Body:
In Joel's blog on evidence based scheduling he suggests making estimates based on the smallest unit of work and logging extra work back to the original task.

The problem I'm now experiencing is that I'll have create object A with subtask method A which creates object B and test all of the above.

I create tasks for each of these that seems to be resulting in ok-ish estimates (need practice), but when I go to log work I find that I worked on 4 tasks at once because I tweak method A and find a bug in the test and refactor object B all while coding it.

How should I go about logging this work? should I say I spent, for example, 2 hours on each of the 4 tasks I worked on in the 8 hour day?


答:
You have a couple of ways you can go about this sort of thing.  If you spot a problem in something you have worked on before, you could:

Fix the problem as a part of the task you are working on - refactoring dependencies to ensure your current task completes successfully.

Log a bug, and provide estimates to fix it in your issue tracker.  Then prioritize the task so that you either,

complete the dependent task first, or

complete the current task with tests showing an error, then go on to fix the bug you've logged, and on completion wait for tests in both cases to pass before checking it all in.

Personally I'm not in favour of leaving things in error while fixing other things.  If the bug is new, and it's something in a dependency, then I simply fix the problem as a part of the task that I am working on.  Once a task is complete, it's complete, and if it has a bug, it has a bug.  Hopefully your testing avoids this situation, but if your tests still pass, then the prior task should be finished, closed, and left alone.

If you have made your tasks very granular, then you need to ensure that you have dealt with dependency items first.  If you have two tasks with common dependency, you might complete the dependency in one task so that it is available when you move onto the next task. So by effectively completing tasks, You shouldn't need to worry about jumping back and forth between two tasks. It should just be a case of logging a bug, or fixing it as a necessary part of the thing you might be working on at the time.

Yes, this could all mess with your estimates, but if this is something that happens often and you are using Evidence Based Scheduling, then your estimations will all work out fine (statistically) after a short while, so I wouldn't worry to much about it. :-)


问:
How can a large, Fortran-based number crunching codebase be modernized?
A friend in academia asked me for advice (I'm a C# business application developer).

He has a legacy codebase which he wrote in Fortran in the medical imaging field. It does a huge amount of number crunching using vectors. He uses a cluster (30ish cores) and has now gone towards a single workstation with 500ish GPUS in it.

However where to go next with the codebase so:

Other people can maintain it over next 10 year cycle

Get faster at tweaking the software

Can run on different infrastructures without recompiles

After some research from me (this is a super interesting area) some options are:

Use Python and CUDA from Nvidia

Rewrite in a functional language. For example, F# or Haskell

Go cloud based and use something like Hadoop and Java

Learn C

What has been your experience with this? What should my friend be looking at to modernize his codebase?

UPDATE: Thanks @Mark and everyone who has answered. The reasons my friend is asking this question is that it's a perfect time in the projects lifecycle to do a review.  Bringing research assistants up to speed in Fortran takes time (I like C#, and especially the tooling and can't imagine going back to older languages!!)

I liked the suggestion of keeping the pure number crunching in Fortran, but wrapping it in something newer. Perhaps Python as that seems to be getting a stronghold in academia as a general-purpose programming language that is fairly easy to pick up.

See Medical Imaging and a guy who has written a Fortran wrapper for CUDA, Can I legally publish my Fortran 90 wrappers to Nvidias' CUFFT library (from the CUDA SDK)?.

答:
I am currently in a situation very similar to your friend's. I am also desperate to "modernize" my 40-something KLOC Fortran-77 legacy code. And despite that Fortran is still considered the king in number crunching applications, I would like to say that all is not lost. (What follows is rant-ish so bear with me).

Just because Fortran is the best language for numerical code doesn't mean we have to carry this huge baggage of a messy, complicated code with us all the time (Yes a Fortran code is bound to be messy, especially Fortran-77 that is a language that has literally no regard for software-engineering, when it crosses a certain KLOCs). Those who advocate Fortran for number-crunching forget the general observation that when you do performance analysis of such codes, it's only 5% or 10% of the code that is performance intensive and for the remaining 90%+ Fortran is a useless overhead, just there to make your life as a "software engineer" a living hell.

When you are moving to Fortran-90 from Fortran-77, you're essentially willing to trade-off performance with language features to an extent. Fortran is a powerful number cruncher primarily because of Fortran-77. You might say Fortran-90 is as fast, but the kind of optimization issues compiler writers had to deal with while adding Fortran-90/2003 features and still keeping Fortran-77 performance are not much different from the issues C compiler writers had to deal with (and as a result C is considered as fast too, not to mention C allows inline-assembly as well). So why not start adding C code bit by bit (instead of Fortran-90) into a Fortran-77 code. My code already has pieces in C and pieces in Fortran-77 and it works great subject to some issues like passing strings, zero-indexing/one-indexing etc. But the advantage I get from C, in terms of File I/O, string manipulation, better community support, more familiarity among new programmers etc, etc, would I get that from Fortran-90?

I'd go one step further. Even C (and definitely Fortran-90/95/2003) is too low-level if you want a nice "humane" interface to a number crunching code. I'm thinking of moving to a Python-Fortran-77 or a Python-C hybrid. A code in which 90% of the code is Python (including Numpy, Scipy, plotability, and all that sweetness) and only the performance intensive 5%-10% remains as Fortran-77 or C code.


答:
I was lead dev on a project from 2001-2003 which ported a 100KLOC windows application from FORTRAN to C#. It was a number crunching application which had its own custom GUI bindings to Win32 libraries. The port to C# and WinForms made the management of the code far simpler and gave everyone a richer development environment in Visual Studio. There was a fair bit of resistance early (especially in terms of format statements), but in the end it was definitely worthwhile.

In my opinion it makes sense to bite the bullet and get rid of the maximum amount of FORTRAN code possible. Speed was never an issue - initial tests running code in C# compared to FORTRAN found the performance difference to be negligible, even though C# is running managed code. Your needs with vectors may be a bit different however, and having a minority amount of FORTRAN code left over would also be acceptable.

Another reason to do it is of course the long term availability of people with FORTRAN experience who can maintain your code as compared to C# developers. Also, it helps team morale to be working in a modern, well supported language.

Title: How can a large, Fortran-based number crunching codebase be modernized?

Body:
A friend in academia asked me for advice (I'm a C# business application developer).

He has a legacy codebase which he wrote in Fortran in the medical imaging field. It does a huge amount of number crunching using vectors. He uses a cluster (30ish cores) and has now gone towards a single workstation with 500ish GPUS in it.

However where to go next with the codebase so:

Other people can maintain it over next 10 year cycle

Get faster at tweaking the software

Can run on different infrastructures without recompiles

After some research from me (this is a super interesting area) some options are:

Use Python and CUDA from Nvidia

Rewrite in a functional language. For example, F# or Haskell

Go cloud based and use something like Hadoop and Java

Learn C

What has been your experience with this? What should my friend be looking at to modernize his codebase?

UPDATE: Thanks @Mark and everyone who has answered. The reasons my friend is asking this question is that it's a perfect time in the projects lifecycle to do a review.  Bringing research assistants up to speed in Fortran takes time (I like C#, and especially the tooling and can't imagine going back to older languages!!)

I liked the suggestion of keeping the pure number crunching in Fortran, but wrapping it in something newer. Perhaps Python as that seems to be getting a stronghold in academia as a general-purpose programming language that is fairly easy to pick up.

See Medical Imaging and a guy who has written a Fortran wrapper for CUDA, Can I legally publish my Fortran 90 wrappers to Nvidias' CUFFT library (from the CUDA SDK)?.


问:
What is a good way to comment if-else-clauses?
Whenever I'm writing a typical if-else-construct in any language I wonder what would be the best way (in terms of readability and overview) to add comments to it. Especially when commenting the else clause the comments always feel out-of-place for me. Say we have a construct like this (examples are written down in PHP):

```<code>if ($big == true) {
    bigMagic();
} else {
    smallMagic()
}
</code>```

I could comment it like this:

```<code>// check, what kind of magic should happen
if ($big == true) {
    // do some big magic stuff
    bigMagic();
} else {
    // small magic is enough
    smallMagic()
}
</code>```

or

```<code>// check, what kind of magic should happen
// do some big magic stuff
if ($big == true) {
    bigMagic();
}
// small magic is enough
else {
   smallMagic()
}
</code>```

or

```<code>// check, what kind of magic should happen
// if:   do some big magic stuff
// else: small magic is enough
if ($big == true) {
    bigMagic();
} else {
    smallMagic()
}
</code>```

What are your best-practice examples for commenting this?

答:
Keep your conditional blocks really short.

Call a method with a nice descriptive name if it looks like your conditional code is going to be more than a simple line or two.

Use nice descriptive names for your variables.

Make sure the conditional statement is clear in it's meaning, and not obfuscated or long.  Use a method if it helps to keep things clean and readable.

If all of the above fails, add a very small descriptive comment before the if statement, to clarify your intent.  Otherwise, there really shouldn't be a need to comment at all.


问:
"// ..." comments at end of code block after } - good or bad?
I've often seen such comments be used:

```<code>function foo() {
   ...
} // foo

while (...) {
   ...
} // while

if (...) {
   ...
} // if
</code>```

and sometimes even as far as

```<code>if (condition) {
   ...
} // if (condition)
</code>```

I've never understood this practice and thus never applied it. If your code is so long that you need to know what this ending } is then perhaps you should consider splitting it up into separate functions. Also, most developers tools are able to jump to the matching bracket. And finally the last is, for me, a clear violation to the DRY principle; if you change the condition you would have to remember to change the comment as well (or else it could get messy for the maintainer, or even for you).

So why do people use this? Should we use it, or is it bad practice?

答:
In C++ there are two holdovers where this is still useful and the advice of "split up your code" doesn't necessary hold:

For namespaces.  A namespace can encompass an entire file, and that last bracket can sometimes throw people off, so adding a comment to indicate the bracket is the closing of a namespace is useful.  For the particular coding style at my company this is important because we do not indent namespaces as it was decided that such indentation would just waste space in a file.

For #ifdef / #endif pairs.  Sometimes there's a lot of code in there for conditional compilation, it can get nasty with nesting, and the editor we use often heavy-handedly "helpfully" eliminates indentation, so the comments are useful during a quick overview.


问:
Intel mnemonic to machine code converter library
I'm trying to do the following: take a single IA32 instruction in the Intel syntax (such as ADD EAX, EBX) and produce the corresponding machine code for this instruction. Is there some small library, preferably open source, that can do this for me?

答:
You can do it with FASM.

There is a sample GUI application distributed with FASM DLL

Or, you can use Python interpreter, with Python binding for FASM DLL


问:
Function parameter names
I just found the following code in our code base:

```<code>public String identifyArchitectureName(String platformName, String input) ...
</code>```

In my opinion input is one of the most meaningless names for a variable that can be. Is it just me? I can just quietly change it, but should I address the fellow programmer that has done it?

答:
Do you mean input? Just change it, if you think there is a better name.

It's parameter, renaming it won't break any code.

Title: Function parameter names


答:
Part of working with others is educating/teaching/mentoring them, in particular if you have seniority.

By all means, take it up with the developer and come up with a better name together.

Title: Function parameter names

Body:
I just found the following code in our code base:

```<code>public String identifyArchitectureName(String platformName, String input) ...
</code>```

In my opinion input is one of the most meaningless names for a variable that can be. Is it just me? I can just quietly change it, but should I address the fellow programmer that has done it?


答:
It depends on the context to me.

```<code>string GetEncrypted(string input)
</code>```

quite obviously, input is a string to be encrypted. What would you rename this parameter to?

I also use str for methods that perform conversions or string manipulations

```<code>MyEnum Parse(string str) // what could str be? login? password? text to be parsed?

public static int? TryToInt(this string str)
</code>```

I don't think this is the same as

```<code>public String identifyArchitectureName(String platformName, String input)
</code>```

Title: Function parameter names

Body:
It depends on the context to me.

string GetEncrypted(string input)

quite obviously, input is a string to be encrypted. What would you rename this parameter to?

I also use str for methods that perform conversions or string manipulations

MyEnum Parse(string str) // what could str be? login? password? text to be parsed?

public static int? TryToInt(this string str)

I don't think this is the same as

public String identifyArchitectureName(String platformName, String input)


答:
I'm in two minds about whether you should confront the other programmer.

My first thought is that I'd be inclined just to rename it and be done with it.

While we should all be big boys about receiving critique, having a conversation about a parameter name on face value seems almost a little petty or over the top.

That being said, if this was just one of a series of "little petty" things I can see it might be the straw that breaks the camel's back.

Do you have a formal peer review process that you could cover this in?

Title: Function parameter names


问:
Is the abundance of frameworks dumbing down programmers?
With all of the frameworks available these days, ORMs, dependency injection (DI), Inversion of control (IoC), etc., I find that many programmers are losing or don't have the problem solving skills needed to solve difficult issues. Many times, I've seen unexpected behaviour creep into applications and the developers unable to really dig in and find the issues. It seems to me that deep understanding of what's going on under the hood is being lost.

Don't get me wrong, I'm not suggesting these frameworks aren't good and haven't moved the industry forward, only asking if, as a unintended consequence, developers aren't gaining the knowledge and skill needed for deep understanding of systems.

答:
No, learning the frameworks improves the skills of a programmer. Framework is the extension of a programming language. Some languages are already framework based. I work with both PHP and Java. PHP needs a framework like template engine (sometimes). Java don't need a framework (most times), it already has many methods and libraries.   </p>

<p>Most Frameworks will have functions that programmers use again and again. </p>

Body:
No, learning the frameworks improves the skills of a programmer. Framework is the extension of a programming language. Some languages are already framework based. I work with both PHP and Java. PHP needs a framework like template engine (sometimes). Java don't need a framework (most times), it already has many methods and libraries.

Most Frameworks will have functions that programmers use again and again.


问:
Inexpensive generation of hierarchical unique IDs
My application is building a hierarchical structure like this:

```<code>root = {
  'id': 'root',
  'children': [ {
    'name': 'root_foo',
    'children': []
  }, {
    'id': 'root_foo2',
    'children': [ {
      'id': 'root_foo2_bar',
      'children': []
      } ]
  } ]
}
</code>```

in other words, it's a tree of nodes, where each node might have child elements and unique identifier I call "id". When a new child is added, I need to generate a unique identifier for it, however I have two problems:

identifiers are getting too long

adding many children takes slower, as I need to find first available id

My requirement is:

naming of a child X must be determined only from the state in their ancestors

When I re-generate tree with same contents, the IDs must be same

or in other words, when we have nodes A and B, creating child in A, must not affect the name given to children of B.

I know that one way to optimize would be to introduce counter in each node and append it to the names which will solve my performance issue, but will not address the issue with the "long identifiers".

Could you suggest me the algorithm for quickly coming up with new IDs?

答:
if children are ordered, then you can use the following schema:

empty string means the root

1.0.3 means the fourth child of the first child of the second child of the root.

It is short, allows you to fetch a node from its ID, is unique, and is hierachical. It is a kind of prefix tree.


问:
Effectiveness of "what is your greatest strength/weakness" interview questions
As someone who is now finding himself on the other end of the interview table, I'm wondering how useful these questions are from an employer's perspective. Some of my coworkers think they're good because you can see "how they respond," but I'm not convinced it tells you anything useful, for several reasons:

It's not a very comfortable question and can lead people to twist their answers, even if not on purpose

People may not fully know their greatest strengths or weaknesses (i.e. judge them by their peers)

Explaining what a strength is isn't as good as showing it

I still don't know any more about the candidate afterwards

The rationale of my coworkers is that it can help weed out people that give ridiculous responses, like one guy that said his greatest strength was "his intellect" or people that try to turn the weakness question into a strength like "I work too hard." But I think there's more effective ways to determine such things. If you want to see if someone's smart, ask them technical questions. If you want to see if someone is productive, look at their work history. If you want to see how someone reacts under stress or change, ask them how they've dealt with it and ask for concrete examples.

What are people's thoughts on these questions, from the perspective of an interviewer? What do they really tell you about a candidate, and what are better alternatives? How do I convince my colleagues of this?

答:
The purpose of the "greatest weakness" question is greatly misunderstood!

The idea is not to talk about your weakness as a person (e.g. "boy, I'm a workaholic!"), it's to give you an opportunity to be up front about what they are already going to find out. It's about how well of a match you are for the job requirements.

For example:

"Your ad says you want svn admin experience, but I've only worked with hg, however I'm fast at learning."

"Your ad says that fluency in Spanish is desired, but I only took two years of it in high school."

Naturally, you should do the same comparison of your skills/experience for the "greatest strength" question too.

Also, if the ad really describes you perfectly, when asked for your weakness simply say "I don't think there are any. I'm a good fit for this job."

I'm trying to imagine how the original meaning of this question got to be misinterpreted to be about personality, and it probably happens when a more junior interviewer is given the list of questions to ask and they don't know what it means. If you are in the position to change this at your company, reword the question to be specific: "This job requires A, B, C, what are your weaknesses in these areas?" [The question actually does the interviewee a favor: Their resume might show no experience with X, but you might find something that compensates for that.]


答:
You are right that the name input doesn't communicate it's intention really well. Uncle Bob talks about "Boy Scout Rule" in his book Clean Code: "Leave the campground cleaner than you found it." The idea is that if you refactor code every time you touch, it is impossible for the code quality to degrade. So feel free to replace the parameter name to more descriptive one.

I wouldn't necessarily confront my coworker for a single instance like that. If that sort of bad naming conventions are typical in you project, then you should gather your team together and come up with common conventions about naming, style etc. Then after everybody knows the rules, they can be enforced with code reviews.

Still, everybody makes mistakes and nitpicking about one parameter name is not cool :) just fix it and get on with whatever you are doing

Title: Function parameter names


问:
Do you prefer conciseness or readability in your code?
Language shortcuts can often be used to make code more concise.

For example, ternary and null coalescing operators can reduce the amount of code, but arguably to the detriment of readability:

In C#:

```<code>Person newGuy = new Person();
if (boss == null) {
    newGuy.Boss = GetDefaultBoss();
} else {
    newGuy.Boss = boss;
}
</code>```

is functionally equivalent to:

```<code>Person newGuy = new Person();
newGuy.Boss = boss ?? GetDefaultBoss();
</code>```

but obviously a lot more verbose.

Where do you draw the line when it comes to conciseness vs readability?

答:
Readability comes first where it conflicts with conciseness, because code is modified more often than it is initially written.  On the other hand:

Syntactic noise and boilerplate code often obscure intentions and thus hurt readability.  Sometimes the more concise code is also more readable.  For example, think lambda functions or delegates/first-class functions versus single-method classes that implement a single-method interface.

Readability should be assessed based on how easy the code is to read for a reasonably experienced programmer who knows the language and its unique/advanced features fairly well, not some barely competent code monkey who only knows the lowest common denominator.


答:
Change it?  Sure.

Confront the other person?  Not so fast.  I'd rather see  you kick off a group discussion about coding standards, and add a paragraph to the coding standards document (you have one, right?) that specifies that in non-trivial cases, formal  parameters should be self documenting.

Title: Function parameter names


问:
Why is my class worse than the hierarchy of classes in the book (beginner OOP)?
I am reading PHP Objects, Patterns, and Practice. The author is trying to model a lesson in a college. The goal is to output the lesson type (lecture or seminar), and the charges for the lesson depending on whether it is an hourly or fixed price lesson. So the output should be

```<code>Lesson charge 20. Charge type: hourly rate. Lesson type: seminar.
Lesson charge 30. Charge type: fixed rate. Lesson type: lecture.
</code>```

when the input is as follows:

```<code>$lessons[] = new Lesson('hourly rate', 4, 'seminar');
$lessons[] = new Lesson('fixed rate', null, 'lecture');
</code>```

I wrote this:

```<code>class Lesson {
    private $chargeType;
    private $duration;
    private $lessonType;

    public function __construct($chargeType, $duration, $lessonType) {
        $this->chargeType = $chargeType;
        $this->duration = $duration;
        $this->lessonType = $lessonType;
    }

    public function getChargeType() {
        return $this->getChargeType;
    }

    public function getLessonType() {
        return $this->getLessonType;
    }

    public function cost() {
        if($this->chargeType == 'fixed rate') {
            return "30";
        } else {
            return $this->duration * 5;
        }
    }
}

$lessons[] = new Lesson('hourly rate', 4, 'seminar');
$lessons[] = new Lesson('fixed rate', null, 'lecture');

foreach($lessons as $lesson) {
    print "Lesson charge {$lesson->cost()}.";
    print " Charge type: {$lesson->getChargeType()}.";
    print " Lesson type: {$lesson->getLessonType()}.";
    print "<br />";
}
</code>```

But according to the book, I am wrong (I am pretty sure I am, too). Instead, the author gave a large hierarchy of classes as the solution. In a previous chapter, the author stated the following 'four signposts' as the time when I should consider changing my class structure:

Code duplication

The class who knew too much about its context

The jack of all trades - classes that try to do many things

Conditional statements

The only problem I can see is conditional statements, and that too in a vague manner - so why refactor this? What problems do you think might arise in the future that I have not foreseen?

Update: I forgot to mention - this is the class structure the author has provided as a solution - the strategy pattern:

答:
First of all you can change "magic numbers" like 30 and 5 in cost() function to more meaningfull variables :)

And to be honest, I think that you should not worry about this. When you will need to change the class then you will change it. Try to create value first then move onto refactorization.

And why are you thinking that you are wrong ? Isn't this class "good enough" for you ? Why are you worried about some book ;)


问:
Good interview programming projects
I'm looking for some small programming projects that I can give potential employees to gauge their programming abilities. These will be programmers straight out of college. I'm looking for projects that would take someone a couple of hours and they would email back their answers post-interview.

One example would be to take this paragraph of text and return a list of alphabetized unique words. After each word tell me how many times the word appeared and in what sentance(s) the word appreared in.

Anyone have any good suggestions?

答:
You might want to check out Jon Jagger's fantastic Cyber-Dojo.

It's a web based integrated environment designed for doing deliberate practice of Test Driven Development and learning about team dynamics. It has lots of small programming tasks (kata's) and supports a range of languages, from Python and Ruby to Java and C++.

Unlike IDE's designed for productivity, there is no code-completion, syntax highlighting or auto-refactoring, so you get to see what your interviewee can do without these.

The best thing is, after doing a kata you can then go back and look at the red/green progression (or maybe not if they don't do TDD *8') of each of kata. Every compile/test commits the changes to a git repository along with the results of the test.

I think using this for interview coding tests could tell you a lot about not only a candidates ability to solve a problem, but also their approach to problem solving and the process they use when not constrained by external factors, just select a kata appropriate to the time you want the candidate spend on it.

If you want your own CyberDojo server, the whole project can be found at github and there is even a Turnkey Linux appliance virtual machine linked from there, which means that assuming you already have VMware player or VirtualBox installed, you can be up and running within a few minutes of downloading the appliance!

Title: Good interview programming projects


问:
Which specific practices could be called "software craftsmanship" rather than "software engineering"?
Although not a new idea there seems to have been a big increase in the interest in software craftsmanship over the last couple of years (notably the often recommended book Clean Code's full title is Clean Code: A Handbook of Agile Software Craftsmanship).

Personally I see software craftsmanship as good software engineering with an added interest in ensuring that the end result is a joy to work with (both as an end user and as someone maintaining that software) - and also that its focus is more at the coding level of things than the higher level process things.

To draw an analogy - there were lots of buildings constructed in the 50s and 60s in a very modern style which took very little account of the people who would be living in them or how those buildings would age over time. Many of those buildings rapidly developed into slums or have been demolished long before their expected lifespans. I'm sure most developers with a few years under their belts will have experienced similar codebases.

What are the specific things that a software craftsman might do that a software engineer (possibly a bad one) might not?

答:
Refactoring To Patterns.

That is, build something that satisfies 90% of the software requirements, then refactor the whole project into some clean, elegant design.

Normally, software engineering would prevent you from doing this, because satisfying 90% of the requirements means that the software has enough business value to the customer that it should not be modified in any significant way (except high-priority bugfixes).

Software engineering would instead advise you to stabilize the software at this point.

Furthermore, if a project does not start with that elegant design from the very beginning, it would be considered a poorly executed project (regardless of the project's outcome), according to software engineering.

Spike Solution.

A design that is inspired from a spike solution is normally not acceptable according to the prevailing software engineering methodology.

Deprecation, for whatever reason.

In software engineering, any kind of deprecation is allowed to happen only at the end of a software system's life cycle. This must be planned as part of the SDLC.

In practice, it is rather common that the shortcomings of a specific part of the software interface being discovered a few years into production, and that specific part can be deprecated in the middle of the life cycle, without invalidating the rest of the software. This would have required a re-certification of the entire software system after the deprecation, according to software engineering.

In the end, software craftsmanship is a personal strive for good judgments from individuals, whereas software engineering is a conservative body of knowledge. Allowing that good judgment into the project's decision making is what separates software craftsmanship from software engineering.


答:
I guess that what the book aims at teaching is to avoid things like:

```<code>public function cost() {
    if($this->chargeType == 'fixed rate') {
        return "30";
    } else {
        return $this->duration * 5;
    }
}
</code>```

My interpretation of the book is that you should have three classes:

AbstractLesson

HourlyRateLesson

FixedRateLesson

You should then reimplement the cost function on both subclass.

My personal opinion

for simple cases like that: don't. It is strange that your book favors deeper class hierarchy to avoid simple conditional statements. What's more, with your input spec, Lesson will have to be a factory with a dispatch which is a conditional statement. So with the book solution you will have:

3 classes instead of 1

1 inheritance level instead of 0

the same number of conditional statements

That's more complexity with no added benefit.

Title: Why is my class worse than the hierarchy of classes in the book (beginner OOP)?

Body:
I am reading PHP Objects, Patterns, and Practice. The author is trying to model a lesson in a college. The goal is to output the lesson type (lecture or seminar), and the charges for the lesson depending on whether it is an hourly or fixed price lesson. So the output should be

```<code>Lesson charge 20. Charge type: hourly rate. Lesson type: seminar.
Lesson charge 30. Charge type: fixed rate. Lesson type: lecture.
</code>```

when the input is as follows:

```<code>$lessons[] = new Lesson('hourly rate', 4, 'seminar');
$lessons[] = new Lesson('fixed rate', null, 'lecture');
</code>```

I wrote this:

```<code>class Lesson {
    private $chargeType;
    private $duration;
    private $lessonType;

    public function __construct($chargeType, $duration, $lessonType) {
        $this->chargeType = $chargeType;
        $this->duration = $duration;
        $this->lessonType = $lessonType;
    }

    public function getChargeType() {
        return $this->getChargeType;
    }

    public function getLessonType() {
        return $this->getLessonType;
    }

    public function cost() {
        if($this->chargeType == 'fixed rate') {
            return "30";
        } else {
            return $this->duration * 5;
        }
    }
}

$lessons[] = new Lesson('hourly rate', 4, 'seminar');
$lessons[] = new Lesson('fixed rate', null, 'lecture');

foreach($lessons as $lesson) {
    print "Lesson charge {$lesson->cost()}.";
    print " Charge type: {$lesson->getChargeType()}.";
    print " Lesson type: {$lesson->getLessonType()}.";
    print "<br />";
}
</code>```

But according to the book, I am wrong (I am pretty sure I am, too). Instead, the author gave a large hierarchy of classes as the solution. In a previous chapter, the author stated the following 'four signposts' as the time when I should consider changing my class structure:

Code duplication

The class who knew too much about its context

The jack of all trades - classes that try to do many things

Conditional statements

The only problem I can see is conditional statements, and that too in a vague manner - so why refactor this? What problems do you think might arise in the future that I have not foreseen?

Update: I forgot to mention - this is the class structure the author has provided as a solution - the strategy pattern:

Body:
I guess that what the book aims at teaching is to avoid things like:

public function cost() {
    if($this->chargeType == 'fixed rate') {
        return "30";
    } else {
        return $this->duration * 5;
    }
}

My interpretation of the book is that you should have three classes:

AbstractLesson

HourlyRateLesson

FixedRateLesson

You should then reimplement the cost function on both subclass.

My personal opinion

for simple cases like that: don't. It is strange that your book favors deeper class hierarchy to avoid simple conditional statements. What's more, with your input spec, Lesson will have to be a factory with a dispatch which is a conditional statement. So with the book solution you will have:

3 classes instead of 1

1 inheritance level instead of 0

the same number of conditional statements

That's more complexity with no added benefit.


答: There's absolutely no need whatsoever to implement any additional classes. You have a bit of a MAGIC_NUMBER problem in your cost() function, but that's it. Anything else is a massive over-engineering. However, it's unfortunately common for very bad advice to be given out- Circle inherits Shape, for example. It's definitely not efficient in any way to derive a class for the simple inheritance of one function. You could use a functional approach to customize it instead.


答:
The example in the book is pretty strange. From your question, the original statement is:

The goal is to output the Lesson Type (Lecture or Seminar), and the Charges for the lesson depending on whether it is a hourly or fixed price lesson.

which, in the context of a chapter on OOP, would mean that the author probably wants you to have following structure:

```<code>+ abstract Lesson
    - Lecture inherits Lesson
    - Seminar inherits Lesson

+ abstract Charge
    - HourlyCharge inherits Charge
    - FixedCharge inherits Charge
</code>```

But then comes the input you quoted:

```<code>$lessons[] = new Lesson('hourly rate', 4, 'seminar');
$lessons[] = new Lesson('fixed rate', null, 'lecture');
</code>```

i.e. something which is called stringly typed code, and which, honestly, in this context when the reader is intended to learn OOP, is horrible.

This also means that if I'm right about the intention of the book author (i.e. creating those abstract and inherited classes I listed above), this will lead to duplicate and pretty unreadable and ugly code:

```<code>const string $HourlyRate = 'hourly rate';
const string $FixedRate = 'fixed rate';

// [...]

Charge $charge;
switch ($chargeType)
{
    case $HourlyRate:
        $charge = new HourlyCharge();
        break;

    case $FixedRate:
        $charge = new FixedCharge();
        break;

    default:
        throw new ParserException('The value of chargeType is unexpected.');
}

// Imagine the similar code for lecture/seminar, and the similar code for both on output.
</code>```

As for the "signposts":

Code Duplication

Your code doesn't have duplication. The code the author expects you to write does.

The Class Who Knew Too Much About His Context

Your class just passes strings from the input to the output, and doesn't know anything at all. The expected code on the other hand can be criticized for knowing too much.

The Jack of All Trades - Classes that try to do many things

Again, you are just passing strings, nothing more.

Conditional Statements

There is one conditional statement in your code. It is readable and easy to understand.

Maybe, in fact, the author expected you to write a much more refactored code than the one with six classes above. For example you could use factory pattern for lessons and charges, etc.

```<code>+ abstract Lesson
    - Lecture inherits Lesson
    - Seminar inherits Lesson

+ abstract Charge
    - HourlyCharge inherits Charge
    - FixedCharge inherits Charge

+ LessonFactory

+ ChargeFactory

+ Parser // Uses factories to transform the input into `Lesson`.
</code>```

In this case, you'll end up with nine classes, which will be a perfect example of an over-architecture.

Instead, you ended up with an easy to understand, clean code, which is ten times shorter.

Body:
The example in the book is pretty strange. From your question, the original statement is:

The goal is to output the Lesson Type (Lecture or Seminar), and the Charges for the lesson depending on whether it is a hourly or fixed price lesson.

which, in the context of a chapter on OOP, would mean that the author probably wants you to have following structure:

+ abstract Lesson
    - Lecture inherits Lesson
    - Seminar inherits Lesson

+ abstract Charge
    - HourlyCharge inherits Charge
    - FixedCharge inherits Charge

But then comes the input you quoted:

$lessons[] = new Lesson('hourly rate', 4, 'seminar');
$lessons[] = new Lesson('fixed rate', null, 'lecture');

i.e. something which is called stringly typed code, and which, honestly, in this context when the reader is intended to learn OOP, is horrible.

This also means that if I'm right about the intention of the book author (i.e. creating those abstract and inherited classes I listed above), this will lead to duplicate and pretty unreadable and ugly code:

const string $HourlyRate = 'hourly rate';
const string $FixedRate = 'fixed rate';

// [...]

Charge $charge;
switch ($chargeType)
{
    case $HourlyRate:
        $charge = new HourlyCharge();
        break;

    case $FixedRate:
        $charge = new FixedCharge();
        break;

    default:
        throw new ParserException('The value of chargeType is unexpected.');
}

// Imagine the similar code for lecture/seminar, and the similar code for both on output.

As for the "signposts":

Code Duplication

Your code doesn't have duplication. The code the author expects you to write does.

The Class Who Knew Too Much About His Context

Your class just passes strings from the input to the output, and doesn't know anything at all. The expected code on the other hand can be criticized for knowing too much.

The Jack of All Trades - Classes that try to do many things

Again, you are just passing strings, nothing more.

Conditional Statements

There is one conditional statement in your code. It is readable and easy to understand.

Maybe, in fact, the author expected you to write a much more refactored code than the one with six classes above. For example you could use factory pattern for lessons and charges, etc.

+ abstract Lesson
    - Lecture inherits Lesson
    - Seminar inherits Lesson

+ abstract Charge
    - HourlyCharge inherits Charge
    - FixedCharge inherits Charge

+ LessonFactory

+ ChargeFactory

+ Parser // Uses factories to transform the input into `Lesson`.

In this case, you'll end up with nine classes, which will be a perfect example of an over-architecture.

Instead, you ended up with an easy to understand, clean code, which is ten times shorter.


答:
It's funny that the book doesn't state it clearly, but the reason why it favours a class hierarchy over if statements inside the same class is probably the Open/Closed principle This widely-known software design rule states that a class should be closed to modification but open for extension.

In your example, adding a new lesson type would mean changing the Lesson class's source code, making it fragile and regression prone. If you had a base class and one derivative for each lesson type, you would instead just have to add another subclass, which is generally considered cleaner.

You can put that rule under the "Conditional Statements" section if you will, however I consider that "signpost" to be a bit vague. If statements are generally just code smells, symptoms. They can result from a wide variety of bad design decisions.


问:
How to recover from finite-state-machine breakdown?
My question may seems very scientific but I think it's a common problem and seasoned developers and programmers hopefully will have some advice to avoid the problem I mention in title. Btw., what I describe bellow is a real problem I am trying to proactively solve in my iOS project, I want to avoid it at all cost.

By finite state machine I mean this >
I have a UI with a few buttons, several session states relevant to that UI and what this UI represents, I have some data which values are partly displayed in the UI, I receive and handle some external triggers (represented by callbacks from sensors).
I made state diagrams to better map the relevant scenarios that are desirable and alowable in that UI and application.
As I slowly implement the code, the app starts to behave more and more like it should. However, I am not very confident that it is robust enough.
My doubts come from watching my own thinking and implementation process as it goes. I was confident that I had everything covered, but it was enough to make a few brute tests in the UI and I quickly realized that there are still gaps in the behavior ..I patched them.
However, as each component depends and behaves based on input from some other component, a certain input from user or some external source trigers a chain of events, state changes..etc.
I have several components and each behave like this
Trigger received on input -> trigger and its sender analyzed -> output something (a message, a state change) based on analysis

The problem is, this is not completely selfcontained, and my components (a database item, a session state, some button's state)...COULD be changed, influenced, deleted, or otherwise modified, outside the scope of the event-chain or desirable scenario. (phone crashes, battery is empty phone turn of suddenly)
This will introduce a nonvalid situation into the system, from which the system potentially COULD NOT BE ABLE to recover.
I see this (althought people do not realize this is the problem) in many of my competitors apps that are on apple store, customers write things like this>
"I added three documents, and after going there and there, i cannot open them, even if a see them." or "I recorded videos everyday, but after recording a too log video,  I cannot turn of captions on them.., and the button for captions doesn't work"..

These are just shortened examples, customers often describe it in more detail..from the descriptions and behavior described in them,  I assume that the particular app has a FSM breakdown.

So the ultimate question is how can I avoid this, and how to protect the system from blocking itself?

EDIT> I am talking in the context of one viewcontroller's view on the phone, I mean one part of the application. I Understand the MVC pattern, I have separate modules for distinct functionality..everything I describe is relevant to one canvas on the UI.

答:
The best way to avoid this is Automated Testing.

The only way to have real confidence about what your code does based on certain inputs is to test them. You can click around in your application and try to do things incorrectly, but that does not scale well to ensure you don't have any regressions. Instead, you can create a test that passes bad input into a component of your code and ensures that it handles it in a sane way.

This will not be able prove that the state machine can never be broken, but it will tell you that many of the common cases are handled correctly and don't break other things.


问:
Does TDD's "Obvious Implementation" mean code first, test after?
My friend and I are relatively new TDD and have a dispute about the "Obvious Implementation" technique (from "TDD By Example" by Kent Beck). My friend says it means that if the implementation is obvious, you should go ahead and write it - before any test for that new behavior. And indeed the book says:

How do you implement simple operations? Just implement them.

Also:

Sometimes you are sure you know how to implement an operation. Go ahead.

I think what the author means is you should test first, and then "just implement" it - as opposed to the "Fake It ('Till You Make It)" and other techniques, which require smaller steps in the implementation stage. Also after these quotes the author talks about getting "red bars" (failing tests) when doing "Obvious Implementation" - how can you get a red bar without a test?.

Yet I couldn't find any quote from the book saying "obvious" still means test first.

What do you think? Should we test first or after when the implementation is "obvious" (according to TDD, of course)? Do you know a book or blog post saying just that?

答:
I have learned that for trivial code there should be no unittest at all.

example: If you have a java getter/setter method that maps a method to a local variable a unittest for this would be overkill.

may be this is what the author means with

```<code>> "How do you implement simple operations? Just implement them."
> "Sometimes you are sure you know how to implement an operation. Go ahead."
</code>```

Body:
I have learned that for trivial code there should be no unittest at all.

example: If you have a java getter/setter method that maps a method to a local variable a unittest for this would be overkill.

may be this is what the author means with

> "How do you implement simple operations? Just implement them."
> "Sometimes you are sure you know how to implement an operation. Go ahead."


答:
Regular expressions are implemented as finite state machines.  The transition table generated by the library code will have a failure state built in, to handle what happens if input does not match the pattern. There's at least an implicit transition to the failure state from almost every other state.

Programming language grammars are not FSMs, but the parser generators (like Yacc or bison) generally have a way to put in one or more error states, so that unexpected inputs can cause the generated code to end up in an error state.

Sounds like your FSM needs an error state or a failure state or the moral equivalent, along with both explicit (for cases you anticipate) and implicit (for cases you don't anticipate) transitions to one of the failure or error states.

Title: How to recover from finite-state-machine breakdown?

Body:
My question may seems very scientific but I think it's a common problem and seasoned developers and programmers hopefully will have some advice to avoid the problem I mention in title. Btw., what I describe bellow is a real problem I am trying to proactively solve in my iOS project, I want to avoid it at all cost.

By finite state machine I mean this >
I have a UI with a few buttons, several session states relevant to that UI and what this UI represents, I have some data which values are partly displayed in the UI, I receive and handle some external triggers (represented by callbacks from sensors).
I made state diagrams to better map the relevant scenarios that are desirable and alowable in that UI and application.
As I slowly implement the code, the app starts to behave more and more like it should. However, I am not very confident that it is robust enough.
My doubts come from watching my own thinking and implementation process as it goes. I was confident that I had everything covered, but it was enough to make a few brute tests in the UI and I quickly realized that there are still gaps in the behavior ..I patched them.
However, as each component depends and behaves based on input from some other component, a certain input from user or some external source trigers a chain of events, state changes..etc.
I have several components and each behave like this
Trigger received on input -> trigger and its sender analyzed -> output something (a message, a state change) based on analysis

The problem is, this is not completely selfcontained, and my components (a database item, a session state, some button's state)...COULD be changed, influenced, deleted, or otherwise modified, outside the scope of the event-chain or desirable scenario. (phone crashes, battery is empty phone turn of suddenly)
This will introduce a nonvalid situation into the system, from which the system potentially COULD NOT BE ABLE to recover.
I see this (althought people do not realize this is the problem) in many of my competitors apps that are on apple store, customers write things like this>
"I added three documents, and after going there and there, i cannot open them, even if a see them." or "I recorded videos everyday, but after recording a too log video,  I cannot turn of captions on them.., and the button for captions doesn't work"..

These are just shortened examples, customers often describe it in more detail..from the descriptions and behavior described in them,  I assume that the particular app has a FSM breakdown.

So the ultimate question is how can I avoid this, and how to protect the system from blocking itself?

EDIT> I am talking in the context of one viewcontroller's view on the phone, I mean one part of the application. I Understand the MVC pattern, I have separate modules for distinct functionality..everything I describe is relevant to one canvas on the UI.


答:
Forget your finite-state-machine.  What you have here is a serious multi-threading situation.  Any button can be pressed at any time and your external triggers could go off at any time.  The buttons are probably all on one thread, but a trigger could litterally go off at the same instant as one of the buttons or one, many, or all of the other triggers.

What you must do is determine your state at the moment you decide to act.  Get all the buttons and trigger states.  Save them in local variables.  The original values may change every time you look at them.  Then act on the situation as you have it.  It is a snapshot of how the system looked at one point.  A millisecond later it could look very different, but with multi-threading there is no real current "now" that you can hang on to, only a picture you have saved in local variables.

Then you have to respond to your saved--historical--state.  Everything is fixed and you ought to have an action for all possible states.  It will not take into account changes made between the time you took the snapshot and the time you display your results, but that's life in the multi-threading world.  And you may need to use synchronization to keep your snapshot from being too blurred.  (You cannot be up-to-date, but you can come close to getting your entire state from one particular instant in time.)

Read up on multi-threading.  You have a lot to learn.  And because of those triggers, I don't think you can use a lot of the tricks often provided to make parallel processing easy ("Worker Threads" and such).  You are not doing "parallel processing"; you are not trying to use 75% of 8 cores.  You're using 1% of the entire CPU, but you have highly independent, highly interacting threads, and it will need a lot of thought to synchronize them and keep the synchronizing from locking up the system.

Test on both single core and multi-core machines; I've found they behave rather differently with multi-threading.  The single-core machines turn up fewer multi-threading bugs, but those bugs are far more weird.  (Though the multi-core machines will boggle your mind till you get used to them.)

One last unpleasant thought:  this is not easy stuff to test.  You'll need to generate random triggers and button presses and let the system run flat out for a while to see what turns up.  Multi-threaded code is not deterministic.  Something can fail once in a billion runs, just because the timing was off for a nanosecond.  Put in debug statements (with careful if-statements to avoid 999,999,999 unneeded messages) and you need to make a billion runs just to get one useful message.  Fortunately, machines are real fast these days.

Sorry to dump all this on you this early in your career.  Hopefully someone will come up with another answer with a way around all this (I think there's stuff out there that might tame the triggers, but you've still got the trigger/button conflict).  If so, this answer will at least let you know what you're missing.  Good luck.


答:
The point of a finite state machine is that it has explicit rules for everything that can happen in a state. That's why it is finite.

For instance:

```<code>if a:
  print a
elif b:
  print b
</code>```

Is not finite, because we could get input c. This:

```<code>if a:
  print a
elif b:
  print b
else:
  print error
</code>```

is finite, because all possible input is accounted for. This accounts for the possible inputs to a state, which may be separate from error checking. Imagine a state machine with the following states:

```<code>No money state.
Not enough money state.
Pick soda state.
</code>```

Within the defined states, all possible inputs are handled for money inserted and soda selected. Power failure is outside the state machine, and "does not exist". A state machine can only handle inputs for states that it has, so you have two choices.

Guarantee that everything action is atomic. The machine can have total power loss and still leave everything in a stable, correct state.

Extend your states to include unknown problem, and have errors kick you to this state, where issues are handled.

For reference, the wiki article on state machines is thorough. I also suggest Code Complete, for the chapters on building stable, dependable software.

Body:
The point of a finite state machine is that it has explicit rules for everything that can happen in a state. That's why it is finite.

For instance:

if a:
  print a
elif b:
  print b

Is not finite, because we could get input c. This:

if a:
  print a
elif b:
  print b
else:
  print error

is finite, because all possible input is accounted for. This accounts for the possible inputs to a state, which may be separate from error checking. Imagine a state machine with the following states:

No money state.
Not enough money state.
Pick soda state.

Within the defined states, all possible inputs are handled for money inserted and soda selected. Power failure is outside the state machine, and "does not exist". A state machine can only handle inputs for states that it has, so you have two choices.

Guarantee that everything action is atomic. The machine can have total power loss and still leave everything in a stable, correct state.

Extend your states to include unknown problem, and have errors kick you to this state, where issues are handled.

For reference, the wiki article on state machines is thorough. I also suggest Code Complete, for the chapters on building stable, dependable software.


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

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

I'll start off with an easy one:

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

答: A method that requires me to scroll down to read it all.</p>


答:
what you are looking for is exception handling. A design philosophy to avoid staying in an inconsistant state is documented as the way of the samurai: return victorious or do not return. In other words: a component should check all its inputs and make sure that it will be able to process them normally. It it is not the case, it should raise an exception containing useful information.

Once an exception is raised, it bubbles up the stack. You should define an error handling layer which will know what to do. If a user file is corrupted, explain to your client that the data is lost, and recreate a clean empty file.

The important part here is to get back to a working state, and avoid error propagation. When you are done with this, you can work on individual components to make them more robust.

I am not an objective-c expert, but this page should be a good starting point:

http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/objectivec/Chapters/ocExceptionHandling.html


问:
Where should a programmer explain the extended logic behind the code?
I have developed a few quantitative libraries in C# where it is important to understand not only the classic information that goes with the XMLDoc comments (which contains basic information with the method signature) but also the mathematical formulas being use within the methods.

Hence I would like to be able to include extended documentation with the code, which could contain, for example Latex formulas, graphs, and so on.

Do you think such information should be included in the API documentation?

Or should it be included in a dev blog for examples?

Are there common tools that are usually used for this kind of purposes?

答: You can include such documentation within the XML comments, and generate LaTeX manuals, web pages and other documents from it using doxygen.  Use the <remarks> and <example> elements for the extended prose.

ContentLicense: CC BY-SA 4.0


答: I would use external documentation if you need to include class diagrams, graphs, formulas, images, etc. to explain how your libraries work. Include this external documentation as part of your library releases in whatever format you deem appropriate (LaTeX or otherwise). You can refer to this document from your code if you wish (e.g. "See the "Readme" documentation for more information.").</p>

Title: Where should a programmer explain the extended logic behind the code?

Body:
I have developed a few quantitative libraries in C# where it is important to understand not only the classic information that goes with the XMLDoc comments (which contains basic information with the method signature) but also the mathematical formulas being use within the methods.

Hence I would like to be able to include extended documentation with the code, which could contain, for example Latex formulas, graphs, and so on.

Do you think such information should be included in the API documentation?

Or should it be included in a dev blog for examples?

Are there common tools that are usually used for this kind of purposes?


问:
What is this algorithm for converting strings into numbers called?
I've been doing some work in Parsec recently, and for my toy language I wanted multi-based fractional numbers to be expressible.  After digging around in Parsec's source a bit, I found their implementation of a floating-point number parser, and copied it to make the needed modifications.

So I understand what this code does, and vaguely why (I haven't worked out the math fully yet, but I think I get the gist).  But where did it come from?  This seems like a pretty clever way to turn strings into floats and ints, is there a name for this algorithm?  Or is it just something basic that's a hole in my knowledge?  Did the folks behind Parsec devise it?

Here's the code, first for integers:

```<code>number' :: Integer -> Parser Integer
number' base =
    do { digits <- many1 ( oneOf ( sigilRange base ))
       ; let n = foldl (\x d -> base * x + toInteger (convertDigit base d)) 0 digits
       ; seq n (return n)
       }
</code>```

So the basic idea here is that digits contains the string representing the whole number part, ie "192".  The foldl converts each digit individually into a number, then adds that to the running total multiplied by the base, which means that by the end each digit has been multiplied by the correct factor (in aggregate) to position it.

The fractional part is even more interesting:

```<code>fraction' :: Integer -> Parser Double
fraction' base =
    do { digits <- many1 ( oneOf ( sigilRange base ))
       ; let base' = fromIntegral base
       ; let f = foldr (\d x -> (x + fromIntegral (convertDigit base d))/base') 0.0 digits
       ; seq f (return f)
</code>```

Same general idea, but now a foldr and using repeated division.  I don't quite understand why you add first and then divide for the fraction, but multiply first then add for the whole.  I know it works, just haven't sorted out why.

Anyway, I feel dumb not working it out myself, it's very simple and clever looking at it.  Is there a name for this algorithm?  Maybe the imperative version using a loop would be more familiar?

答:
It's not actually that clever, but rather just a consequence of how the decimal system works. It may look a bit unusual in Haskell because the loops are expressed as folds, but the basic algorithm is pretty much the most straightforward way one could possibly go about this (except for hard-coding digit factors, which is ugly and bad in so many ways).

So I doubt anyone has bothered naming this algorithm, really.


问:
Essential management tools for a small/medium software development shop
I've recently started work with an organisation that is rapidly expanding and is recruiting or growing several development teams (including two web-based products and a data warehouse/BI team). They are basically working to agile methodologies but haven't formalised a standard way of working yet.

Despite the fact that it is early days, I've been surprised by the lack of tools being used to manage the development processes (e.g. no issue tracker, no tool to manage the product backlog etc.)

Although it's not my primary responsibility, I'd like to help them out with some recommendations on the most important tools they should get in place.

What are the 3-5 top priority tools to establish for management of a good development shop?  Why are they necessary?  How do they improve the software development process, and how do I justify them to my bosses?

答:
Ensure that these types of tools are being utilized:

Source control: Track changes to the software being developed.

Bug/issue tracker: Track issues/enhancements for the software being developed.

Wiki: Document development process, developer guidelines, etc.

Continuous integration (build) server: Build software continuously to check for stability, missing dependencies, etc.

I'll leave it up to you to consider what you should get, but I suggest looking at open source solutions first. Keep in mind it's important to track information about the project as well as communicate information effectively between management and the development team, so utilize the tools that will help you do this.


答:
The key, I believe, is consistency. If you've consistently annotated the methods with comments that can be extracted by e.g. Doxygen, it only makes sense to include the extended logic description there as well since that's where fellow developers are most likely to look. Suddenly pointing the developer to some other document seems unnecessary and will only confuse the developers.

However, if the description of the entire program is given elsewhere, then you should stick with that and give the extended logic description there.


答:
The major red flag for me is duplicated code blocks, because it shows that the person either doesn't understand programming fundamentals or was too scared to make the proper changes to an existing code base.

I used to also count lack of comments as a red flag, but having recently worked on a lot of very good code with no comments I've eased back on that.


问:
How do you maintain focus when a particular aspect of programming takes 10+ seconds to complete?
I have a very difficult time focusing on what I'm doing (programming-wise) when something (compilation, startup time, etc.) takes more than just a few seconds.  Anecdotally it seems that threshold is about 10 seconds (and I recall reading about study that said the same thing, though I can't find it now).  So what typically happens is I make a change and then run the program to test it.  That takes about 30 seconds, so I start reading something else, and before I know it 20 minutes have passed, and then it takes (if I'm lucky!) another 10+ minutes to deal with the context switch to getting back into programming.

It's not an exaggeration to say that some things that should take me minutes literally take hours to complete.

I'm very curious about what other programmers do to combat this tendency (or if I'm unique and they don't have this tendency?).  Suggestions of any type at all are welcome - anything from "sit on your hands after hitting the compile button", to mental tricks, to "if it takes 30 seconds to start up something to test a change, then something's wrong with your development process!"

答:
Development is a creative process. You can't be constantly productive, especially if there are lots of distractions in your office. That's why the Joel Test suggests quiet working conditions.

Joel Spolsky also explains what it means to "not being in the zone". Each time something prevents you from doing your work, you have to spend ten minutes, often more to get back in the zone and become productive again.

There are lots of distractions:

A phone call from your wife,

A phone call to the business person in the office space close to yours,

A colleague asking you for help,

Being hungry,

Having personal problems,

Having to work on legacy code written by an inexperienced developer ten years ago and never refactored,

Having a slow PC or a slow Internet connection,

Having a long compile process,

etc.

There is nothing to do with it. The only thing you can do is to remove the distractions themselves:

No phones in your office,

Quiet working conditions,

Fast computer and Internet access,

Fast compile process,

etc.

In your case, if it's the compiler which distracts you, try to reduce the compile time by:

Reducing the size of your program (some IDEs for example let you unload some projects from a solution, strongly reducing the compile time),

Using nightly builds and compiling less during your work,

Buying a faster machine (if there is nothing else to do),

etc.


答:
During those 10-30 seconds go and do something :

that doesn't require lots of mental activity

open the code you are compiling, and check it again (you might find something wrong, or a way to improve it)

During that time, do not do stuff that you know it is going to take you long (unless you can afford to spend some time) like :

starting to read a book

read emails if you know it can take you long

etc

Also, do not install some audio alarm to signal the end of compilation. Your colleagues will appreciate it.

Title: How do you maintain focus when a particular aspect of programming takes 10+ seconds to complete?

Body:
I have a very difficult time focusing on what I'm doing (programming-wise) when something (compilation, startup time, etc.) takes more than just a few seconds.  Anecdotally it seems that threshold is about 10 seconds (and I recall reading about study that said the same thing, though I can't find it now).  So what typically happens is I make a change and then run the program to test it.  That takes about 30 seconds, so I start reading something else, and before I know it 20 minutes have passed, and then it takes (if I'm lucky!) another 10+ minutes to deal with the context switch to getting back into programming.

It's not an exaggeration to say that some things that should take me minutes literally take hours to complete.

I'm very curious about what other programmers do to combat this tendency (or if I'm unique and they don't have this tendency?).  Suggestions of any type at all are welcome - anything from "sit on your hands after hitting the compile button", to mental tricks, to "if it takes 30 seconds to start up something to test a change, then something's wrong with your development process!"


答:
I wrote a little commandline utility called 'alert' which will cause the computer to beep / play a sound / etc.  Then, when I have a lengthy command to run such as a make, I run make; alert.  Where I can, I will also have it take an argument so it makes a different sound depending on the argument.  Thus I can do make; alert $? and I'll know a) the build is done, and b) it passed or failed.  You don't have to be that fancy with it; just an echo -e "\a" can be enough.

If you wanted to get really fancy/annoying, use some text-to-speech package and trigger a dialog popup.

The main idea here is to interrupt your distraction as soon as the work-related task completes.