问:
Clang warning flags for Objective-C development
As a C & Objective-C programmer, I'm a bit paranoid with the compiler warning flags.

I usually try to find a complete list of warning flags for the compiler I use, and turn most of them on, unless I have a really good reason not to turn it on.

I personally think this may actually improve coding skills, as well as potential code portability, prevent some issues, as it forces you to be aware of every little detail, potential implementation and architecture issues, and so on...

It's also in my opinion a good every day learning tool, even if you're an experienced programmer.

For the subjective part of this question, I'm interested in hearing other developers (mainly C, Objective-C and C++) about this topic.

Do you actually care about stuff like pedantic warnings, etc? And if yes or no, why?

Now about Objective-C, I recently completely switched to the LLVM toolchain (with Clang), instead of GCC.

On my production code, I usually set this warning flags (explicitly, even if some of them may be covered by -Wall):

-Wall

-Wbad-function-cast

-Wcast-align

-Wconversion

-Wdeclaration-after-statement

-Wdeprecated-implementations

-Wextra

-Wfloat-equal

-Wformat=2

-Wformat-nonliteral

-Wfour-char-constants

-Wimplicit-atomic-properties

-Wmissing-braces

-Wmissing-declarations

-Wmissing-field-initializers

-Wmissing-format-attribute

-Wmissing-noreturn

-Wmissing-prototypes

-Wnested-externs

-Wnewline-eof

-Wold-style-definition

-Woverlength-strings

-Wparentheses

-Wpointer-arith

-Wredundant-decls

-Wreturn-type

-Wsequence-point

-Wshadow

-Wshorten-64-to-32

-Wsign-compare

-Wsign-conversion

-Wstrict-prototypes

-Wstrict-selector-match

-Wswitch

-Wswitch-default

-Wswitch-enum

-Wundeclared-selector

-Wuninitialized

-Wunknown-pragmas

-Wunreachable-code

-Wunused-function

-Wunused-label

-Wunused-parameter

-Wunused-value

-Wunused-variable

-Wwrite-strings

I'm interested in hearing what other developers have to say about this.

For instance, do you think I missed a particular flag for Clang (Objective-C), and why?

Or do you think a particular flag is not useful (or not wanted at all), and why?

EDIT

To clarify the question, note that -Wall only provides a few basic warnings.

They are actually a lot more warning flags, not covered by -Wall, hence the question, and the list I provide.

答:
Generally, I lean more toward -Wall, and definitely believe in also including -Werror.  A module should never have expected warnings.  You'll eventually get another warning and miss it.  And that will be the one that is actually a problem.

It also depends on whether you are adding "-Wall -Werror" to a new or old project.  If it's new, then go for it and demand perfection, otherwise you are probably in for days or weeks of edits and testing.  I just did this on an older somewhat small project and I spent two or three days removing the warnings.  I think the code is cleaner now.

In other words, try it and see.

Randy

OwnerDisplayName: Macmade


问:
Patterns for Continuous Integration and DVCS
We currently use Subversion and TeamCity, we're going to move to using Mercurial (specifically Kiln as we're FogBugz users).

Obviously this will result in changes - hopefully improvements - in our development patterns (all two of us!) but the one issue I'm stuggling with is how to structure things so that we still enjoy the benefits of continuous integration/our CI server (that there are and will remain benefits is a given, discussion of which is outside the scope of this question).

With SVN we are committing to a limited number of central repositories - effectively one per project (more or less one Visual Studio Solution) so its easy to trigger a build and to get the reassurance that all the files have been commited and that there are no stray dependencies etc, etc. But if we're going to take proper advantge of mercurial we're going to want to have more repository instances - where I'd expect changes to generally flow towards a definitive "live" repo. The problem I'm struggling with is that the live repo seems to me to be too "late" to trigger my CI builds OTOH one CI build per project per developer is probably excessive (and causes other issues). I think that live is too late because - given that we can/should have more repos (clones of) - live should be deployable whereas we want to be building/running tests (unit at commit, integration at scheduled intervals) on development commits.

I'm fishing a bit but that's because one of the things that a central subversion repo gives one (me, with our setup!) is a lot of clarity about what to build when.

n.b. I'm not asking about the mechanics of using mercurial with continuous integration - I have that working a treat for a personal project, its patterns and structures and working practice/workflow that I'm trying to get my head round.

答:
If you move to a DVCS, like Hg, you're not only getting the "distributed part", you're also getting the full power of good branching and merging.

Considering that now you'll have a good issue tracker and a good SCM... why not creating a branch for each task?

The "branch per task" pattern is not new (check Berczuk's book) but it is definitely something to try.

I explained it in detail here, and the pros and cons of CI vs "controlled" here.

ContentLicense: CC BY-SA 3.0


问:
FP and OO orthogonal?
I have heard this time and again and I am trying to understand and validate the idea that FP and OO are orthogonal.

First of all, what does it mean for 2 concepts to be orthogonal ?

FP encourages immutability and purity as much as possible.
and OO seems like something that is built for state and mutation(a slightly  organized version of imperative programming?). And I do realize that objects can be immutable. But OO seems to imply state/change to me.

They seem like opposites. Does that meant they are orthogonal ?

A language like Scala makes it easy to do OO and FP both, does this affect the orthogonality of the 2 methods ?

答:
*I have heard this time and again and I am trying to understand and validate the idea that FP and OO are orthogonal.  *

First of all, what does it mean for 2 concepts to be orthogonal ?

Wikipedia quote: "Orthogonality guarantees that modifying the technical effect produced by a component of a system neither creates nor propagates side effects to other components of the system."

Simply, it just means that the change to one system does not, and cannot affect a change in the other system.

For example, a car has orthogonal components and controls (e.g. accelerating the vehicle does not influence anything else but the components involved exclusively with the acceleration function. It does not affect radio for example (although I'm not sure whether it affect CD playing, since mine does skip sometimes)).

FP encourages immutability and purity as much as possible. and OO seems like something that is built for state and mutation(a slightly organized version of imperative programming?). And I do realize that objects can be immutable. But OO seems to imply state/change to me.

They seem like opposites. Does that meant they are orthogonal ?

Kinda. The problem is that none of these concepts are really rock hard defined. But yes, you got the gist of it.

ContentLicense: CC BY-SA 2.5

Title: FP and OO orthogonal?


问:
Does a webapp need a connection monitoring feature?
I developing a client using Flex and ActionScript that is run in the browser and communicates with our server backend. There has been concern that the application "needs" to have a graphic indicator to show whether the client has a connection to the server or not.

Part of the problem of this requirement is that is coming from a high-level perspective that because the interface looks "broken" (i.e. doesn't update properly). I have an idea where the problem is, but that doesn't mean that the error is in the interface.

I believe that a connection monitor feature is unnecessary because:

Users won't be able to do squat. Our user base is largely non-technical.

Flex generates HTTP error events but does not specify what happened. I can't tell what real problem is which could be:

The user actually has no network connection.

The application server code is broken in some way.

The server itself is messed up (i.e. "Oops, I broke the Apache config").

Server load is too high and becomes unresponsive.

There is a some other problem (e.g. network or hardware) beyond my or users' control.

How do I convince that this feature is not valuable to develop? If it is something worth keeping, what are alternatives to showing a "network status" or server connection problem in the client? I would rather spend the time to dig at the root of the problem and prevent it from happening rather than creating an additional "feature" that doesn't solve anything.

答: It's not possible to show the network status of an http connection because it's not a stateful connection. at best you can have an ajax method ping a high up time site like Google and say they have an active internet connection, which isn't very useful.</p>


问:
What can be the cause of new bugs appearing somewhere else when a known bug is solved?
During a discussion, one of my colleagues told that he has some difficulties with his current project while trying to solve bugs. "When I solve one bug, something else stops working elsewhere", he said.

I started to think about how this could happen, but can't figure it out.

I have sometimes similar problems when I am too tired/sleepy to do the work correctly and to have an overall view of the part of the code I was working on. Here, the problem seems to be for a few days or weeks, and is not related to the focus of my colleague.

I can also imagine this problem arising on a very large project, very badly managed, where teammates don't have any idea of who does what, and what effect on other's work can have a change they are doing. This is not the case here neither: it's a rather small project with only one developer.

It can also be an issue with old, badly maintained and never documented codebase, where the only developers who can really imagine the consequences of a change had left the company years ago. Here, the project just started, and the developer doesn't use anyone's codebase.

So what can be the cause of such issue on a fresh, small-size codebase written by a single developer who stays focused on his work?

What may help?

Unit tests (there are none)?

Proper architecture (I'm pretty sure that the codebase has no architecture at all and was written with no preliminary thinking), requiring the whole refactoring?

Pair programming?

Something else?

答:
I just encountered this when a test was incorrect. The test checked a given permission state that was !correct. I updated the code and ran the permission test. It worked. Then I ran all tests. All of the other tests that used the checked resource failed. I corrected the test and the permission check, but there was a bit of panic at first.

Inconsistent specifications happen as well. Then it's almost guaranteed that fixing one bug will create another (exciting when that particular part of the spec isn't exercised until later in the project).


问:
Be liberal in what you accept... or not?
[Disclaimer: this question is subjective, but I would prefer getting answers backed by facts and/or reflexions]

I think everyone knows about the Robustness Principle, usually summed up by Postel's Law:

Be conservative in what you send; be liberal in what you accept.

I would agree that for the design of a widespread communication protocol this may make sense (with the goal of allowing easy extension), however I have always thought that its application to HTML / CSS was a total failure, each browser implementing its own silent tweak detection / behavior, making it near impossible to obtain a consistent rendering across multiple browsers.

I do notice though that there the RFC of the TCP protocol deems "Silent Failure" acceptable unless otherwise specified... which is an interesting behavior, to say the least.

There are other examples of the application of this principle throughout the software trade that regularly pop up because they have bitten developpers, from the top off my head:

Javascript semi-colon insertion

C (silent) builtin conversions (which would not be so bad if it did not truncated...)

and there are tools to help implement "smart" behavior:

name matching phonetic algorithms (Double Metaphone)

string distances algorithms (Levenshtein distance)

However I find that this approach, while it may be helpful when dealing with non-technical users or to help users in the process of error recovery, has some drawbacks when applied to the design of library/classes interface:

it is somewhat subjective whether the algorithm guesses "right", and thus it may go against the Principle of Least Astonishment

it makes the implementation more difficult, thus more chances to introduce bugs (violation of YAGNI ?)

it makes the behavior more susceptible to change, as any modification of the "guess" routine may break old programs, nearly excluding refactoring possibilities... from the start!

And this is what led me to the following question:

When designing an interface (library, class, message), do you lean toward the robustness principle or not ?

I myself tend to be quite strict, using extensive input validation on my interfaces, and I was wondering if I was perhaps too strict.

答:
Definitely not. Techniques such as defensive programming obscures bugs, making their appearance less likely and more random which makes their detection harder which makes isolating them more difficult.

The vastly under-rated Writing Solid Code was tremendous in repeatedly emphasizing the need, and techniques, of making bugs as difficult to introduce or hide. Through application of its principles such as, "Eliminate random behavior. Force bugs to be reproducible." and, "Always look for, and eliminate, flaws in your interfaces." developers will vastly improve the quality of their software by eliminating the ambiguity and uncontrolled side-effects that is responsible for a large quantity of bugs.


问:
How was the first Malbolge interpreter tested?
According to Wikipedia, Malbolge was so difficult to understand when it arrived that it took two years for the first Malbolge program to appear.

If this is true, how was the first Malbolge interpreter tested (to check if it did the right thing when a Malbolge program was given)? Was it tested at all?

答: Tested against what?  Wikipedia notes that the official specification and the interpreter do not match precisely.  When you consider that the language was named after Dante's eight circle of Hell and designed to be needlessly complicated and difficult to use, it's likely that any such discrepancies are by design, which is kind of antithetical to the purposes of testing.</p>


问:
How can Continuous Delivery work in practice?
Continuous Delivery sounds good, but my years of software development experience suggest that in practice it can't work.

(Edit: To make it clear, I always have lots of tests running automatically. My question  is about how to get the confidence to deliver on each checkin, which  I understand is the full form of CD. The alternative is not year-long cycles. It is iterations every week (which some might consider still CD if done correctly), two weeks, or month; including an old-fashioned QA at the end of each one, supplementing the automated tests.)

Full test coverage is impossible. You have to put in lots of time -- and time is money -- for every little thing. This is valuable, but the time could be spent  contributing to quality in other ways.

Some things are hard to test automatically. E.g. GUI. Even Selenium won't tell you  if your GUI is wonky. Database access is hard to test without bulky fixtures, and even that won't cover weird corner cases in your data storage. Likewise security and many other things. Only business-layer code is effectively unit-testable.

Even in the business layer, most code out there is not simple functions whose arguments and return values can be easily isolated for test purposes. You can spend lots of time building mock objects, which might not correspond to the real implementations.

Integration/functional tests supplement unit tests, but these take a lot of time to run because they usually involve reinitializing the entire system on each test. (If you don't reinitialize, the test environment is inconsistent.)

Refactoring or any other changes break lots of  tests. You spend lots of time fixing them. If it's a matter of validating meaningful spec changes, that's fine, but often tests break because of meaningless low-level implementation details, not stuff that really provides important information. Often the tweaking is focused on reworking the internals of the test, not on truly checking the functionality that is being tested.

Field reports on bugs cannot easily be matched with the precise micro-version of the code.

答:
my years of software development experience suggest that in practice it can't work.

Have you tried it? Dave and I wrote the book based on many collective years of experience, both of ourselves and of other senior people in ThoughtWorks, actually doing the things we discuss. Nothing in the book is speculative. Everything we discuss has been tried and tested even on large, distributed projects. But we don't suggest you take it on faith. Of course you should try it yourself, and please write up what you find works and what doesn't, including the relevant context, so that others can learn from your experiences.

Continuous Delivery has a big focus on automated testing. We spend about 1/3 of the book talking about it. We do this because the alternative - manual testing - is expensive and error-prone, and actually not a great way to build high quality software (as Deming said, "Cease dependence on mass inspection to achieve quality. Improve the process and build quality into the product in the first place")

Full test coverage is impossible. You have to put in lots of time -- and time is money -- for every little thing. This is valuable, but the time could be spent contributing to quality in other ways.

Of course full test coverage is impossible, but what's the alternative: zero test coverage? There is a trade-off. Somewhere in between is the correct answer for your project. We find that in general you should expect to spend about 50% of your time creating or maintaining automated tests. That might sound expensive until you consider the cost of comprehensive manual testing, and of fixing the bugs that get out to users.

Some things are hard to test automatically. E.g. GUI. Even Selenium won't tell you if your GUI is wonky.

Of course. Check out Brian Marick's test quadrant. You still need to perform exploratory testing and usability testing manually. But that's what you should be using your expensive and valuable human beings for - not regression testing. The key is that you need to put a deployment pipeline in place so that you only bother running expensive manual validations against builds that have passed a comprehensive suite of automated tests. Thus you both reduce the amount of money you spend on manual testing, and the number of bugs that ever make it to manual test or production (by which time they are very expensive to fix). Automated testing done right is much cheaper over the lifecycle of the product, but of course it's a capital expenditure that amortizes itself over time.

Database access is hard to test without bulky fixtures, and even that won't cover weird corner cases in your data storage. Likewise security and many other things. Only business-layer code is effectively unit-testable.

Database access is tested implicitly by your end-to-end scenario based functional acceptance tests. Security will require a combination of automated and manual testing - automated penetration testing and static analysis to find (e.g.) buffer overruns.

Even in the business layer, most code out there is not simple functions whose arguments and return values can be easily isolated for test purposes. You can spend lots of time building mock objects, which might not correspond to the real implementations.

Of course automated tests are expensive if you build your software and your tests badly. I highly recommend checking out the book "growing object-oriented software, guided by tests" to understand how to do it right so that your tests and code are maintainable over time.

Integration/functional tests supplement unit tests, but these take a lot of time to run because they usually involve reinitializing the entire system on each test. (If you don't reinitialize, the test environment is inconsistent.)

One of the products I used to work on has a suite of 3,500 end-to-end acceptance tests that takes 18h to run. We run it in parallel on a grid of 70 boxes and get feedback in 45m. Still longer than ideal really, which is why we run it as the second stage in the pipeline after the unit tests have run in a few minutes so we don't waste our resources on a build that we don't have some basic level of confidence in.

Refactoring or any other changes break lots of tests. You spend lots of time fixing them. If it's a matter of validating meaningful spec changes, that's fine, but often tests break because of meaningless low-level implementation details, not stuff that really provides important information. Often the tweaking is focused on reworking the internals of the test, not on truly checking the functionality that is being tested.

If your code and tests are well encapsulated and loosely coupled, refactoring will not break lots of tests. We describe in our book how to do the same thing for functional tests too. If your acceptance tests break, that's a sign that you're missing one or more unit tests, so part of CD involves constantly improving your test coverage to try and find bugs earlier in the delivery process where the tests are more fine-grained and the bugs are cheaper to fix.

Field reports on bugs cannot easily be matched with the precise micro-version of the code.

If you're testing and releasing more frequently (part of the point of CD) then it is relatively straightforward to identify the change that caused the bug. The whole point of CD is to optimize the feedback cycle so you can identify bugs as soon as possible after they are checked in to version control - and indeed, preferably before they're checked in (which is why we run the build and unit tests before check-in).


答:
Gmail has an indicator if your network connection is flaky.

What are the consequences of losing connection to the server? Can users lose work?

When I try to check something into version control, there are numerous things that can go wrong, some of which version control might have no influence of, but I absolutely expect it to tell me if there is a problem.

Title: Does a webapp need a connection monitoring feature?

Body:
I developing a client using Flex and ActionScript that is run in the browser and communicates with our server backend. There has been concern that the application "needs" to have a graphic indicator to show whether the client has a connection to the server or not.

Part of the problem of this requirement is that is coming from a high-level perspective that because the interface looks "broken" (i.e. doesn't update properly). I have an idea where the problem is, but that doesn't mean that the error is in the interface.

I believe that a connection monitor feature is unnecessary because:

Users won't be able to do squat. Our user base is largely non-technical.

Flex generates HTTP error events but does not specify what happened. I can't tell what real problem is which could be:

The user actually has no network connection.

The application server code is broken in some way.

The server itself is messed up (i.e. "Oops, I broke the Apache config").

Server load is too high and becomes unresponsive.

There is a some other problem (e.g. network or hardware) beyond my or users' control.

How do I convince that this feature is not valuable to develop? If it is something worth keeping, what are alternatives to showing a "network status" or server connection problem in the client? I would rather spend the time to dig at the root of the problem and prevent it from happening rather than creating an additional "feature" that doesn't solve anything.


答:
Having developed this feature for an AIR app (using URLMonitor) I think it is a worthwhile feature to add, though I can see where you are coming from.

What we did for our connection monitor is create a script on the server that the client app can ping for a response at some set interval (say, once every 10 seconds). Based on that response we can say our server is available or unavailable and display this via a little icon in the app's status bar. The server being unavailable is typically the result of some change on the server that breaks something or the user not being connected to the internet. This is helpful to the us and the user to a couple ways.

First, if the server is broken or under heavy load and unresponsive we can avoid hitting it with even more requests. Since the client app keeps track of whether or not the server is available before sending requests we can do something like:

```<code>if (serverIsAvailable)
{
   sendRequest();
}
else
{
   showUnAvailableMessage();
}
</code>```

Second, we provide a better user experience. Rather than the client app just breaking or hanging because it can't get a response to a request we can throw up an error message along the lines of "Sorry, this operation could not be completed because we could not contact the server." As an added benefit, we've found that when users contact support about this issue they will say, "I got this message about the server being unavailable" which helps us pinpoint problems faster.

If the goal is to avoid a bad user experience you shouldn't really be concerned so much with why the server is unavailable, only that it is unavailable.

To answer your question more directly, yes, I think this is a worthwhile feature to add. Having your application break for some unknown reason and not displaying the most helpful error message possible to your user is a poor experience. I agree with you that the goal should be to prevent errors from arising in the first place but errors will happen no matter what you do (especially when your application requires an internet connection) and you should always handle them gracefully.

As far as displaying this to the user, we try to keep it out of the way. At all times there is an icon in the application status bar indicating status. The only time we ever show any kind of dialog related to server connection status is when the user initiates some action that will require a server connection and the server is currently unavailable.

Body:
Having developed this feature for an AIR app (using URLMonitor) I think it is a worthwhile feature to add, though I can see where you are coming from.

What we did for our connection monitor is create a script on the server that the client app can ping for a response at some set interval (say, once every 10 seconds). Based on that response we can say our server is available or unavailable and display this via a little icon in the app's status bar. The server being unavailable is typically the result of some change on the server that breaks something or the user not being connected to the internet. This is helpful to the us and the user to a couple ways.

First, if the server is broken or under heavy load and unresponsive we can avoid hitting it with even more requests. Since the client app keeps track of whether or not the server is available before sending requests we can do something like:

if (serverIsAvailable)
{
   sendRequest();
}
else
{
   showUnAvailableMessage();
}

Second, we provide a better user experience. Rather than the client app just breaking or hanging because it can't get a response to a request we can throw up an error message along the lines of "Sorry, this operation could not be completed because we could not contact the server." As an added benefit, we've found that when users contact support about this issue they will say, "I got this message about the server being unavailable" which helps us pinpoint problems faster.

If the goal is to avoid a bad user experience you shouldn't really be concerned so much with why the server is unavailable, only that it is unavailable.

To answer your question more directly, yes, I think this is a worthwhile feature to add. Having your application break for some unknown reason and not displaying the most helpful error message possible to your user is a poor experience. I agree with you that the goal should be to prevent errors from arising in the first place but errors will happen no matter what you do (especially when your application requires an internet connection) and you should always handle them gracefully.

As far as displaying this to the user, we try to keep it out of the way. At all times there is an icon in the application status bar indicating status. The only time we ever show any kind of dialog related to server connection status is when the user initiates some action that will require a server connection and the server is currently unavailable.


问:
What (free) on-line conferences or video sites about tech stuff do you know?
Instead of TV, I prefer to watch (free) on-line conferences or videos.
As a software developer, my favorites are:

InfoQ

MSDN Channel 9

Google TechTalks

LinkedIn TechTalks

TED

Business Of Software blog (I like entrepreneurship too)

Maybe I'm losing other valuable sources (about software and startups) of these kind of content.
So, can you suggest other specialized sites like these?

答:
Check out iTunesU and more specifically the Stanford section (you need iTunes for that...)

Marakana has some very good lecture from java/android/web conferences and user groups

The Google Developers Channel has all the sessions from Google I/O conferences

For the entrepreneur in you, check out TechCrunch TV and Robert Scoble's Videos


问:
How to detect impacts caused by changes?
I've often run on this problem. Now I am working on a team of 4 and we built a lot of stuff. We are still finishing somethings and making changes. The problem is that those changes can (and most probably will) cause interface/business to crash.

We do not have any kind of map that show us something like "If you change the DataSource of this table the code X on that table will have to change. And on the screen X the list will have to be changed".

Unit tests can help validate business rules, what about interface business? Can it also validate code bound to the interface? Should we rely only on unit tests? And how deep does it have to be to prevent the code breaking because of changes? Should we use some other approach as well?

答:
You need (preferably automated) integration / system tests too, apart from unit tests, precisely to verify that changes like your example don't break existing - seemingly unrelated - functionality in your system as a whole.

UI testing is much more difficult than unit testing, but there are tools which can help at least somewhat. For web pages, e.g. HttpUnit or Selenium are recommended by many. If you tell more about the type of your system, we may be able to give more precise advice.

An intermediate path may be to write subsystem tests, which are technically like bigger unit tests, possibly involving the DB too. DbUnit is a tool which can help you in this. Subsystem tests may allow you to verify dependencies / assumptions like the one you describe, so that if you change the data source of table T, some test for code X will fail, forcing you to update that code too.

The underlying problem is that you apparently don't understand how your system works. This is sadly common for legacy apps, but your descriptions seems to suggest that this system has been built by your team from the start - in which case there is a fundamental problem with the way you work. You must absolutely learn to document dependencies within your system - and you must also work on reducing and controlling these dependencies. Pay attention to coupling and cohesion in your architecture, in order to divide your system into independent modules/components which only affect each other in well defined ways.


答:
It sounds like these "new" bugs are not actually "new" bugs.  They were just not a problem, until the other code that was broken, was actually fixed.  In other words your colleague does not realize he actually had two bugs the entire time.  If the code that is not proving to be broken wasn't broken, it wouldn't have failed, once the other peice of code was actually fixed.

In both cases a better automated test regimen might be helpful.  It sounds like your colleague needs to unit test the current code base.  In the future regression testing will verify existing code continues to function.

Title: What can be the cause of new bugs appearing somewhere else when a known bug is solved?

Body:
During a discussion, one of my colleagues told that he has some difficulties with his current project while trying to solve bugs. "When I solve one bug, something else stops working elsewhere", he said.

I started to think about how this could happen, but can't figure it out.

I have sometimes similar problems when I am too tired/sleepy to do the work correctly and to have an overall view of the part of the code I was working on. Here, the problem seems to be for a few days or weeks, and is not related to the focus of my colleague.

I can also imagine this problem arising on a very large project, very badly managed, where teammates don't have any idea of who does what, and what effect on other's work can have a change they are doing. This is not the case here neither: it's a rather small project with only one developer.

It can also be an issue with old, badly maintained and never documented codebase, where the only developers who can really imagine the consequences of a change had left the company years ago. Here, the project just started, and the developer doesn't use anyone's codebase.

So what can be the cause of such issue on a fresh, small-size codebase written by a single developer who stays focused on his work?

What may help?

Unit tests (there are none)?

Proper architecture (I'm pretty sure that the codebase has no architecture at all and was written with no preliminary thinking), requiring the whole refactoring?

Pair programming?

Something else?


问:
Why is it impossible to produce truly random numbers?
I was trying to solve a hobby problem that required generating a million random numbers. But I quickly realized, it is becoming difficult to make them unique. I picked up Algorithm Design Manual to read about random number generation.

It has the following paragraph that I am fully not able to understand.

Unfortunately, generating random numbers looks a lot easier than it really is. Indeed, it is fundamentally impossible to produce truly random numbers on any deterministic device. Von Neumann [Neu63] said it best: “Anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin.” The best we can hope for are pseudo-random numbers, a stream of numbers that appear as if they were generated randomly.

Why is it impossible to produce truly random numbers in any deterministic device? What does this sentence mean?

答:
Generating truly random numbers in software is indeed not possible as others have pointed out, however it is possible with hardware to build a device which can generate truly random numbers*.  There are quite a few examples of this on the internet, and there are a variety of methods used, from reading the time between ticks on Geiger counter to sampling the white noise (mostly background radiation from the universe) of an untuned receiver.  I myself have built a few using a few of the methods available.

*Any good physics geek will point out that given the way the universe operates none of these are hyper-technicaly truely random but there is no reasonable way to predict the results so for the sake of this discussion they are sufficiant.


问:
Why do new programmers seem to ignore compiler error messages/runtime exception messages?
I think we’ve all seen this. Beginners ask questions on Stack Overflow that follow the basic outline...

I’m trying to do (very vague description of the goal) but it doesn’t work/I get an error/exception. Please help!

Isn’t it bizarre that so many of them seem to consider it unnecessary to paste the error message?

I wonder what the psychology of this is. What is it about error messages that makes people initially assume that they are useless and not worth paying any attention to?

The answer I’m looking for is not “they don’t understand the error message”. That doesn’t explain why they wouldn’t consider telling anyone else who might understand it.

答:
I believe that they are just not used to think about error codes, and by the time they reach the place where they should give them, they already feel like they fully explained the problem, and are therefore even less likely to stop and think about whether they should give additional information.

Asking a question involves a few stages, and they are most logically arranged in this order:

you need to describe what you were doing

you need to describe how you were doing that

you need to describe what happened when it failed (or how it failed)

you need to give the post mortem report

The post mortem report is where the error message will be, and it is at the very end. By the time newbies reach this point they are at the end of the mental challenge of explaining their problem and are more likely to miss something (for a newbie, there's an information overload problem). Further, at this point they already feel like they described all aspects of the problem, and they have past habits that prevent them from remembering about the error codes: after all, other fields of life have no error codes, so they are not used to think about them.

It may also be that even if they do remember about the error codes, they seem too cryptic to be of actual use. Just what is error 034982? Does this really mean anything to anybody? And does it really add something to that detailed description of what I was doing, how I was doing it, and how it failed? Surly this information stands for itself.


答:
I would say robustness when it doesn't introduce ambiguities.

For example:
When parsing a comma separated list, whether or not there's a space before/after the comma doesn't change the semantic meaning.

When parsing a string guid it should accept any number of the common formats (with or without dashes, with or without surrounding curly braces).

Most programming languages are robust with white space usage.  Specifically everywhere that it doesn't affect the meaning of code.  Even in Python where whitespace is relevant, it's still flexible when you're inside of a list or dictionary declaration.

I definitely agree that if something can be interpreted multiple ways or if it's not 100% clear what was meant then too much robustness can end up being a pain though, but there's much room for robustness without being ambiguous.

Title: Be liberal in what you accept... or not?

Body:
[Disclaimer: this question is subjective, but I would prefer getting answers backed by facts and/or reflexions]

I think everyone knows about the Robustness Principle, usually summed up by Postel's Law:

Be conservative in what you send; be liberal in what you accept.

I would agree that for the design of a widespread communication protocol this may make sense (with the goal of allowing easy extension), however I have always thought that its application to HTML / CSS was a total failure, each browser implementing its own silent tweak detection / behavior, making it near impossible to obtain a consistent rendering across multiple browsers.

I do notice though that there the RFC of the TCP protocol deems "Silent Failure" acceptable unless otherwise specified... which is an interesting behavior, to say the least.

There are other examples of the application of this principle throughout the software trade that regularly pop up because they have bitten developpers, from the top off my head:

Javascript semi-colon insertion

C (silent) builtin conversions (which would not be so bad if it did not truncated...)

and there are tools to help implement "smart" behavior:

name matching phonetic algorithms (Double Metaphone)

string distances algorithms (Levenshtein distance)

However I find that this approach, while it may be helpful when dealing with non-technical users or to help users in the process of error recovery, has some drawbacks when applied to the design of library/classes interface:

it is somewhat subjective whether the algorithm guesses "right", and thus it may go against the Principle of Least Astonishment

it makes the implementation more difficult, thus more chances to introduce bugs (violation of YAGNI ?)

it makes the behavior more susceptible to change, as any modification of the "guess" routine may break old programs, nearly excluding refactoring possibilities... from the start!

And this is what led me to the following question:

When designing an interface (library, class, message), do you lean toward the robustness principle or not ?

I myself tend to be quite strict, using extensive input validation on my interfaces, and I was wondering if I was perhaps too strict.


答:
Imagine that you have a complete product. Then you add something new, everything seems fine, but you broke something else, which depends on some code that you change to make the new feature work. Even if you don't change any code, just add functionality to existing, it might broke something else.

So basically you nearly answered yourself:

loose coupling

lack of tests

Just learn to adapt TDD principle (at least for new features) and try to test every possible state that can happen.

Pair programming is great, but not always "available" (time, money, both..).
But code reviews (by your colleagues for example) once a day/week/set of commits will help greatly too, especially, when the review includes the test suite.
(I find it hard to not write bugs to test suites... sometimes I must test the test internally (sanity check) :) ).


问:
How long would it take to learn Python?
I have decided to take the time out after work to learn Python. Python appeals to me because at work (Web and eLearning Company), I have to follow out very repetitive tasks like delete all these tags, rename all these tasks and even more advanced repetive tasks. Additionally it would be good for me to get an understanding of Python first because of its fairly easy to learn syntax.

How long would it take to learn the basics of Python?

答:
Depends if you want to learn "syntax" (then the link @jokoon posted would be enough) or if you want to learn the "language" (including all principles, common  patterns, performance problems/advantages etc.).

Btw Python is often used as a starting language for students at schools... It is easy to understand.

EDIT: I will add this link, it's very helpful. The guy explains everything clearly, even for total newcomers.
http://code.google.com/edu/languages/google-python-class/

Title: How long would it take to learn Python?


答:
Good for you, it'll help you immensely. As to learning it without any background in programming, might I suggest A Byte of Python?

It will go through not only learning python, but fundamental concepts like, variables, functions, and control flow. Follow this up with Python Module of the Week, for an introduction to all the handy pieces of the standard library that come with python.

Title: How long would it take to learn Python?

Body:
I have decided to take the time out after work to learn Python. Python appeals to me because at work (Web and eLearning Company), I have to follow out very repetitive tasks like delete all these tags, rename all these tasks and even more advanced repetive tasks. Additionally it would be good for me to get an understanding of Python first because of its fairly easy to learn syntax.

How long would it take to learn the basics of Python?


问:
S-expressions readability
In a nutshell and for those who didn't know it, Lisp functions/operators/constructs are all uniformly called like this:

```<code>(function arg0 arg1 ... argN)
</code>```

So what in a C-like language you would express as

```<code>if (a > b && foo(param))
</code>```

is transformed to a Lisp sexp like

```<code>(if (and (> a b) (foo param)))
</code>```

. As things get more real/complicated, so do their corresponding s-expressions, for me.

I'm aware that this is most likely a subjective question, but - is for many Lisp hackers this one little annoyance one will have to always deal with?

Or does one mostly get used to this (lack of) syntax sooner or later?

In any case, is adding breaklines (that you wouldn't add in your C equivalent, most times) for readability a good idea, especially on the long run? Any other suggestions would be welcome.

答:
How do you parse

```<code>if (a > b && foo(param)) {
  doSomething();
} else {
  doSomethingElse();
}
</code>```

The parse tree probably looks something like

```<code>if:
  condition:
    and:
      lt:
        left: a
        right: b
      function:
        name: foo
        param: param
  true-block:
    function:
      name: doSomething
  false-block:
    function:
      name: doSomethingElse
</code>```

hmm... let's serialize this tree into a list, prefix notation

```<code>if(and(<(a, b), function(foo, param)), function(doSomething), function(doSomethingElse))
</code>```

This parse tree format is pretty easy to manipulate, but I have one problem. I hate separators. I like terminators. At the same time, I like sprinkling in whitespace.

```<code>if( and (<(a b) function(foo param)) function (doSomething) function ( doSomethingElse))
</code>```

hmm... the additional whitespace makes certain things harder to parse... Maybe I could just make a rule that the tree is represented as (root leaf leaf leaf).

```<code>(if (and (< a b) (function foo param)) (function doSomething) (function doSomethineElse)
</code>```

Now my serialization of a parse tree is lisp (rename function to apply, and this probably runs). If I want programs that write programs, it's kind of nice to just manipulate parse trees.

This isn't entirely how s-expressions came about, but it was identified early, and it is one feature that lisp programmers use. Our programs are pre-parsed in some sense, and writing programs to manipulate programs is fairly easy because of the format. That's why the lack of syntax is sometimes considered a strength.

But as David said, use an s-expression aware editor. You are more likely to lose track of a closing brace in an s-expression than a closing brace in xml (</foo> only closes <foo>, but right paren closes ANY s-expression). In racket, the use of square brackets for some expressions, coupled with good indenting style, fixes most problems.

The lisp version:

```<code>(if (and (< a b) (foo param))
  (doSomething)
  (doSomethingElse))
</code>```

Not too bad.

Title: S-expressions readability

Body:
How do you parse

if (a > b && foo(param)) {
  doSomething();
} else {
  doSomethingElse();
}

The parse tree probably looks something like

if:
  condition:
    and:
      lt:
        left: a
        right: b
      function:
        name: foo
        param: param
  true-block:
    function:
      name: doSomething
  false-block:
    function:
      name: doSomethingElse

hmm... let's serialize this tree into a list, prefix notation

if(and(<(a, b), function(foo, param)), function(doSomething), function(doSomethingElse))

This parse tree format is pretty easy to manipulate, but I have one problem. I hate separators. I like terminators. At the same time, I like sprinkling in whitespace.

if( and (<(a b) function(foo param)) function (doSomething) function ( doSomethingElse))

hmm... the additional whitespace makes certain things harder to parse... Maybe I could just make a rule that the tree is represented as (root leaf leaf leaf).

(if (and (< a b) (function foo param)) (function doSomething) (function doSomethineElse)

Now my serialization of a parse tree is lisp (rename function to apply, and this probably runs). If I want programs that write programs, it's kind of nice to just manipulate parse trees.

This isn't entirely how s-expressions came about, but it was identified early, and it is one feature that lisp programmers use. Our programs are pre-parsed in some sense, and writing programs to manipulate programs is fairly easy because of the format. That's why the lack of syntax is sometimes considered a strength.

But as David said, use an s-expression aware editor. You are more likely to lose track of a closing brace in an s-expression than a closing brace in xml (</foo> only closes <foo>, but right paren closes ANY s-expression). In racket, the use of square brackets for some expressions, coupled with good indenting style, fixes most problems.

The lisp version:

(if (and (< a b) (foo param))
  (doSomething)
  (doSomethingElse))

Not too bad.


问:
Is there a valid reason to wrap built in type with your own
I am editing some c++ and all of the built in types have been wrapped in a corresponding wrapper class. All of the operators have been overloaded to do bizarre things like operator[] coded to ignore the argument or to exactly what the underlying type would do.  Is this malevolent or is there some possibility this is a good idea in some other universe.    </p>

答:
IMO, your question is made of 2 questions:

Is a good idea to wrap built-in/3rd party types in own types?

Depends. Having own types around existing types is great when you change the underlying type because the existing logic can be preserved (ideally) with no changes. Is like having a 3 tire architecture and you can change the database without changing the business logic. However, creating all those types takes time and developers also need time to learn them...

Is a good idea to code own types that behave different from the original types when using the same syntax?

No. Is bad because it has side effects. Strange bugs may appear because one wasn't aware of the new behavior. Also makes debugging complicated and increases the time/cost of the development process.


问:
What differentiates the exceptional programmers from the really good ones?
You know who they are.  They are the rock stars of programming:

They code 10X
faster.

Their code just works.

They not only know their primary
language inside and out, but they
also know how it works under the
hood.

They know the answer to most any
question before you ask it.

A few of them invented the programming
principles we all use.

And they tend to be
uncharacteristically humble, as well.

What is it about these folks?  Is there something about their thought process that is fundamentally different from the above-average programmer?  Or are they simply very talented people that work hard?

To put it another way: How can I be like them?  I know what I think I need to learn to be that good, but it seems like it will take me the next ten years to learn it, and then my knowledge will be obsolete.

答:
but it seems like it will take me the next ten years to learn it, and then my knowledge will be obsolete.

It will. You've already established that these guys are 10x faster, which is why they learn it in 1 year and it takes you 10. For the serious part of the answer I think it's that they're already super smart (could be very successful at anything), they love coding, and they for some reason have (or find) an abundance of free time to practice coding or work on personal projects.

If you're asking this question here you probably don't have what it takes (don't worry I'm answering here so I probably don't either). Don't fret though you can still get to be crazy good if you love coding.


答:
There are lots of well intentioned posts here about Humility, Engineering, Passion, Patient, Troubleshooter. IMO these are all required. However, they describe the top 30% of programmers.

I think you're asking about the truly exceptional programmers, the top 1%.

One of the things that I envy about the occasional very rare talent I work with is their ability to keep a very large amount of detail about a complex system in their head at one time, and to be able to recall it quickly.  I think that I can do this on occasion, maybe once a month, when I'm truly in the zone. This feeling is wonderful. The developer I'm thinking of seems to be able to be in that zone most of the time.

It is this one trait, IMO, in addition to the Humility, Curiosity, Engineering, Passion, Patience and Troubleshooting ability that make them truly exceptional.

Title: What differentiates the exceptional programmers from the really good ones?

Body:
You know who they are.  They are the rock stars of programming:

They code 10X
faster.

Their code just works.

They not only know their primary
language inside and out, but they
also know how it works under the
hood.

They know the answer to most any
question before you ask it.

A few of them invented the programming
principles we all use.

And they tend to be
uncharacteristically humble, as well.

What is it about these folks?  Is there something about their thought process that is fundamentally different from the above-average programmer?  Or are they simply very talented people that work hard?

To put it another way: How can I be like them?  I know what I think I need to learn to be that good, but it seems like it will take me the next ten years to learn it, and then my knowledge will be obsolete.


答:
First of all, what does it mean for 2 concepts to be orthogonal ?

It means that the two concepts do not have contrasting ideas or are not incompatible with each other.

FP encourages immutability and purity as much as possible. and OO seems like something that is built for state and mutation(a slightly organized version of imperative programming?). And I do realize that objects can be immutable. But OO seems to imply state/change to me.

They seem like opposites. How does it affect their orthogonality ?

A language like Scala makes it easy to do OO and FP both, does this affect the orthogonality of the 2 methods ?

OO is about encapsulation, object composition, data abstraction, polymorphism via subtyping, and controlled mutation when necessary (immutability is encouraged in OO as well). FP is about function composition, control abstraction, and constrained polymorphism (aka parametric polymorphism). Thus the two ideas are not contradictory. They both provide you with different kinds of powers and abstraction mechanisms, which are certainly possible to have in one language. In fact, this is the thesis on which Scala was built!

In his Scala Experiment talk at Google, Martin Odersky explains it very well how he believes the two concepts - OO and FP - are orthogonal to each other and how Scala unifies the two paradigms elegantly and seamlessly into a new paradigm popularly known in Scala community as object-functional paradigm. Must watch talk for you. :-)

Other examples of object-functional languages: OCaml, F#, Nemerle.

Title: FP and OO orthogonal?

Body:
I have heard this time and again and I am trying to understand and validate the idea that FP and OO are orthogonal.

First of all, what does it mean for 2 concepts to be orthogonal ?

FP encourages immutability and purity as much as possible.
and OO seems like something that is built for state and mutation(a slightly  organized version of imperative programming?). And I do realize that objects can be immutable. But OO seems to imply state/change to me.

They seem like opposites. Does that meant they are orthogonal ?

A language like Scala makes it easy to do OO and FP both, does this affect the orthogonality of the 2 methods ?


问:
Pros and Cons of Joint Application Design
I was asked to lead "JAD sessions", which I've heard of before, but never facilated before; at least in name, they appear just to be a fancy name for stakeholder workshops.

My experience has been that "group think" and "follow the leader" are common issues with this approach, but trying to stay open to the concept.

Based on what I'm able to tell the phrase has been around since the 1980s, so clearly it's no "silver bullet".

What are the key pros and cons of this approach?

答:
It was popular in the pre-Agile days. It seems like it's less so today, at least judging from what you see from recruiter's listings and such.

On the pro side, it helped get input from actual users on what they wanted/needed. Unlike Agile, it doesn't require ongoing communication between developers and stakeholders which can be good in some organizations and not so good in others. Often you can get a free lunch or two from the sessions.

On the con side, users are often good at throwing in a huge laundry list of demands and making them all 'must haves'. As you noted, there can be a follow-the-leader thing going on where someone takes over the meeting. Even worse, you can have two or more wannabe leaders in attendance and a nasty political fight over the project will ensue with developers caught in the middle. In contrast to Agile, it's much easier for stakeholders to come back with a "that's not what I meant" due to the lack of ongoing communication. And, sometimes the free lunch consists of cold delivery pizza.


问:
What am I missing from my CI stack?
Right now, the current deploy process at my work is based around tagging from the trunk and switching various PHP web sites for clients on our QA and Production servers.  While this is simple from the technical level, it becomes really tedious when you have over a dozen updates to a dozen different sites that need to go out in one day.

Towards this end, I'm implementing the following stack:

SVN

Hudson

Capistrano

And it will work like this:

Code goes into svn

svn post-commit hook triggers hudson

hudson runs a capistrano script to deploy to the dev server

project managers check out the dev server, and if the bug is fixed, they go into hudson and promote the build

hudson runs a post-promotion script which tags and deploys the code to whatever server is specified by the promotion

Capistrano (along with the symfony framework) will be used to migrate the databases.

Am I missing anything here?  I've never done anything more complicated than subversion before, so that's why I'm asking.

答:
One big thing is missing -- how do you roll back if the build fails? Especially, how do you snap shot the database before deploying?

I'm not horribly familiar with Capistrano so it might cover this. But a quick read of the project page doesn't indicate that it does.

Title: What am I missing from my CI stack?


答:
I have a very simple definition of Pseudo Random:

Too many unknown variables to predict.

I also have a simple definition of True Random:

Infinite unknown variables.

The problem with a computer is that it always knows ALL variables.  The random number is simply a mathematical function of some seed value.

The best we can do is to give the computer a pseudo-random seed value, which is usually based off a variable that we can't predict (such as exact time).

Even though a computer is absolutely unable to create a random number, it is good at introducing too many variables to predict!

Title: Why is it impossible to produce truly random numbers?

Body:
I was trying to solve a hobby problem that required generating a million random numbers. But I quickly realized, it is becoming difficult to make them unique. I picked up Algorithm Design Manual to read about random number generation.

It has the following paragraph that I am fully not able to understand.

Unfortunately, generating random numbers looks a lot easier than it really is. Indeed, it is fundamentally impossible to produce truly random numbers on any deterministic device. Von Neumann [Neu63] said it best: “Anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin.” The best we can hope for are pseudo-random numbers, a stream of numbers that appear as if they were generated randomly.

Why is it impossible to produce truly random numbers in any deterministic device? What does this sentence mean?


答:
What's really nice about s-exp is that after a short period of time,
you don't see them anymore, it's like python to your eyes BUT the
computer still has the tree easily.

So indentation is automatic, there is no ambiguity, you don't have
to press tab twice or something like that when you want to end a
block.

If you pick some random code, the whole stuff is easily indented
with just one command from your favorite editor

You can navigate through your code really easily, jump between
s-exp, swap them and so on with a good editor

Plus, because the data you're manipulating are the same that the code
you're writing, you could use the same language to manipulate your
code right ?

Well, you can do it, that's what macros are, you manipulate the code
you're writing before it is evaluated as like any others list, that's
why it is said that Lisp is a "Programmable Programming Language". You
write code that write your code for you.

Here is a nice article which describes the nature of Lisp and why Lisp programmers grinned when they see XML.

Title: S-expressions readability

Body:
In a nutshell and for those who didn't know it, Lisp functions/operators/constructs are all uniformly called like this:

```<code>(function arg0 arg1 ... argN)
</code>```

So what in a C-like language you would express as

```<code>if (a > b && foo(param))
</code>```

is transformed to a Lisp sexp like

```<code>(if (and (> a b) (foo param)))
</code>```

. As things get more real/complicated, so do their corresponding s-expressions, for me.

I'm aware that this is most likely a subjective question, but - is for many Lisp hackers this one little annoyance one will have to always deal with?

Or does one mostly get used to this (lack of) syntax sooner or later?

In any case, is adding breaklines (that you wouldn't add in your C equivalent, most times) for readability a good idea, especially on the long run? Any other suggestions would be welcome.


答:
I had almost exactly the same question recently, and I came across this book:

http://www.amazon.co.uk/Expert-PHP-Tools-Dirk-Merkel/dp/1847198384

It is aimed at PHP, but a lot of the processes it describes can be implemented (albeit in similar but slightly different ways) in other languages!

I would say this is a must for any serious developer / development team.

Title: What am I missing from my CI stack?

Body:
Right now, the current deploy process at my work is based around tagging from the trunk and switching various PHP web sites for clients on our QA and Production servers.  While this is simple from the technical level, it becomes really tedious when you have over a dozen updates to a dozen different sites that need to go out in one day.

Towards this end, I'm implementing the following stack:

SVN

Hudson

Capistrano

And it will work like this:

Code goes into svn

svn post-commit hook triggers hudson

hudson runs a capistrano script to deploy to the dev server

project managers check out the dev server, and if the bug is fixed, they go into hudson and promote the build

hudson runs a post-promotion script which tags and deploys the code to whatever server is specified by the promotion

Capistrano (along with the symfony framework) will be used to migrate the databases.

Am I missing anything here?  I've never done anything more complicated than subversion before, so that's why I'm asking.


答:
Continuous Delivery is a book you should read. But I think you'll find the main advice you'll get from it matches the advice you've had in comments: Use a DVCS instead of SVN, and get your test coverage (unit and integration) sorted out.

I would add to that, use Jenkins instead of Hudson. Oracle now own Hudson and Jenkins was branched from it just before they took over. The open-source support from a very engaged community is likely to out-strip Oracle's support pretty quickly.

Title: What am I missing from my CI stack?


答:
Determinism is essentially a function.  Remember from Algebra that a function is a correspondence between a domain and range such that each member of the domain corresponds to exactly one member of the range.

So if f(x) = z, f(x) != y unless y is z.  That is a function.  Imagine JavaScript:

```<code>function Add(A, B) {
      return A + B;
}

var addedNumber = Add(2,3);//returns 5
addedNumber = Add(2,3);//still 5
</code>```

No matter how many times you call Add(2,3) it will always return 5. In other words, Add() is a deterministic function.

External factors can make Add behave in a non-deterministic fashion.  For example, if you introduce multithreading into the equation.  Human input also causes non-determinism.

Now, this is where things get interesting.

“Anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin.”

Note Von Neumann states, "arithmetical methods of producing [...]".  This is not talking about human input, concurrency, sample wind speeds read from a precise instrument or other non-algorithmic ways of producing random input to a deterministic function.

This simply states a function or system of functions is not going to suddenly become non-deterministic.  In other words, Add(2,3) will not somehow return 6 or anything other than 5 given the same inputs.  That is  impossible.

The quoting author takes it a step further.

The best we can hope for are pseudo-random numbers, a stream of numbers that appear as if they were generated randomly.

The context is previously defined to be "on any deterministic device". I could end the argument here.  But, what if we change up the context by introducing a new element to the system?  A non-deterministic element added as input makes the system a non-deterministic system.  Although, by removing the non-deterministic element we are reduced back to a deterministic system.  If we can somehow trace or otherwise reproduce the inputs we can reproduce a result.  But this entire paragraph is tangetenial to what the author is saying.  Remember the context.

One could argue over the meaning of non-determinism.  Once again, tangetenial.  Remember the context.

So he is correct. On any deterministic device it is impossible for a deterministic system to produce a true random result.

Body:
Determinism is essentially a function.  Remember from Algebra that a function is a correspondence between a domain and range such that each member of the domain corresponds to exactly one member of the range.

So if f(x) = z, f(x) != y unless y is z.  That is a function.  Imagine JavaScript:

function Add(A, B) {
      return A + B;
}

var addedNumber = Add(2,3);//returns 5
addedNumber = Add(2,3);//still 5

No matter how many times you call Add(2,3) it will always return 5. In other words, Add() is a deterministic function.

External factors can make Add behave in a non-deterministic fashion.  For example, if you introduce multithreading into the equation.  Human input also causes non-determinism.

Now, this is where things get interesting.

“Anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin.”

Note Von Neumann states, "arithmetical methods of producing [...]".  This is not talking about human input, concurrency, sample wind speeds read from a precise instrument or other non-algorithmic ways of producing random input to a deterministic function.

This simply states a function or system of functions is not going to suddenly become non-deterministic.  In other words, Add(2,3) will not somehow return 6 or anything other than 5 given the same inputs.  That is  impossible.

The quoting author takes it a step further.

The best we can hope for are pseudo-random numbers, a stream of numbers that appear as if they were generated randomly.

The context is previously defined to be "on any deterministic device". I could end the argument here.  But, what if we change up the context by introducing a new element to the system?  A non-deterministic element added as input makes the system a non-deterministic system.  Although, by removing the non-deterministic element we are reduced back to a deterministic system.  If we can somehow trace or otherwise reproduce the inputs we can reproduce a result.  But this entire paragraph is tangetenial to what the author is saying.  Remember the context.

One could argue over the meaning of non-determinism.  Once again, tangetenial.  Remember the context.

So he is correct. On any deterministic device it is impossible for a deterministic system to produce a true random result.


问:
If your algorithm is correct, does it matter how long it took you to write it?
I recently found out that Facebook had a programming challenge that if completed correctly you automatically get a phone interview.

There is a sample challenge that asks you to write an algorithm that can solve a Tower of Hanoi type problem. Given a number of pegs and discs, an initial and final configuration; Your algorithm must determine the fewest steps possible to get to the final configuration and output the steps.

This sample challenge gives you a 45 minute time limit but allows you to still test your code to see if it passes once your time limit expires.

I did not know of any cute math solution that could solve it, and I didn't want to look for one since I think that would be cheating. So I tried to solve the challenge the best I could on my own.

I was able to make an algorithm that worked and passed. However, it took me over 4 hours to make, much longer than the 45 minute requirement. Since it took me so much longer than the allotted time, I have not attempted the actual challenge.

This got me wondering though, in reality does it really matter that it took me that long? I mean is this a sign that I will not be able to get a job at a place like this (not just Facebook, but Google, Fog Creek, etc.) and need to lower my aspirations, or does the fact that I actually passed on my first attempt even though it took too long be taken as good?

答:
People don't really care how much time you spend doing something;
just meet your deadlines and all's well.</p>


答:
Tower of Hanoi? That was one of the first programming assignments I had on my freshman course at university (right after Fibonacci - yes, I had classes with one of those functional programming freaks :). And I'm not even on computer science, I'm on computer engineering.

And still, most so-called 'programmers' can't write this kind of algorithm correctly, because most programmers are awful. (search for fizzbuzz for added fun)

Anyway, once you are past a certain threshold, I think your programming skills doesn't matter as much as your ability to finish projects, your resiliency against difficulties, etc. And it seems you are past it for sure.

Facebook wants to hire the top devs, sure, but I don't know how much of them they hope to get with those kinds of games. I think they just don't want to lose time with awfully bad programmers.

A tip I always hear is that if you want to get hired by a cool tech company, try to get involved with open source projects. Also, try to get a internship.

Title: If your algorithm is correct, does it matter how long it took you to write it?

Body:
I recently found out that Facebook had a programming challenge that if completed correctly you automatically get a phone interview.

There is a sample challenge that asks you to write an algorithm that can solve a Tower of Hanoi type problem. Given a number of pegs and discs, an initial and final configuration; Your algorithm must determine the fewest steps possible to get to the final configuration and output the steps.

This sample challenge gives you a 45 minute time limit but allows you to still test your code to see if it passes once your time limit expires.

I did not know of any cute math solution that could solve it, and I didn't want to look for one since I think that would be cheating. So I tried to solve the challenge the best I could on my own.

I was able to make an algorithm that worked and passed. However, it took me over 4 hours to make, much longer than the 45 minute requirement. Since it took me so much longer than the allotted time, I have not attempted the actual challenge.

This got me wondering though, in reality does it really matter that it took me that long? I mean is this a sign that I will not be able to get a job at a place like this (not just Facebook, but Google, Fog Creek, etc.) and need to lower my aspirations, or does the fact that I actually passed on my first attempt even though it took too long be taken as good?


答: Learning Python is really easy, a breeze if you've learned other object oriented programming languages. It easy one the most forgiving in terms of syntax. It's recommended to  be the first language people learn as it contains all the OO concepts but is easier to read and less strongly typed as C++ or to a lesser extent Java.</p>

Title: How long would it take to learn Python?


问:
Datastructure for Peg Board Game
What datastructure would work for the triangular peg board game?

It's a 5x5x5 triangle with 15 holes.

答:
A boolean array of length 15.

Then I'd use either an adjacency list or adjacency matrix to represent which of the holes are next to each other.

Title: Datastructure for Peg Board Game


问:
Applications of Reverse Engineer, and very general process overveiw
As a student programmer, I only have very limited knowledge of the workings of much of the consumer software. I would love to one day be able to reverse engineer software to learn what makes it tick and implement it in different ways. My real question what is the general process that reverse engineering requires. I am aware that this is very broad. I was just wondering the tools such as decompilers that people use.</p>

答:
Alternative

Rather than reverse engineer closed source code, which might be illegal or unethical, I would suggest reading code from open-source projects.

There is no need to go through reverse engineering procedures (unless that is your express goal) and you can learn a lot.

Some open source software is consumer software or comparable to consumer software.

Also closed source commercial software is usually copyrighted.

Reverse-engineering

As for reverse-engineering software which you don't have express access to the source code to, you can use a decompiler. These programs exists for different languages.

For languages compiled for .Net, there exists several software you can use to do this, ie: Jetbrains DotPeek, Telerik JustDecompile, RedGate Reflector.

These softwares will take a compiled .Net dll and show source code.

Know that the authors of the software might have obfuscated their .Net code. This is a procedure designed to render the output of "reflected" or "decompiled" .Net code difficult to read and comprehend.

More on decompilers

Decompilers have been made for several languages. Different languages are easier to decompile than others, so the result will vary.


问:
How to measure when a software project is complete?
I have very limited experience in software project management roles, and I was asked this question by another engineer and I was sort of stumped.

How do I measure when a software project is complete?

The part I'm struggling with is the "measure" part. I know there are measurements such as EVM, but they are more focused on overall project performance. For instance, having a low SPI or low CPI can indicate performance/allocation issues, but it doesn't really indicate how complete a project is.

Is there a rule of thumb here to say my project is XX% complete or am I overthinking this?

答: The project is complete when there isn't anything left to do that the project sponsor is willing to pay for.</p>


答:
You need to plan for project closure as well, possibly marking it as a milestone, that can be crossed subject to some conditions-also in your plan. Just prior to this point you will typically have a project-post-mortem and data archival activities etc.

So in a nutshell, the project ends when the plan for the same says it does! HTH.

Title: How to measure when a software project is complete?

Body:
I have very limited experience in software project management roles, and I was asked this question by another engineer and I was sort of stumped.

How do I measure when a software project is complete?

The part I'm struggling with is the "measure" part. I know there are measurements such as EVM, but they are more focused on overall project performance. For instance, having a low SPI or low CPI can indicate performance/allocation issues, but it doesn't really indicate how complete a project is.

Is there a rule of thumb here to say my project is XX% complete or am I overthinking this?


答: There is no way you can produce a random number without a special hardware. In my freshman year, a couple of classmates and I proposed a random number generator that has basically a AM receiver and tuned to 4 different channels, get the input into a A to D converter and  add them all (modulo your max number). Since the combination of analog input from any arbitrary number of stations is random and we could produce a large number of random numbers from the A2D convertor we proposed this could be a good generator. Of course, even this is not truly random in a philosophical sense, though for most practical purposes this could work. </p>


问:
Is Perl still a useful, viable language?
I know it may have been asked before, but here goes nothing...

Is Perl still something that would be considered useful? If someone was a new programmer (either completely new to programming or just a few month/years of experience) would Perl be something to be considered worthwhile to learn?

Is Perl still used with frequency? Is it still popular?

Or is Perl dying out compared to languages like Python, Ruby, PHP, ASP.NET, etc.?

Basically it boils down to this:

Is it still used/is it still used frequently? If yes, is it dying? If no, will it make a come back?

Is it something that would be worth learning?

How does it compare in demand to languages like Python in both popularity and usability/viability? Could languages like Python or Ruby be considered replacements for Perl?

Also, will newer versions of Perl really bring a large improvement to the Perl community, and perhaps bring Perl back to centerstage compared to other languages?

EDIT:

Okay, I suppose here's a better, reworded question:

Is Perl still growing, or is it "dying"? Is it still a language worth learning and using? What projects does it really "shine" in compared to other languages? What makes Perl a language to choose? Essentially: is Perl growing obsolete compared to other languages, and if so, do you expect that to change, or to continue?

And thank you to everyone who has answered so far, the discussion has been really interesting!

答: I'm not an expert programmer. But I found Perl quite easy to learn (I used the camel book), always a pleasure, and PerlMonks the friendliest help community in programmingland. Perl does seem to have lost its sex appeal in terms of hiring to Ruby and Python, but only in certain industries (web especially).</p>


答:
When there is a lot of supply (many would-be programmers) and a little demand (few programming jobs) employers can be as demanding as they wish to be. As a matter of fact, they have to be demanding, or else they would be spending inordinate amounts of time interviewing people instead of getting any work done. So, they are giving candidates extremely hard tests so as to get a short list as quickly as possible, and so as to ensure that they will be interviewing people who are not just good, not even very good, but actually charismatic.

So, the fact that you did not complete the test within the allotted time frame does not mean you are a bad programmer; you just do not happen to fit the definition of what facebook considers charismatic. In my opinion, that's okay.


答:
In practice it does matter how long it takes you.  One that can solve the problem in 45 minutes is - all else equal - five times more productive than one that takes 4 hours, and hence more attractive to an employer.

That said, you do not say why you took four hours to solve this problem.

Were you at your best (well-fed, not tired, fully concentrated)?

Was the problem well specified, or did you need to do additional research on your own?

Did you have to learn new things to do this?

Were the tools familiar or not?

etc.

Any and all of these things might influence the time it takes you, and it is actually more important to be able to solve a problem when under pressure, without being told everything, and with the tools at hand, since that WILL happen during your career and it is usually at a point where it is very important to somebody whether you succeed or not.


答:
It's quite tense, It would require me to read about what is tower of Hanoi -15min, start the IDE, create a blank solution -5min, so that's only 25 minutes to solve the problem. Simply writing code with all the plumbing like safe classes with good interface design would require some time as well -10min, so it's 15 minutes left for the actual idea. Depending on what is the tower on Hanoi, it might be enough, bit it might be not. And sometimes, I just need to let the problem solve itself while I'm working on other problems, because I don't see the solution right there on the spot. So it gets solved for free in a parallel thread, but it doesn't happen in an instant.

Anyway, it's one of the largest companies, so they can do whatever they want. But time limit is one of the worst factors in interviews IMHO, I always feel pressed, rushed, can't do everything clean, and can't concentrate on all details which are very important when actually working. :) Sure you can solve solutions fast, like, set access to admin so that everything works + 'SELECT * FROM pass WHERE usr == ' + user_input, but for any secure and well written task I would be proud with, I would need some time and 45 minutes is really quite intense.


问:
Implicitly or explicitly sorted elements?
So, I've got the following problem:

I have a number of ordered elements, ordered in the following way:

Type 1: Must be the first element. (only one possible, always present)

Type 2: Must be the second and following elements, if present.

Type 3: Must be the ordered last.

Stated a bit more succintly / pseudoregex:

12*3+

Now, when constructing these elements, I do so in a method, where it is easy to do something like:

```<code>public List<IElement> CreateElements(...)
{
    var list = ...;
    list.Add(new Type1());
    list.AddRange(GetType2Elements());
    list.AddRange(GetType3Elements());
}
</code>```

However, there is no explicit semantic ordering - it's just a list, that I happen to construct in a certain way.

A more explicit way is to have IElement implement IComparable, and then use an explicitly sorted list and returning that instead. That would carry the "sortedness" out of my construction method, and sort the entities irregardless how they are created.

However, it is suddenly a bit less trivial, since atleast 3 different Compare methods must be implemented.

What would you choose?

答:
I would solve it like this:

```<code>// returns a list of elements, ordered by type 1, type 2 and type 3
public List<IElement> CreateElementsOrdered(...)
{
    ...
}
</code>```

Since the name and the comment of your function define the contract, every consumer of your method can rely on the fact that the list is ordered in this way. On the other hand, anyone modifying CreateElementsOrdered will now know that changing the order of the elements returned (in a way that breaks the 1 - 2 - 3 order) will break backwards compatibility.

Body:
I would solve it like this:

// returns a list of elements, ordered by type 1, type 2 and type 3
public List<IElement> CreateElementsOrdered(...)
{
    ...
}

Since the name and the comment of your function define the contract, every consumer of your method can rely on the fact that the list is ordered in this way. On the other hand, anyone modifying CreateElementsOrdered will now know that changing the order of the elements returned (in a way that breaks the 1 - 2 - 3 order) will break backwards compatibility.


答:
Wouldn't a simple class be better here than a list?  You can create a class which has the three elements in it and then a constructor/factory method to create it in the required order.

For example:

```<code>public class Wrapper
{
    public Type1 MainObject { get; set; }
    public List<Type2> SubElements { get; set; }
    public List<Type3> OtherElements { get; set; }
}

public Wrapper() { }

public static Wrapper FactoryCreateOrdered()
{
    return new Wrapper
    {
        MainObject = new Type1();
        SubElements = //null if not present or a list of Type2s
        OtherElements = GetType3Elements();
    };
}
</code>```

This is a much more obvious structure than dealing with a list which might have a null at position 2 but data at positions 3 onwards.  Putting this in a list is asking for exceptions in production because there will be one code path which is rarely used, doesn't have great/any unit tests and the developer didn't expect an element in his list to be null.

Edit: I got a little distracted from the question which was about sorting but now that you have a custom class, you can apply whatever sorting criteria you want to and it's going to be miles easier than trying to fudge a list to work for you.

Title: Implicitly or explicitly sorted elements?

Body:
So, I've got the following problem:

I have a number of ordered elements, ordered in the following way:

Type 1: Must be the first element. (only one possible, always present)

Type 2: Must be the second and following elements, if present.

Type 3: Must be the ordered last.

Stated a bit more succintly / pseudoregex:

12*3+

Now, when constructing these elements, I do so in a method, where it is easy to do something like:

```<code>public List<IElement> CreateElements(...)
{
    var list = ...;
    list.Add(new Type1());
    list.AddRange(GetType2Elements());
    list.AddRange(GetType3Elements());
}
</code>```

However, there is no explicit semantic ordering - it's just a list, that I happen to construct in a certain way.

A more explicit way is to have IElement implement IComparable, and then use an explicitly sorted list and returning that instead. That would carry the "sortedness" out of my construction method, and sort the entities irregardless how they are created.

However, it is suddenly a bit less trivial, since atleast 3 different Compare methods must be implemented.

What would you choose?

Body:
Wouldn't a simple class be better here than a list?  You can create a class which has the three elements in it and then a constructor/factory method to create it in the required order.

For example:

public class Wrapper
{
    public Type1 MainObject { get; set; }
    public List<Type2> SubElements { get; set; }
    public List<Type3> OtherElements { get; set; }
}

public Wrapper() { }

public static Wrapper FactoryCreateOrdered()
{
    return new Wrapper
    {
        MainObject = new Type1();
        SubElements = //null if not present or a list of Type2s
        OtherElements = GetType3Elements();
    };
}

This is a much more obvious structure than dealing with a list which might have a null at position 2 but data at positions 3 onwards.  Putting this in a list is asking for exceptions in production because there will be one code path which is rarely used, doesn't have great/any unit tests and the developer didn't expect an element in his list to be null.

Edit: I got a little distracted from the question which was about sorting but now that you have a custom class, you can apply whatever sorting criteria you want to and it's going to be miles easier than trying to fudge a list to work for you.


问:
in doubt of using code generators
I am now entering the world of java ee 6. And I am supposed to used different technologies like jsf, jpa, different kinds of beans and all that stuff.

I am learning using the netbeans IDE, which is, I should say, very efficient when it comes to getting the work done.

It is just that, I came from the old school servlet programming environment using scriptlets on them jsp pages where you get to write every line and every request parameter/attribute you have to set manually. which is somehow good because you get to understand you program THAT WELL.

but with this java ee 6, with the code generators from NETBEANS, I get to create controllers, jsf pages and entities without writing any code (taken aside the DB part though). I do understand the flow of the application but not to the degree that I can understand what the line does, how does it reached, what are the use of the variables and what does it do after. all the nitty gritty stuff.

to make it short, I am using generators without REALLY understanding the code that well (mostly on the new tags by jsf). I just want to ask if this is a bad path/practice or is it ok because we want PRODUCTIVITY?

答:
In the book "The Pragmatic Programmer", there is a whole chapter dedictated to the problem you are mentioning. Their answer is clear: Don't use generated code you don't understand.

A probably more pragmatic (pun intended) approach is: If you have to use generated code you don't understand, for god's sake, don't touch it.

Title: in doubt of using code generators


答:
I am now entering the world of assembly language, and I am
supposed to used different technologies like text editors,
linkers, assemblers.

I am learning using those, which is, I should say, very efficient
when it comes to getting the work done.

It is just that, I came from the old school of programming where
you get to enter every instruction on a front panel manually,
which is somehow good because you get to understand you program
THAT WELL.

But with this assembly language stuff, with the code generators
from the assembler, I get to create program without touching any
switches (taken aside the debugging part though). I do understand
the flow of the application but not to the degree that I can
understand what every bit does.

To make it short, I am using generators without REALLY
understanding the code that well. I just want to ask if this is a
bad path/practice or is it ok because we want PRODUCTIVITY?

Title: in doubt of using code generators

Body:
I am now entering the world of java ee 6. And I am supposed to used different technologies like jsf, jpa, different kinds of beans and all that stuff.

I am learning using the netbeans IDE, which is, I should say, very efficient when it comes to getting the work done.

It is just that, I came from the old school servlet programming environment using scriptlets on them jsp pages where you get to write every line and every request parameter/attribute you have to set manually. which is somehow good because you get to understand you program THAT WELL.

but with this java ee 6, with the code generators from NETBEANS, I get to create controllers, jsf pages and entities without writing any code (taken aside the DB part though). I do understand the flow of the application but not to the degree that I can understand what the line does, how does it reached, what are the use of the variables and what does it do after. all the nitty gritty stuff.

to make it short, I am using generators without REALLY understanding the code that well (mostly on the new tags by jsf). I just want to ask if this is a bad path/practice or is it ok because we want PRODUCTIVITY?


答:
The ability to abstract is one of the most powerful tools of the human brain. It allows it to handle complex systems as simple entities, provided the abstractions it works with are suitable.

This concept is very often applied to programming, because inevitably, we have to handle complex systems. Even Java as a language is already an abstraction of the JVM, which in turn is an abstraction of the actual machine you are running on. SQL is an abstraction of relational databases, which in turn are an abstraction of storage.

All this works well, because you think in terms of concepts in one abstraction layer, and this layer is separated from the layers below through an abstraction barrier. This is very well explained in SICP.

Based on this is the rather common approach of abstracting architecture and infrastructure. Libraries that do that are commonly referred to as frameworks (although nowadays everything is referred to as a framework).

One thing you will have to accept with frameworks is, that you must think within the abstraction layer they provide. How they work internally is none of your concern (assuming they work as specified) except for personal curiosity.

It is important to understand what a software component does, not how. In fact relying on the how is a good way of shooting yourself in the foot. Standing on the shoulders of giants is good.

Now to come back to code generators: Code generators are in a way an instrument of abstraction. You say: I want a controller for this and that, and zooooom it's there. You don't have to think about how it ties into the rest of the infrastructure, because all that is abstracted away. This is good.

However, I earlier mentioned the concept of abstraction barriers. An inherent problem of code generators is they provide no abstraction barrier. All the stuff they need, they do not hide it from you, but instead they throw it in your face. And you have code that consists of parts that you must change and parts that you mustn't change (as long as you want to stay in the same abstraction layer).

In some languages, Java being the canonical example, code generators are inevitable if you want to reach certain levels of abstraction. But as long as you have a clear understanding what the purpose of the code is that you generate and know which parts not to touch, you're on the safe side.

Title: in doubt of using code generators


问:
Design Methodology for Developing Interoperable Systems?
A bit of background

The company I work for has been creating database applications since around 1980 and, until relatively recently, most of these systems have been stand-alone "silo" systems.

However, in the last few years, we've seen more of a shift towards gathering "intelligence" across all systems within our customers requirements.  For example, a system that might collect data about people's dental records may need to talk to a system that collects data about people's optician records, share information about the same person and provide search capabilities across both systems (makes sense, although the example I've used is fictional).

In the fictional example above, the dental and optician systems may or may not both be written by the company I work for (in other words we are looking at both internally-developed interfaces and interfaces to systems from third-party providers).

What we've done so far

We have a basic web-services API (.asmx) for one of our products, but I'm concerned about the change management, in terms of keeping it up-to-date as we add new features to the main product (in terms of providing the new features through the API without breaking compatibility with older interfaces).

We have also produced one WCF service.  The rigid contracts put my mind slightly more at ease than working with the ASMX service, but I think a lack of experience within the company is holding us back, so I'm looking for some guidance on best practice that I can read up on to help move us along (or at least point us in the right direction).

The question

Is there a particular methodology or programming practice for designing systems to maximise their ability to interface to other systems?

Are there any good online (or offline) resources for these programming practices (assuming they exist)?

Any other advice you can provide based on the information above would be appreciated, but not essential.

We primarily develop in Microsoft .NET (mainly ASP.NET, with some windows forms applications as well) with a SQL Server/Oracle database back-end, although I expect the programming practices might be language independent.  (I've used the .NET tag as an afterthought, but I might take it out later..!)

Thanks for your time.

答:
You can follow the Jeff Bezos method as described here https://plus.google.com/112678702228711889851/posts/eVeouesvaVX

His Big Mandate went something along these lines:

1) All teams will henceforth expose their data and functionality through service interfaces.

2) Teams must communicate with each other through these interfaces.

3) There will be no other form of interprocess communication allowed: no direct linking, no direct reads of another team's data store, no shared-memory model, no back-doors whatsoever. The only communication allowed is via service interface calls over the network.

4) It doesn't matter what technology they use. HTTP, Corba, Pubsub, custom protocols -- doesn't matter. Bezos doesn't care.

5) All service interfaces, without exception, must be designed from the ground up to be externalizable. That is to say, the team must plan and design to be able to expose the interface to developers in the outside world. No exceptions.

6) Anyone who doesn't do this will be fired.

7) Thank you; have a nice day!