答:
I don't really think that Code Complete is the right resource for you here. This isn't a code problem, it's a process problem, and maybe a management problem.

If part of your process is particularly weak, then it's time to bust out the Theory of Constraints:

Identify the constraint.

This means finding the slowest or most inefficient part of the overall process. In your case, it's testing. But what part of the testing? Is it:

Preparing the test environment?

Determining what to test?

Functional (acceptance) tests?

Regression tests?

Exploratory testing?

Reporting bugs/defects from the tests?

Determining the steps to reproduce a bug?

Getting clarifications from developers or project managers?

Fixing the issues found in the QA stage?

These are all very different problems and call for different solutions. You need to decide which is the most costly/important. Justifying it to management should not be hard, as all of the above activities cost time (AKA money) and only a couple of them are value-added time.

Exploit the constraint.

In other words, optimize around the constraining process. Don't ever let the testers be idle. This essentially amounts to:

Putting testers inside development teams, if they aren't already, so there is a continuous feedback loop with developers.

Having frequent test deployments, so there is always something new/fixed to test.

Making communication faster and more frequent. For example, favour instant messaging over email threads.

Ensuring that testers have the best tools available (fast machines, multiple monitors, streamlined bug tracking, etc.)

This stage isn't about optimizing the test process itself (yet), it's more about reducing overhead. Don't waste testers' time. Eliminating time that is truly wasted should also be an easy sell to management.

Subordinate other activities to the constraint.

At this point, the testers are as productive as they can possibly be by themselves, so we need to start borrowing productivity from other areas:

Instruct developers and operations staff to give the testers first priority, no matter what else they're working on.

If you don't have cross-functional teams, reserve a meeting room every day at a preset time so that the testers never have to waste time trying to book one.

Divert some larger percentage of developer (and possibly operations) time away from feature work; for example, focus on bug fixes, tech debt/refactoring, code review, and unit testing.

Test continuously and incrementally - don't develop for 3 weeks and then kick it over to the testers. Have developers work on making their code immediately testable, e.g. with scaffolding or prototype UIs.

Elevate the constraint.

If the testers are working at full capacity - both in terms of productivity and minimal overhead - and it's still not fast enough, then you need to start investing more in testing.

If you rely on manual test deployments, automate it through the use of continuous integration and configuration management scripts.

If test plans take a long time to create, work on getting better acceptance criteria (i.e. INVEST). Most organizations are initially very bad at this.

If acceptance tests are taking too long, start automating them. Use a tool like Cucumber or FitNesse, or write xUnit-type tests if you must. There's also Selenium, Watij, and other browser automation tools if the UI testing takes a long time.

If regression tests are taking too long, automate that too. If it can't be automated, focus on improving quality out of the gate, i.e. with even greater emphasis on code review, unit testing, static analysis tools, etc. Developers should be fairly confident that there are very few actual bugs before passing it to QA (product defects are a different story).

If exploratory testing is the bottleneck, you could potentially defer some of that until after the release, or contract out to a testing firm to do highly parallelizable things like testing the same workflow in multiple browsers.

If testers are unable to repro a lot of bugs, consider building out a capacity-testing environment to be able to start reproducing intermittent errors. Or, try just running your automated acceptance tests in parallel and continuously, all day long, keeping detailed logs.

If it takes too long to fix the bugs, then start partitioning your projects and/or seriously consider rearchitecting your solutions. Or, alternative, don't fix some of them; not every bug is critical, you should be able to prioritize them alongside feature work.

If all else fails, hire more testers.

Go back to Step 1.

I would like to say that this is all common sense, but unfortunately it's not, at least not in most organizations. If you are getting a lot of resistance from management, an invaluable technique is Value Stream Mapping (a technique from lean manufacturing), which you can use to show how much time and therefore money is actually being wasted every day by a release candidate being unable to move to the next stage. Opportunity cost is hard to understand but this is one of the best ways I've found to visualize and demonstrate it.

And if none of that works... then maybe you're in a dysfunctional company, get out before it's too late!

But you won't solve this problem simply by dropping a few papers on the manager's desk and asking them to throw money at the problem, because they will assume (correctly) that throwing money at it might not actually solve it, and might even make it worse. You need to provide solutions, and that's what this answer is about. If you introduce the issue as "here's a list of ways we can start solving this problem, in descending order of cost/benefit" rather than "we need more testers", then you will have a lot more success.

Title: The cost of longer delay between development and QA

Body:
At my current position, QA has become a bottleneck.  We have had the unfortunate occurence of features being held out of the current build so that QA could finish testing.  This means features that are done being developed may not get tested for 2-3 weeks after the developer has already moved on.  With dev moving faster thean QA, this time gap is only going to get bigger.

I keep flipping through my copy of Code Complete, looking for a "Hard Data" snippet that shows the cost of fixing defects grows exponentially the longer it exists.  Can someone point me to some studies that back up this concept?  I am trying to convince the powers that be that the QA bottleneck is a lot more costly than they think.


问:
How to document requirements for an API systematically?
I am currently working on a project, where I have to analyze the requirements of two given IT systems, that use cloud computing, for a Cloud API. In other words, I have to analyze what requirements these systems have for a Cloud API, such that they would be able to switch it, while being able to accomplish their current goals.

Let me give you an example for some informal requirements of Project A:

When starting virtual machines in the cloud through the API, it must be possible to specify the memory size, CPU type, operating system and a SSH key for the root user.

It must be possible to monitor the inbound and outbound network traffic per hour per virtual machine.

The API must support the assignment of public IPs to a virtual machine and the retrieval of the public IPs.

...

In a later stage of the project I will analyze some Cloud Computing standards that standardize cloud APIs to find out where possible shortcomings in the current standards are. A finding could and will probably be, that a certain standard does not support monitoring resource usage and thus is not currently usable.

I am currently trying to find a way to systematically write down and classify my requirements. I feel that the way I currently have them written down (like the three points above) is too informal.

I have read in a couple of requirements enineering and software architecture books, but they all focus too much on details and implementation. I do really only care about the functionalities provided through the API/interface and I don't think UML diagrams etc. are the right choice for me. I think currently the requirements that I collected can be described as user stories, but is that already enough for a sophisticated requirements analysis? Probably I should go "one level deeper" ...

答:
Read Documenting Software Architectures, second edition: Views and Beyond, Chapter 7: Documenting Software Interfaces.

Or at least check some well-known API documentations, like Google's (Maps, GData - outdated but complex) Amazon's (S3 ) or inspect the documentation for Microsoft applications and services, gathered together on MSDN (for Live services, but even for Windows)

Usually an API documentation has 3 parts:

an overview on what the thing is for, what someone could make out of it, perhaps an architectural overview

A developer's guide, explaining some common tasks with the API, usually with code samples and downloadable sample applications.

An API reference of how it should work

In theory - if we believe Brook's Mythical Man Month - you design the documentation and make sure there's a matching implementation.

Now back to practice

Designing requirements for an API goes like any software design goes.

You enlist the different actors who are to be using the API (using a context diagram for example)

You detail each actor's typical needs of the system with use cases

For each use case, you develop a set of scenarios on how the imagined system would be used (the book Writing Effective Use Cases might help you on that)

You either create robustness diagrams, sequence diagrams or activity diagrams, but you design behaviour based on  the scenarios  to make out what messages are needed to be passed

From the messages, you deduce underlying data architecture, by looking at what parameters are needed for each message to be successfully communicated.

Many people would start with the underlying data structure, but I think that's silly: computers (and objects, for that matter) are about interactions. You need to understand what needs to be communicated from either side in order to run a succesful interaction. Data is only the parameter of those interactions.

I usually do activity diagrams or simple flowcharts which show the passed arguments as objects or classes. That is, there's a control flow going on, but we see what information did one of the parties pass to the other.

After you've finished all these, you grab your scenarios again, and start to craft acceptance tests. That's because APIs are to be used by computer clients, therefore, your first code should be a computer client which does automated retrieval as a test.

Acceptance tests are either written in "provided input"-"expected output" form, or as code. You can find lots of books on BDD and TDD which will explain to you how to write good tests.

Also, around here, you start to bring out books on REST interfaces and similar in case you're building a web API, as your tests have to be executable from day one .

From the scenarios, you also build sample code, and developer's guide.

From the sequence diagrams and data architecture diagrams, you develop the API reference.

Add a sprinkle of HTML, make sure all the tests pass, and that your application is fast, secure, and robust enough, and let's get out with it!

(I know, this was waterfall-ish: Agile is the same, except you always do only a tiny part of this, eg, a few scenarios per sprint)

OwnerDisplayName: Heinrich

ContentLicense: CC BY-SA 3.0


问:
Is it possible to implement a completely-stateless multiplayer game?
I'm facing a challenge understanding how to program a web version of a card game that is completely stateless.

I create my object graph when the game begins and distribute cards to PlayerA and PlayerB so I lay them out on the screen. At this point I could assume that HTML and the querystring is what holds at least some of my state and just keep a snapshot copy of the game state on the server-side for the sole purpose of validating the inputs I receive from the web clients.

Still it appears to me that the state of the game is by its nature mutable: cards are being dealt from the deck, etc.

Am I just not getting it? Or should I just strive to minimize the side-effects of my functions to the objects that I take as my input? How would you design a stateless card game?

答:
It's not state what causes problems in scalability but keeping up with state.

I don't know if you are to design a REST interface, which is about state transfer, not statelesness. Statelesness would mean, that doing the same action twice has the same result.

This doesn't even apply to HTTP. If you do a DELETE request twice, the second one is pretty much supposed to fail.

In case you're developing an HTML-based game, nothing stops you to maintain state on the client in JavaScript.

In servers, the problem with state is usually its mutability:

getting half-changed data (eg, if a Knight in chess moves, both coordinates change. If part of the system would get data with only one of the coordinates changed, there'd be potential trouble)

data changing between transfer: suppose A calls B, and both use C. A is assuming C has a certain state, and expects B to behave accordingly. Yet in the meanwhile, C has changed, and B is acting differently. Bugs happen.

Also, there's a problem with concurrency:

parallel components getting different state and thinking theirs is right: this is called conflict. An example would be, when in a realtime game, you hit an opponent, an opponent also hits you, and both shots are fatal. Each of them would think the other one is dead and they've won

And finally, there's a problem with storage&retrieval and failure:

dying components: suppose there's a webshop, and the user has a basket. If the basket is maintained by a single compoennt, it could die if there are too many customers. If it is managed by 10 components, each of them managing a subset of customers, what happens if the component which was managing the current user's state dies?

So, state is normal. It's part of life. Computers are about interactions: a non-interactive computer is called book or newspaper, or rather, a poster (as a book has both open and closed states). Interaction changes state. While we try to minimize maintenance of state, we can't avoid it by nature.


问:
Should I continue my self-taught coding practice or learn how to do coding professionally?
Lately I've been getting professional work, hanging out with other programmers, and making friends in the industry. The only thing is I'm 100% self-taught. It's caused my style to extremely deviate from the style of those that are properly trained. It's the techniques and organization of my code that's different.

It's a mixture of several things I do. I tend to blend several programming paradigms together. Like Functional and OO. I lean to the Functional side more than OO, but I see the use of OO when something would make more sense as an abstract entity. Like a game object. Next I also go the simple route when doing something. When in contrast, it seems like sometimes the code I see from professional programmers is complicated for the sake of it! I use lots of closures. And lastly, I'm not the best commenter. I find it easier just to read through my code than reading the comment. And most cases I just end up reading the code even if there are comments. Plus I've been told that, because of how simply I write my code, it's very easy to read it.

I hear professionally trained programmers go on and on about things like unit tests. Something I've never used before so I haven't even the faintest idea of what they are or how they work. Lots and lots of underscores "_", which aren't really my taste. Most of the techniques I use are straight from me, or a few books I've read. Don't know anything about MVC, I've heard a lot about it though with things like backbone.js. I think it's a way to organize an application. It just confuses me though because by now I've made my own organizational structures.

It's a bit of a pain. I can't use template applications at all when learning something new like with Ubuntu's Quickly. I have trouble understanding code that I can tell is from someone trained. Complete OO programming really leaves a bad taste in my mouth, yet that seems to be what EVERYONE else is strictly using.

It's left me not that confident in the look of my code, or wondering whether I'll cause sparks when joining a company or maybe contributing to open source projects. In fact I'm rather scared of the fact that people will eventually be checking out my code. Is this just something normal any programmer goes through or should I really look to change up my techniques?

答:
Short answer: yes.

Teaching yourself is almost all good.

Filter with good sense, good advice.

WRT learning professional programming, yes.

What do you have in mind?

Conferences, seminars, certification, a degree?

Each has a cost/benefit.

When the ROI is good, if you have the resources, go for it.

Weigh advice on degrees by considering the source: people with/without them have vested interests.

Talk to a half dozen of each.

Is academia isolated from industry?  Often.

Is a degree worthless?  Dollar-wise, hard to argue.

Grads almost always make more money, but watch out for college loans.

Knowledge-wise?  Maybe.

If you hate school, you won't get more out than you put in.

If you feel like a degree is a worthy goal for you, it probably is.

Dig deeper and find out about the program of study, the costs, the environment.  Make sure you have the interest, commitment, time, and resources.  You probably went to school for thirteen years, so what is another four?  They will be the most expensive, and the main person you will rely on to make them the most valuable is you.

Costs can be pretty scary, but they only tell a part of the story because there are many grants and scholarships for merit, need, and one hundred other reasons.

If you go, pick smart profs and buds.


答: You really don't need to get any more "formal" than what you have.  You're writing it for humans to read and probably mostly yourself, so keep that in mind.  My one suggestion is to put it in a hierarchy and number it in outline format.  That way in reviews, checklists and such, you can refer to a number like 3.0.1 as a shorthand and to easily disambiguate what you're talking about.</p>

Title: How to document requirements for an API systematically?

Body:
I am currently working on a project, where I have to analyze the requirements of two given IT systems, that use cloud computing, for a Cloud API. In other words, I have to analyze what requirements these systems have for a Cloud API, such that they would be able to switch it, while being able to accomplish their current goals.

Let me give you an example for some informal requirements of Project A:

When starting virtual machines in the cloud through the API, it must be possible to specify the memory size, CPU type, operating system and a SSH key for the root user.

It must be possible to monitor the inbound and outbound network traffic per hour per virtual machine.

The API must support the assignment of public IPs to a virtual machine and the retrieval of the public IPs.

...

In a later stage of the project I will analyze some Cloud Computing standards that standardize cloud APIs to find out where possible shortcomings in the current standards are. A finding could and will probably be, that a certain standard does not support monitoring resource usage and thus is not currently usable.

I am currently trying to find a way to systematically write down and classify my requirements. I feel that the way I currently have them written down (like the three points above) is too informal.

I have read in a couple of requirements enineering and software architecture books, but they all focus too much on details and implementation. I do really only care about the functionalities provided through the API/interface and I don't think UML diagrams etc. are the right choice for me. I think currently the requirements that I collected can be described as user stories, but is that already enough for a sophisticated requirements analysis? Probably I should go "one level deeper" ...


问:
Dependency Injection/IoC container practices when writing frameworks
I've used various IoC containers (Castle.Windsor, Autofac, MEF, etc) for .Net in a number of projects. I have found they tend to be frequently abused and encourage a number of bad practices.

Are there any established practices for IoC container use, particularly when providing a platform/framework? My aim as a framework writer is to make code as simple and as easy to use as possible. I'd rather write one line of code to construct an object than ten or even just two.

For example, a couple of code smells that I've noticed and don't have good suggestions to:

Large number of parameters (>5) for constructors. Creating services tends to be complex; all of the dependencies are injected via the constructor - despite the fact that the components are rarely optional (except for maybe in testing).

Lack of private and internal classes; this one may be a specific limitation of using C# and Silverlight, but I'm interested in how it is solved. It's difficult to tell what a frameworks interface is if all the classes are public; it allows me access to private parts that I probably shouldnt touch.

Coupling the object lifecycle to the IoC container. It is often difficult to manually construct the dependencies required to create objects. Object lifecycle is too often managed by the IoC framework. I've seen projects where most classes are registered as Singletons. You get a lack of explicit control and are also forced to manage the internals (it relates to the above point, all classes are public and you have to inject them).

For example, .Net framework has many static methods. such as, DateTime.UtcNow. Many times I have seen this wrapped and injected as a construction parameter.

Depending on concrete implementation makes my code hard to test.
Injecting a dependency makes my code hard to use - particularly if the class has many parameters.

How do I provide both a testable interface, as well as one that is easy to use?
What are the best practices?

答:
The only legitimate dependency injection anti-pattern that I'm aware of is the Service Locator pattern, which is an anti-pattern when a DI framework is used for it.

All of the other so-called DI anti-patterns that I've heard about, here or elsewhere, are just slightly more specific cases of general OO/software design anti-patterns. For instance:

Constructor over-injection is a violation of the Single Responsibility Principle. Too many constructor arguments indicates too many dependencies; too many dependencies indicates that the class is trying to do too much. Usually this error correlates with other code smells, such as unusually long or ambiguous ("manager") class names. Static analysis tools can easily detect excessive afferent/efferent coupling.

Injection of data, as opposed to behaviour, is a subtype of the poltergeist anti-pattern, with the 'geist in this case being the container. If a class needs to be aware of the current date and time, you don't inject a DateTime, which is data; instead, you inject an abstraction over the system clock (I usually call mine ISystemClock, although I think there's a more general one in the SystemWrappers project). This is not only correct for DI; it is absolutely essential for testability, so that you can test time-varying functions without needing to actually wait on them.

Declaring every life cycle as Singleton is, to me, a perfect example of cargo cult programming and to a lesser degree the colloquially-named "object cesspool". I've seen more singleton abuse than I care to remember, and very little of it involves DI.

Another common error is implementation-specific interface types (with strange names like IOracleRepository) done just to be able to register it in the container. This is in and of itself a violation of the Dependency Inversion Principle (just because it's an interface, does not mean it's truly abstract) and often also includes interface bloat which violates the Interface Segregation Principle.

The last error I usually see is the "optional dependency", which they did in NerdDinner. In other words, there is a constructor that accepts dependency injection, but also another constructor that uses a "default" implementation. This also violates the DIP and tends to lead to LSP violations as well, as developers, over time, start making assumptions around the default implementation, and/or start new-ing up instances using the default constructor.

As the old saying goes, you can write FORTRAN in any language. Dependency Injection isn't a silver bullet that will prevent developers from screwing up their dependency management, but it does prevent a number of common errors/anti-patterns:

Abstraction inversion

Circular dependencies

Spaghetti code (sort of)

...and so on.

Obviously you don't want to design a framework to depend on a specific IoC container implementation, like Unity or AutoFac. That is, once again, violating the DIP. But if you find yourself even thinking about doing something like that, then you must have already made several design errors, because Dependency Injection is a general-purpose dependency-management technique and is not tied to the concept of an IoC container.

Anything can construct a dependency tree; maybe it's an IoC container, maybe it's a unit test with a bunch of mocks, maybe it's a test driver supplying dummy data. Your framework shouldn't care, and most frameworks I've seen don't care, but they still make heavy use of dependency injection so that it can be easily integrated into the end user's IoC container of choice.

DI isn't rocket science. Just try to avoid new and static except when there's a compelling reason to use them, such as a utility method that has no external dependencies, or a utility class that could not possibly have any purpose outside the framework (interop wrappers and dictionary keys are common examples of this).

Many of the problems with IoC frameworks come up when developers are first learning how to use them, and instead of actually changing the way they handle dependencies and abstractions to fit the IoC model, instead try to manipulate the IoC container to meet the expectations of their old coding style, which would often involve high coupling and low cohesion. Bad code is bad code, whether it uses DI techniques or not.


问:
How should I incorporate a hotfix back into a feature branch using gitflow?
I've started using gitflow for a project, and I have an outstanding feature branch as well as a newly created hotfix. Per the gitflow workflow, the hotfix gets applied to both the master and develop branches, but nothing is said or done about extant feature branches.

Nevertheless, I'd like to incorporate the hotfix changes back into my feature branch, which as near as I can tell leaves three options:

Don't incorporate the changes. If the changes were needed for the feature branch, it should've been part of the feature branch.

Merge develop back into the feature branch. This seems to follow the gitflow workflow the best, but would cause out-of-order commits.

Rebase the feature branch onto develop. This would preserve commit order but rebasing seems to be completely absent from the general gitflow workflow.

What's the best practice here?

答: I don't see anything wrong with rebasing your feature branch onto develop to pick up the latest hot fixes.  Actually, frequently rebasing your feature branch against develop can be helpful, since it lets you keep your branch "up to date," which makes merging much easier when you get to that stage.


答:
Second Question - Can I use my own style?

You have two questions.

The first is in your title.  Please see my earlier answer.

The second is detailed in about five paragraphs where you characterize how your style differs from professional style with the points listed below:

100% self taught.

Different in technique and organization.

Blend of functional and object oriented.

Less complicated.

Lots of closures.

Few comments.

No unit tests.

Few underscores.

No MVC.

No backbone.js.

No template applications.

Summarized, I think you are asking if it OK that you use the Frank Sinatra approach - "I did it my way."  I sense ambivalence as you call other people's code professional, but you are not on board with it.  Style is a sticky personal issue, and the debate about what is good code is endless and often a waste of time.  Some issues may be easier if your group uses a written coding convention.  Please check out:

http://en.wikipedia.org/wiki/Coding_conventions

There is an etiquette to killing someone else's code, and that is another things you should work on with your team.  Put your thick skin on and hope they are not too brutal, but whatever you do, don't go to war.

You commented about anxiety about others seeing your code.  Get ready because not only will they see it, but they will rewrite it and tell you what is wrong with your style.  Your coworkers may be flexible or rigid.  Either way, I recommend you not rewrite their code for style or make each point of style a negotiation.

Reasons for having uniform code (and uniform training) are to increase the velocity and productivity of development, and to in someway, institutionalize the learning of best practices.  Issues like camelCase or use_underbars can seem trivial and petty, but there are benefits to consistency.

Please be open to unit testing and test driven development.  When you are alone, not part of doing projects for pay, it is more like a hobby.  Your stuff doesn't need to mesh with what other people are doing.  If your code crashes, no big deal.  But when you are involved with a team, the code that you write can effect the entire team, particularly if it gets to customers.

Similarly, if your team uses MVC, please learn about it, hopefully from the same sources they reference.  Methods of structuring programs can make a huge difference as has been shown by experiment.  Again, take the example and leadership from your team.

If your team uses backbone.js, you use it too.  Your team is like ducks flying in formation.  Lining up together helps them expend less energy, makes them safer, and helps them gets where they are going more effectively.  The analogy breaks down if you push it very much, but there are big advantages to using common tools, techniques, and aligning behind the teams decisions.

Title: Should I continue my self-taught coding practice or learn how to do coding professionally?

Body:
Lately I've been getting professional work, hanging out with other programmers, and making friends in the industry. The only thing is I'm 100% self-taught. It's caused my style to extremely deviate from the style of those that are properly trained. It's the techniques and organization of my code that's different.

It's a mixture of several things I do. I tend to blend several programming paradigms together. Like Functional and OO. I lean to the Functional side more than OO, but I see the use of OO when something would make more sense as an abstract entity. Like a game object. Next I also go the simple route when doing something. When in contrast, it seems like sometimes the code I see from professional programmers is complicated for the sake of it! I use lots of closures. And lastly, I'm not the best commenter. I find it easier just to read through my code than reading the comment. And most cases I just end up reading the code even if there are comments. Plus I've been told that, because of how simply I write my code, it's very easy to read it.

I hear professionally trained programmers go on and on about things like unit tests. Something I've never used before so I haven't even the faintest idea of what they are or how they work. Lots and lots of underscores "_", which aren't really my taste. Most of the techniques I use are straight from me, or a few books I've read. Don't know anything about MVC, I've heard a lot about it though with things like backbone.js. I think it's a way to organize an application. It just confuses me though because by now I've made my own organizational structures.

It's a bit of a pain. I can't use template applications at all when learning something new like with Ubuntu's Quickly. I have trouble understanding code that I can tell is from someone trained. Complete OO programming really leaves a bad taste in my mouth, yet that seems to be what EVERYONE else is strictly using.

It's left me not that confident in the look of my code, or wondering whether I'll cause sparks when joining a company or maybe contributing to open source projects. In fact I'm rather scared of the fact that people will eventually be checking out my code. Is this just something normal any programmer goes through or should I really look to change up my techniques?


问:
Is there any benefit to obsession with making code "look pretty"?
Sometimes I spend ridiculous amounts of time (hours) agonizing over making code "look pretty". I mean making things look symmetrical. I will actually rapidly scroll through an entire class to see if anything jumps out as not looking "pretty" or "clean".

Am I wasting my time? Is there any value in this kind of behavior? Sometimes the functionality or design of the code won't even change, I'll just re-structure it so it looks nicer.

Am I just being totally OCD or is there some benefit hidden in this?

答:
You recognize the problem (compulsive behavior) and the symptom (formatting obsessively).

What about the cause and cure?

Are you working too many hours?

Are you frustrated, bored, anxious?

What is your next task?  Is it something you don't want to do?

When did you last have a vacation?  Promotion?  Recognition for an accomplishment?

Is it a burn out related issue?

Are you on a Death March?

Sometimes these symptoms are a sign it is time to make bold changes or move on.

Despite its downer title, Yourdon's book has many helpful suggestions and for many organizations, is making a pretty real description.

http://dev.co.ua/docs/Edward%20Yourdon%20-%20Death%20March.pdf

You seem pretty insightful and I think you might know the answer.

Now, give yourself permission to act on it.


问:
How to learn to make better estimates?
I suck at estimates. When someone asks me how long something will take, I don't even dare to make a guess since I will be completely off the mark. Usually I'm way too optimistic, and should probably multiply my guess with some large X factor...

How can I learn to make better estimates? It's not taught at my uni, and even though we have deadlines for all laborations I never think about how long something will actually take. Which I should. For everyone's sake (especially mine).

答: You could try to build a track record of what was the estimate and what was the actual for various tasks to build up enough of a record to then know what multiplier to have for specific things that get repeated in your list.  Granted this is a trial and error exercise but it has seemed to work fine for me.  There is also something to be said for many trials before the pattern emerges probably.  This is likely similar to a lot of other answers that would say that one could boil down to, "Just do it!" as that is really how most of us developed the skill.  Is it a major pain to see how wrong one can be when making estimates?  Yes, but if the estimates get better then everyone can be happy eventually.</p>

ContentLicense: CC BY-SA 2.5

Title: How to learn to make better estimates?


问:
Compiler design in Lisp
With some googling, I could easily find some documents in compiler design in C, Java, and C# and even in Haskell, but not in Lisp except implementing Scheme/Lisp in Lisp.

Is Lisp not so popular in implementing other (not functional) programming languages?
Do you know of some good documentation about implementing a compiler in LISP?

答:
I assume by books about "implementing SCHEME/LISP in LISP" you mean such titles, as Lisp in Small Pieces.

Regarding implementing other languages in Lisp, the tradition is, actually, very mature. For instance, first prototypes of Smalltalk were implemented in Lisp back in the 70s, while for a more modern example you can take a look at CL-JavaScript. And unlike other languages, in which there's only one way to go — lexing-parsing-intermediate representation transformation-code generation — in Lisp there are 2 ways: the conventional one  and building on top of Lisp.

Regarding the former approach, it's actually no different from other languages, so you can start with the Dragon Book and apply the same technics. Regarding the latter approach, it has some syntactic limitations, but it also has two advantages: using Lisp's built-in configurable lexer and parser, and the ability to tap into Lisp itself and use its facilities alongside the language you're implementing. It is called DSL-oriented programming, and some of the best books about it were mentioned in the previous answers: On Lisp and Let Over Lambda.

OwnerDisplayName: prosseek

Title: Compiler design in Lisp


问:
Functional programming readability
I'm curious about this because I recall before learning any functional languages, I thought them all horribly, awfully, terribly unreadable. Now that I know Haskell and f#, I find it takes a little longer to read less code, but that little code does far more than an equivalent amount would in an imperative language, so it feels like a net gain and I'm not extremely practiced in functional.

Here's my question, I constantly hear from OOP folks that functional style is terribly unreadable. I'm curious if this is the case and I'm deluding myself, or if they took the time to learn a functional language, the whole style would no longer be more unreadable than OOP?

Has anybody seen any evidence or got any anecdotes where they saw this go one way or another with frequency enough to possibly say? If writing functionally really is of lower readability then I don't want to keep using it, but I really don't know if that's the case or not..

答:
I think one of the reasons is that functional programming tends to work with much more abstract concepts. This makes code shorter and more readable for people who know and understand the concepts (because they aptly expresses the essence of the problem), but it is unreadable for people who are not familiar with them.

For example, for a functional programmer it is natural to write a code that can fail at different points within the Maybe monad, or Either monad. Or, to write a stateful computation with the help of the State monad. But for someone who doesn't understand the concept of monads, this all seems like some kind of black sorcery.

So I think it'd be reasonable to use bits of functional programming even in a team of OOP people, as long as one use concepts that are easy to understand or learn, like mapping over a collection with a function or closures.

(And of course, it also depends on the programmer who wrote some piece of code. You can write horribly unreadable code in any language, as well as you can write in a nice and clean style.)

Title: Functional programming readability


答:
Code readability is very subjective. Because of this, different people would consider the same code readable or unreadable.

An assignment, x = x + 1 sounds weird to a mathematician, because an assignment looks misleadingly similar to a comparison.

A simple OOP design pattern would be totally unclear for someone who is not familiar with these patterns. Consider singleton. Someone would ask "Why do I need a private constructor? What is the mysterious method getInstance() ? Why don't we make a global variable and assign an object there?"

The very same applies to an FP code. Unless you know the logical patterns behind the scenes, it will be very difficult even to understand something very basic, e.g. how to pass a function as an argument to another function.

Having this said, one should understand that FP is not a silver bullet. There are many applications where FP would be difficult to apply and therefore, it will lead to a worse readable code.

Title: Functional programming readability

Body:
I'm curious about this because I recall before learning any functional languages, I thought them all horribly, awfully, terribly unreadable. Now that I know Haskell and f#, I find it takes a little longer to read less code, but that little code does far more than an equivalent amount would in an imperative language, so it feels like a net gain and I'm not extremely practiced in functional.

Here's my question, I constantly hear from OOP folks that functional style is terribly unreadable. I'm curious if this is the case and I'm deluding myself, or if they took the time to learn a functional language, the whole style would no longer be more unreadable than OOP?

Has anybody seen any evidence or got any anecdotes where they saw this go one way or another with frequency enough to possibly say? If writing functionally really is of lower readability then I don't want to keep using it, but I really don't know if that's the case or not..


答:
Short answer:

One of the elements which make people say that functional programming code is difficult to read is that it gives preference to a more compact syntax.

Long answer:

Functional programming itself cannot be readable or unreadable, since it's a paradigm, not a style of writing code. In C# for example, functional programming looks like:

```<code>return this.Data.Products
    .Where(c => c.IsEnabled)
    .GroupBy(c => c.Category)
    .Select(c => new PricesPerCategory(category: c.Key, minimum: c.Min(d => d.Price), maximum: c.Max(d => d.Price)));
</code>```

and would be considered readable by any person with enough experience in Java, C# or similar languages.

The language syntax, on the other hand, is more compact for many functional languages (including Haskell and F#) compared to popular OOP languages, giving a preference to symbols rather than word in plain English.

This applies to languages outside FP as well. If you compare popular OOP languages to some less popular which tend to use more English words, the last ones would feel easier to understand for people with no programming experience.

Compare:

```<code>public void IsWithinRanges<T>(T number, param Range<T>[] ranges) where T : INumeric
{
    foreach (var range in ranges)
    {
        if (number >= range.Left && number <= range.Right)
        {
            return true;
        }
    }

    return false;
}
</code>```

to:

```<code>public function void IsWithinRanges
    with parameters T number, param array of (Range of T) ranges
    using generic type T
    given that T implements INumeric
{
    for each (var range in ranges)
    {
        if (number is from range.Left to range.Right)
        {
            return true;
        }
    }

    return false;
}
</code>```

In the same way:

```<code>var a = ((b - c) in 1..n) ? d : 0;
</code>```

could be expressed in an imaginary language as:

```<code>define variable a being equal to d if (b minus c) is between 1 and n or 0 otherwise;
</code>```

When shorter syntax is better?

While more verbose syntax is easier to understand for a beginner, more compact syntax is easier for experienced developers. Shorter code means less characters to type, which means more productivity.

Especially, it really doesn't make sense forcing a person to type a keyword to indicate something which may be deduced from the syntax.

Examples:

In PHP you need to type function before every function or method, with no specific reason to do it.

Ada always horrified me for forcing the developers to type lots of English words, especially since there is no correct IDE with auto-completion. I haven't used Ada recently and their official tutorial is down so I can't give an example; if anybody has an example, feel free to modify my answer.

The syntax 1..n, used in many FP (and Matlab), could be replaced by between 1, n or between 1 and n or between (1, n). The between keyword makes it much easier to understand for people who are not familiar with the language syntax, but still, two dots are much faster to type.

Title: Functional programming readability

Body:
Short answer:

One of the elements which make people say that functional programming code is difficult to read is that it gives preference to a more compact syntax.

Long answer:

Functional programming itself cannot be readable or unreadable, since it's a paradigm, not a style of writing code. In C# for example, functional programming looks like:

return this.Data.Products
    .Where(c => c.IsEnabled)
    .GroupBy(c => c.Category)
    .Select(c => new PricesPerCategory(category: c.Key, minimum: c.Min(d => d.Price), maximum: c.Max(d => d.Price)));

and would be considered readable by any person with enough experience in Java, C# or similar languages.

The language syntax, on the other hand, is more compact for many functional languages (including Haskell and F#) compared to popular OOP languages, giving a preference to symbols rather than word in plain English.

This applies to languages outside FP as well. If you compare popular OOP languages to some less popular which tend to use more English words, the last ones would feel easier to understand for people with no programming experience.

Compare:

public void IsWithinRanges<T>(T number, param Range<T>[] ranges) where T : INumeric
{
    foreach (var range in ranges)
    {
        if (number >= range.Left && number <= range.Right)
        {
            return true;
        }
    }

    return false;
}

to:

public function void IsWithinRanges
    with parameters T number, param array of (Range of T) ranges
    using generic type T
    given that T implements INumeric
{
    for each (var range in ranges)
    {
        if (number is from range.Left to range.Right)
        {
            return true;
        }
    }

    return false;
}

In the same way:

var a = ((b - c) in 1..n) ? d : 0;

could be expressed in an imaginary language as:

define variable a being equal to d if (b minus c) is between 1 and n or 0 otherwise;

When shorter syntax is better?

While more verbose syntax is easier to understand for a beginner, more compact syntax is easier for experienced developers. Shorter code means less characters to type, which means more productivity.

Especially, it really doesn't make sense forcing a person to type a keyword to indicate something which may be deduced from the syntax.

Examples:

In PHP you need to type function before every function or method, with no specific reason to do it.

Ada always horrified me for forcing the developers to type lots of English words, especially since there is no correct IDE with auto-completion. I haven't used Ada recently and their official tutorial is down so I can't give an example; if anybody has an example, feel free to modify my answer.

The syntax 1..n, used in many FP (and Matlab), could be replaced by between 1, n or between 1 and n or between (1, n). The between keyword makes it much easier to understand for people who are not familiar with the language syntax, but still, two dots are much faster to type.


答:
Code readability is subjective. I'm sure that some people criticise it through lack of understanding. There are are naturally different idioms in the way common patterns are implemented. For example, the Visitor pattern doesn't really make sense in a language with pattern matching.

Type inference can be a tricky feature. Usually, it's a great accelerator of development, however, it can sometimes be difficult to figure out what types are involved due to the lack of context leading to confusing errors. This is not limited to what Functional Programming languages - I've seen it in C++ templates too!

Modern languages tend to be multi-paradigm. This includes both C# and F#. It is possible to write a functional style in C# and an imperative style in F#. The same people who criticise Functional languages probably write functional code in their object oriented language.

Commercial development in Functional languages is still relatively immature. I've seen a number of mistakes made that would be considered bad form in any language. Such as:

Changing style as you learn the language (and not refactoring) leading to inconsistency.

Too much in one file.

Too many statements on one line.

Title: Functional programming readability


答:
Readability has nothing to do with the paradigms, models and such. The more code reflects the semantics of your problem domain, the more it is operating a terminology and idioms of such a problem domain, the more readable it is.

This is the reason why OOP code is not that readable at all: not that many real world problems are naturally expressed in terms of hierarchical taxonomies. Objects passing messages to each other is a weird concept, and it is very far from anything "real". Surprisingly, there are much more real world concepts that can be naturally mapped to the functional idioms. Problems tend to be defined declaratively, therefore a declarative solution is more natural.

Although, there are many other semantics that could be closer to the real world than a pure functional, pure OOP, pure dataflow or pure whatever would ever be. And due to this fact, a language-oriented approach to problem solving produces the most readable code, beating all the existing "pure" paradigms. With the domain-specific languages, every problem is expressed in its own natural terminology. And functional languages are slightly better than the OOP mainstream stuff in facilitating DSLs implementation (although, much better approaches are available).

Title: Functional programming readability


问:
Where (if there is) is the IEEE glossary newer than 1990?
I have been looking for some formal definitons but could not find any IEEE newer than 610, which is from 1990. Could you help me please?</p>

答:
Like Mat says in his comment, IEEE Standard 610-1990 has been withdrawn (effective April 20, 2001), which means that it is no longer maintained and the information may be obsolete or erroneous.

Although it's more than just a glossary of terms, the Guide to the Software Engineering Body of Knowledge (free HTML format, paid PDF and dead-tree format) typically provides formal definitions for terms that relate to each knowledge area that come from widely accepted publications. However, this document does cite IEEE 610-1990 for some definitions. I would assume that even though 610-1990 might contain obsolete information, the selected definitions that come from this document are still valid (especially considering the final publication of the SWEBOK was 3 years about 610-1990 was withdrawn, which is sufficient time to update anything that could be considered obsolete).


问:
Issues with time slicing
I was trying to see the effect of  time slicing, and how it can consume significant amount of time. Actually, I was trying to divide a certain task into a number of threads and see the effect.

I have a two core processor. So two threads can run in parallel. I was trying to see if I have a task w that is done by 2 threads, and if I have the same task executed by t threads with each thread doing w/t of the task. How much does time slicing play a role in it.

As time slicing is time consuming process, I was expecting that when I do the same task using a two thread process or by a t thread process, the amount of time taken by the t thread process will be more.

Any suggestions?

答:
time slicing is a small cost - each time the thread quantum expires and the scheduler switches to another thread, all the registers have to be saved and the new thread's old state restored. If you do this continually, you will see this context switching take a lot of the overall time, but if you have 2 threads running on 2 CPUs, you're not going to see any switching at all. How long exactly does a context switch take? depends on the CPU - risc processors have more registers so take longer. How long is a thread quanta? depends on the OS.

The other cost is in CPU cache invalidation - if 2 threads are running on the same CPU, and each one is working of different data, then the required data will have to re-fetched which will slow things down tremendously on modern CPUs (you won't see this effect so much on older CPUs)

Title: Issues with time slicing


问:
What scripting languages can be embedded within HTML?
Most of scripting languages (like Pythong, Perl, etc) generates the whole HTMLfile. However, PHP code can be embedded within html codes. PHP will process only code between <?php ?> tags and ignore other lines.

What other scripting languages are available with possibility to be embedded within HTML?

答:
As delnan noted in his comment, any templating language would do that.

If your question is rather about what are the languages where you can mix both this language and the HTML, here's some which come into mind:

C# and VB.NET (through ASP.NET or ASP.NET MVC, given that those are not languages, but frameworks).

Note that while you can embed C#/VB.NET source code into templates (.aspx files or Razor templates), there is a clear separation between application source code - the one which is compiled during the build, and the code within the templates - the one which is published in plain text and is compiled only by the server when needed.

Java (through JSP).

VBScript and JScript (through ASP).

JavaScript.


问:
How do I break down and plan a personal programming project?
I've just started a programming job where I'm applying my 'How to code' knowledge to what I'm being taught of 'How to Program' (They are different!). As part of this, I've been taught how to capture requirements from clients before starting a new project. But...

How do I do this for a nebulous personal project?

I say nebulous, as I often find halfway through programming something, I want to expand what my program will do, or alter the result. Eventually, I'm tangled in code and have to restart. This can be frustrating and off-putting. Conversely, when given a fixed task and fixed requirements, it's much easier to dig in and get it done.

At work I might be told "Today/This week you need to add XYZ to program 1" That is easy to do. At home (for fun) I want to make, say, a program that creates arbitrary lists. It's a very generic task. How do I start with that? I don't need it to do anything, but I want it to do something.

So how do I plan a personal programming project?

Related: What to plan before starting development on a project?

答:
There is nothing wrong with what you are doing if your purpose is to learn. Many developers leave a string of half-written applications behind them when they had finished everything interesting in them.

However, if you want to write something and finish it, pick a problem you want solved then do the minimum you need to solve it. Use existing libraries and code examples and hack it together. Once you have something working then go back and clean it up and expand it.

[Edit]

If you are looking for inspiration, there are lots of places to start. Microsoft has the coding 4 fun site. There are thousands of open source applications out there that need fixes, improvements, automated tests and documentation on sites like github.com and codeplex.com. Reading other people's code also helps you learn new techniques and libraries.


问:
C++ Library API Design
I'm looking for a good resource for learning about good API design for C++ libraries, looking at shared objects/dlls etc. There are many resources on writing nice APIs, nice classes, templates and so on at source level, but barely anything about putting things together in shared libs and executables. Books like Large-Scale C++ Software Design by John Lakos are interesting but massively outdated.

What I'm looking for is advice i.e. on handling templates. With templates in my API I often end up with library code in my executable (or other library) so if I fix a bug in there I can't simply roll out the new library but have to recompile and redistribute all clients of that code. (and yes, I know some solutions like trying to instantiate at least the most common versions inside the library etc.)

I'm also looking for other caveats and things to mind for keeping binary compatibility while working on C++ libraries.

Is there a good website or book on such things?

答: There is in-fact a book that is precisely what you seek. It is call, appropriately enough, API Design for C++.The book's website has source code from the book and Errata as well.</p>

Title: C++ Library API Design


答:
I agree with akton.

If you are trying to create a working product. Define it, design it and then code it.

Jeff Attwood wrote a blog about KISS and YAGNI.

Look into Test Driven Development to avoid scrapping projects and restarting from scratch.  If your app passes all your tests, you can refactor parts of the code that you don't like. Red, Green, Refactor.

Title: How do I break down and plan a personal programming project?

Body:
I've just started a programming job where I'm applying my 'How to code' knowledge to what I'm being taught of 'How to Program' (They are different!). As part of this, I've been taught how to capture requirements from clients before starting a new project. But...

How do I do this for a nebulous personal project?

I say nebulous, as I often find halfway through programming something, I want to expand what my program will do, or alter the result. Eventually, I'm tangled in code and have to restart. This can be frustrating and off-putting. Conversely, when given a fixed task and fixed requirements, it's much easier to dig in and get it done.

At work I might be told "Today/This week you need to add XYZ to program 1" That is easy to do. At home (for fun) I want to make, say, a program that creates arbitrary lists. It's a very generic task. How do I start with that? I don't need it to do anything, but I want it to do something.

So how do I plan a personal programming project?

Related: What to plan before starting development on a project?


答:
This is pretty much impossible. The simple fact is that sometimes, you need the compiler to do a job, and you can't just magic that necessity away. There is no function that can make std::vector not a header-only library. The compiler can make many magics work, but you can't have them without invoking it, and that's a fact of life.

Here's what you can do: don't use templates where you don't need them. Here's what you can't do: anything else.

The simple fact is that recompiling with the new version really isn't that big of a burden compared to the advantages of performance, safety, and functionality you can get with statically typed libraries.

Title: C++ Library API Design

Body:
I'm looking for a good resource for learning about good API design for C++ libraries, looking at shared objects/dlls etc. There are many resources on writing nice APIs, nice classes, templates and so on at source level, but barely anything about putting things together in shared libs and executables. Books like Large-Scale C++ Software Design by John Lakos are interesting but massively outdated.

What I'm looking for is advice i.e. on handling templates. With templates in my API I often end up with library code in my executable (or other library) so if I fix a bug in there I can't simply roll out the new library but have to recompile and redistribute all clients of that code. (and yes, I know some solutions like trying to instantiate at least the most common versions inside the library etc.)

I'm also looking for other caveats and things to mind for keeping binary compatibility while working on C++ libraries.

Is there a good website or book on such things?


答:
You remind me of my self after going to college to be a Software Engineer. If you want to be a programmer I would say take a position. You are going to need to comment your code, write unit tests, understand, fully, object oriented code. But right now you have no real reason to do so. As long as you are just working on personal small projects. Where you don't have to answer to any one but yourself. You will not grow any further as a developer.

By taking on large projects that many people are working on and having to answer managements questions like "Is this release bug free? Because we are going to releasing it to the customer.". You will grow as a programmer / engineer. You will get some hard knocks. You may find the things you mentioned more valuable and you may find new things that no one has though of before. You will grow.

Even my college failed to teach me these things even though they tried.

For Unit Testing look for Test Driven Development.

For Commenting think of code that you have written after your gone. And the time other people will spend reverse engineering it.

For Object Oriented Languages. Understand it at least. It's a tool that you can use to solve problems in a more readable fashion.

Good Luck :D


问:
Grading an algorithm: Readability vs. Compactness
Consider the following exam / interview question:

Implement the strcpy() function in C: void strcpy(char *destination, char *source);

The strcpy function copies the C string pointed by source into the array pointed by destination, including the terminating null character. Assume that the size of the array pointed by destination is long enough to contain the same C string as source, and does not overlap in memory with source.

Say you were the interviewer \ examiner, how would you grade the following answers to this question?

1)

```<code>void strcpy(char *destination, char *source)
{
  while (*source != '\0')
    {
      *destination = *source;
       source++;
       destination++;
    }
    *destination = *source;
}
</code>```

2)

```<code>void strcpy(char *destination, char *source)
    {
       while (*(destination++) = *(source++)) ;
    }
</code>```

The first implementation is straightforward - it is readable and programmer-friendly.

The second implementation is shorter (one line of code) but less programmer-friendly; it's not so easy to understand the way this code is working, and if you're not familiar with the priorities in this code then it's a problem.

I'm wondering if the first answer would show more complexity and more advanced thinking, in the interviewer's \ examiner's eyes, even though both algorithms behave the same, and although code readability is considered to be more important than code compactness.
It seems to me that since making an algorithm this compact is more difficult to implement, it will show a higher level of thinking as an answer in an exam. However, it is also possible that an interviewer \ examiner would consider the second answer not good because it's not readable.

I would also like to mention that this is not specific to this example, but general for code readability vs. compactness when implementing an algorithm, specifically in exams \ interviews.

答:
The second answer shows the developer understands the C edge cases better. However, the first version is easier to read and understand because it does not require understanding of these edge cases.

If you are asked the question, ask the interviewer or examiner what they are looking for. If in doubt, go for readable code over compactness every time. Interviewers and examiners can reach decision fatigue quickly and making it easier on them will help you.

If the interviewer or examiner wants more, do the readable version first then given them the second version and explain why it works. This will also help you because you can make shorter conceptual leaps.


答:
It all depends on the requirements for that piece of code.

Is it meant to be fast?

Is it meant to use minimal memory?

Is it meant to be reliable?

It it meant to be maintainable?

The other thing you need to consider is the guideline:

Make it right, then make it fast

The first example would be the ideal first implementation of the function which would satisfy the 3rd and 4th requirements on my list above. It would also be sufficient for an application that wasn't time critical or memory limited etc. The second example might be what you would code if you needed to satisfy the 1st and 2nd requirements or you later discovered issues with your initial code (unlikely in this specific case).

As far as a tester is concerned the actual complementation shouldn't be a factor in determining whether the code passes the tests or not. All that matters is that it:

Produces the correct result

Does so in a "reasonable" time (which will vary from application to application)

Uses a "reasonable" amount of computer resources (ditto)

However, on re-reading your question I see that you are using the word "tester" for the person conducting the interview. In this case as you are looking at the code to judge the skill level or competency of the programmer, then the second example would be "better" as it shows that the programmer understands how pointers and pointer incrementation works.

The caveat to that though is unless the code is truly "write once" (i.e. it's never going to be looked at again) you'd want the code in the first example.

Title: Grading an algorithm: Readability vs. Compactness

Body:
Consider the following exam / interview question:

Implement the strcpy() function in C: void strcpy(char *destination, char *source);

The strcpy function copies the C string pointed by source into the array pointed by destination, including the terminating null character. Assume that the size of the array pointed by destination is long enough to contain the same C string as source, and does not overlap in memory with source.

Say you were the interviewer \ examiner, how would you grade the following answers to this question?

1)

```<code>void strcpy(char *destination, char *source)
{
  while (*source != '\0')
    {
      *destination = *source;
       source++;
       destination++;
    }
    *destination = *source;
}
</code>```

2)

```<code>void strcpy(char *destination, char *source)
    {
       while (*(destination++) = *(source++)) ;
    }
</code>```

The first implementation is straightforward - it is readable and programmer-friendly.

The second implementation is shorter (one line of code) but less programmer-friendly; it's not so easy to understand the way this code is working, and if you're not familiar with the priorities in this code then it's a problem.

I'm wondering if the first answer would show more complexity and more advanced thinking, in the interviewer's \ examiner's eyes, even though both algorithms behave the same, and although code readability is considered to be more important than code compactness.
It seems to me that since making an algorithm this compact is more difficult to implement, it will show a higher level of thinking as an answer in an exam. However, it is also possible that an interviewer \ examiner would consider the second answer not good because it's not readable.

I would also like to mention that this is not specific to this example, but general for code readability vs. compactness when implementing an algorithm, specifically in exams \ interviews.


答:
There are a few things which come to mind.

If it works, it should be good enough. Focusing obsessively on code formatting isn't any more productive as focusing obsessively on premature optimization. In most cases it adds no value.

You mentioned "it's not so easy to understand the way this code is working, and if you're not familiar with the priorities in this code then it's a problem.". That is then a problem because the programmer isn't competent enough with such structures. Such compact structures are actually quite common in simple pieces of code like that, and any experienced programmer immediately understands and actually prefers them because they are simple.

This is highly a matter of style, which varies between persons. I don't think there's a correct answer to question like this.


答:
In general, if I'm asking people to write code in an interview, I'm looking to see if they write code that I'd want to debug and maintain.  That would lead me to prefer answers like the first example.

However, anyone asking this specific question is probably testing to see if the interviewee knows the very common strcpy idiom in the second example.  This is a test of their knowledge of pointers and C, not of the readability or compactness of their code.


答:
Congratulations on your expanding role.  Requirements elicitation and requirements management are two great skills for developers.  Sometimes these roles are entirely controlled by product managers outside the development organization and the result can be very limiting.

Architecting software for ease of expansion and maintenance has profound impact on everything we do.  In a paper called "On the Criteria To Be Used in Decomposing Systems into Modules", D.L. Parnas implemented a project twice, once with functional decomposition and once with data oriented decomposition.  Then he added some new features and took metrics about the impact on the code.  The main take away was that the two methods had very different properties for changeability, independent development, and comprehensibility.

Later work published by Parnas as a case study of the A-7E Avionics System and it use of encapsulation, information hiding, and essentially proto-object oriented design was very influential on object oriented programming languages and later analysis and design.  It is also documented in the book "Software Architecture in Practice" by Bass, Clements, and Kazman.

You mention that your code gets tangled up as you expand the scope of your personal projects.  Consider using the following to help keep it on track:

Are you using an object oriented where the code is implemented as classes?  This approach is powerful in terms of promoting maintainability and reusability of code.

How big are your classes?  A big class that does many things can often be had to maintain.  If you can make each class do one thing well (a technique called separation of concerns), it is usually easier to implement and test.

Are you using unit testing or test driven development (TDD)?  If you create tests that verify your code works, then with each iteration or increment, you can verify that it still works.

Are you using Git or some other source control tool?  Using a tool to lock in your changes at the end of each cycle of modifications and testing (usually scoped to one day or less) can give you (and others on your team) a safety net.  Having the code revisions saved can let you back out changes, but more importantly, it can help you enumerate what you changed between when it worked and when it broke.  Usually one of those changes can be changed again to get back to a working state.

Are you using iterative/incremental approaches?  You can read about these approaches from on this page by Alistair Cockburn who writes extensively about Agile development.  Wikipedia also has a nice description.

Hope this helps.  I am sure your question will elicit a great variety of helpful responses here on Stack Exchange.


问:
git for personal (one-man) projects. Overkill?
I know, and use, two version control systems: Subversion and git. Subversion, as of now, gets used for personal projects where I am the only developer and git gets used for open source projects and projects where I believe others will also work on the project. This is mostly because of git's amazing forking and merging capabilities, where everyone may work on their own branch; very handy.

Now, I use Subversion for personal projects, as I think git makes little sense there. It seems to be a little bit of overkill. It is OK for me if it is centralized (on my home server, usually) when I am the only developer; I take regular backups anyway. I don't need the ability to make my own branch, the main branch is my branch. Yes, SVN has simple support for branching, but much more powerful support for it makes no sense, I think. Merging can be a pain with it, or at least from my little experience.

Is there any good reason for me to use git on personal projects, or is it just simply overkill?

答:
It can be a powerful mental paradigm shift to understand that what we do is experimentation. Having a cheap / easy tool to support this, enhances your ability to move forward, in part because it enhances your ability to back out of any experiment when it turns out poorly.

Many developers say, Well I just make copies of my code. But these copies become difficult to manage and end up as clutter.  You have multiple copies and can't remember which copy  for what, and then try to figure out when it is safe to delete them.

All this becomes even more valuable when the experiment entails coordinated changes across multiple files.  And when it is a solo pfoject using Git becomes even simpler.

Instead of wondering whether I should use it on a solo project, I now think what a shame I hadn't discovered this sooner.


问:
What's so bad about pointers in C++?
To continue the discussion in Why are pointers not recommended when coding with C++?

Suppose you have a class that encapsulates objects which need some initialisation to be valid - like a network socket.

```<code>// Blah manages some data and transmits it over a socket
class socket; // forward declaration, so nice weak linkage.

class blah
{
  ... stuff
  TcpSocket *socket;
}

~blah {
   // TcpSocket dtor handles disconnect
   delete socket; // or better, wrap it in a smart pointer
}
</code>```

The ctor ensures that socket is marked NULL, then later in the code when I have the information to initialise the object.

```<code>// initialising blah
if ( !socket ) {
   // I know socket hasn't been created/connected
   // create it in a known initialised state and handle any errors
   // RAII is a good thing !
   socket = new TcpSocket(ip,port);
}

// and when i actually need to use it
if (socket) {
   // if socket exists then it must be connected and valid
}
</code>```

This seems better than having the socket on the stack, having it created in some 'pending' state at program start and then having to continually check some isOK() or isConnected() function before every use.

Additionally if TcpSocket ctor throws an exception it's a lot easier to handle at the point a Tcp connection is made rather than at program start.

Obviously the socket is just an example, but I'm having a hard time thinking of when an encapsulated object with any sort of internal state shouldn't be created and initialised with new.

答:
Pointers do have good reasons to be used too, as you argue. Though, in most cases you should get away with the standardized smart pointers introduced in C++11 to gain additional safety, while retaining the flexibility pointers give to you.

Though, it's also true that they might seem confusing to people who aren't so familiar with C++, so from maintenance perspective it'd be perhaps best to rely on the most simplest to understand techniques and methodologies to implement things.

Title: What's so bad about pointers in C++?


答:
In my opinion the pointers are described as difficult to handle or bad because they break 2 important aspects of any application design:

semantics

syntax

if you remember, a basic concept in the programming world is given by the fact that if I wrote 4 on a blackboard, this means nothing until i give a context and a semantic to what i have wrote on the blackboard, for example if after i have wrote 45 i say that what is on the blackboard it's my age, you can get 45 as a real information, but without a context/semantics that 45 is useless and without a clear interpretation: the real information and its representation are different.

This is even clearer in technology like OpenGL, you can do almost nothing with your pointer if you don't supply a context, the same thing happens in C++, if you don't provide a context ( a target type ) for a pointer or a reference, the pointer alone means nothing and it's useless.

The syntax is also important because it set boundaries about the business logic of your application and the lifetime of your components, pointers can potentially break all the boundaries and your business logic, never the less, pointers contains references so they do not even have a real state, they just point to something in memory that they can't handle during the lifetime of your application, they are more like post-it with a memory address rather than objects with a well defined state and a well defined lifetime.

All the major difference between the old C++ and C++11 are differences about design, which means syntax and semantics that can drive the logic of your application; the smart pointers are nothing more than pointers but with a big plus related to a specific design that comes within the pointer itself, so you can have more control over it.

In the end the pointers can't have a state and need a context to be handled, this is something that a safe and good application design can't usually accept, the smart pointers are a step in the design oriented world which is basically the modern approach to the programming world.

Title: What's so bad about pointers in C++?

Body:
To continue the discussion in Why are pointers not recommended when coding with C++?

Suppose you have a class that encapsulates objects which need some initialisation to be valid - like a network socket.

```<code>// Blah manages some data and transmits it over a socket
class socket; // forward declaration, so nice weak linkage.

class blah
{
  ... stuff
  TcpSocket *socket;
}

~blah {
   // TcpSocket dtor handles disconnect
   delete socket; // or better, wrap it in a smart pointer
}
</code>```

The ctor ensures that socket is marked NULL, then later in the code when I have the information to initialise the object.

```<code>// initialising blah
if ( !socket ) {
   // I know socket hasn't been created/connected
   // create it in a known initialised state and handle any errors
   // RAII is a good thing !
   socket = new TcpSocket(ip,port);
}

// and when i actually need to use it
if (socket) {
   // if socket exists then it must be connected and valid
}
</code>```

This seems better than having the socket on the stack, having it created in some 'pending' state at program start and then having to continually check some isOK() or isConnected() function before every use.

Additionally if TcpSocket ctor throws an exception it's a lot easier to handle at the point a Tcp connection is made rather than at program start.

Obviously the socket is just an example, but I'm having a hard time thinking of when an encapsulated object with any sort of internal state shouldn't be created and initialised with new.


答:
Tester context

First, let us define testers.  The distinction between software development and software testing roles happens to involve source code access.  Developers are constantly in touch with details of the code, focusing on unit testing.  Team members called testers are nearly always intentionally oblivious of the lowest levels of implementation, focusing on integration testing, stress testing, load testing, compatibility testing.  A tester is therefore most likely to notice source code structure when a typo breaks a build or when a stack trace makes it to the logs.

Using whatever style that other members of your team find easy to maintain usually means that testers will see fewer build breaks and behavior deficiencies in the long run.  When in doubt, ask your team or go after simplicity.

Code review context

When code is being reviewed by a fellow developer prior to commit, differences in code style do matter, of course.  The one that is standard within the organization/product/project, or otherwise familiar to other team members, is the correct one.  The others are incorrect - minus points and rework.

If a developer can explain why a particular practice is in their view better than the current standard, and why the standard should be updated (this question already provides a plenty of available arguments either way), that is plus points, but there is no reason for intentionally deviating first and explaining only second.

Interview context

During an interview, typos, indentation differences, etc.,  do not really matter.  Your two implementations compile to the exact same binary code.  Compared to the standard (pun intended) implementations of the same task, either of our equivalent samples is much easier to read, much slower, and also much safer to use to people not deeply familiar with the standard C library. This is partly because the "does not overlap" part of the task might have been translated to the restrict keyword but wasn't.

The difference in coding style does say things about the soul of the developer.  Both coding styles shown are completely industry standard ones, so it would be silly to judge the experience or skills of the candidate based on coding style alone.  However, it is possible that the two programmers would eventually be offered differently oriented roles, or that a particular organization would find a fit with only one of those two personality styles.


答:
You can mix even perl (with eperl), but it's generally a bad practice.

You should think through the following:

Is your data to be indexed by Google?

Is this a webpage or an application?

If it's an application, which won't be indexed by Google, grab JavaScript, CoffeeScript, Dart or Flash, and write a standard MVC application, with your server providing the backend in form of JSON-based services. It's just way more easier to think this way and still deal with application-level complexity.

If this has to be indexed by google, and/or it's a webpage, then build a WebMVC webpage, with templates, in Spring (java), Ruby on Rails (ruby), Django (python), Symfony (php), Catalyst Framework (perl), whatever. It's easier to accommodate data changes usually with such.

Both of these solution scale considerably.

Remember, every application started small.

Title: What scripting languages can be embedded within HTML?

Body:
Most of scripting languages (like Pythong, Perl, etc) generates the whole HTMLfile. However, PHP code can be embedded within html codes. PHP will process only code between <?php ?> tags and ignore other lines.

What other scripting languages are available with possibility to be embedded within HTML?


答:
In C the expression x++=y++ is extremely common and thus easily understood, and IMO should be preferred over the longer x=y; x++; y++; whenever possible as it expresses the INTENT better.  That leaves the check for terminating the loop.

```<code>while(*source != '\0')
</code>```

vs

```<code>while(*source)
</code>```

vs

```<code>while(*destination++ = *source++){}
</code>```

Understanding the 2nd and 3rd depends upon understanding two things, that C considers zero to be false and everything non-zero to be true and that the assignment operators return a result.

Both of these should be ingrained in even a junior C programmer and easily picked up by those coming from another language.

In short, I don't consider the second harder to read, and in fact find the first more difficult to read in the context of a C program -- in a language without ++ the first would of course be required, but programming in langauge a as if it was language b is confusing.  The question "why is this code doing that" is much harder than "what is this code doing", and non-standard usage makes me ask why...

Now, if you want to mark these down for some reason, look no further than the lack of comments. When dealing with pointers, such unstated restrictions are just begging for mistakes.

Body:
In C the expression x++=y++ is extremely common and thus easily understood, and IMO should be preferred over the longer x=y; x++; y++; whenever possible as it expresses the INTENT better.  That leaves the check for terminating the loop.

while(*source != '\0')

vs

while(*source)

vs

while(*destination++ = *source++){}

Understanding the 2nd and 3rd depends upon understanding two things, that C considers zero to be false and everything non-zero to be true and that the assignment operators return a result.

Both of these should be ingrained in even a junior C programmer and easily picked up by those coming from another language.

In short, I don't consider the second harder to read, and in fact find the first more difficult to read in the context of a C program -- in a language without ++ the first would of course be required, but programming in langauge a as if it was language b is confusing.  The question "why is this code doing that" is much harder than "what is this code doing", and non-standard usage makes me ask why...

Now, if you want to mark these down for some reason, look no further than the lack of comments. When dealing with pointers, such unstated restrictions are just begging for mistakes.


答: Pretty much every modern language has one or more server page language. PHP is just the only language who's primary reason for existence is for writing server pages. Most modern languages will also have more than one template language.</p>


答:
Pointers are bad for the following reasons:

Information about memory areas disappears. It is no longer clear if your TcpSocket memory is inside the blah object or outside of it. References and composition can fix it. (reference=outside, composition=inside)

Pointer can be NULL. How well you expect the program to work if the function call behaviour is not respected. If you call connect() function, it better do the connection, but failing simply because some ptr is NULL is not good behaviour -- failures should have real reasons like network disconnected. Failing simply because some previous call failed is not good behaviour.

Dynamic behaviour like the ptr==NULL should be done with booleans and not this kind of hidden behaviour where ptr==NULL. Then it would be easier to figure out the reason for the failure when booleans have proper names independent of the pointer.

Best choice for failures is that they just never happen.

2nd best choice is that part of the application is disabled when network is not available - like no new information appears, and connection is restored as soon as possible.

If your socket functions can fail, the function prototype better have that information. Your void connect() is not acceptable, int connect() with error code is better. Returning some object which contains fail bit is also ok.

Example of what kind of alternatives are available: (the composition one)

```<code>class Blah {
public:
  Blah(ip,port) : s(ip,port) { }
private:
  TcpSocket s;
  bool failbit;
};
</code>```

Or with references:

```<code>class Blah {
public:
  Blah(TcpSocket &s) : s(s) { }
private:
  TcpSocket &s;
};
</code>```

If the connection has to be created afterwards, like address not known early enough in constructor, then use this:

```<code>class Blah {
public:
   Blah() : sock(NULL) { }
   TcpSocket &connect(ip, port) {
     delete sock;
     sock = new TcpSocket(ip,port);
     return *sock;
    }
  ~Blah() { delete sock; }
private:
  TcpSocket *sock;
};
</code>```

But this is usually not the best alternative... (call connect twice and previous one loses connection -- the returned TcpSocket must not be stored anywhere) The next alternative will need std::vector < TcpSocket*>...

```<code>class Blah {
public:
   Blah() : vec(), error("logfile.txt") { }
   int connect(ip,port) {
      vec.push_back(new TcpSocket(ip,port));
      return vec.size()-1;
   }
   int write(int conn, char *data) {
      if (vec[conn])
         { vec[conn]->write(data); return OK; }
      else return ERR;
   }
  TcpSocket &connection(int conn) const
      { if (vec[conn]) return *vec[conn]; else return error; }
  void disconnect(int conn) { delete vec[conn]; vec[conn]=NULL; }
   ~Blah() { for(int i=0;i<vec.size();i++) delete vec[i]; }
private:
   std::vector<TcpSocket*> vec;
   TcpSocket error;
};
</code>```

Note that returning index to the connection std::vector prevents removing connections (indexes will get broken/have to make them NULL). The last one just have a problem that connect() return value and write() return value is different. Should use some kind of type checking trick to make them different ints:

```<code>struct Err { int error; };
Err write(int conn, char *data);
</code>```

Title: What's so bad about pointers in C++?

Body:
Pointers are bad for the following reasons:

Information about memory areas disappears. It is no longer clear if your TcpSocket memory is inside the blah object or outside of it. References and composition can fix it. (reference=outside, composition=inside)

Pointer can be NULL. How well you expect the program to work if the function call behaviour is not respected. If you call connect() function, it better do the connection, but failing simply because some ptr is NULL is not good behaviour -- failures should have real reasons like network disconnected. Failing simply because some previous call failed is not good behaviour.

Dynamic behaviour like the ptr==NULL should be done with booleans and not this kind of hidden behaviour where ptr==NULL. Then it would be easier to figure out the reason for the failure when booleans have proper names independent of the pointer.

Best choice for failures is that they just never happen.

2nd best choice is that part of the application is disabled when network is not available - like no new information appears, and connection is restored as soon as possible.

If your socket functions can fail, the function prototype better have that information. Your void connect() is not acceptable, int connect() with error code is better. Returning some object which contains fail bit is also ok.

Example of what kind of alternatives are available: (the composition one)

class Blah {
public:
  Blah(ip,port) : s(ip,port) { }
private:
  TcpSocket s;
  bool failbit;
};

Or with references:

class Blah {
public:
  Blah(TcpSocket &s) : s(s) { }
private:
  TcpSocket &s;
};

If the connection has to be created afterwards, like address not known early enough in constructor, then use this:

class Blah {
public:
   Blah() : sock(NULL) { }
   TcpSocket &connect(ip, port) {
     delete sock;
     sock = new TcpSocket(ip,port);
     return *sock;
    }
  ~Blah() { delete sock; }
private:
  TcpSocket *sock;
};

But this is usually not the best alternative... (call connect twice and previous one loses connection -- the returned TcpSocket must not be stored anywhere) The next alternative will need std::vector < TcpSocket*>...

class Blah {
public:
   Blah() : vec(), error("logfile.txt") { }
   int connect(ip,port) {
      vec.push_back(new TcpSocket(ip,port));
      return vec.size()-1;
   }
   int write(int conn, char *data) {
      if (vec[conn])
         { vec[conn]->write(data); return OK; }
      else return ERR;
   }
  TcpSocket &connection(int conn) const
      { if (vec[conn]) return *vec[conn]; else return error; }
  void disconnect(int conn) { delete vec[conn]; vec[conn]=NULL; }
   ~Blah() { for(int i=0;i<vec.size();i++) delete vec[i]; }
private:
   std::vector<TcpSocket*> vec;
   TcpSocket error;
};

Note that returning index to the connection std::vector prevents removing connections (indexes will get broken/have to make them NULL). The last one just have a problem that connect() return value and write() return value is different. Should use some kind of type checking trick to make them different ints:

struct Err { int error; };
Err write(int conn, char *data);


答:
In general, programming constructs and techniques are commonly considered to be 'bad' when there are 'better' alternatives available for a particular task.
The use of a pointer may be technically correct in a lot of places, but it's rare in C++ for a situation to arise where the use of a raw pointer doesn't have a better alternative.

Most of the time, using references, smart pointers, iterators and standard library containers will result in safer/cleaner/more idiomatic code when compared to an equivalent solution using pointers;  and usually at no extra cost to the programmer (quite frequently at a lower cost in fact).

There will always be occasions when a raw pointer is the most sensible option, and in those cases nobody gains by trying to find "clever" ways of avoiding pointers; particularly if avoiding a raw pointer means risking larger breaking changes to working legacy code which may otherwise have not needed to change; but for new code at least these situations are unusual for anybody using a modern C++11 implementation.

Title: What's so bad about pointers in C++?


问:
How is this number calculated?
I have numbers;

```<code>A == 0x20000000
B == 18
C == (B/10)
D == 0x20000004 == (A + C)
</code>```

A and D are in hex, but I'm not sure what the assumed numeric bases of the others are (although I'd assume base 10 since they don't explicitly state a base.

It may or may not be relevant but I'm dealing with memory addresses, A and D are pointers.

The part I'm failing to understand is how 18/10 gives me 0x4.

Edit: Code for clarity:

```<code>*address1 (pointer is to address: 0x20000000)

printf("Test1: %p\n", address1);
printf("Test2: %p\n", address1+(18/10));
printf("Test3: %p\n", address1+(21/10));
</code>```

Output:

```<code>Test1: 0x20000000
Test2: 0x20000004
Test3: 0x20000008
</code>```

答:
Notice some facts:

1) when you add a value to the address it gets increased by that value multiplied by the number of bytes contained in a word, not by simply that value;

2) 18/10 == 1 when it comes to integers;

3) 21/10 == 2 when it comes to integers;

4) word size is 4 in this case (as you notice by the pointer's size, being 32 bit);

Consequently:

```<code>0x20000000 + 4 * (18/10) = 0x20000000 + 4 * 1 = 0x20000004
0x20000000 + 4 * (21/10) = 0x20000000 + 4 * 2 = 0x20000008
</code>```

Edit:

As Vatine pointed out, it's important understanding that the pointer is incremented by a value multiplied by 4 (i.e a word's size in a 32-bit system) because that's the size of the data type the pointer variable was created for (an int).

Title: How is this number calculated?

Body:
Notice some facts:

1) when you add a value to the address it gets increased by that value multiplied by the number of bytes contained in a word, not by simply that value;

2) 18/10 == 1 when it comes to integers;

3) 21/10 == 2 when it comes to integers;

4) word size is 4 in this case (as you notice by the pointer's size, being 32 bit);

Consequently:

0x20000000 + 4 * (18/10) = 0x20000000 + 4 * 1 = 0x20000004
0x20000000 + 4 * (21/10) = 0x20000000 + 4 * 2 = 0x20000008

Edit:

As Vatine pointed out, it's important understanding that the pointer is incremented by a value multiplied by 4 (i.e a word's size in a 32-bit system) because that's the size of the data type the pointer variable was created for (an int).


问:
How do I advertise for volunteers for my open source project
I have found a couple of related questions here on programmers.SE:

How/where would I best advertise my open source project, in order to maximize my odds of finding collaborators?

https://softwareengineering.stackexchange.com/questions/60830/where-to-find-open-source-volunteers

My question is slightly different because I am primarily looking for non-coders to help with a few things in my new open source project. In particular, I'd like one or more people to create an icon and other graphics and to work on a web site, wiki pages, and/or other documentation.

My project is a front-end for a baseball card database. So reaching out to baseball card collectors might be useful. Other than that, I would just like anyone who would like to contribute in small ways to a modest project. Where are some good places to advertise and find non-coder volunteers?

答:
This is one of many topics covered in Producing Open Source Software - a free (e)book by Karl Fogel.

If you want to lead an open source project and make it successful, this is very good place to start. It focuses mostly on the people side of a project and on how to present the project to the world.


答: If you can decompose the project into smaller tasks and do estimates for those you will be more accurate over-all. Any task bigger than a couple days should be broken down further. If you can't break it down further than you probably have a requirements gap. If you have to do a back-of-the-napkin estimate for a one-line requirement well...nothing can really help you much. Sadly a lot of shops work this way much of the time.</p>

Title: How to learn to make better estimates?

Body:
I suck at estimates. When someone asks me how long something will take, I don't even dare to make a guess since I will be completely off the mark. Usually I'm way too optimistic, and should probably multiply my guess with some large X factor...

How can I learn to make better estimates? It's not taught at my uni, and even though we have deadlines for all laborations I never think about how long something will actually take. Which I should. For everyone's sake (especially mine).


问:
Productivity strategies for one developer using many PCs
In a talk about time management, a famous computer scientist said:

"One machine in your life is the right number."

He recommended a laptop with a docking station.

After trying this approach for about a month, I miss my more powerful desktop (i7 quad core hyperthread), but it is not in my technology road map (or budget) to upgrade from my old Intel Core 2 Duo (2006) notebook this year.

What strategies can help me use the desktop while at my desk and without much manual effort the notebook when I am on the go?

答:
You've not really specified what your actual problem is so I can only speculate from personal experience:

Does your company offer a VPN so you can work from home? If so maybe you can remote desktop into your desktop machine. Otherwise, maybe ask for a laptop cooler so the OS doesn't underclock the CPU as often when it gets hot. Or ask for more RAM, it's cheap these days.

If your problem is about sharing data get an external HD with an encrypted partition, or remember to check stuff you've done into source control at the end of the day.