答:
I work on a code-base for a product that has been in continuous development since 1999, so as you can imagine it is pretty complex by now. The biggest source of hackiness in our codebase is from the numerous times we've had to port it from ASP Classic to ASP.NET, from ADO to ADO.NET, from postbacks to Ajax, switching UI libraries, coding standards, etc.

All in all we've done a reasonable job of keeping the code base maintainable. The main things we have done that contributed to that are:

1) Constant refactoring - If you have to touch a piece of code that is hacky or hard to understand, you are expected to take the extra time to clean it up and are given the leeway in the schedule to do so. Unit tests make this a lot less scary, because you can test against regressions more easily.

2) Keep a neat development environment - Be vigilant about deleting code that is no longer used, and don't leave backup copies/working copies/experimental code exist in the project directory.

3) Consistent coding standards for the life of the Project - Let's face it, our views on coding standards evolve over time. I suggest sticking with the coding standard you started with for the life of a project unless you have time to go back and retrofit all the code to comply with the new standard. It's great that you are over Hungarian notation now, but apply that lesson to new projects and don't just switch mid-stream on that new project.


问:
Simulating/developing_a_testing_strategy for factors that might cause the same algorithm to produce different results in Distributed Systems
This is a Purely Academic Question

Context:

I am working with some algorithms which are meant to arrive at a consensus in distributed systems. I intended to tackle Byzantine faults with these algorithms. For this I have implemented several algorithms published in IEEE papers and need a platform to test these algorithms. I wanted to test the merit of existing algorithms. For this I implemented thousands of Linux Containers on my system and now i want to do message passing between them, or say simulate my distributed system. But the question is the data that is flowing must have faults. This is the genesis of this question. Why I need something more sophisticated than RNG's is that I will need to attach some real credibility to my work. I want it to tackle some real world application generating faults rather than just fix the faults I myself generated in an algorithm.

So, I need to simulate the factors that result in Byzantine faults.

OR, to quote FrustatedWithFormsDesigner:
I need to develop a testing strategy that will have a deliberate number of faults to test fault-handling

To Summarize:

Say I am running a program in a distributed environment, then what are the factors that might end up generating Byzantine faults and is it possible for me to inculcate these factors in my simulation and how?

So, what I need is:

A program that will make a small no. of mistakes every now and then, and I should not know what mistakes it has made and when.

I do not need it to make multiple mistakes in one set(run of the algorithm), but rather I plan on making (say) 10,000 runs of the program, and I need it to make mistakes 2000 times ..

Very importantly, I must be sanguine that there are no more than (1/5)n mistakes, where n is the total no. of results generated using the program.

The results that I am talking about here can be anything that is quantifiable and verifiable, like eg. an array of values.

Doing something like this:

```<code>1for(int i=0; i<10000; i++)
2   //one fifth of the times put garbage in the array using random function!!
3   for (int j=0; j<5; j++)
4      array[j]=j;
</code>```

using a RNG in step 2 to hide where the fault is present is too simplistic, trivial and not real enough.

I thought I could use some algorithm built around some mathematical function that is bound to fail 1/5th of the times, But I could not think of any.

P.S.
Please tell me if you need more data to understand the problem.

答:
You are not offering much information here, and you seem to contradict yourself several times.  To rephase your question--so if I head off in the wrong direction you will at least know what wrong direction I headed in--you want to run a short program 10,000 times and have it give one wrong answer in 200 runs.  This gives a 2% failure rate, and even in the failures only one (out of maybe 10,000 numbers output) is wrong.

A random number generator will do this for you.  Decide at the start of a run if it is to be good or bad.  Then pick an output number at random and give it a bad value.  (You don't want to check each number or you might get less than or more than one bad number in the run.)

Now the real trick is that a random number generator starts with a seed, which usually comes from the system time.  If system time comes in, say 100ths of a second rather than microseconds, and your program runs real fast, most of your runs will have identical random numbers.  In short, your numbers aren't random.  You are going to need to save the seed from one run and feed it into the next one, presumably with a disk file.  (Or space out your runs somehow.)

I have no idea why you want to do this, but you might want to arrange to have your failures come in waves.  You could divide your runs into groups of 1000, half of which would have no failures and the other half of which would average 40 failures each.  This could lure testers into a false sense of security, or get them so bored they're not looking when the shooting starts.  Of course, if this is what you are trying to do, you should come up with much more fiendish patterns that this.

ContentLicense: CC BY-SA 3.0


答:
There are a few different kinds of faults that can occur in a distributed system:

Sensor noise

Dropped messages

Duplicate messages

Corrupted messages

All of these can occur in isolation, or as a "run" of several failures of the same type in a row.

The best way to simulate sensor noise is with a gaussian distribution, which you get by feeding a uniformly distributed RNG into a Box-Muller transform.  This will produce values that look more "real," by usually being only off by a little bit, but every once in a while off by a lot.

For the others, you just use a regular RNG to cause the fault with a certain probability.  The trick is figuring out the individual probability so you aren't likely to exceed 20% faults at the same time.  This is where my math gets rusty, but you could probably solve it monte carlo style.  Set the probability of one fault to a certain value, then run your simulation 10,000 times to see if you ever get more than 20% at once, then adjust your individual probability accordingly.  You aren't going to be able to guarantee it without flat out disallowing more faults than that, but you can make the probability sufficiently small.  It depends if you want a realistic simulation or a thorough test of boundary conditions, because in real life you can't guarantee less than 20% either.

Title: Simulating/developing_a_testing_strategy for factors that might cause the same algorithm to produce different results in Distributed Systems

Body:
This is a Purely Academic Question

Context:

I am working with some algorithms which are meant to arrive at a consensus in distributed systems. I intended to tackle Byzantine faults with these algorithms. For this I have implemented several algorithms published in IEEE papers and need a platform to test these algorithms. I wanted to test the merit of existing algorithms. For this I implemented thousands of Linux Containers on my system and now i want to do message passing between them, or say simulate my distributed system. But the question is the data that is flowing must have faults. This is the genesis of this question. Why I need something more sophisticated than RNG's is that I will need to attach some real credibility to my work. I want it to tackle some real world application generating faults rather than just fix the faults I myself generated in an algorithm.

So, I need to simulate the factors that result in Byzantine faults.

OR, to quote FrustatedWithFormsDesigner:
I need to develop a testing strategy that will have a deliberate number of faults to test fault-handling

To Summarize:

Say I am running a program in a distributed environment, then what are the factors that might end up generating Byzantine faults and is it possible for me to inculcate these factors in my simulation and how?

So, what I need is:

A program that will make a small no. of mistakes every now and then, and I should not know what mistakes it has made and when.

I do not need it to make multiple mistakes in one set(run of the algorithm), but rather I plan on making (say) 10,000 runs of the program, and I need it to make mistakes 2000 times ..

Very importantly, I must be sanguine that there are no more than (1/5)n mistakes, where n is the total no. of results generated using the program.

The results that I am talking about here can be anything that is quantifiable and verifiable, like eg. an array of values.

Doing something like this:

```<code>1for(int i=0; i<10000; i++)
2   //one fifth of the times put garbage in the array using random function!!
3   for (int j=0; j<5; j++)
4      array[j]=j;
</code>```

using a RNG in step 2 to hide where the fault is present is too simplistic, trivial and not real enough.

I thought I could use some algorithm built around some mathematical function that is bound to fail 1/5th of the times, But I could not think of any.

P.S.
Please tell me if you need more data to understand the problem.


问:
How do I go about choosing a development lifecycle model model?
Based on this question about alternatives to the agile philosophy and its answers and comments I thought it might be useful to discuss what goes into the decision of what "methodology" to use when at the start of the project.

Seems the consensus is that if what you are building requires exact specifications that waterfall is the way to go over agile. That seems to leave a HUGE space for agile development. Beyond "this is how are shop develops software" are there questions or "indicators" at the early planning stage that might give a better indication of what might work best for the client/project?

Like with languages the idea is best tool for the job so as professional developers what do you do to make sure you're using the correct development methodology for a project you're about to start?

Is it really as cut and dry as "if it's a bridge or nuke reactor type project use waterfall else use agile?

I am a self taught programmer working for company that gives a lot of flexibility and they put a lot of trust in me so this kind of question is important to me. I want to make sure I am addressing my work/projects in the most efficient cost/time manner as possible.

答:
Mature agile and waterfall approaches look virtually in distinguishable from each other. Your main goal should be that the business drives the software development. It doesn't matter what model you use if you can't point to a feature and refer back to the business requirement for that feature. That is where QA comes in.

You need a solid QA environment that is the system of record for business requirements. QA stands for quality assurance, not testing. All of those tests that QA runs are to ensure that the system being built maps to the finalized requirements that are in their possession. And developers now have a direction to go when developing their software.

To make these things work well with the development team. You need to have short release cycles so that the business does not get overwhelmed with making decisions about what should be developed next. Also QA will have a better chance of determining if a specific feature does what it is supposed to do, and the feedback to the development team will be more specific because there are less assumptions about what is or isn't breaking that part of the system.

All of these things go towards making quality software. The development methodology is what glues them together into a cohesive solution that allows everyone to work together in a predictable manner. The waterfall approach tends to start out with the business having an easier time of adapting, where as the agile approach is more developer focused. But the both meet in the middle eventually.


问:
How do I choose a package format for Linux software distribution?
We have a Java-based application that, to date, we've been distributing as a tarball with instructions for deploying. It's mostly self-contained so deployment is fairly straight-forward:

Untar on the disk you'd like it to live on;

Make sure Java is in your path and a suitable distro and version;

Verify ownership and group on all the files

Start up the server processes with our start script

If the user wants to get in to start-on-boot stuff with SysV we have some written instructions and a template init file for it in our tarball.

We'd like to make this installation process a little more seamless; take care of the permissions and the init script deployment. We're also going to start bundling our own JRE with the application so that we're mostly free of external dependencies.

The question we're faced with now is: how do we pick a package format for distribution? Is RPM the standard? Can all package management tools deal with it now? Our clients primarily run RHEL and CentOS, but we do have some using SuSE and even Debian. If we can pick a distro-agnostic format we'd prefer that.

What about a self-extracting shell script? Something akin to how Java is distributed. If we're dependency-free would the self-extracting script be sufficient? What features or conveniences would we lose out on going with the script versus a proper package format meant for use by a package manager?

答:
I have some experience with packaging applications for Linux (have been a distro maintainer for a while), so let me get this straight to you: you're in trouble no matter what you do. Even an advanced packaging system like RPM does not allow you to create one package and have it work on several distributions. For example, another answer recommends "declare a dependency on JRE". How do you do it? In RPM, you add a requirement

jre >= 1.45

but if the distro called the JRE package not "jre" but "java_runtime_environment", you're out of luck and your package has a broken dependency. Preparing a package which does not hardcode the location of files and your dependencies is far from trivial, and requires relying on the assumption that the distros follow some common standard (which they don't, at least not consistently).

By far the easiest approach for you and your clients is to make a self-contained package. If you want to save space and bandwidth, provide two versions: with and without JRE, with clear instructions how to install the JRE and a link to where a compatible version can be downloaded at Oracle website.


问:
Is there a viable alternative to the agile development methodology?
The two predominant software-development methodologies are waterfall and agile.  When discussing these two, there is often much focus on the particular practices that distinguish them (pair programming, TDD, etc. vs. functional spec, big up-front design, etc.)

But the real differences are far deeper, in that these practices come from a philosophy.

Waterfall says:  Change is costly, so it should be minimized.

Agile says:  Change is inevitable, so make change cheap.

My question is, regardless of what you think of TDD or functional specs, is the waterfall development methodology really viable?

Does anyone really think that minimizing change in software is a viable option for those that desire to deliver valuable software?  Or is the question really about what sort of practices work best in our situations to manage the inevitable change?

答: Mature agile and waterfall approaches are indistinguishable from each other. Your assumption about the goal of the waterfall approach is incorrect. They both have the goal of producing quality software. When you don't have a solid development approach for the company as a whole, you need to look at which approach will provide the least amount of friction to adoption. In the end short development cycles, a solid QA team, and a business that drives the development are what is most important to producing top notch software.


问:
What are your initial three steps when you are first presented with a software problem?
I am curious about the very early steps that a programmer's mind takes when it first encounters a problem that it is supposed to solve. How do you start reasoning about it ? What are the first questions you ask yourself ??.

Ok, let me make it more concrete for those of you who think the question is too vague or entirely situation dependent. Pick any of the following   requirements and think out loud about your very first hunches/impressions/tendencies about how to solve it.

1) build a simple word processor with about as much functionality as MS Word Pad

 2) design a single person card game (e.g. Solitaire)

 3) build a scientific calculator

 4) Any  problem of your choosing with similar scale/complexity as the above three

答:
All of the projects you list are non-trivial if you want to do them properly - i.e. a finished, polished, tested product. Therefore my initial steps are:

1. Requirements/Specifications. Write down what it should do and what it should not do. Prioritize the to-do items - essential (can't function without it), nice-to-have and 'if there's time to kill'. Order the items in priority order. Agree with whoever is paying for the project that this is the correct order. Stay on step 1 until you have agreement.

2. Design. Draw out the UI - what will the features look like to the user. This doesn't have to be pretty - pencil and paper will do - but it will help you work through the user workflow and out of this will come the High Level Design, the major components/modules of the application. This doesn't have to be a 'big up-front design' effort, but a poor UI or workflow will kill any chance of success. Work with the project sponsor (whoever is paying) until they're happy with the UX.

3. Iterative Development. Implement just enough code to achieve the next requirement on the prioritized list, complying with the design and workflow. Check in this code. Demonstrate to project sponsor. Goto 3.

OwnerDisplayName: mumtaz

LastEditorDisplayName: mumtaz

ContentLicense: CC BY-SA 2.5


问:
How to keep a big and complex software product maintainable over the years?
I have been working as a software developer for many years now. It has been my experience that projects get more complex and unmaintainable as more developers get involved in the development of the product.

It seems that software at a certain stage of development has the tendency to get "hackier" and "hackier" especially when none of the team members that defined the architecture work at the company any more.

I find it frustrating that a developer who has to change something has a hard time getting the big picture of the architecture. Therefore, there is a tendency to fix problems or make changes in a way that works against the original architecture. The result is code that gets more and more complex and even harder to understand.

Is there any helpful advice on how to keep source code really maintainable over the years?

答:
Simple answer: you can't.

That's why you should aim for writing small and simple software. It's not easy.

That's only possible if you think long enough about your seemingly complex problem to define it in as a simple and concise manner as possible.

Solution to problems that truly are big and complex can often still be solved by building upon small and simple modules.

In other words, as others pointed out, simplicity and loose coupling are the key ingredients.

If that's not possible or feasible, you are probably doing research (complex problems with no known simple solutions, or no known solution at all). Don't expect research to directly produce maintainable products, that's not what research is for.


问:
The case for code obfuscation?
What are the top reasons to write obfuscated code, in terms of a real benefit to the people developing the code, and the business that runs that code (if the code in question is in fact commericial code)? Are there documented cases (available online in some location) which describe when obfuscation did more good than bad? Are there well-known examples where, for example, obfuscation was proven to meaningfully delay a malicious 3rd party from getting at the code? It seems that, just like rolling up your car windows won't stop people from breaking them and stealing your stereo, obfuscating your code just keeps honest people honest.

=========

Background:

This is an attempt to purposely challenge my assumptions on this topic.

I'm big-time against using code obfuscation in general, but I'm curious if I'm missing something. I get why, in cases like JavaScript, minification helps things load faster and all (there's a real, functional benefit there), but I can't seem to come up with a single reason why code obfuscation, for the purpose of being an obstacle to discovering what an section of code/algorithm does, is actually effective for any purpose whatsoever.

With open source being crazy popular, the question seems to be "share the code, or keep it proprietary?" When it comes to commercial code, I can understand why you can't share everything, and you've got the law in your side to fight theft.

BTW, if the reason someone is writing obfuscated code is "job security"  then I would fire any programmer found to be consistently, and purposely using obfuscation with the sole purpose of helping to keep their jobs, unless they could reasonably show that it had some business benefit. It's so completely anti-team that it's ridiculous, and points to someone that's more concerned with keeping their job through misguided practices, then keeping it because they write awesome software.

I only mention this specific case because, while I realize people are usually joking, I'd like to deter any answers whose basic thrust is that obfuscation for job security alone is a good idea.

答: Reading and understanding (and obviously writing) obfuscated code can be an interesting mental challenge. It probably falls outside the scope of what you were asking, but examples like IOCCC may be a source of amusement as well as horror.</p>

Title: The case for code obfuscation?


问:
Would be semantically correct to make a “Login” constructor in an api class?
Since the methods of the class will only work if the user is logged in, is it right or is there some problem that might make my code slow/inneficient?</p>

答: I suggest you handle login separately (outside of your API class) and use PHP's session module to confirm the current session is authenticated.</p>


答:
There's certainly nothing wrong with forcing your users to pass in credentials when they instantiate a copy of your service client, if that's what you want them to do.

However, you have to be careful. You can NEVER trust ANYTHING your consumers give you. So, say this is a web service, for which you are providing a service client API that just plugs in. You cannot be sure that the code that is calling your service is your service client, being used as you intended. Pretty much any communications protocol can be reverse-engineered as to its methodology and form, if not the exact data being sent in any given usage.

Therefore, if it is important for the user to be authenticated before doing anything else, I would check for authentication as the first step of any other task the service can perform. That does not preclude the development of a "login constructor", but it's an extra level of code security that protects you if a consumer should try to get around your implementation.

Title: Would be semantically correct to make a “Login” constructor in an api class?

Body: Since the methods of the class will only work if the user is logged in, is it right or is there some problem that might make my code slow/inneficient?</p>


问:
How can I license networked applications?
I have five applications residing on server(s). Some of these applications are socket (C/C++) based, others are web based (Java, PHP). I need to give licenses to these applications on the basis of the number of users that can access, the type of functionalities and type of users. What kind of business model should I use? I have a few in mind:

Create a java webservice that will be mounted on a license data, and all the servers will communicate with it when a user logins to any of the above applications.

Do a socket based server.

Mount a license file on each server and make each one communicate with its file individually and act as the license rules.

If you have other solutions please shoot.

答:
Use a local digitally signed license file encoding business rules

I've split my answer to cover generally accepted requirements, a matching business strategy and the technical aspects of the problem.

General requirements

Few things annoy users more than having their work interrupted as a result of a license issue. To that end you want to have a system that:

is resilient against network and hardware failure (no single point of failure)

scales well (new servers and more users arrive as the business grows)

is resilient against forgery of licenses

warns administrators when they are approaching the limits of their license

doesn't ever present a false positive (if unsure allow access is the rule for customer-friendly licensing behaviour)

to name but a few.

Business strategy

Your company will want total control over the license, otherwise the customer will manipulate the values to their advantage. However, the customer will not want your company looking over their shoulder and so the system will need to be self-contained on their site.

The customer will not want their entire system to fail if a license is unable to be verified. This obvious demand rules out a networked cental authentication approach because it could fail for a multitude of reasons (network, poor coding, power outage, hardware failure etc). While the central license authenticator is being repaired (could be days to get that done) the customer is unable to do anything - totally unacceptable.

With the above in mind, the strategy to keep your customer happy is to take a bit of a hit in terms of maintenance by using a local license file containing the rules for the given server.

Technical implementation

To achieve that goal, and minimise the hit, I would suggest that you will need to do the following:

Write a license configuration tool for your company. This file defines the user limit, allowed functions, and user types for each product in the form of a digitally signed license file issued by your company using a private key.

The servers must load the license file and verify the digital signature using your public key which is hosted on a well-known public key site (pgp.mit.edu) or embedded directly in the code on startup or after maintenance

Each server verifies it's current user load, type and tasks against the signed license file as traffic occurs. Loading approaching the limit of the license should trigger an email or message to the system administrators.

Servers can update their license file in response to a socket-based PUT request that has a suitable digital signature (again verified by the remote key site). This will allow an automated script to provide license changes when one of your guys is on site providing maintenance.


问:
Should SpecFlow be used with BDD as a solo developer?
I am a long time fan of TDD and after reading the RSpec book, would like to transistion to a BDD process. I like the idea of driving from the outside in, as it is presented in the book.

What I am having a hard time getting a handle on is how to structure the tests. I have tried SpecFlow, but it seems cumbersome to use when I am the only one really ever going to be looking at the tests. I like the idea of just using straight NUnit, rather then adding another framework, like it is presented here.

Is this a good way to try and structure BDD tests? Is there more information out there on comparing the two ways (that may even be more recent)?

答:
It's possible to use NUnit to write BDD-level tests, just like it's possible to use SpecFlow in a completely non-behaviour-driven way. But, before I did either, I'd need a good reason why I wasn't going to use the tool built for the job.

What is it about SpecFlow that "seems cumbersome"? Why would it be good for a team and not for an individual? Is your instinct telling you that it seems cumbersome because you're inexperienced with it?

Even if it is a bit cumbersome for a one-man job, would it be good practice for using it in a bigger team later?

If you answer all those questions and you still can't see any point then by all means, use NUnit with BDD-style test names.


答:
Are you sure that you want to write this?

Have you looked into existing license control applications/services?

If the cost is not prohibitive, this sounds like a classic not-worth-inventing-here application.

Title: How can I license networked applications?

Body:
I have five applications residing on server(s). Some of these applications are socket (C/C++) based, others are web based (Java, PHP). I need to give licenses to these applications on the basis of the number of users that can access, the type of functionalities and type of users. What kind of business model should I use? I have a few in mind:

Create a java webservice that will be mounted on a license data, and all the servers will communicate with it when a user logins to any of the above applications.

Do a socket based server.

Mount a license file on each server and make each one communicate with its file individually and act as the license rules.

If you have other solutions please shoot.


问:
Should web browsers include popular web framework libraries?
What reasons are there for web browsers to not have a library of popular web frameworks.

For example if a web page included jQuery, why shouldn't the browser have it's own static version, which is separate from the normal cached items?

I would imagine if most libraries were preloaded into a browsers cache, before any request was made with a document that included a library, then this would remove the initial request to a CDN and have a potential performance improvement.

But if the browser 'preloaded cache' didn't include the library then the browser should request the resource that is included in the document.

答:
Because within a month, the browser's built-in version of jQuery would be out-of-date, negating the whole reason for using a third party library in the first place.  Within 6 months, developers would be wanting to use features in the latest release of jQuery that weren't in what was built-in to the browser, but they wouldn't without including the whole new version of jQuery - negating the whole reason of bundling it in in the first place.

Browsers should follow and implement standards and developers will benefit years later when the older browsers stop being used or by writing browser-specific code to take advantage of the newest features.  The path for browsers to get more jQuery-like functionality is via that standards process.

The whole point of the cross browser framework is that you can specify one specific version of the framework and know that you get the exact same behavior everywhere right now because that version of the framework takes care of it for you.  That would never be the case with built-in frameworks (because the web developer is stuck with a different version of jQuery built into each targetted browser) so developers would just go about including the latest version of the framework and now you'd not be leveraging what was built-in.


问:
What is the most effective work rhythm for a programmer?
I was wondering what is the best work rhythm for the job a programmer does? I am coding all day long and sometimes I get stuck in a problem and it keeps me occupied a few hours before I realize that maybe I need a break.

Some say frequent and short brakes help you but sometimes when I am focused on a problem I feel like a break would not help, but rather loose my focus. So how often should a break be taken, and how long? The more basic question regarding this issue is comes from the fact that, you can get tons of "good ideas" ('promodo' for instance) on the net, that promise you will be more effective in whatever you do.

Are these principles good or, this is something everybody should decide for himself?
I wonder if any of them can accomplish what it promises! I mean what they promise is that (if the conditions are met) it works for everybody. Are there really such principles? And if there are, what are these and how can we find them?

答: The most important thing for good programming is good sleep. It does not matter what time you program at or for how long. Whether you drink caffeine loaded drink or munch on chocolate all the time. What matters is that you have a good long peaceful sleep every few days. As someone with a young child I can tell you for a fact that lack of deep rest saps your ability to be creative. There have been studies that have shown that artist that are the most creative require the most sleep and workers in non demanding repetitive jobs the least.</p>


问:
Help on a Dynamic Programming definition in Cormen
I am reading about Dynamic Programming from Cormen.

In the beginning of the chapter it says (relating to the term Dynamic Programming):

"Programming” in this context refers to a tabular method, not to
  writing computer code.

I can not really understand what this statement means.

I mean, I understand that the dynamic programming algorithms look up solutions, but I get a feeling that this point here defines something fundamental on the Dynamic Programming that I am not grasping.

Any help?

答: Dynamic programming was invented in the first half of the 20th century, when the term "computer" was a job title rather than an inanimate object. Teams of "computers" would fill out the table on paper using mechanical calculators, nobody was writing any computer code. In those days "programming" was primarily a math term, referring to solving a set of simultaneous equations. I suspect they're making the point because folks sometimes think that dynamic programming refers to some sort of self-modifying code.</p>


问:
When and how a programmer should start own business?
The title says it all but here's some explanation of what I want to know: Let's suppose a programmer has around 5 years of experience in multiple, mainstream languages. Also suppose that the programmer has worked in different positions from junior developer to senior s/w engineer to a team lead. How would he know this is the time to stop working for others and start his/her own business. How important the technical skills and requirements are in addition to of-course financial requirements.

The second part of question is, if he decides to role own company, how he should take a start?

Ok, here's some more info: I am single, have no expenses other than my own mobile bills and university dues. Also there's no house rent for me since we have a joint family system (this is not only common but also appreciable in my culture and community).

I noted that most people have supposed that I want to build a new product or web site. While I appreciate getting your ideas on this, can you people also throw some light on another aspect? What if I would like to build a new, small software shop (or software house as we call it here)?

答: You know you are ready when you feel like there's more you need to do with your life. If you have the gut feeling that you can accomplish more, and you would like to push yourself then you are ready to start your own business. If you're content in working for someone else then there is no rush to do anything on your own. You have to have the desire if you want to run a successful business because it won't just fall in your lap.</p>


问:
Best version control habits for solo developer?
I'm a sole developer at my work and while I understand the benefits of VCS; I find it hard to stick to good practices.  At the moment I'm using git to develop mostly web apps (which will never be open sourced due to my work).

My current workflow is make lots of changes to the development site, test, revise, test, be happy and commit changes, and then push the commit to the live site (so if I'm working on a big new change; I may only commit once a week; but my IDE has a good undo history for uncommitted stuff).

Basically, I'm only using git when switching between machines (e.g., work dev computer to home dev computer or to live machine), but during the day I don't really see the benefit.  This leads me to have long laundry lists of changes (and I have trouble finding good msg for each commit; and whenever I'm in a rush - I tend to leave crappy messages like 'misc changes to admin and templates').

How often should I be committing?  Should each one-line change get a commit?  Should I commit before any test (e.g., at least for syntax/compiling errors and then have to totally undo it; as the idea didn't work or the message is a lie)?

Should I make sure I commit each morning/afternoon before I stop working for dinner while its still fresh?  What I am missing out on by having bad VCS habits?

答:
You are missing a lot.

I'm solo too, in a way. I commit every time a make a significant change, or before I start a significant one so I can go back if I screw things up, and every now and then even if I'm not making anything big. Not everyday really, but close. Sometimes a few times a day.

What I get is that I can go back anytime I want. Which is a lot. Also, having the branches ordered helps.

I guess it gives me a lot of order.

I'm using svn, and I'm getting sick of it. But cannot spend more time learning anythings else.

Good luck.


答:
I always try to start development with 3 questions in mind:

Do I understand the the real business need?

Quite often, the "presenting problem" is not the real problem.

For example, I was recenly asked to produce a complex project management framwork when all the user needed was a static list of tasks with a progress text box next to each one.

Questions like "what will the users actually use it for?" are useful in getting to the real problem.

Is this really a programming problem"?

Does the required functionality already exist in an application that we already have? That we can buy? Could we use pen and paper instead?

For example, the "build an simple word processor with about as much functionality as MS Word Pad" should be answered with "have you considered using WordPad" rather than a programming project.

I was once asked to build a database that would store information on industrial processes, with a series of management reports that would enumerate the processes that fell into certain categories. It turned out that a maximum of 33 records would be created in the database, and that it would be used by 3 people who sat adjacent one another. The perfect solution was a physical file containing 33 sheets of A4 paper. The users could have physically counted the pages to produce their management reports. (Curiously, management decided to buy in a system instead! At least I was free to go and do some value work).

Do I understand the customer's real priorities?

In any application, some features are more important than others. It is important to get clear idea of what really matters to your users. Sometimes, the things that are important to us as developers (eg. that complicated bit) are less important to our custiomers (eg. the look and feel of the application).

A fellow developer recently told me about a demo of web app that he did to verify that the app met their needs. He was frustrated becasuse the users were unable to see past the design of the pages. For these users, appearence was more initially important than functionality, so needed to be prioritised by the dev team.

Title: What are your initial three steps when you are first presented with a software problem?

Body:
I am curious about the very early steps that a programmer's mind takes when it first encounters a problem that it is supposed to solve. How do you start reasoning about it ? What are the first questions you ask yourself ??.

Ok, let me make it more concrete for those of you who think the question is too vague or entirely situation dependent. Pick any of the following   requirements and think out loud about your very first hunches/impressions/tendencies about how to solve it.

1) build a simple word processor with about as much functionality as MS Word Pad

 2) design a single person card game (e.g. Solitaire)

 3) build a scientific calculator

 4) Any  problem of your choosing with similar scale/complexity as the above three


答:
You should commit often.  You should certainly commit after reaching some logical milestone.  If that takes longer than a day, you should at least commit at the end of your work day, or better yet, break up your work into smaller chunks.

There are many reasons for doing that. For example, what if your computer crashes? It is much better to lose only a day's worth of work than a week's or a month's.  Another reason is that frequent commits make it easier to isolate a bug.  You can do a binary search and figure out which small change caused the bug.

Another thing: before you commit, you should do a diff and look at all the changes you have made.  This allows you to check that all the changes make sense, and that you have not forgotten anything.  This also helps you to come up with a better commit message.  And, of course, this is another reason to commit often: it is much easier to go through a day's worth of changes than a month's worth.

Title: Best version control habits for solo developer?

Body:
I'm a sole developer at my work and while I understand the benefits of VCS; I find it hard to stick to good practices.  At the moment I'm using git to develop mostly web apps (which will never be open sourced due to my work).

My current workflow is make lots of changes to the development site, test, revise, test, be happy and commit changes, and then push the commit to the live site (so if I'm working on a big new change; I may only commit once a week; but my IDE has a good undo history for uncommitted stuff).

Basically, I'm only using git when switching between machines (e.g., work dev computer to home dev computer or to live machine), but during the day I don't really see the benefit.  This leads me to have long laundry lists of changes (and I have trouble finding good msg for each commit; and whenever I'm in a rush - I tend to leave crappy messages like 'misc changes to admin and templates').

How often should I be committing?  Should each one-line change get a commit?  Should I commit before any test (e.g., at least for syntax/compiling errors and then have to totally undo it; as the idea didn't work or the message is a lie)?

Should I make sure I commit each morning/afternoon before I stop working for dinner while its still fresh?  What I am missing out on by having bad VCS habits?


答:
I'd say the biggest thing you're missing out on by grouping changes together like that is the ability to track down when and where bugs were introduced.

In my experience, there have been a couple of times where some bug is noticed two-three weeks after it was introduced and having to sift through a week's worth of commits is difficult that long after the fact.  In these cases, it was helpful to simply binary search through the commits to track down which individual change caused the problem.  These bugs were mostly memory usage bugs on C++ code, so it may not happen as often for your project.

Other benefits come into play when developing on a team - simple commit comments, easier merges, relating commits to bug fixes, etc.

I'd guess with your workflow that if you do start committing daily or semi-daily, you'll need to use tags or bookmarks to keep track of which version of code is in use on the live site.  I'd say that's the most important thing to keep track of.


问:
Better way to train new hires
The team I currently am part of experiences fairly high turnover, with members typically moving to different projects within the same company.
Currently our "training" for new members is to pair them with a primary contact (usually the most recent person to complete their training) who will provide them with hands-on experience and will ask more senior developers if the newer hire ask something the mentor doesn't know. It provides a chance for the new hire to get involved quickly, and challenges the mentor to improve his/her understanding of the system also.

However, as you can imagine, this style of training is very time consuming, and doesn't provide a very good knowledge transfer (misconceptions propagate, gaps expand).

I've been tasked with generating documentation and training materials for our future new hires. I already do technical writing occasionally, but it's for the end user and is highly specific with lots of screenshots and consumes a large amount of time to complete.

Creating the new documentation for new hires is considered low priority and I've only currently got ~40 hours to work on it. Documenting the system the current way I write technical documentation would barely scratch the surface in 40 hours. Especially considering I have to document not only about the code base, but also about deployments and support.

How can I quickly write documentation to get new hires up to date as quickly as possible without investing significant time in writing the documentation?

Additional Information:

We currently have both a wiki, and some training documentation, however both are kind of sparse.

答:
You cannot combine doing something like this good without spending time. At least, if you want to do it yourself. You should ask yourself whether it is really necessary to document it as precise as you are trying?

The only alternative would be to let the new hires do the main job. Let them write some parts. The time you spend to correct these (in the form of feedback), will be less than in your current situations. Provide some good templates and you don't have to worry about lay-out.

Title: Better way to train new hires


答:
I believe you already know that they have tasked you with mission impossible. As a writer you are probably already familiar with the quote from Mark Twain:

If I had more time, I would have written less.

Given virtually no resources, probably the best you can do is get a file cabinet and ask everyone to make a copy of what they already have and put the copy in the file cabinet. That way you can at least say to the new hire "If you want to look up something about the system the place to start is in the file cabinet."

Good writing takes time, period. Further it needs to be tailored to the target audience. What works for end users will not be what a programmer needs.

Not to mention that good training is not limited to written materials, it would include full gambit of educational resources including on-line, classroom,  multimedia etc.

As they say, "If you think education is expensive, try the cost of ignorance."

Further it goes without saying that viewing documentation as something to be done after the fact rather than making it an integral part of the process from day one is indicative of a systemic organizational problem.

Title: Better way to train new hires

Body:
The team I currently am part of experiences fairly high turnover, with members typically moving to different projects within the same company.
Currently our "training" for new members is to pair them with a primary contact (usually the most recent person to complete their training) who will provide them with hands-on experience and will ask more senior developers if the newer hire ask something the mentor doesn't know. It provides a chance for the new hire to get involved quickly, and challenges the mentor to improve his/her understanding of the system also.

However, as you can imagine, this style of training is very time consuming, and doesn't provide a very good knowledge transfer (misconceptions propagate, gaps expand).

I've been tasked with generating documentation and training materials for our future new hires. I already do technical writing occasionally, but it's for the end user and is highly specific with lots of screenshots and consumes a large amount of time to complete.

Creating the new documentation for new hires is considered low priority and I've only currently got ~40 hours to work on it. Documenting the system the current way I write technical documentation would barely scratch the surface in 40 hours. Especially considering I have to document not only about the code base, but also about deployments and support.

How can I quickly write documentation to get new hires up to date as quickly as possible without investing significant time in writing the documentation?

Additional Information:

We currently have both a wiki, and some training documentation, however both are kind of sparse.


问:
Object oriented programming concepts

Specifically, programming without inheritance is distinctly not
  object-oriented; we call it programming with abstract data types.

I found this great line from Grady Booch's "Object-Oriented Analysis and Design With Applications" book. So in order for a program to be an OO one, are inheritance, abstraction, encapsulation, and polymorphism(?) must-to-be things?

Could anybody please explain me?

答:
Quick Short Answer

The answer is that is very subjective to the Software Analyst or Software Modeler.

Extended Boring Answer

There are several concepts that related or part of the Object Oriented Paradigm.
You already mention most of them.

For example, one concept you didn't mention, is message-passing, that is missing in most current O.O. programming languages, and was available, together with encapsulation and inheritance in the early O.O. programming languages ("Simula").

I worked sometimes with several variants or "idioms" of Object Oriented Pascal,
that had several of those features, and there was a variant that allowed to use "messages",
as part of the programming language (keyword "message"), similar to "try catch" exceptions, but, without interrupting execution.

While, other variants, and other programming languages provided as optional libraries (functions not keywords).

Summary

You may find that sometimes a programming language may skip some of them, and still be considered by some people O.O., while other not. Its very subjective.

Are you asking for plain intellectual curiosity ?

Do you wonder if the programming language you are using, is fully O.O. ?

Are you working with a collegue / university homework custom O.O. programming language ?

Are you working with a hobbyst, pet project, custom O.O. programming language ?

These questions, is my own curiosity, but, also to know how to make my answer more clear ;-)

There are some programming language & programming paradigms comparison courses at collegues and universities, that deal with this subject.

Cheers.

OwnerDisplayName: Prakash Bala

Title: Object oriented programming concepts

OwnerDisplayName: umlcat


答: You could model any domain without inheritance. Inheritance helps to sometimes be more clear about classes, but it is not a mandatory thing in object orientation, despite Booch's quote.</p>

Title: Object oriented programming concepts

Body:
Specifically, programming without inheritance is distinctly not
  object-oriented; we call it programming with abstract data types.

I found this great line from Grady Booch's "Object-Oriented Analysis and Design With Applications" book. So in order for a program to be an OO one, are inheritance, abstraction, encapsulation, and polymorphism(?) must-to-be things?

Could anybody please explain me?

OwnerDisplayName: JuanZe


答:
First, I would suggest that you don't have to make your new hire training doc as thorough as something you'd write for a client. It needs to be technical enough for a new dev to be able to use as a guide, but not so detailed that it outlines every small thing. They will be able to talk with the team if they have questions after all.

What are the top 10 things a new hire needs to know to be useful to your team? Concentrate on these things. Make them your hit list of items so that a new dev will have enough to do, and enough information to keep them going. If you have too many things on the list ask yourself if they will be doing it in their first two or three weeks. If they won't be doing something in this time, then perhaps it shouldn't be in the on boarding guide.

For each section of your guide, make sure there is a go-to person highlighted right at the top. This way, if the new hire has any questions they know who to go to for help. Also, make sure that one team member isn't the go-to person for too many sections. You don't want to take one person's time up with new hire questions if they are not the mentor.

Don't spend your full week on this document. Leave yourself some time to adjust it after you let at least one new hire go through it. See what works well, what doesn't, and fix.

Title: Better way to train new hires


答:
Good question. Programmer on-the-job training is very rarely taken seriously, nor is it talked about often.

Some ideas I've seen work well:

In your wiki, have a new-hire rampup document (the one you're writing). In that document, describe teh tasks that the new hire will perform for the first 1-2 weeks. Where I work, there's loads to know from the get-go, from internal software/tools, to processes, to locations of specific types of information. edit> we have instructions like "install x, y, z in order" with screenshots for configuration etc. So configuring a system or farm (VMs) with Win Server, SQL Server, SharePoint, BizTalk, our software is not as simple as it sounds. This goes for the other versions of those applications that we support.

Practice problems. Where I am, we have a product that exposes a large-ish API. So it's always beneficial for us to go through our own products documentation for writing (pre-determined) extensions just as our clients/customers would. So if you had a math library as part of your product's API, have a practice problem that is "write a calculator using our API" or something like that.

Mentors are good. Keep them. We do that here too, and not only is it a good way to meet people/make friends, but they're invaluable as a source of learning. I recommend not having it be the most recent person to finish the training as they don't have the corporate knowledge history that someone else might. Have everyone do it on a rotation.

We do (roughly) weekly presentations/tech talks. Have the new hires pick something from your product (or assign it) and do a presentation after their 3rd week. Make sure they know that there is room for them to be wrong, and the team can correct them if they bugger anything up in the presentation.

Have the new hires work on documentation when they start. It forces them to read it.

As Dan McGrath notes, it's a good idea to encourage new hires to improve the wiki for them as well.

Title: Better way to train new hires


答:
1. Does the program already exist? If the program already exists in the market, can I do significantly better? Is anybody interested in a better version?

2. Would developing that program be interesting to me? Would it be a growthful experience? With experience, developers generally have more opportunities to do programming than they have available time.

3. What ressources do I have? Not enough? Negotiate. Now is the right time.

Basically, when I have a opportunity of developing a program, or solving a problem, my first thoughts always revolve around the question: Do I want to be involved?

Managers often think that they can get an engineer to solve anything. It is important to take care of oneself to avoid getting into a mess.


答:
Abstraction and Encapsulation are really the only things required for something to be object- oriented.

Inheritance and polymorphism are strategies to take advantage of NOT "reinventing the wheel" which is a benefit to using OO designs.

The base idea behind OO design is to get a large amount of programmers to work together on project X without incurring massive communication overhead, and breaking a project down into objects with defined communication between them is an elegant solution.

Title: Object oriented programming concepts


答: Dynamic programming is a way to solve problems by decomposing them into sub-problems in a manner that the results of many of the sub-problems can be used many times throughout the solution. A table of the sub-problem results can be created, so that actual computations only need to be performed once per sub-problem.</p>

Title: Help on a Dynamic Programming definition in Cormen

Body:
I am reading about Dynamic Programming from Cormen.

In the beginning of the chapter it says (relating to the term Dynamic Programming):

"Programming” in this context refers to a tabular method, not to
  writing computer code.

I can not really understand what this statement means.

I mean, I understand that the dynamic programming algorithms look up solutions, but I get a feeling that this point here defines something fundamental on the Dynamic Programming that I am not grasping.

Any help?


答:
One property of highly maitainable code is function purity.

Purity means that functions should return the same result for the same arguments. That is, they should not depend on side effects of other functions. Additionally, it is useful if they do not have side effects themselves.

This property is easier to witness than coupling/cohesion properties. You don't have to go out of your way to achieve it, and I personally consider it more valuable.

When your function is pure, its type is a very good documentation by itself. In addition, writing and reading documentation in terms of arguments/return value is much easier than one mentioning some global state (possibly accessed by other threads O_O).

As an example of using purity extensively to help maintainability, you can see GHC. It is a large project about 20 years old where large refactorings are being done and new major features are still being introduced.

Last, I don't like the "Keep it simple" point too much. You can't keep your program simple when you are modelling complex things. Try making a simple compiler and your generated code will likely end up dead slow. Sure, you can (and should) make individual functions simple, but the whole program will not be simple as a result.

Title: How to keep a big and complex software product maintainable over the years?

Body:
I have been working as a software developer for many years now. It has been my experience that projects get more complex and unmaintainable as more developers get involved in the development of the product.

It seems that software at a certain stage of development has the tendency to get "hackier" and "hackier" especially when none of the team members that defined the architecture work at the company any more.

I find it frustrating that a developer who has to change something has a hard time getting the big picture of the architecture. Therefore, there is a tendency to fix problems or make changes in a way that works against the original architecture. The result is code that gets more and more complex and even harder to understand.

Is there any helpful advice on how to keep source code really maintainable over the years?


答:
Useful quotes from the C++ Faq Lite (don't be annoyed by its relation with C++, the concepts are the same in any OOP language):

"Inheritance is what separates abstract data type (ADT) programming from OO programming."

"Programming with classes but without dynamic binding is called object based, but not object oriented." Note that dynamic binding is another term for polymorphism. Also AFAIK inheritance is necessary to implement polymorphic classes.

So to answer your main question, yes, all the things that you are mentioning are "a must" for writing good OOP code.

Title: Object oriented programming concepts


答:
To get the most out of CVS you should work on one feature/bug-fix at a time, and commit when that feature/bug-fix is complete.  By doing this you'll gain:

commit messages will will be easier to create and will make more sense;

easier tracking of future bugs back to the changes that introduced them;

easier reverting to a previous state (even if that means losing a failed feature but keeping bug-fixes that occured afterwards).

Also, since you switch between PCs you should have at least two branches:

a "Ready to go" branch that always works (excepting the bugs you are working on in the development branch, of course)

a development branch that may be in an unrunnable state from time to time (like during your trip home from work ;) .


问:
Simulating/developing_a_testing_strategy for factors that might cause the same algorithm to produce different results in Distributed Systems
This is a Purely Academic Question

Context:

I am working with some algorithms which are meant to arrive at a consensus in distributed systems. I intended to tackle Byzantine faults with these algorithms. For this I have implemented several algorithms published in IEEE papers and need a platform to test these algorithms. I wanted to test the merit of existing algorithms. For this I implemented thousands of Linux Containers on my system and now i want to do message passing between them, or say simulate my distributed system. But the question is the data that is flowing must have faults. This is the genesis of this question. Why I need something more sophisticated than RNG's is that I will need to attach some real credibility to my work. I want it to tackle some real world application generating faults rather than just fix the faults I myself generated in an algorithm.

So, I need to simulate the factors that result in Byzantine faults.

OR, to quote FrustatedWithFormsDesigner:
I need to develop a testing strategy that will have a deliberate number of faults to test fault-handling

To Summarize:

Say I am running a program in a distributed environment, then what are the factors that might end up generating Byzantine faults and is it possible for me to inculcate these factors in my simulation and how?

So, what I need is:

A program that will make a small no. of mistakes every now and then, and I should not know what mistakes it has made and when.

I do not need it to make multiple mistakes in one set(run of the algorithm), but rather I plan on making (say) 10,000 runs of the program, and I need it to make mistakes 2000 times ..

Very importantly, I must be sanguine that there are no more than (1/5)n mistakes, where n is the total no. of results generated using the program.

The results that I am talking about here can be anything that is quantifiable and verifiable, like eg. an array of values.

Doing something like this:

```<code>1for(int i=0; i<10000; i++)
2   //one fifth of the times put garbage in the array using random function!!
3   for (int j=0; j<5; j++)
4      array[j]=j;
</code>```

using a RNG in step 2 to hide where the fault is present is too simplistic, trivial and not real enough.

I thought I could use some algorithm built around some mathematical function that is bound to fail 1/5th of the times, But I could not think of any.

P.S.
Please tell me if you need more data to understand the problem.

答:
Is the problem that you want faults to occur randomly, and with something like a uniform distribution, but want a hard cap?

If you want k events out of n tries, randomly, create an event with a probability of k/n.  Now, do this again:  you want either k or k-1 events out of n-1 tries, depending on whether you got the event or not.  Continue until the denominator (i.e., number of remaining tries) hits zero.  Once you have k events, the numerator will be stuck at 0, so you don't get any more.  The distribution will (IIRC) be uniform.


问:
Commented short fancy code vs. uncommented longer easy-to-understand code - which is preferred?
Sometimes an algorithm can be written in two ways:

The short, fancy way; or

The longer, easy-to-understand way.

For example, here is a longer, easier way of copying a string source to dest in C:

```<code>*dest = *source;
while (*source != '\0') {
    source++;
    dest++;
    *dest = *source;
} (true);
</code>```

And here is a short, fancy way.

```<code>// Copy string source to dest
while (*dest++ = *source++);
</code>```

I've always heard and read that fancy code should be avoided, and I tend to agree. But what if we take comments into account? Assume that, as in the examples above, we have an uncommented, longer and supposedly easier-to-understand code, and a well-commented, short, fancy code? Is the non-fancy code still preferred?

EDIT: Many have commented on variable names, so I've modified the example code as to not make that a factor when preferring on over the other. I tried to remove the double assignment in the first example, but that only made the code less readable.

Perhaps this wasn't the best of examples because many find the 'fancy' code more readable and understandable than the longer code. The idea was to have one longer code which was much easier to understand than a very short but complicated code.

EDIT2: Here's a new examle I got from SO:

Commented fancy version:

```<code>//direct formula for xoring all numbers from 1 to N
int Sum = (N & (N % 2 ? 0 : ~0) | ( ((N & 2)>>1) ^ (N & 1) ) );
</code>```

Non-commented long version:

```<code>int Sum = 0;
for (int i = 1; i < N; ++i)
{
   Sum ^= i; //or Sum = Sum ^ i;
}
</code>```

答: Don't write fancy code in production software. I know it feels good to be able to actually write that, and it's shorter. Writing fancy code significantly increases the "WTF/minute" value, in other words decreases quality.


答:
I am a solo developer too, I use SVN, and I love it. I have even written a tool to convert the structure of my database and the test data in it to xml so that I can include that in source control.

I usually commit whenever I have completed an autonomous unit of work. Sometimes, if I perform a bunch of trivial and unrelated single-line fixes here and there then I commit all of them together, but if a single-line fix happens to occur between two unrelated big autonomous units of work, then it gets its own commit, there is nothing wrong with that.

Also, I always commit code which compiles, and almost always code which also passes all the basic tests. If not, I make sure to include "DOES NOT WORK" in the commit message. The only case when this happens is when I have done important changes which I do not want to lose even though they do not quite work yet, and on top of this I am about to embark in a great refactoring adventure that I am not sure whether it will be successful. So, then, I use the repository as a backup of the work I have done so far before risking to mess it up and have to throw it away.

This means that I always commit when my source code needs to be committed; it makes absolutely no sense to have morning commit or evening commit rules. It is the state that the code is in which dictates whether or not it is time to commit.

The messages that you put in the repository do not matter much. If you absolutely cannot come up with something meaningful, it is still better to commit with a blank message than to not commit at all when you should.

If you can't think of a good commit message because everything you come up with sounds stupid, bear in mind that this is okay; commit messages are expected to state the obvious, so they are bound to sound stupid to you when you are writing them. But trust me, if you need to examine old revisions a month later you will be grateful for even the stupid messages over no messages.


答:
I think you should look at the FlexLm.

For awhile SUN was using it to provide distributed licence services for their products.


问:
Make a big deal out of == true?
There is a colleague of mine who constantly writes:

```<code>if (someBool == true)
</code>```

It drives me up the wall!  Should I make a big deal of it or just drop it?

答:
Yes, it's a big deal because the name of the boolean should tell that it is boolean. Says if you have this piece of code:

```<code>bool arrayIsEmpty = array.length == 0;
if (arrayIsEmpty) { ... }
</code>```

It is already easy to read so you won't need == true, even for the person or programmer with less sense of evaluation.

Title: Make a big deal out of == true?

Body:
Yes, it's a big deal because the name of the boolean should tell that it is boolean. Says if you have this piece of code:

bool arrayIsEmpty = array.length == 0;
if (arrayIsEmpty) { ... }

It is already easy to read so you won't need == true, even for the person or programmer with less sense of evaluation.


答:
Should each one-line change get a commit?

If that is what fixes a bug, sure.

What I am missing out on by having bad VCS habits?

I worked with a guy who had "bad VCS habits". He loved to work all by himself and he was in charge of a product line that brought in something like $1,000,000/year. He'd only make committs when the boss nagged him. Then one day his hard drive crashed. After getting a replacement set up for him, we discovered his last check-in was 6 months previously. Since the VCS was Source Safe, you can guess what else went wrong - the last commit was corrupted. We had to go back more than a year to get a non-corrupted version of his product line. He didn't get fired, even though he should have been.

Another anecdote involves myself. I used to store code for hobby and research projects on removable hard drives. One day, my apartment was broken into. The laptop (which was broken) and all the removable hard drives were stolen. Every DVD (with the exception of Red Dawn) was stolen. None of the desktop computers were stolen. If I had offsite source control, I would not have lost 15 years worth of projects, especially since some were based off academic projects - many of the profs left academia to go to private industry so those projects vanished into a corporate IP black hole making the lost code impossible to recover.

How often should I be committing?

I break it down into a few metrics:

How much work are you willing to lose if your computer dies? or gets stolen?

If this fixes Bug_1234, then check the code in with the comment "fixes Bug_1234".

If this is a logical delivery/milestone, then check it in with a comment like "Bug_1234, form_xyz" (or Task_1234 as appropriate).

Always check in code on Friday evening before you head home. Also do a check-in (or undo the checkouts) of everything before leaving on vacation.

Whenever the company policy dictates.


问:
Example bad code project to motivate refactoring / good design
This is sort of the opposite of https://softwareengineering.stackexchange.com/questions/121571/is-there-an-open-source-project-that-can-be-an-example-of-well-written-code.

I am teaching software engineering to undergraduates and I would like a blob of object oriented code that demonstrates tight coupling, bad abstraction, low encapsulation, poor maintainability, the works.  Anyone have a good example?  Something that is digestible (as in, able to skim in an hour or less) would be great.  Thanks in advance.

答:
While still a student project, I shamefully submit part of my capstone project. It is open source software written in Java.

It is large enough that you probably wouldn't want to scrap it and start again.

It features some absolutely horrible constructs, but should have enough structure to make some key sections palatable.

Disclaimer: We only had 3 out of 5 team members and were self-teaching ourselves Java as part of the project to make it more of a challenge.

I will be available for questions/answers or anything else if you end up looking at it.


答:
Truly dismal code doesn't often last long enough for people to notice.  You might want to check out inactive or pre-alpha projects on sourceforge for a start.

Also, Clean Code by Robert Martin has a lot of before and after examples taking those sorts of concepts one at a time.  Not exactly one canonical example, but that's one book I wish every new hire had read in college.

Title: Example bad code project to motivate refactoring / good design

Body:
This is sort of the opposite of https://softwareengineering.stackexchange.com/questions/121571/is-there-an-open-source-project-that-can-be-an-example-of-well-written-code.

I am teaching software engineering to undergraduates and I would like a blob of object oriented code that demonstrates tight coupling, bad abstraction, low encapsulation, poor maintainability, the works.  Anyone have a good example?  Something that is digestible (as in, able to skim in an hour or less) would be great.  Thanks in advance.


问:
Python: What is the point of using "import"?
I am not very clear on this aspect. Let's say you have a bunch of .py files that are their own separate modules.

Why does each .py file need to import the others when they use that class? Or do they? Because I was pretty sure that other languages (Java, for instance), did not require import when referring to classes/files in the same directory. I might be wrong.

答:
There are some important differences between Python and Java; while Java has a "one class per file" rule, Python does not.  Also, not everything in Python is a class.

So a module can have classes, functions, and just plain old variables -- usually all related in some way (such as random functions in random, math routines in math, string contstants in string, etc).

If you want to access any of classes/function/variables from a particular module, you must first import it.

Why is this a Good Thing?

Keeps module name spaces clean (not cluttered with names you will never use)

Easier to track back to the appropriate module when something goes wrong

Allows you to use names without fear of either an error because the name is in use, or clobbering the already in-use name (you can have math.sin and your own sin functions)

Helps clarify program structure.


答:
Programming conventions are not necessarily "right" or "wrong". They exist to give the program a familiar structure to those reading it, so that possible mistakes will stand out more clearly -- it is difficult to "see" a problem if everything is slightly wrong-looking to you.

The important thing is that conventions be clearly defined and agreed upon by all participants (even if the agreement is like "I agree to use this convention while I work here" :), otherwise it does more harm than good.

Of course, the particularly case of comparing a boolean to true is plain wrong and to be avoided at all costs. ;-)

Title: Make a big deal out of == true?

Body:
There is a colleague of mine who constantly writes:

```<code>if (someBool == true)
</code>```

It drives me up the wall!  Should I make a big deal of it or just drop it?


答:
Do not think in terms of number of lines changes.  Think in chunks of functionality.  VCS allow you to give a heading in a central place for each functionality chunk so you can easily see the "what has happened here" with e.g. git log.

Also, IDE's like Eclipse allow you to point to a given line and go to the commit that brought it into the shape you see.  In other words, you can go directly from a source line to the commit.  If the commit is small and has a good message, it is much more helpful than "fixed tons of bugs".


答: One of the most important concepts in Python is that of namespaces (do import this at the prompt some time to find out what the others are). I know that namespaces exist in other languages too, but in Python you only have access to the current namespace, which is what's defined in the current module. To get access to other identifiers, you need to import them into the current namespace: either by importing their containing module (the import foo syntax) or the names themselves (from foo import bar).

Title: Python: What is the point of using "import"?

Body:
I am not very clear on this aspect. Let's say you have a bunch of .py files that are their own separate modules.

Why does each .py file need to import the others when they use that class? Or do they? Because I was pretty sure that other languages (Java, for instance), did not require import when referring to classes/files in the same directory. I might be wrong.


问:
Computation Program Not Running at 100% CPU Utilization
I have a program which has a GUI and performs some very heavy mathematical computations for a couple of minutes and then outputs a result. When I try to directly interface it through its DLL's, it runs fine, but it doesn't run at 100% CPU usage like the GUI does. Why is this?

I understand the reason why computational heavy program might not run at 100% is due to I/O that it might be doing but this program doesn't do any, not even a single printf(). Files are being generated at the end of execution in both the GUI and DLL versions of the program. The interface program makes mulitple calls to the DLL during execution as well.

It is written in C, compiled using VS2008 CL compiler running in Release mode. Running on Intel i5 CPU with 4GB RAM (60% utilization average, never above 70%). When I set affinity to the process to one CPU (in this case, 1/4 "CPU's", 2 cores with 2 threads each), the GUI uses 100% of that dedicated CPU for about 2 min. My interfacing application uses anywhere from 60-80% CPU for about 5 minutes. I use Window's Performance Tab upon performing CTRL+SHFT+ESC.

---EDIT---

I found that database calls (there are a few specific ones) are being preempted a lot for extended periods of time (usually 5 times slower). Using Process Explorer I was able to find out that each program uses exactly the same amount of CPU time -> leading to my conclusion about preemption. For anyone that doesn't know about this tool, download Process Explorer from SysInternals, very useful.

---EDIT---

I found that the GUI opens a single static connection to the database. While my interface doesn't do that, leading to opening and closing the connection thousands of times. Opening it once for the lifetime brought the CPU up to 100%.

答: Remember that your program is not the only one run by the OS. Each program has a priority assigned to it. You need to check that out and see if you can give you program a higher priority or reduce other running programs priorities when possible.</p>


问:
For what common problems is functional programming not a good fit?
Functional programming is a declarative paradigm. One of the strenghts with FP is that side-effects are avoided. It's said that for some problems FP isn't a good fit.

For what common problems isn't functional programming a good fit?

答:
You can't easily dismiss any problem set for not suited for functional programming per se.

Much depends on the actual language used for functional programming and its features.

One example is the already mentioned Erlang for realtime embedded-systems.

State-fullness is also not a good criterium against functional programming, there are several successful ways implemented in functional programming languages to deal with this.

Side effects are also often mentioned against functional programming.  Every program that is not totally solipsistic has side effects.  So every real world FP language has some way to deal with this, its only a matter how elegantly to encapsulate the world side effects.

There is no need for arbitrary side effects like global variables at all.

But there are problem sets that make it easier to get into functional programming because they don't twist your familiar way of looking at the problem as much.  But once you manage to think functional more and more problem sets are open to less side-effects.

Even when programming C it is always a good idea to reduce arbitrary side effects like global variables as much as possible.


答:
You might Google for "refactoring". Often there's a before-and-after picture or even a step-by-step process that can supply you with a "bad code" starting point.

If that doesn't work, why not teach them how to write bad code? It might be an interesting exercise in contrarian thinking. Post the "rules of bad code" on the blackboard/whiteboard:

1) Try to bury misspellings in method names

2) Use extremely short, long, or meaningless variable names

3) Try to reuse variable names or similar variable names in different scopes

4) Write lengthy comments that either don't match the code or are meaningless (getSalesTax - a method which gets the sales tax)

5) Put as much functionality into a single line as possible

Others are welcome to add the missing 95 rules to this answer.


答:
Programming with abstract data types means that when you write:

```<code>struct A { int i; float k; };
</code>```

You can use A a; as abstraction of some bits like [00000000][00000000] (with proper number of bits).

Inheritance adds the following feature:

```<code>class A { public: virtual void f()=0; };
class B1 : public A { public: void f() { ... } int a; int b; };
class B2 : public A { public: void f() { ... } int i; float k; };
void algo(A &a) { a.f(); a.f(); }
int main() { B1 b; algo(b); B2 b2; algo(b2); }
</code>```

i.e. When there are several classes like B1,B2,B3 the algorithms like algo() can work with all of them, even if the format of the bits is changing between B1 and B2, like the { int a; int b; } is different from { int i; float k; }. Only f() needs to be rewritten, not the whole algo().

Title: Object oriented programming concepts

Body:
Programming with abstract data types means that when you write:

struct A { int i; float k; };

You can use A a; as abstraction of some bits like [00000000][00000000] (with proper number of bits).

Inheritance adds the following feature:

class A { public: virtual void f()=0; };
class B1 : public A { public: void f() { ... } int a; int b; };
class B2 : public A { public: void f() { ... } int i; float k; };
void algo(A &a) { a.f(); a.f(); }
int main() { B1 b; algo(b); B2 b2; algo(b2); }

i.e. When there are several classes like B1,B2,B3 the algorithms like algo() can work with all of them, even if the format of the bits is changing between B1 and B2, like the { int a; int b; } is different from { int i; float k; }. Only f() needs to be rewritten, not the whole algo().


答:
How often should I be committing?

As a solo developer I generally commit whenever I feel I have made a significant change, after basic testing, and when I leave a project at the end of the night.

Should each one-line change get a commit?

No, unless that one-line change is going to significantly change a feature or bug.

Should I commit before any test (e.g., at least for syntax/compiling errors and then have to totally undo it; as the idea didn't work or the message is a lie)?

Probably not. At least for me I do most of my testing and coding on a 'working copy' and commit after I am happy with my changes. In many IDE's it will show me what changed before I actually make the commit and give me an opportunity to attach notes to the commit

Should I make sure I commit each morning/afternoon before I stop working for dinner while its still fresh? What I am missing out on by having bad VCS habits?

I am not very familiar with VCS or what bad habits it causes. I think I have mostly shared my opinion on this in answer to the first question.

In response to the general question postulated, you seem to be mostly using commits as branches which is addressed in another responders post. I'm not sure which IDE you are using that has a good undo history etc, but I haven't found one that I felt was good beyond restarts of the IDE and moving in between machines.


答:
You might want to specify the language you're searching for a project in.  About a year ago I wrote a client and server for four-dimensional go in C++ with Qt.  It is about 4,000 lines of code if I remember correctly, and should work on both Windows and Linux.

The code abuses exceptions, tight coupling (I think there's even bad friendship somewhere in there), RTTI, uses a ridiculously bad network protocol (which is entirely undocumented), and has at least two classes that do way too much (Server and Client).  Oh, and it lacks any kind of unit tests.  It took me about three weeks to write if I remember correctly, so it may be too small.

Feel free to contact me with questions/complaints if you choose to use it.

I think an interesting way of generating such projects would be to take existing student projects and then demand that students add features to them in a timespan that is not quite long enough.  After a few of those, which probably get tacked on quickly, you could teach them to refactor and then request another feature at the end (in a similar time slot) to further demonstrate the benefits of what they've learnt/done.


问:
How to keep a big and complex software product maintainable over the years?
I have been working as a software developer for many years now. It has been my experience that projects get more complex and unmaintainable as more developers get involved in the development of the product.

It seems that software at a certain stage of development has the tendency to get "hackier" and "hackier" especially when none of the team members that defined the architecture work at the company any more.

I find it frustrating that a developer who has to change something has a hard time getting the big picture of the architecture. Therefore, there is a tendency to fix problems or make changes in a way that works against the original architecture. The result is code that gets more and more complex and even harder to understand.

Is there any helpful advice on how to keep source code really maintainable over the years?

答:
Clean rotted code by refactoring, while writing unit tests. Pay down (this) design debt on all the code you touch, whenever you:

Develop a new feature

Fix a problem

Greatly speed your test-first development cycle by:

Refactoring to convert code modules to a scripting language

Use fast, cloud-based test machines

Refactor code to use low coupling (of highly internally-cohesive units) by:

Simpler, (more) functions (routines)

Modules

Objects (and classes or prototypes)

Pure functions (without side effects)

Preferring delegation, over inheritance

Layers (with API's)

Collections of small, one-purpose programs which can operate together

Organic growth is good; big up-front design is bad.

Have a leader who is knowledgeable about the current design. If not, read the project's code until you are knowledgeable.

Read refactoring books.


答:
Be a scout. Always leave the code cleaner than you found it.

Fix the broken windows. All those comments "change in version 2.0" when you're on version 3.0.

When there are major hacks, design a better solution as a team and do it. If you can't fix the hack as a team, then you don't understand the system well enough.  "Ask an adult for help." The oldest people around might have seen this before. Try drawing or extracting a diagram of the system. Try drawing or extracting the use cases that are particularly hacky as interaction diagrams. This doesn't fix it, but at least you can see it.

What assumptions are no longer true that pushed the design in a particular direction? There might be a small refactoring hiding behind some of that mess.

If you explain how the system works (even just one use case) and find yourself having to apologize of a subsystem over and over again, it's the problem. What behavoir would make the rest of the system simpler (no matter how hard it looks to implement compared to what is there). The classic subsystem to rewrite is one that pollutes every other subsystem with its operating semantics and implementation. "Oh, you have to groz the values before you feed them into the the froo subsystem, then you un-groz them again as you get output from the froo. Maybe all values should be groz'ed when read from the user & storage, and the rest of the system is wrong? This gets more exciting when there are two or more different grozifications.

Spend a week as a team removing warnings so that real problems are visible.

Reformat all the code to the coding standard.

Ensure your version control system is tied to your bug tracker. This means future changes are nice and accountable, and you can work out WHY.

Do some archeology. Find the original design documents and review them. They might be on that old PC in the corner of the office, in the abandoned office space or in the filing cabinet nobody ever opens.

Republish the design documents on a wiki. This helps institutionalize knowledge.

Write checklist-like procedures for releases and builds. This stops people having to think, so they can concentrate on solving problems. Automate builds wherever possible.

Try continuous integration. The sooner you get a failed build, the less time the project can spend off the rails.

If your team lead does not do these things, well that's bad for the company.

Try to ensure all new code gets proper unit tests with measured coverage. So the problem can't get much worse.

Try to unit test some of the old bits that are not unit tested. This helps cut back the fear of change.

Automate your integration and regression test if you can. At least have a checklist. Pilots are smart and get paid lots and they use checklists. They also screw up pretty rarely.


答: Pretty easy, think of a project, have the person/group code it up in a day or two and then walk them through why it is bad design. People learn a lot better than it is relevant to what they know (in this case, their own code).</p>


问:
Choosing language to write general library in
I'm about to start writing a library to support machine learning algorithms (decision trees, ANNs, Bayes nets, etc.), and I'm planning on making this a very general library. By this, I mean I want to be able to plug this module into as many languages as possible.

To clarify, here's why I've started writing it in C++ (Windows headers):

I know I can import C++ libraries into C#, and I've heard you can import C++ into Python. So, obviously, the library can be used in 3 languages, possibly 4 if I don't use system-specific headers.

Is there a language where I can cover a wider spread, weighted by popularity of languages? (For example, C# and C++ have pretty high weight to me because I use both frequently, Python less so.)

答:
If wide compatibility and portability are your main concerns, I think there are two serious options:

C/C++ - this will be most easily importable into most other languages, as nearly every language has some mechanism for calling C code. You can compile C/C++ code on pretty much any platform. Also if performance is a priority, it's nice to be able to code very close to the metal.

Java - it's the most popular language overall, with definitely the widest spread and portability of any of the major VM platforms, also is a very common choice for machine learning development. I suspect the majority of your potential library users will want to use Java. An additional advantage of pure Java is that it gives you binary (bytecode) portability so you don't even need to recompile for different platforms. The downside is that calling Java from other languages is a bit more tricky (one solution to this would be to provide a REST-style or socket API)

My personal recommendation would probably be to go for Java, because that's where the majority of your potential library users will be (research, enterprise software development, cloud startups etc.). If you want to make it really easy for these people to adopt your library, then a pure Java library will be much nicer than a set of native code bindings.

P.S. I do have quite a bit of experience in this space and have researched the options quite extensively, I'm currently writing a machine learning library on the JVM using Java + Clojure.


问:
Resources on learning to program in machine code?
I'm a student, fresh into programming and loving it, from Java to C++ and down to C. I moved backwards to the barebones and thought to go further down to Assembly.

But, to my surprise, a lot of people said it's not as fast as C and there is no use. They suggested learning either how to program a kernel or writing a C compiler. My dream is to learn to program in binary (machine code) or maybe program bare metal (program micro-controller physically) or write bios or boot loaders or something of that nature.

The only possible thing I heard after so much research is that a hex editor is the closest thing to machine language I could find in this age and era. Are there other things I'm unaware of? Are there any resources to learn to program in machine code? Preferably on a 8-bit micro-controller/microprocessor.

This question is similar to mine, but I'm interested in practical learning first and then understanding the theory.

答:
My suggestion? Learn MIPS and learn how to build a (simple) MIPS processor. It's actually easier than it seems.

The advantage of MIPS over some of the other architectures is simplicity. You won't get caught up in a ton of little details, but you will still learn all of the big ideas you need to write code in other architectures.

Coincidentally, this was the final project for my (third) intro CS class. If you want, you can read the assignment and browse through the lectures as videos or slides.

Among other things, we did cover how MIPS code gets turned into binary; we even had to decode some (very simple) machine code on the exams.

Even if you don't want to cover everything, most of the lectures were given by one of the students' favorite lecturers and are fun to watch by themselves.


答:
I agree. It's a redundant construction, specially in strong typed languages.

To add another misuse of booleans, I have found this kind of construction a bunch of times in Javascript, (specially at some spaghetti-like monster functions, as in 100+ lines):

```<code>//create the variable, not initializing it
var flag;
//...
//assing a value to the var, by the example
flag=$("mycheckbox").selected;
//...

//and at the moment of use it:
if(flag!=true) {
   //code to execute when the checkbox is unchecked
}
</code>```

It seems, that due to the lack of an strict type definition in this language, some programmers prefer not have to be messing around with the false|undefined values.

Title: Make a big deal out of == true?

Body:
I agree. It's a redundant construction, specially in strong typed languages.

To add another misuse of booleans, I have found this kind of construction a bunch of times in Javascript, (specially at some spaghetti-like monster functions, as in 100+ lines):

//create the variable, not initializing it
var flag;
//...
//assing a value to the var, by the example
flag=$("mycheckbox").selected;
//...

//and at the moment of use it:
if(flag!=true) {
   //code to execute when the checkbox is unchecked
}

It seems, that due to the lack of an strict type definition in this language, some programmers prefer not have to be messing around with the false|undefined values.


答:
I'm a student, fresh into programming and loving it, from Java to C++ and down to C. I moved backwards to the barebones and thought to go further down to Assembly.

Excellent path to take. My jump (fall?) from C to Assembly and lower was a university course Computer Organization and Design, based on the book by the same name.

Highly recommend this book for the first chapters on basic MIPS assembly, all the way through pipelining and memory architecture. Even better would be to take a course around the same theme, or find some lectures online.

Also see the MARS MIPS Simulator to get your hands dirty writing assembly.

Title: Resources on learning to program in machine code?

Body:
I'm a student, fresh into programming and loving it, from Java to C++ and down to C. I moved backwards to the barebones and thought to go further down to Assembly.

But, to my surprise, a lot of people said it's not as fast as C and there is no use. They suggested learning either how to program a kernel or writing a C compiler. My dream is to learn to program in binary (machine code) or maybe program bare metal (program micro-controller physically) or write bios or boot loaders or something of that nature.

The only possible thing I heard after so much research is that a hex editor is the closest thing to machine language I could find in this age and era. Are there other things I'm unaware of? Are there any resources to learn to program in machine code? Preferably on a 8-bit micro-controller/microprocessor.

This question is similar to mine, but I'm interested in practical learning first and then understanding the theory.


答:
I have an instruction set that was made for this, a simulator, and some tutorials on the basics one instruction or concept per lesson.  Just type the program, run it then learn what it does, move on to the next lesson.

http://www.github.com/dwelch67/lsasim

I also have simulators for a few mainstream instruction sets as well.  Any or all of which are good for using to learn asm (if you really feel you have to learn x86, learn it last, and use a simulator like the one I have forked, 8088/86 first then move forward).  Learning against a simulator has pros and cons, one major pro, esp when starting out, is you dont crash anything and you have great visibility.  Jumping in head first into an embedded platform, microcontroller, etc to learn a new instruction set you have to overcome the hurdles of not being able to see what is going on, leading to a long list of ways to fail...