问:
Research on software defects
There is a chapter in "Making Software: What really works and why we believe it" By Andy Oram and Greg Wilson about software defects, and what metrics can be used to predict them.

To summarize (from what I can remember), they explained that they used a C codebase that was open source and had a published defect tracking history. They used a variety of well known metrics to see what was best at predicting the presence of defects. The first metric that they started with was lines of code (minus comments), which showed a correlation to defects (.i.e. as LOC increase so do defects). They did the same for a variety of other metrics (don't remember what off the top of my head) and ultimately concluded that more complex metrics were not significantly better at predicting defects than simple LOC count.

It would be easy to infer from this that choosing a less verbose language (a dynamic language?) will result in less lines of code and thus less defects. But the research in "Making Software" did not discuss the effect of language choice on defects, or on the class of defects. For example, perhaps a java program can be rewritten in clojure (or scala, or groovy, or...) resulting in more than 10x LOC savings. And you might infer 10x less defects because of that.

But is it possible that the concise language, while less verbose, is more prone to programmer errors (relative to the more verbose language)? Or, that defects written in the less verbose language are 10x harder to find and fix? The research in "Making Software" was a fine start, but it left me wanting more. Is there anything published on this topic?

答:
It would be easy to infer from this that choosing a less verbose language (a dynamic language?) will result in less lines of code and thus less defects.

Easy and as close to correct as you can get with that dataset.  Lines of code are where the errors must be.  Less code is less places to harbor errors.

But the research in "Making Software" did not discuss the effect of language choice on defects, or on the class of defects.

Actually.  It did.  It gave you the facts.  Fewer lines of code means fewer errors.

For example, perhaps a java program can be rewritten in clojure (or scala, or groovy, or...) resulting in more than 10x LOC savings. And you might infer 10x less defects because of that.

That would not be correct.  They said it correlated.  They did not say that the relationship is linear.

There are errors outside the code.  Specification errors.  Testing errors.  There are non-code defects as well as code defects.

But is it possible that the concise language, while less verbose, is more prone to programmer errors (relative to the more verbose language)?

No.  Concise languages have fewer errors.  It really is that simple.

The problem is that super-concise languages can be difficult to write.  So the cost goes up even though the number of errors goes down.  Maintenance can be very difficult.  Languages like APL or I are often write-once languages.  The code is so dense that it's hard to make a change; it's often easier to begin again from the beginning and write all new programs.

The other problem is that non-code errors start to dominate after a while.  A good, concise language -- particularly a DSL that's really a good fit to the problem domain -- reveals that there are numerous other sources of errors.

To avoid a lot of nuanced (and pointless) discussion.

The study quoted is obviously incomplete.

If you have a more nuanced explanation, please conduct your own study and publish your own results so that we can discuss them.

Please focus on question, if possible.  If you want to introduce new evidence, either open a new question or comment on the question itself to introduce new evidence.

Title: Research on software defects


问:
Maintainability of Boolean logic - Is nesting if statements needed?
Which of these is better for maintainability?

```<code>if (byteArrayVariable != null)
    if (byteArrayVariable .Length != 0)
         //Do something with byteArrayVariable
</code>```

OR

```<code>if ((byteArrayVariable != null) && (byteArrayVariable.Length != 0))
  //Do something with byteArrayVariable
</code>```

I prefer reading and writing the second, but I recall reading in code complete that doing things like that is bad for maintainability.

This is because you are relying on the language to not evaluate the second part of the if if the first part is false and not all languages do that.  (The second part will throw an exception if evaluated with a null byteArrayVariable.)

I don't know if that is really something to worry about or not, and I would like general feedback on the question.

Thanks.

答:
I prefer the second option, because it is more readable.

If the logic you're implementing is more complex (checking that a string is not null and not empty is just an example), then you can make a useful refactoring: extract a boolean function.  I'm with @mipadi on the "Code Complete" remark ("it doesn't matter if all languages do that...")  If the reader of your code isn't interested in looking inside the extracted function, then the order in which boolean operands are evaluated becomes a moot question to them.

ContentLicense: CC BY-SA 2.5


问:
SVN: Working with branches using the same working copy
We've just moved to SVN from CVS. We have a small team and everyone checks in code on the trunk and we have never ever used branches for development.

We each have directories on a remote dev server with the codebase checked out. Each developer works on their own sandbox with an associated URL to pull up the app in a browser (something like the setup here: Trade-offs of local vs remote development workflows for a web development team).

I've decided that for my current project, I'll use a branch because it would span multiple releases. I've already cut a branch out, but I am using the same directory as the one originally checked out (i.e. for the trunk).

Since it's the same directory (or working copy) for both the branch and the trunk, if for e.g. a bug pops up in the app I switch to the trunk and commit the change there, and then switch back to my branch for my project development.

My questions are:

Is this a sane way to work with branches?

Are there any pitfalls that I need to be aware of?

What would be the optimal way to work with branches if separate working copies are out of the question?

I haven't had issues yet as I have just started doing this way but all the tutorials/books/blog posts I have seen about branching with SVN imply working with different working copies (or perhaps I haven't come across an explanation of mixed working copies in plain English).

I just don't want to be sorry three months down the road when its time to integrate the branch back to the trunk.

答:
This is not a pit fall - but a clear warning if you are starting out branches a fresh.

I just don't want to be sorry three months down the road when its time
  to integrate the branch back to the trunk.

When the work of the branch is complete - you want to merge, one needs to carefully not introduce diff in both ways which become incompatible. If it does happens - ideally you should take all changes from branch to trunk before going up.

Also, you must make sure you remember start of the SVN branch and last merge. If you take same revisions point and try to merge that diff twice - results will be problematic.

Branching is a must for all practically large projects.

ContentLicense: CC BY-SA 3.0


问:
What is a realistic way to handle customer-specific software patches?
I'm trying to gather effective ways that others have solved the following problem.  At work we've been forced to release a software patch (to be installed on end-user systems) that we only want visible to a specific customer.  The custom code is in its own source-control branch.  The problem is we have two parallel code lines (and build scripts) to keep in sync, and every time we patch the original code we have to patch and test the customer-specific code.

I'm curious, how do other organizations handle this scenario?  We're open to business solutions and not just technical (source-control related) ones.  For example, we've talked about telling the customer they can't receive updates on that branch.

Our branching strategy is like this (based on the Visual Studio TFS Branching Guide, although we're using Subversion for it)

答:
How about introducing an extension mechanism into your code?

Your main code has:

```<code>class Foo
{
}
</code>```

When the program launches it checks for DLL/moral equivalent, in its startup folder for local customizations. If it finds one, it loads and it might contain company specific version of Foo

```<code>class FooForABC : Foo
{
}
</code>```

FooForABC implements the same behavior as Foo but overrides functions as necessary to provide the specific behavior that ABC needs. The technique should be flexible enough to handle any scenario you need to support.

Body:
How about introducing an extension mechanism into your code?

Your main code has:

class Foo
{
}

When the program launches it checks for DLL/moral equivalent, in its startup folder for local customizations. If it finds one, it loads and it might contain company specific version of Foo

class FooForABC : Foo
{
}

FooForABC implements the same behavior as Foo but overrides functions as necessary to provide the specific behavior that ABC needs. The technique should be flexible enough to handle any scenario you need to support.


问:
How can I reuse generic code for consulting between companies?
I am employed full time for company X and approached by company Y to do consulting services to write embedded C for them. While I know the basics of conflicts of interests and the big no-no's of sharing proprietary information, company knowledge and proprietary algorithms, I do have some questions regarding basic generic items that I need to reuse:

Software architecture: I have a personal preference of layering application, abstraction layer and hardware drivers. I don't want to have to do something different and it is not proprietary to the company. Would this be a problem if shared?

Generic functions: table look ups, sine/cosine functions, parsers, etc. I wrote all this code myself. Can I copy-paste this or do I have to rewrite, insert random spaces, change indentation, var names, table sizes, etc?

Function naming: I use a specific naming convention, e.g. MATH_Sin(). However, compiled to a DLL, company X can find a MATH_Sin() function available in company Y's DLL and assume that I copied their code. Do I need to rename all functions to hide any similarities?

Public knowledge turned into source code: say you find an algorithm on an paper that describes how to search for a pattern in a string and you turned the paper content into source code. Again, would a copy-paste be a no-no here too? Rewrite changing a few things or completely dismiss and find for another way to do it? In the end it is an implementation of public knowledge.

I asked around my peers and I cannot get a straight answer on what to do. Software is digital and very traceable and can always be traced back to the developer.

Thanks.

Update: I have approached my manager and HR and they strongly discouraged me to pursue this. They claimed that by using the same skill set (embedded programming or programming in general) for another company, there will be always the opportunity for company X to challenge myself or company Y. I asked then what would NOT be considered a conflict of interest and they answered "You could invest in a restaurant...". Seriously?

Company X is a very large corporation. There is no negotiation between employer and company, there is no acceptance of open source/licensed code and it seems they believe they own me and my skill set. While I do agree with some of their reasoning, I do not agree that they own my education and, while employed for them, I can't make use of my basic skills for other endeavors. Therefore I have decided to follow the advice below and open source all my personal code that does not belong to the company nor was written using company equipment or company time. I won't be making money or signing contracts, but at least I can keep my personal code and continue developing my career outside this restrictive environment.

Thanks for all answers. Hope this serves as a reference for others pursuing the same goal.

答:
This is bordering legal advice and this site is not really definitive source if you need accurate info.  While switching jobs a while ago, this very same question popped into my head and I did a bit research, but take whatever I say with a grain of salt.

If you are a full-time employee, the code written on company time belongs to that company.

You need to be very careful about "developing on your own time". A lot of companies consider any code written while employed by them to also be owned by them.  A while ago Joel wrote a very good write up about this exact topic. He does raise good points that in some cases companies include in the contract that any code you produce while employed with them is theirs.  After all we are salaried and don't have set hours.  I might be special case, but for me most productive time is 12am to 5am.  So how do you prove what constitutes "company time"?

When switching from one job for another, I left a relatively large personal collection of code behind. I never even considered taking any of that code because a) it's probably not the most ethical thing to do in the world and b) I've read enough stories to steer completely clear of anything that involves my previous employers code.  However, when I started working in my current company, I found that the first 3-5 months I've spent rewriting a lot of what I already wrote once.  It felt weird because even though I wasn't looking at the old code, I knew it well enough where I could easily duplicate something that would look very similar.  After doing a bunch of reading, I could only conclude that while company X owns the copyright, they don't own your brain.  You are free to write the same thing as many times as you want as long as it can never be physically proven that you had company X's code in front of your eyes while working for Y. In light of that, I would advise against simply changing white spacing and variable names.

In my case, I ended up writing a lot of it from memory but at the same time, since I've worked with previous libraries for years, I knew where they were lacking or were a pain to work with.  So when I switched to company Y, I also took the time to rebuild this code from scratch but with extra embedded experience.

I'm not looking forward to doing this with my next job, but the only thing I can think of is in the future before accepting an employment contract, finding a position with the company whose management is not completely against open source anything.  I think I would be leaning towards companies, who wouldn't mind if non-business related libraries could be released under MIT license.

OwnerDisplayName: PaulG


问:
How much effort should you put into a junior developer?
At what point should one give up?

I've tried helping them out by having them shadow me.  We agree to break a minute, and then they go missing in action for a while...then just go back to their desk.  Even when I know they've done this, part of me feels like I shouldn't have to go get them but that they should be showing interest in learning.  Frankly, it's a bunch of time I don't have explaining things as I go when I could just do it.  Am I expecting too much to expect that if they want to learn they'll make sure I know they're ready and willing?

They go to meetings that they were not told they had to attend...good, but then sit in the corner and sleep...bad.  I don't even know what to do with that.

Sometimes I give them something small to do and they do it great, so I give them something just a touch harder and they totally fail, hard.

They check in things without testing them.

Part of me thinks that maybe I should be spending more time with them but at the same time I don't see a lot of interest and I really, honestly don't have time teaching the same things over and over.  Sometimes I get asked questions that are really, really easy to answer if you just do a little bit of your own work trying to find out.  Other times I'm not asked anything.

I'm sure I could be doing better but honestly...I don't really want to anymore.

答:
Interesting question, I can see both sides of the story, there are some key pieces of information missing:

There seems to be a massive mismatch across the board between their expectations and yours of why they're there and what they're supposed to be doing. And you've never discussed this with them.

What are your, their, your company's and their college's expectations about this intern program? To what extent is this internship aligned/not aligned with their course of study, career goals etc? Do 50+% of the interns come back upon graduation? or go to your competitors? or flee the industry? Does your company have that much to teach them, frankly? What level and year are they: HS, community college, AA, BS, MS or PhD - that makes a world of difference? Do you have them working on (say) QA or sysadmin when they really want to work on (say) speech recognition or cloud? Did you have a brief to-the-point conversation with them to get to the bottom of this and why? (That's your responsibility to initiate, not theirs. This is overdue.) I would certainly phrase things like "Are you really interested in this work and dept, if not what can we change?" instead of "Do X,Y and Z or you're fired, because I say so". Do they want to be reassigned? Was your company and dept their last choice instead of flipping burgers? Maybe their college sucks AND your company sucks and they're just doing it for the $$ or resume bullet, in which case you're all trying to put lipstick on a plurality of pigs. Don't expect them to have a "junior developer" mentality if they don't see themselves as such, or have no interest. Invoking a disciplinary process on a lowly intern is pointless if none of this shared context is in place. Solicit their constructive suggestions too.

> "Part of me thinks that maybe I should be spending more time with them but at the same time I don't see a lot of interest"

Well does your company consider the interning arrangement to be a subsidy of your time to their college's research, or extra labor for your dept, or something in between? You could just let them sit and read Calvin and Hobbes and play ping-pong all day and not bother you.

> "they go missing in action for a while... Frankly, it's a bunch of time I don't have explaining things as I go when I could just do it."

Well if the intern arrangement isn't working for either of you, who foisted this intern program on your dept anyway, and who interviewed these people? Did you interview this intern? If no (why not?), who did and either way why did they get assigned to you? If they aren't contributing to your productivity, how do other people manage their interns? Are they at your company to do research or purely hourly-wage tasks or some reasonable mix? Do they have a meaningful project or deliverable in which they have a personal interest? Do they have milestones and are you monitoring them (sounds like no)? Do they make a presentation at the end of it? Does your company (not you personally) exit-interview your interns? What are their criticisms and suggestions? Are you paying them competitive $$, below-market $$ or free? Do they have any prior work experience, whether software or whatsoever? Maybe you should read resumes and interview more carefully, gauge their initiative and work style.

> "They go to meetings that they were not told they had to attend...good, but then sit in the corner and sleep...bad. I don't even know what to do with that."

Maybe they're trying to understand the wider organization/product/industry (are you or other people giving them that?), maybe they don't like shadowing you programming 8(?) hours a day, maybe they're totally demoralized by their lack of progress, or maybe they're just simply slacking off - can't tell based on what you said.

There's a well-known tactic to turn that unnecessary-meetings into something positive: tell them you may call on them at any point to stand up at your dept meeting and deliver a verbal summary of any of those meetings. Or, simply give them a list of meetings you think they don't need to attend, and ask if they're ok with that, and if not why. Maybe you or your HR or intern dept should set up some lunch or presentation schedule for them and other interns to meet a wide variety of people and job functions across the company. All the good intern programs do that, benchmark yourselves against them. If that doesn't exist, make it happen! It should benefit all of you. Take ownership of this intern program.

Come to think of it, set up a meeting for your own people managing interns on "Best Practises for Managing Interns" (absolutely don't invite the interns to that one. But probably give them a redacted summary). Have you talked to someone there who managed interns before about these issues?

That was the big-picture context you're not answering, then here's the specific detail stuff:

you want them to shadow you at your desk (how many hours a day? 2? 8?), maybe that's not for them. This sounds like micromanaging? If you solved the checkin breakage issue and held code reviews (suggestions below), should that really be necessary? I would say no. Why not have them decide when to shadow you? Better still, have them periodically show you on their machine how they are coding/testing/debugging, and you sit and watch and comment?

The general principle is: manage the expectations and review progress regularly (3x/week?); don't micromanage the behavior.

> They check in things without testing them.

ok that's a very simple one to fix: require all their checkins to attach a testcase file + passing logfile. Have the SCM system reject or flag changes without (/email the big boss/record checkin % success rate on a departmental leaderboard/whatever). Setting up the SCM system to enforce that is maybe a suitable intern task. And/or definitely have code reviews, even if it's over Skype, or (when you're busy), email comments. Probably also, limit the scope of which files they can checkin until they stop breaking stuff.

> Sometimes I give them something small to do and they do it great, so I give them something just a touch harder and they totally fail, hard.

Well sounds like the learning process or their thought process aren't working. Did you walk them through a logical set of steps they should have tried to solve it? Read the manuals, wikis, tutorials, user guides, books etc.?

another great practice is to have them start and own a wiki/(document) about methodology. Have them present that and review it. All of these problems are opportunities in disguise - assuming they have the basic ability, motivation and interest, which we don't know based on what you said.

> "Sometimes I get asked questions that are really, really easy to answer if you just do a little bit of your own work trying to find out.."

Tell them they could have answered it for themselves, have them start and own a wiki, and document/link to resources. Again, have them present it when they present on methodology. Also, I assume you mark your calendar with busy/available time ("red time/green time")?

> "Other times I'm not asked anything"

Uh that might either be a bad sign or a good sign - assuming they're not off sleeping in unnecessary meetings or reading Calvin and Hobbes or hiding from you. Assuming you stay in touch via email, IM and have automated emails of code checkins, maybe something deeper is not working.

Can you answer some of the above, then we can take it from there?


问:
Should I intentionally break the build when a bug is found in production?
It seems reasonable to me that if a serious bug is found in production by end-users, a failing unit test should be added to cover that bug, thus intentionally breaking the build until the bug is fixed. My rationale for this is that the build should have been failing all along, but wasn't due to inadequate automated test coverage.

Several of my colleagues have disagreed saying that a failing unit test shouldn't be checked in. I agree with this viewpoint in terms of normal TDD practices, but I think that production bugs should be handled differently - after all why would you want to allow a build to succeed with known defects?

Does anyone else have proven strategies for handling this scenario? I understand intentionally breaking the build could be disruptive to other team members, but that entirely depends on how you're using branches.

答: It depends on the role the tests are supposed to play and how their results are supposed to affect the build system/process adopted. My understanding of breaking the build is the same as Ben's, and at the same time we should not knowingly check in code that breaks existing tests. If those tests came in "later", it might be "okay" to ignore them just to make it less unnecessarily disruptive to others, but I find this practice of ignoring failing tests (so that they appear to pass) rather disturbing (especially so for unit tests), unless there is a way to indicate such tests as neither red nor green.</p>


问:
Is software testing actually done on professional projects?
I've been involved with many projects in several companies because I've been a developer for a long time and I'm a contractor.

I estimate that less than 20% of projects are methodically tested. With methodically tested I mean any testing beyond ad-hoc no plan testing.

I also estimate that less than 10% of projects are thoroughly methodically tested where they have dedicated testers as part of the team, test plan document, where developers write automated tests and then they also track test coverage and measure results.

Two questions

What are your percentage estimates about this issue?

What's your professional experience regarding software testing?

Additional note

Since methodical testing question may get quite biased answers (people like to brag about being superior to others) I encourage other developers (those that're not exposed to methodical testing) to provide their answer as well, because otherwise it will look like testing is being done everywhere... except at your company.

答:
Short answer: Yes

Long answer:

I do not have a good estimate for the first category (it is probably some distance from zero, but how much?), but my experience actually corroborates with your second estimate. It is hard to give meaningful percentages since the amount and type of testing depends on the kind of application being developed, and available timeframe and as well as the skillset of the developers and how the project is run. In practice the most important hurdle for the developers would be the acceptance test since that is an important milestone for billing purposes. But it is also the time where the unexpected may happen (more requirements) and the developers may be pressured to deliver and get by with whatever adhoc testing that is possible and timely (at this stage), on top of time needed for troubleshooting and overcoming the unexpected.

I have been through a variety of projects with different combination of factors mentioned above:

no formal unit tests, only integration tests and mostly adhoc tests

very formal ranging from unit tests to detailed test plans involving dedicated QA resources, automated testing (as conducted by the testers with their own set of tools) and code coverage reports. But these are not always meaningful to the developers as much as to the managers

On the individual level I seek to maintain an understanding of my options when it comes to writing proper tests appropriate for the technology I am dealing with, and exercise them at my own discretion. Basically the things that are actually meaningful and beneficial to my work, and not so much cranking out numbers.


问:
Do you write bad code when under pressure?
When you are under pressure, the deadline is approaching, and a manager is breathing down your neck do you find yourself starting to write bad code? Do TDD and best practices slip by the wayside in order to get things done? What do you do in situations like that? What were your experiences?</p>

答:
I know someone who never writes bad code under pressure. He also has some magic beans you might be interested in.

Everybody writes bad code sometimes and looming deadlines are the usual reason, the trick is to avoid getting into that situation in the first place (and that isn't easy either).


答:
I haven't read Making Software, so I can't comment on the conclusions they have drawn in their book.  Plotting Errors vs Lines Of Code can be misleading at best, because lines of code doesn't necessarily imply the degree of complexity of the logic contained within. Lines of Code is often more useful when determining time vs effort/cost, as a management tool at very roughly gauging a team's capacity for work, and even then it can be flawed.

When using metrics to measure code quality and the likelihood of error, I've found the following to be very useful:

Code Coverage

Instruction Path Length

Cyclomatic Complexity

The use of a good profiler can be of great assistance in providing useful measurements to help not only optimize code, but to get a feel for the likelihood that a significant number of bugs are likely to be inherent in the system. FWIW, I find the Redgate ANT profile to be one of the better .NET profilers.

Now back to your question. Software Metrics have been discussed since at least the early 70's to the best of my knowledge, although If I had to guess I'd say it's likely the topic was of interest even earlier than that.

...is it possible that the concise language, while less verbose, is
  more prone to programmer errors (relative to the more verbose
  language)? Or, that defects written in the less verbose language are
  10x harder to find and fix?

I would say that not only is it entirely possible, it is also very likely, both for the brevity of the language, and also due to its inherent complexity. For example, Assembler is about as brief as a language can get syntactically, and requires very careful attention to detail in order to minimize bugs, yet in being more verbose you are given many more opportunities to confirm the state by setting breakpoints at virtually every state change. That said, it's usually harder to locate problems by eye alone in assembler as compared to a higher level language with well factored code.

If on the other hand by reduced verbosity you mean a high-level language which handles a number of common operations through a single command, then you need to assume that the command as a shortcut is itself without error, and that the purpose to which you've applied the command is also without error. Making the command syntax less verbose can also have the effect of introducing an element of obfuscation to the code depending on the manner in which the syntax is used.

Is there anything published on this topic?

The Wikipedia article on Software Metrics has some links to some papers, and so too do each of the metrics that I listed earlier. As to how well peer reviewed all of that information is I am not entirely certain, but yes, there appears to be a lot of published information out there on this very subject, which is quite likely the meat and potatoes of many an advanced CompSci thesis. ;)

Title: Research on software defects

Body:
There is a chapter in "Making Software: What really works and why we believe it" By Andy Oram and Greg Wilson about software defects, and what metrics can be used to predict them.

To summarize (from what I can remember), they explained that they used a C codebase that was open source and had a published defect tracking history. They used a variety of well known metrics to see what was best at predicting the presence of defects. The first metric that they started with was lines of code (minus comments), which showed a correlation to defects (.i.e. as LOC increase so do defects). They did the same for a variety of other metrics (don't remember what off the top of my head) and ultimately concluded that more complex metrics were not significantly better at predicting defects than simple LOC count.

It would be easy to infer from this that choosing a less verbose language (a dynamic language?) will result in less lines of code and thus less defects. But the research in "Making Software" did not discuss the effect of language choice on defects, or on the class of defects. For example, perhaps a java program can be rewritten in clojure (or scala, or groovy, or...) resulting in more than 10x LOC savings. And you might infer 10x less defects because of that.

But is it possible that the concise language, while less verbose, is more prone to programmer errors (relative to the more verbose language)? Or, that defects written in the less verbose language are 10x harder to find and fix? The research in "Making Software" was a fine start, but it left me wanting more. Is there anything published on this topic?


问:
What are the common approaches & practices for big applications?
Developing big applications requires huge effort. There may be teams for each phase of development and they must use different design patterns and go through the whole SDLC.

I have two years of experience as a software developer on small applications and I'm interested on what are the common approaches & practices for big applications? Especially from a project management perspective.

How can I adopt such working practices?

答:
Working on large teams is definitely a new experience. You are no longer going to be able to understand or probably even have access to the entire code base that makes up your product. You will likely have to go through peculiar process controls that don't really relate to what your team is doing or how they do it, etc.

I am still getting a grasp on this subject myself but I think my key take away so far is:

 Specialize in your area

You don't need to understand the entire eco-system, and trying to do so can actually hinder you especially when initially ramping up. When starting out I would recommend focusing on understanding just your code and the logical boundaries off how your code interact with other teams code (Shared Databases, Caches, SOAP/REST Services, File systems, etc.) and whom your up and downstream dependencies and dependents are.

Become an expert at finding the expert.

In large organizations there are simply too many moving cogs for any one person to have intimate knowledge about the internal workings of each discrete system. Becoming really good at figuring out how to find the one person or wiki page that does have the answers you need to solve your own product or process issues is really a skill set you will want to pick up.

This means knowing a little bit about your organization's structure, and who to ask questions about to get information on a specific subject or who to ask questions on whom to ask questions on who to ask questions on a particular subject.

Knowing and being on good terms with your software architects, project managers, leads developers etc. all comes in very handy here.

Relax. Organizing large software projects is hard. It's a thing. The expectations on how you go about doing things and getting answers is different. The skillsets are a little bit different from the ones you use on smaller teams but you're a go-getter and just like everyone else when they made the jump to large teams you'll get the knack for it. ^_^

As far as design patterns and the technical stuff.

I don't think there are many major changes on the design patterns used on small projects versus large projects. A factory is a factory is a factory right?

At the same time to deal with the large number of people involved there tends to be push to compartmentalize specific components of the application so that they are as independent and decoupled from other components as possible. In my current role I see a lot of N-Tier diagrams with plenty of little boxes denoting specific product functionality. for the most part each team is responsible for one or more of those specific boxes. So we get very precise about what our components ins/outs are and requirements since we cant just change those details willy nilly due to the layers of people involved in making changes.

My division doesn't take this to the extreme that some other businesses do but if you are working on a large distributed solution rather than a single large program like say Ubuntu or Windows you might be digging into a Service Oriented Architecture such as the model Amazon has going on in order to facilitate this separation of concerns.

Much like the n-tier architecture diagrams with specific logical components, SOA is very handy in that if you do things in the correct manner and implement solid interface version control mechanisms and communicate upcoming interface changes upfront you can enable multiple teams to work on VNext solutions in parallel by working against stubbed endpoints and predetermined interfaces until some point down streams when the various services are functional enough to begin connecting to directly to one another to begin serving actual responses rather than canned stub/mock responses.

There are also some very interesting processes around development environment setup when working on services with interdependencies between services that are all being developed in parallel, and how you can insure each teams' or the shared companies' development environment has the latest bits possible deployed without introducing major functional breaks that block other teams.


问:
Handling invoices with timestamps
I'm currently going to write something to automatically create invoices with cronjobs by using PHP and timestamps.

I have a, for me, well-considered idea of how to solve it, but I want to ask the community if someone may see errors in reasoning and possible problems with my solution.

I'm trying to describe my idea as detailed as possible so everyone can follow my way of thinking:

In General there are 4 types of invoices:

Paid yearly

Paid semiyearly

Paid quarterly

Paid monthly

Purchased products are saved in a SQL database with the billing cycle:

ID of User

Product ID

Billing Cycle

Last Due Date

Now there is a cronjob that runs once a day to check if it should create a new invoice for each purchased product. In the row Last Due Date I save the timestamp of the first date to pay when it's created.

A code I already wrote calculates the time that has gone by since the Last Due Date timestamp and outputs something like this:

Timestamp is in past or in future

Month gone by

Days gone by

Now my rules for creating a new invoice are:

Paid yearly

if ( Timestamp is in past = true AND Month gone by = 11 AND Days gone by >= 20 )

then ( create a new invoice and set "Last Due Date" to time() )

Paid semiyearly

if ( Timestamp is in past = true AND Month gone by = 5 AND Days gone by >= 20 )

then ( create a new invoice and set "Last Due Date" to time() )

Paid quarterly

if ( Timestamp is in past = true AND Month gone by = 3 AND Days gone by >= 20 )

then ( create a new invoice and set "Last Due Date" to time() )

Paid monthly

if ( Timestamp is in past = true AND Month gone by = 0 AND Days gone by >= 20 )

then ( create a new invoice and set "Last Due Date" to time() )

As you can see a new invoice would be created ~10 days before date of payment and the timestamp in Last Due Date is set to the current time, so when the cronjob checks back the next day no invoice will be created for this purchased product.

My question is if this is an appropriate way of solving this and if you can see any errors in reasoning or problems that may occur?

答:
Problem Definition

Invoices are to generated based on a time cycle.
Data is stored in a table,say To Invoice,with the fields UserID, ProductID, Billing Cycle and Last Due Date. Based on the billing cycle field and the last due date timestamp, invoices are to be generated daily and in advance(10 days).

My assumptions

Last Due Date is a timestamp that's generated at the time of puchase of a product based on the billing cycle. Thus if the time when the data is generated is 20th JAN 2012 and the billing cycle is monthly then last due date would be ~20th FEB 2012

For each row in the To Invoice table, there is a corresponding table linked to this table that contains product qty and value, say Product. Hopefully, there must also be tables that contains billing address and other information, say Supplier.

Invoices are to generated daily

Invoices are to be generated 10 days before the due date

Each row in the To Invoice table is to have a separate invoice

We aren't going to talk about payments

Proposed Solution

A cron job is run.

This job scans the To Invoice table, compares the Last due date with the present date and outputs timestamp status(past or future), months and days and based on this data and the billing cycle,decides whether invoice is to be generated or not

Invoice is then generated based on the data in Product and Supplier tables

This is my understanding of your question. If this is the actual requirement, then there is a major flaw in the design.
There is no explicit way to track whether a product has been invoiced or not. Of course by principle, we can always compare the due date with the present time to get a list of products not invoiced but practically it isn't possible because to make this possible, the cron job must be run everyday at the specified time without a failure and the job must create all invoices without interruption. Both of this are virtually impossible.
Also, a second flaw is that the invoices cannot be altered easily with this design. A lot of invoices can be canceled(in real world) and with the existing design, you need to manually update the timestamp of those products that need to be invoiced again.
Thirdly, though not a flaw, this design doesn't seem to be easily extensible. Lets assume that an another cycle bimonthly is added and a few of the products that are to be invoiced quartely are to be invoiced bimonthly. Then, a whole lot of calculations need to de done to make changes.

Based on the above observations, I suggest the following solution

Instead of saving the due date in the To Invoice table, save the time at which the entry is generated (the time of purchase), lets call this product timestamp

Add a Boolean Filed isInvoiced to keep track of whether the product is invoiced or not with the default value False

Now, the present time would be compared with the product timestamp and together with the billing cycle and if has to be invoiced, then it would be invoiced and the field isInvoiced is updated as True.

In case, the invoice is canceled just change the isInvoiced field to False, the program would automatically generate an invoice the next time it runs the cron job.

To illustrate, lets say a product is purchased on 1st JAN 2012 with a billing cycle of 1 month. It falls due on 31st JAN for which we need to raise an invoice on 21st JAN (10 days in advance). If the cron job fails to run on the 21st and is run only on 22nd, it would still generate an invoice because it will know that the product is not invoiced by checking the isInvoiced field and since the billing cycle is 30 days and the difference between the due date(product timestamp+billing cycle time)and the product timestamp is less than 10 days. The same technique works for canceled invoices as well provided the isInvoiced field is set to zero.I would also suggest to maintain the cycle time in days as it is easier to understand and calculate.

By maintaining the above structure, the cron job could be easily automated with a SQL query and almost all databases provide this kind of query

Title: Handling invoices with timestamps


问:
Is it a good idea to use an unit test framework for another purpose than test code?
I'm about to write a simple script to test a dataset for certain conditions. I was designing it as a set of functions each one describing the condition to be tested and pass them to the test engine:

```<code># The tester engine:
all(f(dataset) for f in conditions)
</code>```

I realized that my approach was similar to unit testing. So, to avoid repeating myself, I am thinking of using my favorite unit testing framework instead.

What do you think about that idea?

Have any of you used an unit test framework for any other purpose than test code?

答:
It's an interesting approach. I'm assuming you are specifically looking for something like a nice summary of the properties your data set has.

e.g.

[X] Set is orthgonal array

[X] Set contains the letter s

[ ] No element has a depth greater than three generations.

Which technically I guess would be a set of Tests ^_^.

You can still test your business logic the same way you would test your custom asserts, and complex stub/mock classes e.g. with more unit tests that test the tester.

So . . . assumming you just want a quick way to get this type of information about your data set using some xUnit framework and the tap format or something probably wont end the world in thunder and flames, divide the earth by zero or anything too bad.

It's a little bit of a "I have a hammer" sort of a solution though.

Personally I would probably just search the nets a bit to see if anyone else has a good open source solution (http://cricket.sourceforge.net/  for example is vaguelly similiar) and if not whip up my own solution and release it.

The basic logic behind the unit test runner isnt too knarly. You use reflection to grab the list of methods in the current class and attributes to tag which methods you want to execute and which methods should be run before and after your "data questions".


问:
What should be the "depth of design"?
We all know that the process of creating a design and the whole architecture of the software is very important before writing the code. But how deep should be dive into the design stuff - should we start from the general architecture and go down til the names of the classes or should be just designate common parts and start coding?</p>

答:
I think most companies these days are adopting Agile software development: http://en.wikipedia.org/wiki/Agile_software_development

The basic idea is that you:

only plan as much as you can accomplish in a short time period, such
as two weeks

do the bare minimum development necessary to meet the requirements of a specific feature (vertical slice) of the system.

Then at then end of your two week iteration, you consider your accomplishments and plan your next iteration. Some of the benefits of this methodology are:

you dont waste time planning for things you wont need

you avoid developing features that needlessly constrain future requirements

you get quicker feedback about how well your system is meeting the (often changing) requirements of the user

Title: What should be the "depth of design"?


问:
What is the reason behind the if syntax of CoffeeScript?
In most other languages the condition comes before the statement to be executed when the condition is met. However, in CoffeeScript (and maybe some other languages) the syntax is:

```<code>number = -42 if opposite
</code>```

Is there any online documentation of what the logic behind this design decision for this syntax was?

答:
I think it's readability. First time I saw this concept was in Ruby which inherits from the Perl philosophy that "it's ok to have more than one ways to do it", where I believe it originates from.

Yukihiro Matsumoto: Ruby inherited the Perl philosophy of having more than one way to do the same thing. (from The Philosophy of Ruby)

There is also the unless statement which equals to "if not" (in CoffeeScript and Ruby). The aim is to have code that is more readable and looks more like "spoken" language. The assumption is that it is faster to understand and maintain.

example:

```<code>if (opposite) {
 x = -42;
}
</code>```

or

```<code>x = opposite ? -42 : x
</code>```

versus your example.

Please also note that you can still use the old syntax.

From "archaeological" perspective it looks like it started from Perl then inherited by Ruby (Ruby: On The Perl Origins Of "&&" And "||" Versus "and" And "or".). Ruby is a source of inspiration for CoffeeScript.

Body:
I think it's readability. First time I saw this concept was in Ruby which inherits from the Perl philosophy that "it's ok to have more than one ways to do it", where I believe it originates from.

Yukihiro Matsumoto: Ruby inherited the Perl philosophy of having more than one way to do the same thing. (from The Philosophy of Ruby)

There is also the unless statement which equals to "if not" (in CoffeeScript and Ruby). The aim is to have code that is more readable and looks more like "spoken" language. The assumption is that it is faster to understand and maintain.

example:

if (opposite) {
 x = -42;
}

or

x = opposite ? -42 : x

versus your example.

Please also note that you can still use the old syntax.

From "archaeological" perspective it looks like it started from Perl then inherited by Ruby (Ruby: On The Perl Origins Of "&&" And "||" Versus "and" And "or".). Ruby is a source of inspiration for CoffeeScript.


问:
When we talk about 'a closure' do we refer to a single variable, or do we refer to all 'closed' variables?
Let's take the following (JavaScript) code that returns a function that closes over variables x and y to illustrate:

```<code>function test() {
  var x = Math.random();
  var y = Math.random();
  var f = function() {
    console.log(x, y);
  };

  return f;
}
test()();
</code>```

The code is nonsensical, I just want to close over x and y.

Variables x and y don't exist outside of the function test but they remain available in the function f.

Barring any compiler optimizations (like inlining), do we say there is a single closure (created by f), or do we say there are two closures (for/over x and y)?

答: "A closure" is a function that closes over one or more variables, not the variable(s) that are closed over.  So it's a single closure.</p>


答:
You asked "... how to adopt to such working practice ...".  I don't think there's any real shortcut answer.  If you want to learn how development happens in a large company, go and work at a large company, and see what they do (and how well it works).  After a few years, go and work at a different large company, see what's different and what's the same.  Repeat this a number of times.

I've been in IT for around 20 years, and I'm still learning how development happens.  I've worked at a large number of companies, both big and small.  They're all different.  They all do some things well and others poorly.  But I've learnt something new about software development at every single one of them.

Sorry, but there's really no way to get experience, other than by getting experience.

Title: What are the common approaches & practices for big applications?

Body:
Developing big applications requires huge effort. There may be teams for each phase of development and they must use different design patterns and go through the whole SDLC.

I have two years of experience as a software developer on small applications and I'm interested on what are the common approaches & practices for big applications? Especially from a project management perspective.

How can I adopt such working practices?


问:
Reengineering the project from scratch

Possible Duplicate:

  When do you rebuild an application or keep on fixing the existing one

I am currently working on a project that has been in development for the last few years used throughout the organization but the way the project has been coded the maintainability of it is completely shot.

Reading the code presents with pages and pages of Anti-Patterns and trying to identify the path of a business workflow takes on occasion days.  At this point I would probably classify the software in its current state as "Working by accident" rather then as intended.  So I am looking for some wisdom as to the following:

At what point would you consider simply dumping the project into an abandonware pile and starting from scratch?

P.S.  I understand that in a lot of cases organization would consider it cheaper to maintain the existing project.

答:
Well I can imagine hypothetical scenarios where I might just throw out the existing code base (hypothetical situations where the bucky balls have zero weight and volume, where no one cares if we lose weeks or months of productivity as we scramble to add overlooked features and bug fixes into the system, and where the system is so trivial and hated by an organization that I can replace the entire thing and army of servers with notepad++ and a netbook in ten minutes and boost everyone’s productivity and moral across the board.)

For almost any real world scenario though I would just recommend refactoring in place. ^_^. There tend to be too many hidden, unanticipated costs to rewrites when undocumented legal and business requirements start to pop-up and the last minute hacking things together last minute starts to ensue.

==Refactoring in Place for greater good, and stuff==

Refactoring legacy code with the regular old incremental approach,

If you have the chance convert to UML and document what little knarly architecture there is.

If you are on version control look into generating some code churn reports and figuring out which files and file sections have been changed the most frequently. Make a note of these as they will likely be the areas you will want to deal with first.

Before you change any code always try to add some test coverage (even ugly full stack functional tests will do).

If dealing with large messy procedurial code extract logic you intend on changing into some reasonably named method or function and if possible add some test cases that verify your new method.  make whatever god awful hack you have to and if possible paramatize the change if it is something commonly tweaked like margin width or title so it will be a little more straight forward to update the next time.

Use the adapter pattern and work away at hiding the knarly bits of legacy code under a rug of logically named classes and methods so that for most common tasks you and the other developers perform you wont need to worry about the scary bits that are going on behind your back behind those nice little clean methods and classes you've hidden that legacy code behind -- like those nice families that keep deformed murderous zombie former family members in barns so that they don't spoil the day to day going-on’s of the farm . . . normally.

As you continue to whittle away and clean up the sections of the code continue to boost your test coverage. Now you can dig down even deeper and "rewrite" even more code when needed/desired with ever increasing confidence.

 Repeat, or apply additional refactoring approaches to continue to improve your codebase.

Branching By Abstraction

Define the trouble spot in the code you want to remove (the persistence layer, the pdf generator, the invoice tally mechanism, the widget generator, etc.).

run (write if necessary) some functional test cases (automated or manual but you know automated) against the code base that targets this functionality along with general behavior.

Extract logic related to that component from the existing sourcebase into a class with some reasonable interface.

Verify all code is now using the new interface to perform activity X which was previously dispersed randomly throughout the code(Grep the code base, add a trace to the new class and verify pages that should be calling it are, etc.), and that you can control which implementation will be used by modifying a single file.(object registry, factory class, whatever   IActivityXClass = Settings.AcitivtyXImplementer();)

 rerun functional test cases that verify everything is still functioning with all of Activity X throwin into your new class.

Write unit tests where possible around the new activity X wrapper class.

implement a new class with less insane spaghetti logic than the legacy implementation that adheres to the same interface as the legacy class.

verify that the new class passes the unit tests you wrote for the legacy class.

update your code by changing the registry/factorymethod/whatever to use the new class instead of the old class.

verify that your functional tests still pass.

Open Closed Principle and a Common Business Logic/Persistence Layer

To some extent you might be able to get away with separating out your presentation, business and persistence layer and writing a new app that is fully backwards compatible with the legacy solution, or at a minimum can still handle data inputted by legacy solution. I would probably not recommend this approach but sometimes it is a reasonable compromise of time/schedule/resources/required new functionality.

 At a minimum separate the presentation layer away from the business and persistence layers.

 implement a new ui and better presentation layer that uses the same common business and persistence layer.

 Verify that data created with new ui does not break old ui.  (you're going to be in hot water if users of the new tool interrupt users of the old tool).

If you are striving for full backwards compatibility you should be saving everything to the same persistence layers. If you just want forward compatibility into the new tool then use a new database and new tables or extension tables to track data not in legacy system.

 For new functionality and persistence layer needs add new tables and methods don't change existing legacy logic, or add columns, constraints to existing tables.

e.g. if you need to start tracking employers emergency contact and some other fields don't modify the existing employee table (we have no idea what assumptions the legacy data makes about that table)  add an extension table employee_ext  id, employee_id, emergency_contact_id, etc_id.

Slowly migrate users onto new system. if possible put legacy system into read only mode, or just add some warning telling users it will no longer be available after date X.

implement any hi priority missed functionality or business requirements in the new ui

 roll over users base.

 continue on to clean-up the business logic and persistence layer users other refactoring methodologies.

Title: Reengineering the project from scratch


问:
Choosing the right branching strategy for releases
Starting with a new dev team on a new project and we have to define our Branching strategy for our source repository (e.g. Microsoft Team Foundation Server 2010). We've run into a sticky discussion over whether or not to...

A. Have one Release branch from which we do production builds and then Label when something is actually released

OR

B. Have a new Release branch for each new Release into production (Ex. Version 1, 2, 3, etc...)

Option A seems pretty straight-forward but we're not sure if this will lead to problems in the long run. Option B seems like it just creates lots of one-time long-lived branches that just pile up over time.

Does anyone have any experience either way that could help us decide? Specifically, I'm looking to hear where the pain-points are for any one choice. Feel free to provide specific experience relative to TFS and/or Release-Management implications.

答:
We have separate branches for each release we put out (appr. 4 a year). It is very convenient when you need to pull a specific release.

If you need to maintain a couple of older releases, I don't think that labelling would do. With specific release branches, you can apply hot-fixes to each branch separately (or to a selection of them) without worrying about any of the other releases.

It also makes comparing releases that much easier when you are hunting for when a bug or a feature was introduced.

Don't worry about the number of branches or about the time they go without changes. Your versioning system is to give you control and to provide a history of your project's development. History has a tendency not to change... And don't worry about your cvs not being able to cope. We use Perforce, 9000+ files in a development branch, up to 50 development branches for the release(s) we are working on and as already said, a single branch per release that we publish. Perforce is not even breathing any harder.

In short: make your life as a developer/maintainer/bug-fixer/problem-hunter easier and don't worry about the number of branches or the number of files. Any self-respecting cvs will cope.

Edit:

We don't suffer any confusion at all with regard to the number of branches we have. Our naming scheme for the release branches and our 1 issue 1 branch policy for the development (or work) branches may have something to do with that.

Release branches are named for the release they hold, ie: R2011SP1 for Release 2011 Service Pack 1. Our work branches have less intelligent names: sub01, sub02, sub03 etc. The "sub" comes from the fact that all work branches are sub branch of the acceptance branch. The acceptance branch being the one where all issues are collected that are ready to be released.

Our 1 issue 1 work branch policy, combined with the fact that our issue tracking system has been customized with a "branch" field ensures that we always know what issue is developed in which branch. When an issue is integrated into the acceptance branch this field is updated. This means we always know which issues are ready for release (once the acceptance testing is done). Similarly we update this field when a release branch is created and this way we can always track down in which release an issue released.


答:
You have a responsibility to educate your juniors and to nurture their skills so that they can become great and independent members of your team. However, your juniors have a responsibility to start their careers behaving as professionals.  Sure, we all get tired, and we have days when the meetings are not interesting, but there is a difference between being disengaged and disrespectful.

As others have said, your vetting process sounds like it needs to be a little more rigorous.  That may come down to how you acquire your juniors in the first place.  The trick there is to go to your local university or college, and ask the CompSci teachers who they feel has not only the talent, but the dedication to make great software developers, then interview a bunch of kids and see where you want to go from there.

As for how much effort to put in, you need to give it your best shot, but at the same time you need to show these kids that you're not there to give them a free ride on the gravy train.  If your company has specific criteria for disciplinary action, apply it.  If the junior fails to meet the same standards of professionalism and doesn't take things seriously, you've got the options of either benching them, trading them, or simply letting them go, much the same as with any other employee who fails to perform.  Obviously you can't expect the same level of expertise, so you work with your junior to improve that if they are showing the dedication you expect of them.

Bringing along your juniors to achieve higher levels of expertise and experience can be an enriching experience for you as well, but you shouldn't act as if they are babies who need to be coddled.  When they are working for you, they are no longer strictly students, and need to be held to a higher standard of professionalism. Explain this all to them up front, and don't let them waste your time which could be better invested into someone else who would be willing to put the effort in.

Title: How much effort should you put into a junior developer?

Body:
At what point should one give up?

I've tried helping them out by having them shadow me.  We agree to break a minute, and then they go missing in action for a while...then just go back to their desk.  Even when I know they've done this, part of me feels like I shouldn't have to go get them but that they should be showing interest in learning.  Frankly, it's a bunch of time I don't have explaining things as I go when I could just do it.  Am I expecting too much to expect that if they want to learn they'll make sure I know they're ready and willing?

They go to meetings that they were not told they had to attend...good, but then sit in the corner and sleep...bad.  I don't even know what to do with that.

Sometimes I give them something small to do and they do it great, so I give them something just a touch harder and they totally fail, hard.

They check in things without testing them.

Part of me thinks that maybe I should be spending more time with them but at the same time I don't see a lot of interest and I really, honestly don't have time teaching the same things over and over.  Sometimes I get asked questions that are really, really easy to answer if you just do a little bit of your own work trying to find out.  Other times I'm not asked anything.

I'm sure I could be doing better but honestly...I don't really want to anymore.


答:
Option A. Just using mainline and tagging for release

Pros:

    You avoid merge hell.

    Keeping to the mainline encourages some best practices like proper release planning, not introducing a lot of WIP, using branching by abstraction to deal with out-of-band long term work, and using the open closed system and configurable features for dealing with managing works in progress that may; or may not; need to be disabled now or in the future in order to release or to avoid a full rollback.

Cons:

Dealing with works in progress becomes an issue and adds to potential surface attack area when it comes time to release.

However, if your developers are disciplined then new features should be configurable and modular and therefore easily disabled/enabled, or there is no WIP and at each release point all work is either completed or has not yet been started (i.e. Scrum).

Large scale/out-of-band changes require more thinking ahead of time to implement (e.g. branching by abstraction).

Personally I prefer this approach. Code coverage and unit tests should identify code that isn't ready to go out the door and people should not be working on code that will not be released during the current iteration. Branching by abstraction or other mechanisms can be used to deal with long term changes and works in progress.

When you don’t do this you start finding yourself dealing with merge issues, stale code, features that never get released, etc.

Option B. Branch by release

Pros:

You can begin working on the next iteration while the current iteration finishes its round of acceptance testing.

Other stuff im sure.

Cons:

 Tons of branches.

 Still need to tag branches at release points.

 Still need to deal with WIP and merge WIP from previous release branch into next release branch if it's not going to make it and still need to disable or yank it of release branch and re-run acceptance tests

 Hot fixes need to be applied to more branches (release branch + hotfix + new tag + merge hotfix into vnext branch and possibly vnextnext depending on where the hotfix falls.)

I'm not a huge fan of this solution ^_^.

Generally I would recommend just trying to stick to the mainline. If your developers are having trouble with not writing WIP that can be easily yanked when it fails the cut or that is checked in early for the next release then you can start talking about tagging the code at the point where it should be code complete and branching from there if necessary to address overlooked defects and bugs that your developers unit tests failed to catch.

Ideally though I think you want that to be the exception process, not the rule.

Option C. Crazy Bonus Option

If you want to get fancy you can also consider a per-user-story/per-feature branching model. (A terrible idea in TFS or any non DVCS while at the same time incredibly trivial to implement if using a DVCS like git or mercurial).

In the past I implemented the below for a previous employers maintenance team which worked with a legacy code base that could not easily be ported over to mercurial from svn. A lot of unnecessary work was involved to meet a business requirement of a always releasable mainline rather than just coordinating releases better but . . .

Features were developed by devs in their teams dev branch.

When a feature is ready to be peer reviewed the devs bundle it together into a single merge from the Dev branch into the CR branch and include the feature id/user story in the title. *Enforced by pre-commit hook*

After it passes CR an admin tool is used to Promote the feature into the QA branch.  (I wrote a little terminal application that listed the user stories present in the various acceptance stages and allowed the operator to promote or demote it inbetween those acceptance stages)

QA runs automation and manual usability tests. If the feature is good its pushed into the release branch (mainline). If the feature is rejected its demoted/reverted out of the QA branch until devs can address the issues brought up during test and add submit a patch to the CR branch.

If code was reverted from the QA branch and a fix is applied the terminal tool will re-apply the necessary changes to bring the feature back onto the QA branch from the CR branch so that QA may re-review the code and either promote it or demote it again.

At any point in time the release branch should be in a stable releasable state.

After a release new Dev, QA, and CR are spun from mainline.

Title: Choosing the right branching strategy for releases

Body:
Starting with a new dev team on a new project and we have to define our Branching strategy for our source repository (e.g. Microsoft Team Foundation Server 2010). We've run into a sticky discussion over whether or not to...

A. Have one Release branch from which we do production builds and then Label when something is actually released

OR

B. Have a new Release branch for each new Release into production (Ex. Version 1, 2, 3, etc...)

Option A seems pretty straight-forward but we're not sure if this will lead to problems in the long run. Option B seems like it just creates lots of one-time long-lived branches that just pile up over time.

Does anyone have any experience either way that could help us decide? Specifically, I'm looking to hear where the pain-points are for any one choice. Feel free to provide specific experience relative to TFS and/or Release-Management implications.


答:
In this instance your two clauses are directly related, so the 2nd form is preferable.

If they weren't related (e.g. a series of guard clauses on different conditions) then I'd prefer the 1st form (or I'd refactor out a method with a name which represents what the compound condition actually represents).

Title: Maintainability of Boolean logic - Is nesting if statements needed?

Body:
Which of these is better for maintainability?

```<code>if (byteArrayVariable != null)
    if (byteArrayVariable .Length != 0)
         //Do something with byteArrayVariable
</code>```

OR

```<code>if ((byteArrayVariable != null) && (byteArrayVariable.Length != 0))
  //Do something with byteArrayVariable
</code>```

I prefer reading and writing the second, but I recall reading in code complete that doing things like that is bad for maintainability.

This is because you are relying on the language to not evaluate the second part of the if if the first part is false and not all languages do that.  (The second part will throw an exception if evaluated with a null byteArrayVariable.)

I don't know if that is really something to worry about or not, and I would like general feedback on the question.

Thanks.


问:
Various programming concepts (from a Python viewpoint)
Ever since I've started lurking on stackoverflow, I keep coming across programming concepts such as abstract classes, virtual functions, contracts, interfaces, etc., from a questions about other languages such as C++, Java, and C#.

As far as I can tell, most of these things are related to object oriented programming but aren't typically mentioned in Python tutorials because Python uses a combination of duck typing and magic to make such concepts redundant.

Nevertheless, I'd still like to know what they are.

What are abstract classes, virtual functions, contracts, interfaces, etc. (explained from a Python standpoint?)  What other programming/OOP concepts should I know about that Python typically doesn't use or require you to know?

答:
abstract class

virtual function

interface

OwnerDisplayName: Deflect

OwnerDisplayName: rauschen


答:
Most of the concepts you mention are not used in Python because those are concepts related to static binding while python uses dynamic binding.

Abstract classes are clases which should not be used directly, but have to be inherited. They are useful when you provide an implementation for some methods, but you are missing one or more. Since python either has or not a method, but cannot have it undefined, it doesn't make sense.

Virtual functions are a C++ concept. Each class has a ptable with pointers to the functions, so that when you call a function the compiler writes a pointer with what it should execute. If you declare a virtual function you add a level of indirection; the compiler doesn't write the address to execute, but at runtime it goes to the class ptable, looks up the pointer and executes that. This allows you to use polymorphism (this is a generic concept, it means a function is different depending on what object calls it, it exists in python, look it up in the wikipedia) so that if the declared object is of class CHILD that has a virtual function from PARENT it uses the function from CHILD and not PARENT (even if it is a pointer declared as PARENT). There is a small price that you have to keep a few pointers and a couple more CPU operations, but it is really inconsequential

Interface is basically a set operations that can be applied to an object. In languages like Java you declare an interface and a class implements it. Then you can just use objects that implement the interface indistinctly, you just call the functions and the appropriate function is called. In python you don't have such concept because you just call a function and if it exists in the object it is called.

Contracts is a runtime guarantee established in the documentation. For instance, in Java there is a contract that if compare() returns 0 then equals() should return true. There is no enforcement (unless you write tests for your class), but it is assumed that if you have the compare() method and it has returned 0 equals will return true. If you write a class that breaks the contract and somebody uses, it has a behaviour that is unexpected. This is useful in python; for instance, you can write a sort method that expects a list of objects with 2 functions comparable and equals, with the conditions I mentioned for java. Then the function can receive any array of objects that follow the contract, without knowing anything at all about the objects except that. If you pass objects that break the contract, it is not guaranteed what will happen; you may get the wrong order or the function may loop continously.

Title: Various programming concepts (from a Python viewpoint)

Body:
Ever since I've started lurking on stackoverflow, I keep coming across programming concepts such as abstract classes, virtual functions, contracts, interfaces, etc., from a questions about other languages such as C++, Java, and C#.

As far as I can tell, most of these things are related to object oriented programming but aren't typically mentioned in Python tutorials because Python uses a combination of duck typing and magic to make such concepts redundant.

Nevertheless, I'd still like to know what they are.

What are abstract classes, virtual functions, contracts, interfaces, etc. (explained from a Python standpoint?)  What other programming/OOP concepts should I know about that Python typically doesn't use or require you to know?

OwnerDisplayName: Luis


答:
Abstract classes

Abstract classes are classes where some methods on the class are missing implementations. Python can (sort of) have these, but they're not quite as explicit as languages like Java, where the program will refuse to build. Typically, you inherit from an abstract class, and fill in the missing pieces, possibly using non-abstract methods from the abstract base class. Consider this class, in Python:

```<code>class Foo(object):
    def bar(self):
        # code code code

    def baz(self):
        raise NotImplementedError()
</code>```

This class is kind of like an abstract class: we can't (realistically) call baz. (We can, but we'll get only exceptions.) Unlike Java or C++, where an abstract class is one that can't be instantiated, we can instantiate Foo. Python provides the abc module if you want more "abstract" classes.

Virtual Functions

Virtual functions are functions that, when called from a reference or pointer to a base class, will call the derived version of that function. In C++, if I have:

```<code>Foo *foo = ClassDerivedFromFoo();
foo->bar();
</code>```

If bar isn't virtual, Foo::bar will get called. If it is, ClassDerivedFromFoo::bar will get called, if it exists. (The most-derived version will get called.)

In Python, an over-simplification would be that one can think of all functions as being virtual. This isn't quite correct: an instance's functions are really just attributes on that instance, and you can easily "monkey-patch" them to be an arbitrary function.

Contract

A contract is an agreement between a function and a caller of a function as to things that happen during the execution of a function. It's essentially the guarantees a function makes. To my knowledge, none of Python/Java/C++ enforce these explicitly. See Design by contract.

Interface

In a loose sense, an interface is the API (note that the "I" is interface) some piece of code (a module, class, function, etc.) exposes: it consists of what function calls are available, what types of data do they take and return, and what should that data be composed of.

Java has a special meaning for interface: An interface is a class-like description that contains member functions that contain no body. A class that contains all of those functions then, "implements" that interface. The interface can be used as a base class of sorts.

Python has similar, but much more abstract concepts. Take the enumerate function. It takes an "iterable", and returns the items from that iterable paired with increasing integers. (If you feed it ['a', 'b', 'c'] it spits out (0, 'a'), (1, 'b'), (2, 'c'). My example was a list, but it'll happily take any iterable: sets, dictionaries, generators, tuples, etc. As long as the item meets the interface of an iterable. This interface isn't (in Python) recorded explicitly, but as long as the object you pass in acts like an iterable, everything should just work. (This is duck typing.)

The Java "interface" idea is closely related to the general idea of abstract base classes, and some of the things the abc module can do might be interesting in regards to interfaces, as well.

Body:
Abstract classes

Abstract classes are classes where some methods on the class are missing implementations. Python can (sort of) have these, but they're not quite as explicit as languages like Java, where the program will refuse to build. Typically, you inherit from an abstract class, and fill in the missing pieces, possibly using non-abstract methods from the abstract base class. Consider this class, in Python:

class Foo(object):
    def bar(self):
        # code code code

    def baz(self):
        raise NotImplementedError()

This class is kind of like an abstract class: we can't (realistically) call baz. (We can, but we'll get only exceptions.) Unlike Java or C++, where an abstract class is one that can't be instantiated, we can instantiate Foo. Python provides the abc module if you want more "abstract" classes.

Virtual Functions

Virtual functions are functions that, when called from a reference or pointer to a base class, will call the derived version of that function. In C++, if I have:

Foo *foo = ClassDerivedFromFoo();
foo->bar();

If bar isn't virtual, Foo::bar will get called. If it is, ClassDerivedFromFoo::bar will get called, if it exists. (The most-derived version will get called.)

In Python, an over-simplification would be that one can think of all functions as being virtual. This isn't quite correct: an instance's functions are really just attributes on that instance, and you can easily "monkey-patch" them to be an arbitrary function.

Contract

A contract is an agreement between a function and a caller of a function as to things that happen during the execution of a function. It's essentially the guarantees a function makes. To my knowledge, none of Python/Java/C++ enforce these explicitly. See Design by contract.

Interface

In a loose sense, an interface is the API (note that the "I" is interface) some piece of code (a module, class, function, etc.) exposes: it consists of what function calls are available, what types of data do they take and return, and what should that data be composed of.

Java has a special meaning for interface: An interface is a class-like description that contains member functions that contain no body. A class that contains all of those functions then, "implements" that interface. The interface can be used as a base class of sorts.

Python has similar, but much more abstract concepts. Take the enumerate function. It takes an "iterable", and returns the items from that iterable paired with increasing integers. (If you feed it ['a', 'b', 'c'] it spits out (0, 'a'), (1, 'b'), (2, 'c'). My example was a list, but it'll happily take any iterable: sets, dictionaries, generators, tuples, etc. As long as the item meets the interface of an iterable. This interface isn't (in Python) recorded explicitly, but as long as the object you pass in acts like an iterable, everything should just work. (This is duck typing.)

The Java "interface" idea is closely related to the general idea of abstract base classes, and some of the things the abc module can do might be interesting in regards to interfaces, as well.

OwnerDisplayName: Thanatos


答:
It's all about context: how often do you release and what is in a release.

Here's a bit of a case study that I had with my old work, using the B method (we called it branch by purpose).

To put the story in context,

A release consisted in new features in our software: new gaming modes, new functionalities, new configuration options.

The release cycle was fairly long: our clients were universities that would stick with one feature set for usually a year.

Main development was made into the trunk until we reached a feature-complete state for a certain release. At that point, we would create a branch, say projectname-january2012 and do our quality testing and bug fixes in that very branch. Once we were ready for a public release, we would tag the code in that branch, and release.

However, development on the release did not end at that tag. Inevitably, we had clients that found bugs or small issues with the release. So in that case, all we need to do is to go back to that branch, patch the code and create a new tagged version of the january2012 branch to be released, and merge the fixes back to the trunk.

In our case, this approach was favorable because some users preferred to stay with older releases with a limited set of features, or simply because the cost of deploying on their infrastructure a whole new version rather than a hotfix caused some issues.

So the questions you have to ask yourself are:

How often do I release?

Are my releases going to be 100% backward compatible?

Will my clients be ok with completely upgrading to fix bugs?

If you release often, then maybe it's not worth it to have branches for each of them. However, if your release cycle is fairly long like my old use case, and that deployment, backwards compatibility and clients clinging to old releases might be risks, option B will certainly save you a lot of pain, will make things a lot easier to support your clients at the minimal cost of dealing with branch clutter.


问:
Is Entity Framework the way to go for our situation?
A little overview about what my group does ...

I work in a development team in a fairly large insurance company.  My group's responsibility consists mostly of building applications for our employees.  Stuff like tracking systems, scheduling applications, contact directories, etc.

Of course we have a decent amount of "shared data" that all applications usually reference.  Stuff like states, employees, and a slew of elements that pertain to our particular business (agents, lines of business, rating companies, etc).  Currently, we have a set of common code that all the applications can leverage to retrieve most of that common data.

Most requests that we get in require either tweaks to the current database objects or creation of many new database objects.  Our group is fairly small, but we still probably have 3-4 sets of database changes going through our Change Management System at any one given time and, depending on priority, some newer changes can leap-frog others on their way to production.

I understand all the benefits EFL brings but I also have a few concerns given our setup:
Since there is the element of shared data, it seems like it'd make sense to have one Data Model for our entire database (which contains all the objects for all the different applications).  Is that a safe assumption?  Or is it possible to build separate Data Models and have them interact with each other?

In the end, we want one class that is called "Employee" and we want that to be able to constant through any application so it seems like we either need to make one mega Data Model so that applications A-Z all have access to the Employee data and all reference the Employee class.  Unless the class can sit in a GAC DLL and then each Data Model can reference .... or, like I asked, separate Data Models can interact with each other.

Then ... if we do go with one mega data model, how difficult would it be to have different individuals making separate changes to that unified data model and then moving it up through a change management system?

I can see the benefits of using such a technology in a silo-ed application ... especially one with minimal maintenance ... but I'm having a hard time envisioning whether the time savings would still be there on a large scale with tons of different data model maintenance happening ... all at the same time.

Any advice given would be greatly appreciated.

答:
My experience is:  it's hell on earth.

We have a large core product that has many modules added to it. A given customer will have a core plus one or more modules, and any customer will have different set of modules to any other. Modules may make changes to  the DB schema, typically to their own tables, but occasionally adding columns to to core tables too.

Previously this was easy, make your sql changes and ship along with installation instructions for each module. No problems whatsoever (unless, of course, it didn't get installed correctly, but that's a problem with anything).

When we moved to EF, it wasn't fun. Firstly, if you make changes to your DB, you change your local EF accordingly. You then have to rebuild all the modules and core that use that EF assembly - or you get errors, or worse, it fails to load a module completely. (ok, you can use the GAC and policy files, but they quickly addup and having a lot of the same dlls in the GAC stops it working, we found)

When it comes to roll out to test, you now have to build a EF assembly that views the DB the customer uses, and rebuild all the components - as you do have a versioning system - or none of them will load.

So we went from writing a text file with sql statements that was run in to whatever DB, to doing that plus updating many different EF dlls and making sure we installed them correctly, plus rebuilding a lot of our modules all the time. Perhaps we could have done it better with sub-EF dlls, but the core one is several Mb so we didn't feel like managing lots of these simultaneously on each customer site.

The savings could well be there in a silo-ed (you mean monolithic) application, but you still have to manage rebuilds as you change the DB schema (or you end up rolling out lots and lots of EF dlls). I might be tempted to do it again and try to get it right, but I think the old way was so simple and foolproof that I can't see why I'd bother. Having LINQ is nice, but writing old sql didn't exactly take all day to write.


问:
Best practice to query data from MS SQL Server in C#?
What is the best way to query data from a MS SQL Server in C#?

I know that it is not good practice to have an SQL query in the code.

Is the best way to create a stored procedure and call it from C# with parameters?

```<code>using (var conn = new SqlConnection(connStr))
using (var command = new SqlCommand("StoredProc", conn) { CommandType = CommandType.StoredProcedure }) {
   conn.Open();
   command.ExecuteNonQuery();
   conn.Close();
}
</code>```

答:
Actually the basic assertion is debatable - there are trade-offs either way between having SQL in the code or having code in the database (which is where you're heading with stored procedures).

The upshot of which is that there is no single "best", this is not something you can generalise because whichever way you go you are making a compromise (you gain benefits but also introduce constraints).

If there is a one to one correspondence between your application and you database then it doesn't really matter. If, on the other hand, you have a large core database shared by a significant number of applications enforcing consistency within the database between those applications becomes much more important.

What's more important is to worry about the architecture and layering of your application - given an appropriate data access layer whether using an ORM like Entity Framework or NHibernate or doing something more direct should isolate most of your application from this decision regardless of whether you build queries or use stored procedures.

I will freely I have tended to work on relatively small projects with small teams (1-3 devs) - using stored procedures is, for me, more trouble than its worth because given that nature of our applications (and my skillset?) deploying new code is generally much easier than updating the schema (even allowing that I have code that makes updating the schema relatively straightforward) and I am able to enforce business rules by use of common data access code. This is clearly a classic example of "Your Mileage May Vary".


问:
Is there a personalizable programming language you can use to convert to others?
Is there a programming language in which you can set your own syntax configurations and it would convert the code to a language you choose?

For instance, you would choose specific configurations like "Python's indexed blocks", [a,b,c] initializes arrays, ^ for exponentiation and others. A script would convert it to your choice language's equivalent.

答:
Yes, but probably not in the way you’re thinking.

Lisp and its relatives have powerful macro systems that let you perform arbitrary transformations on your source, so in principle you can use macros (and reader macros, at the character level) to make just about any extensions you like. Concatenative languages (and languages by authors in related areas) have the potential for similar metaprogramming power. A good example of this is Forth, in which a lot of syntactic constructs (such as comments) can be user-defined. For a contemporary, non-esoteric example, there is an effort to give Perl 6 improved support over Perl 5 for user-defined syntax as well.


问:
How can I sell a legacy program rewrite to the business?
We have a legacy classic ASP application that's been around since 2001.  It badly needs to be re-written, but it's working fine from an end user perspective.

The reason I feel like a rewrite is necessary is that when we need to update it (which is admittedly not that often) then it takes forever to go through all the spaghetti code and fix problems.  Also, adding new features is also a pain since it was architect-ed and coded badly.

I've run cost analysis for them on maintenance but they are willing to spend more for the small maintenance jobs than a rewrite.  Any suggestions on convincing them otherwise?

答:
Don't re-write - the risks and costs are too high for your business. See the Joel Spolsky article referenced by @Grokus for reasons why.

I proffer an alternative option - a combination of refactoring the code that is suitable plus the introduction of a complementary technology alongside. For example, start writing new pages in ASP.NET, gradually migrating more and more code into the .NET world. We've done this successfully - new features are a great opportunity to do this, but simpler parts of the system that can be migrated quickly are also candidates. It may be necessary to concoct some level of abstraction or kind of bridging system (add an API layer to the 'old' system) to get there.

Only you can make the call whether to go for MVC + AJAX, MVC + SilverLight/Flash or similar, but you don't have to park one thing before going forward.

Yes, there'll be some pain and confusion along the way, but you'll have a shippable product the whole time, rather than a long, long, long time 'in development' with an established product becoming obsolete and losing market share to competitors.


问:
How is Python used in the real world?
I'm looking to get a job as a Python programmer. I know the basics of the language and have created a few games with it using pygame. I've also started to experiment with Django.

However, looking at the job market, it doesn't seem very many Python jobs are web-related. On the desktop side of things, it doesn't seem like very many companies use the popular GUI libraries like pyQt or wxPython.

How are companies actually using Python? What areas should one focus on to land a job as a Python programmer?

答:
My boss loves python and uses every chance he gets! So in our application we have a control that acts as a python interpreter. This runs on IronPython, since the main app is .NET based.

I have created a web based diagnostic interface for our new hardware that uses cherrypy.

I have put together an application for monitoring and controlling some aspects of other hardware we make. This uses Qt via the PySide bindings, for license compatibility.

So I don't think I can tell you what to focus on. I think you should look for a job that will satisfy your interests, and then focus on learning python to best suit that.

Title: How is Python used in the real world?


问:
Research on software defects
There is a chapter in "Making Software: What really works and why we believe it" By Andy Oram and Greg Wilson about software defects, and what metrics can be used to predict them.

To summarize (from what I can remember), they explained that they used a C codebase that was open source and had a published defect tracking history. They used a variety of well known metrics to see what was best at predicting the presence of defects. The first metric that they started with was lines of code (minus comments), which showed a correlation to defects (.i.e. as LOC increase so do defects). They did the same for a variety of other metrics (don't remember what off the top of my head) and ultimately concluded that more complex metrics were not significantly better at predicting defects than simple LOC count.

It would be easy to infer from this that choosing a less verbose language (a dynamic language?) will result in less lines of code and thus less defects. But the research in "Making Software" did not discuss the effect of language choice on defects, or on the class of defects. For example, perhaps a java program can be rewritten in clojure (or scala, or groovy, or...) resulting in more than 10x LOC savings. And you might infer 10x less defects because of that.

But is it possible that the concise language, while less verbose, is more prone to programmer errors (relative to the more verbose language)? Or, that defects written in the less verbose language are 10x harder to find and fix? The research in "Making Software" was a fine start, but it left me wanting more. Is there anything published on this topic?

答:
There's interesting stuff out there. These are my favorites, as they include empirical data, and they don't always match Accepted Dogma about bugs:

Andy Ozment's Milk or Wine -  It contradicts the Management Dogma
that Every Piece of Software has an infinite number of bugs (i.e.
fractal bugginess).

Famed Cambridge security researcher Ross Anderson wrote Open and
Closed Systems are Equivalent

Eric Rescorla, Is Finding Security Holes a Good Idea?

Geoffrey Phipps, Comparing Observed Bug and Productivity Rates for
Java and C++

David Atkins, Thomas Ball, Todd Graves, Audris Mockus,   Using
Version Control Data to Evaluate the Impact of Software Tools

Todd Graves, Alan Karr, J.S. Marron, Harvey Siy, Predicting Fault
Incidence Using Software Change History

Title: Research on software defects


答:
A closure is a first class function that captures the lexical bindings of variables defined in it's environment.  When it captures the bindings it is said to have "closed over" the variables.

Note: this means closures only exist at runtime (once it has "closed over" variables).

So in the example above a single closure is created when the code is executed.  This closure is "closed over" the variables x and y.

Title: When we talk about 'a closure' do we refer to a single variable, or do we refer to all 'closed' variables?

Body:
Let's take the following (JavaScript) code that returns a function that closes over variables x and y to illustrate:

```<code>function test() {
  var x = Math.random();
  var y = Math.random();
  var f = function() {
    console.log(x, y);
  };

  return f;
}
test()();
</code>```

The code is nonsensical, I just want to close over x and y.

Variables x and y don't exist outside of the function test but they remain available in the function f.

Barring any compiler optimizations (like inlining), do we say there is a single closure (created by f), or do we say there are two closures (for/over x and y)?