问:
Does Silverlight have a future?
Recently I have read some articles/blogs/comments about the development and history of WPF and Silverlight. In some forums many developers and users criticize the performance of WPF applications (for example Visual Studio 2010). Actually the market share of Silverlight in comparison to Flash is not very high. At PDC 2010 Bob Muglia said something like "our Silverlight strategy and focus going forward has shifted...." and Microsoft wants to push HTML5 in the future.

Additionally, Microsoft has announced HTML5 being a core part of the Windows 8 and Windows Phone 8 ("Mango") platforms.

Recently I have started learning Silverlight and now I must ask myself, if I should continue investing time in learning these (in my opinions) very nice and powerful technologies!? Does they have a future? Does (Windows) desktop (client) applications have a future? Does so called "Rich Internet Applications" have a future? Or will HTML5 become the "absolute truth" in software development?

What is your opinion and what do you think?

答:
Then what should microsoft do?

In this situation, they have to give support for HTML5+js as the maker of the most used browser.

But you can still go with Silverlight. There will be releases and support for this well designed framework no doubt.

Title: Does Silverlight have a future?


问:
Why can't the IT industry deliver large, faultless projects quickly as in other industries?
After watching National Geographic's MegaStructures series, I was surprised how fast large projects are completed. Once the preliminary work (design, specifications, etc.) is done on paper, the realization itself of huge projects takes just a few years or sometimes a few months.

For example, Airbus A380 "formally launched on Dec. 19, 2000", and "in the Early March, 2005", the aircraft was already tested. The same goes for huge oil tankers, skyscrapers, etc.

Comparing this to the delays in the software industry, I can't help wondering why most IT projects are so slow, or more precisely, why they cannot be as fast and faultless, at the same scale, given enough people?

Projects such as the Airbus A380 present both:

Major unforeseen risks: while this is not the first aircraft built, it still pushes the limits of the technology and things which worked well for smaller airliners may not work for the larger one due to physical constraints; in the same way, new technologies are used which were not used before, because for example they were not available in 1969 when the Boeing 747 was certified.

Risks related to human resources and management in general: people quitting in the middle of the project, inability to reach a person because she's on vacation, ordinary human errors, etc.

With those risks, people still achieve projects like those large airliners in a very short period of time, and despite the delivery delays, those projects are still hugely successful and of a high quality.

When it comes to software development, the projects are hardly as large and complicated as an airliner (both technically and in terms of management), and have slightly less unforeseen risks from the real world.

Still, most IT projects are slow and late, and adding more developers to the project is not a solution (going from a team of ten developers to two thousand will sometimes make it possible to deliver the project faster, sometimes not, and sometimes will only harm the project and increase the risk of not finishing it at all).

Those which are still delivered may often contain a lot of bugs, requiring consecutive service packs and regular updates (imagine "installing updates" on every Airbus A380 twice a week to patch the bugs in the original product to prevent the aircraft from crashing).

How can such differences be explained? Is it due exclusively to the fact that the software development industry is too young to be able to manage thousands of people on a single project in order to deliver large scale, nearly faultless products very fast?

答:
To point out some figures:

Change of requirements after implementation started; for example when the first Airbus A380 started to be created in the factory I cannot believe that if someone wanted 200 more seats, those would be put there; but in a large software project even after the programmers started development 5 more types of users can be added.

Complexity - large software projects are extremely complex; probably the most complex projects human kind designed and developed;

Not enough resources are spent in architecture and design phase;

Field immaturity - software engineering is relatively a young discipline compared
with other engineering sisters; this has two implications:
a) Not so many heuristics and good practices;
b) Not so many very-experienced specialists;

Lack of mathematical proof - in most of the cases mathematical formal methods are not used to prove that a piece of software works as required; instead testing is used. This does hold true in other engineering fields which rely more heavily on mathematics;  the reason of this is as complexity;

Rush - many managers have unachievable deadlines; so quality of code is placed second, because of the deadline.

Answering strictly to the question - I tend to believe that others have very high expectations (especially in delivery time) from programmers and do not understand exactly how difficult programming large software is.

ContentLicense: CC BY-SA 4.0

ContentLicense: CC BY-SA 3.0


问:
Distributed application using RabbitMQ
I am on my way to create an application with 4 bounded context using CQRS & event sourcing.

In order to make these bounded context talk to each other I was planning on using Rabbit MQ.

My requisites are the following :

The bounded context must not know about each other

The bounded context must not be hindered if the other bounded context are down or if rabbitMQ is down

If a bounded context is not available the messages, that it should receive, must wait patiently for its return ie : every event published must be forwarded at least once to all the bc interested.

Therefore, I was thinking about having each of them referencing a queue : BandMasterQueue
and creates it if it is not.

When producing an event, the event store stores it and its dispatch consists of two steps :

project on itself this event to every little projection. Each projection has a little tiny store of events already projected to warrant  idempotency over some period of time.

publish this event to the queue BandMasterQueue

if it would fail on step 2 because of no rabbitmq available, then I expect my event store to try again to dispatch the message to the RabbitMQ after sometime (not really though precisely about this part, I must say...)

The bandMaster "bounded context" knows about every different BCs he looks after. He is the one reading the bandMasterQueue and decides which events are public and which are not.
He is also responsible to handle the "sagas" and can send corrective actions to each bc.

In order to do that, he will comunicate with each bounded context using the dedicated queue of the bounded context and creates it if it does not exits.

Each BC is bound to this specific queue, and add the event coming from outside in its own event store, and afterwards project it to its own projection.

Should this "architecture" work or do you see any major flaw in it?

答:
Have a look at ZeroMQs documentation, especially the guide. I think you'd want something along the lines of their Figure 19 - Extended Request-reply. if not, there's a LOT of documentation there that should give you what you need in some combination.

I'm not sure what you mean in point 3, but the rest looks like it needs a disconnected message passing architecture - you fire messages at the network, and if a BC is up and listening, then it will receive the message to process.

If you need to send a message to a BC that is down, then you need a broker that reads them and waits for the BC to start whereupon it will send them to it - however, that means the broker needs to know about the BCs, in order to know whether to store messages for one.

Title: Distributed application using RabbitMQ


问:
What do you need to do when mentoring a new graduate?
Well I have been THE junior developer in a small team for several years. Now, there is a new fresh graduate so I have become the not-so-junior-developer and have been asked to mentor him.

But I have no idea what to do since I have always been kind of a "figure-things-out-on-my-own" person and didn't receive much mentoring.

So, what do you need to do when mentoring a new graduate?

答:
A lot of these items are similar for anyone new to the team, not just a new college graduate.

Introduce the new team member to your team's:

code versioning system

code style standards

work item / defect tracking systems

general project layout and structure

SDLC approach and documentation

system documentation (whatever it may be)

other members, and give an overview of their knowledge domains

Help them get their workstation setup and configured with the standard packages that your team uses.  Help them pull down a copy of the source that they may be working on.

Set up some times to meet every other day for a few weeks and then start spacing out those meetings.  The idea is to help them get up to speed with their assignments and point them in the right direction.

During those meetings go over the things that are necessary for team development but don't get emphasized as much in college.  Adherence to code standards (and why); documentation of design; updates within your work item tracking system; etc..

At a very broad level, think of the basic things you need on a day to day basis and help them get started with those.  Then follow through and make sure that you help show the way as the particulars come up with their first assignments.


答:
You are probably looking for Onboarding process in software development companies.

We have onboarding  process and buddy assignment in our company to welcome a new employee.  I think it is very important to address any questions and provide new employee with company culture, regulation information.

My best experience with new grade students is to have them work side by side with a stronger developer who is welcome to share (a bit talkative and friendly) his experience. Some people have a harder time learning on their own. I guess this is called mentoring....

It is also true that success of your onboarding process will be reflected on new employee's productivity and project's success in long run.

We also have a SharePoint wiki page for each project that new person may use to get information on project(s) and related documentation (after given access permissions of course).

To improve onboarding process the HR personal generally conducts a survey to get feedback from new employee after there first day or week.

Title: What do you need to do when mentoring a new graduate?

Body:
Well I have been THE junior developer in a small team for several years. Now, there is a new fresh graduate so I have become the not-so-junior-developer and have been asked to mentor him.

But I have no idea what to do since I have always been kind of a "figure-things-out-on-my-own" person and didn't receive much mentoring.

So, what do you need to do when mentoring a new graduate?


问:
How stable is Common LISP as a language?
I have been reading a bit about Common Lisp and I am considering trying to learn it (I only know very basic concepts) or even using it for some project.

Question: how stable is Common Lisp as a language? What I mean is, regardless of new libraries, are new language features (involving new syntax and semantics) being added to the language? In other words, if I learn Common Lisp now, would I be able to use the same language in 10 years from now, or read code that was written 10, 20 years ago (apart, of course, from having to get familiar with different libraries and API's)?

答:
There is the ANSI Common Lisp standard and the Common Lisp Hyperspec. It's generally reasonable to assume that standardised languages will stay relatively stable and that most new language additions will be consistent with the standard / not break existing code.

Of course, one of the powers of Lisp is that you can extend the language almost arbitrarily, so there's quite a possibility that some new libraries or DSLs will look completely different from any other previous Lisp code. That's just a danger of the meta-programming territory.  But the core language itself is likely to stay pretty stable.

If you are interested in Lisps in general as opposed to Common Lisp specifically, I'd also recommend you check out Clojure (a modern, pragmatic, functional Lisp) and Scheme (a very clean, elegant Lisp ideal for learning).


答:
Ed Yourdon's Death March touches upon a number of these meta type questions.

In general, the software industry lacks a lot of the following, which gets in the way of large projects.

Standardization and work item breakdown.

This has certainly gotten better, but the design constructs still aren't there to break out a big system. In some ways, software can't even agree on what's needed for a given project, much less being able to break things down into components.

Aerospace, building construction, auto, etc.. all have very component-driven architectures with reasonably tight interfaces to allow fully parallel development. Software still allows too much bleed through in the corresponding areas.

A large body of successful, similar projects. The A380 wasn't the first big airplane that Airbus built. There are a lot of large software applications out there, but many of them have suffered dramatically in some aspect or the other and wouldn't come close to being called "successful."

A large body of designers and builders who have worked on a number of similar and successful projects. Related to the successful project issue, not having the human talent who has been there, done that makes things very difficult from a repeatability point of view.

"Never" building the same thing twice. In many ways, an airplane is like any other airplane. It's got wings, engines, seats, etc.. Large software projects rarely repeat themselves. Each OS kernel is significantly different. Look at the disparity in file systems. And for that matter, how many truly unique OSs are there? The big ones become clones of a base item at some point. AIX, Solaris, HP-UX, ... herald back to AT&T System V. Windows has had an incredible amount of drag forward through each iteration. Linux variants generally all go back to the same core that Linus started. I bring it up, because the variants tend to propagate faster than the truly unique, proprietary OSs.

Really bad project estimation. Since the repeatability factor is so low, it's difficult to project how large it will end up being and how long something will take to build. Given that project managers and Management can't put their hands on the code and actually see what is being done, unrealistic expectations regarding timelines get generated.

QA / QC is not emphasized as heavily as it could or should be for larger projects. This goes back to having looser interfaces between components, and not having rigid specifications for how components should work. That looseness allows for unintended consequences and for bugs to creep in.

Consistently measurable qualifications. Generally, people speak of the number of years they've worked in X language or in programming. Time in is being used as a substitute for caliber or quality of skill. As has been mentioned many times before, interviewing and finding good programming talent is hard. Part of the problem is that the definition of "good" remains very subjective.

I don't mean to be all negative, and I think the software industry has made significant strides from where we've been. Forums like this and others have really helped promote conversation and discussion of design principles. There are organizations working to standardize on "baseline" knowledge for software engineers. There is certainly room for improvement, but I think the industry has come a long way in a reasonably short period of time.

Title: Why can't the IT industry deliver large, faultless projects quickly as in other industries?

Body:
After watching National Geographic's MegaStructures series, I was surprised how fast large projects are completed. Once the preliminary work (design, specifications, etc.) is done on paper, the realization itself of huge projects takes just a few years or sometimes a few months.

For example, Airbus A380 "formally launched on Dec. 19, 2000", and "in the Early March, 2005", the aircraft was already tested. The same goes for huge oil tankers, skyscrapers, etc.

Comparing this to the delays in the software industry, I can't help wondering why most IT projects are so slow, or more precisely, why they cannot be as fast and faultless, at the same scale, given enough people?

Projects such as the Airbus A380 present both:

Major unforeseen risks: while this is not the first aircraft built, it still pushes the limits of the technology and things which worked well for smaller airliners may not work for the larger one due to physical constraints; in the same way, new technologies are used which were not used before, because for example they were not available in 1969 when the Boeing 747 was certified.

Risks related to human resources and management in general: people quitting in the middle of the project, inability to reach a person because she's on vacation, ordinary human errors, etc.

With those risks, people still achieve projects like those large airliners in a very short period of time, and despite the delivery delays, those projects are still hugely successful and of a high quality.

When it comes to software development, the projects are hardly as large and complicated as an airliner (both technically and in terms of management), and have slightly less unforeseen risks from the real world.

Still, most IT projects are slow and late, and adding more developers to the project is not a solution (going from a team of ten developers to two thousand will sometimes make it possible to deliver the project faster, sometimes not, and sometimes will only harm the project and increase the risk of not finishing it at all).

Those which are still delivered may often contain a lot of bugs, requiring consecutive service packs and regular updates (imagine "installing updates" on every Airbus A380 twice a week to patch the bugs in the original product to prevent the aircraft from crashing).

How can such differences be explained? Is it due exclusively to the fact that the software development industry is too young to be able to manage thousands of people on a single project in order to deliver large scale, nearly faultless products very fast?


问:
How to avoid typo errors, etc?
For the first time I have been coding for an open-source software where all my work gets reviewed before being commited. I understand reviewing work isn't an easy task, so I don't like to waste reviewers' time and effort. But many times I make silly typo errors and errors of other kind while making a change in the code.

For example, the last time when I refactored some old code I moved code from one class to another, but forgot to check that $this only worked in the old class and needed to be changed now.

I do run unit tests, but sometime they miss these errors (we have incomplete test coverage right now). And I agree that many times I am in a hurry to submit the change only to get the work done faster.

But, besides wasting reviewers' time, this actually slows down the development process and reduces my credibility (small errors may even hide praise for good work).

What's the best way to avoid such a scenario or, in other words, how can I review my own code before someone else does?

Edit: I use Notepad++ for PHP, please don't ask me to change the IDE right-away; however, suggestions are welcome if they are persuasive ;)

答:
Find someone who can review your code without embarrassing you.

One of your problems is that you feel you're losing face when the whole project reviews your code and finds errors.  Perhaps there's someone either in the project or not who you can pair up with to look at your code.  Screenshares, screencasts, patches, work on another branch, etc., any of those methods can be used to share the code before the rest of the project team get to see it.

In return of course, you should offer the same or some other service to that person, e.g., if you double as an artist you could provide icons or whatever they need.

Make sure a past mistake can't happen again

This is easier in a typed language, but if you find that you occasionally write $thsi instead of $this, for instance, enable your editor's spell-checker.  If it's something more involved, try to write a test case that catches it.

For instance, a couple of times I made mistakes editing property files used for internationalisation so that there was no English value for some keys.  I fixed the files and then wrote a test that loaded up all keys in one go and failed if any were missing.

Invest in better tooling/languages

If there's a better editor than the one you're using, use it.  If there's a better language than the one you're using, use it.  Of course, 'better' depends on various factors, one of which is the code that you already have in the project.  If the target language is really quite bad then you could even generate code from a better language.  There are things you lose by doing that but it's good to be aware of that option.  In practice I've only had to do that once, when given some requirements for some very repetitive Java code that had to be fully documented.  I generated 3000 lines of Java code from 50 lines of another language.

Title: How to avoid typo errors, etc?


答:
The premise of the question is a bit flawed.  Both the A380 and the Boeing 787 were delivered years late.

In the case of the A380 much of the delay was caused by the French and German units of Airbus using different and slightly incompatible versions of CATIA design software. This incompatibly manifested itself as wiring harnesses that didn't quite fit the airplane.

There wasn't anything wrong with CATIA, which is the most widely used aircraft design software, but someone somewhere dropped the software configuration ball.

The Boeing 787 also suffered from software related delays, but most of its problems were more traditional new airplane problems like weight control and delivery of substandard parts by suppliers.

Both the A380 and the B787 had to modify their wing designs after the initial aircraft had structural issues.

Large complex projects are difficult for humans in all fields.


答:
Then how long did the design of those took? Year? Two? Ten years? The design is the most complex part of building something, the construction itself is easy.

Based on this article, it is slowly being understood, that software development is mostly design process where design document is the source code itself. And the design process is totally different from the production process. It requires experienced people and is impossible to plan, because even small requirement changes can result in huge changes in the overall architecture of the project. This understanding is the basis for agile methodologies that focus on improving code quality as the final design document and taking testing and debugging as parts of the design process, just like they test airplane models in wind tunnels.

The construction itself is handled automatically by compilers. And thanks to that, we are able to build whole products in a matter of minutes.

The reason why software projects are finished with huge delays and inflated costs is because managers still think they can estimate, predict and plan such a design process. This backfires more often than it is actually valid. They still think that by tying people into a rigid construction process they can somehow increase quality even though end result is mostly opposite with increased costs and missed deadlines.


答:
The answer is surprisingly simple: those 'other industries' do have a high failure rate.  We're just comparing the wrong things.  Writing software is often called 'build', and so we compare it to the manufacturing or construction phases in other industries.  But if you look at it, it's not construction at all: it's design.  Software designs are written in code, and building is done by computers, whether by compiling software or directly interpreting it on the fly.

Many designs in other industries either take way longer than originally estimated, cost way more, or simply never see completion.  Sound familiar?

So, what are we doing when we're planning software?  Well, we're still designing, but at an earlier stage.

In software, there's no manufacturing line of note.  Building the final component is (comparatively) cheap, and replication of that final product is both perfect and effectively free--you copy the build artifacts.


答:
I have often wondered the same thing. It certainly feels (occassionally) like we're a bunch of amateurs that don't have any idea what we're doing. I dislike explanations that put the blame on managers or other external factors -- we the developers should be responsible for what we create.

I think we are in a business where errors are cheap. Patching software is cheap, compared to rebuilding a skyscraper, or recalling every sold cellphone.

This has created a culture where bugs are a part of everyday life. They are accepted with a shrug. While some bugs are probably unavoidable, should they dominate our day to day work? I completely understand managers who don't feel that QA is worth the trouble, precisely because they expect bugs anyway. I don't understand programmers who don't make every effort to produce error-free code, because correcting bugs is boring as hell.

In essence I believe it is a culture problem, and I hope it will change.


问:
Confusion regarding def function within Python
I've been learning Python for about 2 months now (Started with Learn Python The Hard Way, now reading Dive Into Python), and within both books, I still seem to be confused over this one bit of code.

Lets just take the default code that Dive Into Python uses as an example:

```<code>def buildConnectionString(params):
    """Build a connection string from a dictionary of parameters.

    Returns string."""
    return ";".join(["%s=%s" % (k, v) for k, v in params.items()])

if __name__ == "__main__":
    myParams = {"server":"mpilgrim",
                "database":"master",
                "uid":"sa",
                "pwd":"secret"
               }

print buildConnectionString(myParams)
</code>```

How does the function buildConnectionString with the argument (params) know to get its data from the variable myParams?  Or params.items(), too within the return line?  Wouldn't the argument in buildConnectionString need to be set as buildConnectionString(myParams) in order for it to read properly?  How can you set the variable of your data to myParams, but have the argument of your function be params and have it read?  How does it know to read myParams as params?

And is there a reason behind not naming your variable params, or vice versa naming your argument in your function myParams?  It's just been extremely confusing seeing the argument set as one word, and then having the variable named something completely different, but having the function still be able to read your code, even when the argument name is different from your variable with the data you're printing from.

答:
You need to read this for a complete understanding of how functions and their parameters work in python: http://docs.python.org/tutorial/controlflow.html#defining-functions

A simple explanation is that the python interpreter matches the first parameter in your function call to the first value in the function definition, the second to the second and so on if the parameters in the function call are not named.

In your example, when you do print buildConnectionString(myParams) as you have done, python assumes you meant print buildConnectionString(params=myParams) which is a fair assumption to make. The value of params can be anything you like but if you mess up the parameter name itself, you will get an error.

This will not give you an error: print buildConnectionString(params=whateveryouwant)

But this will give you an error: print buildConnectionString(wrongparametername=myParams)


问:
How to avoid the pitfalls of static analysis
I'm working at a company that would score 11 on Joel Test - at least on paper.

In practice, however, nothing works quite as well as expected, and the project has been on DEFCON 1 for half a year. Now, most of my peers are happy if they can go back home at 6pm - on Sunday.

One of the apparently good practices that struck me as not working is the use of static analysis tools. The project both tracks gcc -Wall warnings and a proprietary and very expensive "C/C++" tool.

Gcc warnings do more often than not point to real(if most of the time inoffensive) bugs.

The proprietary tools, however, list things such as implicit casts and sizeof'ing a string literal. Implicit casts are also blacklisted on their stylebook.

The standard practice is that people is pressed to make every single warning shut up. Note that this does exclude warnings that are predominantly false positives, this is not the problem.

The result is:

People add type casts to every rvalue and to every argument hiding real problematic type mismatches in the process.

People introduce off by one bugs, or use a different problematic language feature.(strlen instead of sizeof, strncpy instead of strcpy, etc.)

The warnings are silenced.

The bug reports start rolling in.

The main point is the original code was working and written by people who were playing safe within their language abilities whereas the fixes were not.

Now, I don't really think this company can be saved. However, I would like to know if there is a better, preferably working, way to use the "pro" tools or if I should just avoid using them altogether in case I am the one making the decision in the future.

A solution which doesn't assume all programmers are geniuses that can't err. Because well, if they are, then there is no need to use the tools in the first place.

答:
As stated in k.steff's answer, static analysis tools for 'C' are useful if you are building software in critical situation (airplane software) and they must be used from day one (not after months of development when a un-reproducible bug occurs).

Using these kinds of tools late in the development process is usually a sign of bad design choices early in the process.

In non-critical software, these kinds of tools are useful to:

-reassure management, make them feel useful (we have done something, we have spent a lot of money to fix the software). It gives them actions that are easy to fulfill in their powerpoint reportings).

-Keep the 'toxic' developers busy. Let them configure the tool and analyze the tool results, so that you can have time to fix their nasty bugs.

-enforce coding rules. In that case it must be used from day one. But a good code review tool may be better choice.

So my opinion is you must avoid these kinds of expensive, time-consuming tools or use them to keep the 'toxic' people busy.


问:
why is a naturally ordered set generated at 9 but not 10 digits
code found at: https://softwareengineering.stackexchange.com/q/158606/44933

Presuming that the problem indicated above is due to the test app and not due specifically to method generateRandomDigits().

When NUMBER_OF_DIGITS_TO_ORDER is <= 9, I do get a naturally ordered sets (just trying to prove that it is possible), but when it is set to 10 I never get such a set and I've run it many times. Why?

I am more than open to suggested improvements to method generateRandomDigits() - it seems a bit convoluted.

答:
The real solution is to comment your code even when it is a toy. I dug this out of the cellar (the random number method) and forgot I was taking advantage of the default value of char and the behavior of a for-loop in the i < whatever when whatever is 0.

As for the code solution, I think the comments I added explain the solution:

```<code>package numgen;

import java.text.DecimalFormat;
import java.text.Format;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.text.NumberFormatter;

public class NumGen {

private static char[] naturalOrderedNums = null;

//change value as desired for any given run
private static final int NUMBER_OF_DIGITS_TO_ORDER = 10;//must be <= 10

//change value as desired for any given run
private static final int TRIALS = 10;

//???????
//should create a number of arrays that allows for each
//possible permutation - hence: 3628800
//???????
//since 10 is max number of digits, 10! will suffice for all <= 10
private static final int NUMBER_OF_CHAR_ARRAYS = 3628800;// 10! = 3628800

private static int attempts = NUMBER_OF_CHAR_ARRAYS * TRIALS;

private static int totalHits = 0;

private static double totalPercentSuccess = 0;

//i already know it is within 8 decimal places, so good enough
private static DecimalFormat df = new DecimalFormat("#.########");

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    loadNaturalOrderedArray();
    double trialPercentSuccess;
    for (int i = 0; i < TRIALS; i++) {
        int trialHits = 0;
        ArrayList<char[]> listOfArrays = new ArrayList<>(NUMBER_OF_CHAR_ARRAYS);
        for (int j = 0; j < NUMBER_OF_CHAR_ARRAYS; j++) {
            listOfArrays.add(j, generateRandomDigits());
        }
        for (int j = 0; j < NUMBER_OF_CHAR_ARRAYS; j++) {
            char[] current = listOfArrays.get(j);
            if (isNaturalOrdered(current)) {
//                    printNaturalOrdered(current);//used only for debug - just want to see it sometimes
                totalHits++;
                trialHits++;
            }
            }
        trialPercentSuccess = ((double) trialHits / (double) NUMBER_OF_CHAR_ARRAYS) * 100;
        System.out.println("trialHits = " + trialHits);
        System.out.println("trialPercentSuccess = " + df.format(trialPercentSuccess));

        System.out.println("trial " + i + " is done");
        System.out.println("--------------------------------\n");
    }
    totalPercentSuccess = ((double) totalHits / (double) attempts) * 100;
    System.out.println("totalHits = " + totalHits);
    double hitsPerTrial = (double) totalHits / (double) TRIALS;
    System.out.println("hitsPerTrial = " + hitsPerTrial);
    System.out.println("totalPercentSuccess = " + df.format(totalPercentSuccess));
    System.out.println("DONE");
}

private static void loadNaturalOrderedArray() {
    naturalOrderedNums = new char[NUMBER_OF_DIGITS_TO_ORDER];
    for (int i = 0; i < NUMBER_OF_DIGITS_TO_ORDER; i++) {
        naturalOrderedNums[i] = Integer.toString(i).charAt(0);
    }
}

private static boolean areEqual(char[] current, char[] other) {
    int targetSize = NUMBER_OF_DIGITS_TO_ORDER;
    boolean areEqual = true;
    for (int i = 0; i < targetSize; i++) {
        if (current[i] != other[i]) {
            areEqual = false;
            break;
        }
    }
    return areEqual;
}

private static void printNaturalOrdered(char[] current) {
    int size = current.length;
    for (int j = 0; j < size; j++) {
        System.out.print(current[j] + " ");
    }
    System.out.println("----------------------------- is natural ordered\n");
}

private static boolean isNaturalOrdered(char[] current) {
    return areEqual(current, naturalOrderedNums);
}

private static char[] generateRandomDigits() {
    int targetSize = NUMBER_OF_DIGITS_TO_ORDER;
    int targetSizeMinusOne = targetSize - 1;
    StringBuilder sb = new StringBuilder(targetSize);
    Random random = new Random();
    char[] chars;
    boolean isUnique;
    while (sb.length() < targetSize) {
        //random.nextInt() WILL NEVER GIVE A NUMBER BEGINING WITH 0
        chars = Integer.toString(Math.abs(random.nextInt())).toCharArray();
        int numberOfChars = chars.length;
        //BY STARTING WITH i = 1 INSTEAD OF i = 0, THE FIRST CHAR IS ALWAYS THROWN OUT
        //THAT MATTERS SINCE, AS NOTED ABOVE: //random.nextInt() WILL NEVER GIVE A NUMBER BEGINING WITH 0
        for (int i = 1; i < numberOfChars; i++) {//WAS i = 0
            int currentValueOfChar = Integer.parseInt(String.valueOf(chars[i]));
            if (currentValueOfChar > targetSizeMinusOne) {//WILL ALWAYS FAIL WHEN NUMBER_OF_DIGITS_TO_ORDER = 10
                continue;
            }
            isUnique = true;
            for (int j = 0; j < sb.length(); j++) {
                if (sb.charAt(j) == chars[i]) {
                    isUnique = false;
                    break;
                }
            }
            if (isUnique && sb.length() < targetSize) {
                sb.append(chars[i]);
            }
        }
    }
    char[] randomNums = new char[targetSize];
    for (int i = 0; i < targetSize; i++) {
        randomNums[i] = sb.charAt(i);
    }
    return randomNums;
}
</code>```

Now, I get ordered nums, on occasion.

edit:

Put whole app in instead of just method. Now has logging as per gnat. Hits are higher than I expected but good enough for now. Incidentally, I've run it many times and I no longer get the error noted in link above; don't have a clue what caused the change.

```<code>package numgen;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Random;

public class NumGen {

    private static char[] naturalOrderedNums = null;

    //change value as desired for any given run
    //reasonably quick results at <= 8
    private static final int NUMBER_OF_DIGITS_TO_ORDER = 8;//must be: 0 >= NUMBER_OF_DIGITS_TO_ORDER <= 10

    //change value as desired for any given run
    private static final int TRIALS = 2;

    private static int numberOfCharArrays;

    private static int attempts;

    private static int totalHits = 0;

    private static double totalPercentSuccess = 0;

    private static ArrayList<char[]> listOfArrays = null;

    //i already know it is within 8 decimal places, so good enough
    private static DecimalFormat df = new DecimalFormat("#.########");

    private static ArrayList<DuplicateSequence> dupSequenceList = new ArrayList<>();

    /**
    * @param args the command line arguments
    */
    public static void main(String[] args) {
        init();
        runTrials();
        printNaturalOrderSummaryData();
    }

    private static void init() {
        loadNaturalOrderedArray();
        calculateNumberOfCharArrays();
        calculateAttempts();
    }

    private static void runTrials() {
        for (int i = 0; i < TRIALS; i++) {
            loadListOfArrays();
            testForNaturalOrder(i);
            testForDuplication();
        }
    }

    private static void printNaturalOrderSummaryData() {
        totalPercentSuccess = ((double) totalHits / (double) attempts) * 100;
        System.out.println("----------------------------------------------------------");
        System.out.println("\nDATA FOR OCCURANCE OF NATURAL ORDERING ACROSS ALL TRIALS:\n");
        System.out.println("\ttotalHits = " + totalHits);
        double hitsPerTrial = (double) totalHits / (double) TRIALS;
        System.out.println("\thitsPerTrial = " + hitsPerTrial);
        System.out.println("\ttotalPercentSuccess = " + df.format(totalPercentSuccess));
        System.out.println("\n\n>>>>>>>>>>>>>>>>>>>>>>>>>> DONE <<<<<<<<<<<<<<<<<<<<<<<<<<");
    }

    private static void loadListOfArrays() {
        listOfArrays = new ArrayList<>(numberOfCharArrays);
        for (int j = 0; j < numberOfCharArrays; j++) {
            listOfArrays.add(j, generateRandomDigits());
        }
    }

    private static void calculateNumberOfCharArrays() {
        int value = 1;
        for (int i = 2; i < (NUMBER_OF_DIGITS_TO_ORDER + 1); i++) {
            value *= i;
        }
        numberOfCharArrays = value;
    }

    private static void calculateAttempts() {
        attempts = numberOfCharArrays * TRIALS;
    }

    private static void testForNaturalOrder(int trialNum) {
        int trialHits = 0;
        double trialPercentSuccess;
        for (int j = 0; j < numberOfCharArrays; j++) {
            char[] current = listOfArrays.get(j);
            if (isNaturalOrdered(current)) {
                totalHits++;
                trialHits++;
            }
        }
        trialPercentSuccess = ((double) trialHits / (double) numberOfCharArrays) * 100;
        System.out.println("----------------------------------------------------------\tTrial " + trialNum + " is done");
        System.out.println("\nTRIAL OCCURANCES OF NATURAL ORDERING:\n");
        System.out.println("\ttrialHits = " + trialHits);
        System.out.println("\ttrialPercentSuccess = " + df.format(trialPercentSuccess));
    }

    private static void updateDupSequenceList(char[] current) {
        int size = dupSequenceList.size();
        boolean isListed = false;
        DuplicateSequence currentDupSeq;
        for (int j = 0; j < size; j++) {
            currentDupSeq = dupSequenceList.get(j);
            char[] dupSeqArray = currentDupSeq.getSequence();
            if (areEqual(current, dupSeqArray)) {
                isListed = true;
                currentDupSeq.incrementCount();
                break;
            }
        }
        if (!isListed) {
            dupSequenceList.add(new DuplicateSequence(current));
        }
    }

    private static void testForDuplication() {
        //create copy because of copy.remove(j); below
        @SuppressWarnings("unchecked")
        ArrayList<char[]> copy = (ArrayList<char[]>) listOfArrays.clone();
        //(copy.size() - 1) because the last item has nothing after it to compare to
        for (int i = 0; i < (copy.size() - 1); i++) {
            char[] current = copy.get(i);

            //j = (i + 1) because j = i or j = 0 would test the current against itself
            for (int j = (i + 1); j < copy.size(); j++) {
                char[] other = copy.get(j);
                if (areEqual(current, other)) {
                    updateDupSequenceList(current);
                    copy.remove(j);//speeds things up - why let it become item at i and check it again?

                    //j-- because copy.remove(j) shifts items, then next unchecked item is now at current j
                    //and would not be checked without decrement.
                    j--;
                }
            }
        }
        System.out.println("\n\nTRIAL DUPLICATION DATA:");
        int totalInstancesOfduplicateNumbers = 0;
        int numberOfSequencesWithDuplicates = dupSequenceList.size();
        System.out.println("");

        for (int i = 0; i < numberOfSequencesWithDuplicates; i++) {
            totalInstancesOfduplicateNumbers += dupSequenceList.get(i).getCount();
            //System.out.println("\tsequence = " + String.valueOf(dupSequenceList.get(i).getSequence()));
            //System.out.println("\tduplicate count for this sequence = " + dupSequenceList.get(i).getCount());
            //System.out.println("\t-------------------------------------\n");
        }
        System.out.println("\tnumberOfSequencesWithDuplicates = " + numberOfSequencesWithDuplicates);

        //because count in DuplicateSequence is the count of duplicates of a given sequence
        //and does not count the original/reference sequence occurance itself
        totalInstancesOfduplicateNumbers += numberOfSequencesWithDuplicates;
        System.out.println("\ttotalInstancesOfduplicateNumbers = " + totalInstancesOfduplicateNumbers);
        //note: duplications seem high
        double percentDuplication = ((double) totalInstancesOfduplicateNumbers / (double) attempts) * 100;
        System.out.println("\tpercentDuplication = " + new DecimalFormat("#.##").format(percentDuplication));
        System.out.println("\n\n");

    }

    private static void loadNaturalOrderedArray() {
        naturalOrderedNums = new char[NUMBER_OF_DIGITS_TO_ORDER];
        for (int i = 0; i < NUMBER_OF_DIGITS_TO_ORDER; i++) {
            naturalOrderedNums[i] = Integer.toString(i).charAt(0);
        }
    }

    private static boolean areEqual(char[] current, char[] other) {
        int targetSize = NUMBER_OF_DIGITS_TO_ORDER;
        boolean areEqual = true;
        for (int i = 0; i < targetSize; i++) {
            if (current[i] != other[i]) {
                areEqual = false;
                break;
            }
        }
        return areEqual;
    }

    private static void printNaturalOrdered(char[] current) {
        int size = current.length;
        for (int j = 0; j < size; j++) {
            System.out.print(current[j] + " ");
        }
        System.out.println("----------------------------- is natural ordered\n");
    }

    private static boolean isNaturalOrdered(char[] current) {
        return areEqual(current, naturalOrderedNums);
    }

    private static char[] generateRandomDigits() {
        int targetSize = NUMBER_OF_DIGITS_TO_ORDER;
        int targetSizeMinusOne = targetSize - 1;
        StringBuilder sb = new StringBuilder(targetSize);
        Random random = new Random();
        char[] chars;
        boolean isUnique;
        while (sb.length() < targetSize) {
            //random.nextInt() WILL NEVER GIVE A NUMBER BEGINNING WITH 0
            //BUT IT WILL RETURN A SINGLE DIGIT AND IT CAN BE 0
            chars = Integer.toString(Math.abs(random.nextInt())).toCharArray();
            int numberOfChars = chars.length;

            char currentChar;
            //random.nextInt() SOMETIMES RETURNS A SINGLE DIGIT AND IT CAN BE 0
            //IN THAT CASE, chars[1] WOULD FAIL
            if (numberOfChars == 1) {
                currentChar = chars[0];
            } else {
                currentChar = chars[1];
            }
            int currentValueOfChar = Integer.parseInt(String.valueOf(currentChar));
            if (currentValueOfChar > targetSizeMinusOne) {//WILL ALWAYS FAIL WHEN NUMBER_OF_DIGITS_TO_ORDER = 10
                continue;
            }
            isUnique = true;
            for (int j = 0; j < sb.length(); j++) {
                if (sb.charAt(j) == currentChar) {
                    isUnique = false;
                    break;
                }
            }
            if (isUnique && sb.length() < targetSize) {
                sb.append(currentValueOfChar);
            }
        }
        char[] randomNums = new char[targetSize];
        for (int i = 0; i < targetSize; i++) {
            randomNums[i] = sb.charAt(i);
        }
        return randomNums;
    }
}

class DuplicateSequence {

    private char[] sequence = null;

    /**
    * @return the sequence
    */
    public char[] getSequence() {
        return sequence.clone();
    }

    //the number of duplications, not total occurances.
    //if one duplicate is found, count is 1 but total
    //occurances is 2. Basically total = count + 1,
    // (duplicates + referenced sequence).
    private int count = 0;

    /**
    * @return the count
    */
    public int getCount() {
        return count;
    }

    public DuplicateSequence(char[] sequence) {
        this.sequence = sequence;
        this.count = 1;
    }

    public void incrementCount() {
        this.count++;
    }
}
</code>```

Body:
The real solution is to comment your code even when it is a toy. I dug this out of the cellar (the random number method) and forgot I was taking advantage of the default value of char and the behavior of a for-loop in the i < whatever when whatever is 0.

As for the code solution, I think the comments I added explain the solution:

package numgen;

import java.text.DecimalFormat;
import java.text.Format;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.text.NumberFormatter;

public class NumGen {

private static char[] naturalOrderedNums = null;

//change value as desired for any given run
private static final int NUMBER_OF_DIGITS_TO_ORDER = 10;//must be <= 10

//change value as desired for any given run
private static final int TRIALS = 10;

//???????
//should create a number of arrays that allows for each
//possible permutation - hence: 3628800
//???????
//since 10 is max number of digits, 10! will suffice for all <= 10
private static final int NUMBER_OF_CHAR_ARRAYS = 3628800;// 10! = 3628800

private static int attempts = NUMBER_OF_CHAR_ARRAYS * TRIALS;

private static int totalHits = 0;

private static double totalPercentSuccess = 0;

//i already know it is within 8 decimal places, so good enough
private static DecimalFormat df = new DecimalFormat("#.########");

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    loadNaturalOrderedArray();
    double trialPercentSuccess;
    for (int i = 0; i < TRIALS; i++) {
        int trialHits = 0;
        ArrayList<char[]> listOfArrays = new ArrayList<>(NUMBER_OF_CHAR_ARRAYS);
        for (int j = 0; j < NUMBER_OF_CHAR_ARRAYS; j++) {
            listOfArrays.add(j, generateRandomDigits());
        }
        for (int j = 0; j < NUMBER_OF_CHAR_ARRAYS; j++) {
            char[] current = listOfArrays.get(j);
            if (isNaturalOrdered(current)) {
//                    printNaturalOrdered(current);//used only for debug - just want to see it sometimes
                totalHits++;
                trialHits++;
            }
            }
        trialPercentSuccess = ((double) trialHits / (double) NUMBER_OF_CHAR_ARRAYS) * 100;
        System.out.println("trialHits = " + trialHits);
        System.out.println("trialPercentSuccess = " + df.format(trialPercentSuccess));

        System.out.println("trial " + i + " is done");
        System.out.println("--------------------------------\n");
    }
    totalPercentSuccess = ((double) totalHits / (double) attempts) * 100;
    System.out.println("totalHits = " + totalHits);
    double hitsPerTrial = (double) totalHits / (double) TRIALS;
    System.out.println("hitsPerTrial = " + hitsPerTrial);
    System.out.println("totalPercentSuccess = " + df.format(totalPercentSuccess));
    System.out.println("DONE");
}

private static void loadNaturalOrderedArray() {
    naturalOrderedNums = new char[NUMBER_OF_DIGITS_TO_ORDER];
    for (int i = 0; i < NUMBER_OF_DIGITS_TO_ORDER; i++) {
        naturalOrderedNums[i] = Integer.toString(i).charAt(0);
    }
}

private static boolean areEqual(char[] current, char[] other) {
    int targetSize = NUMBER_OF_DIGITS_TO_ORDER;
    boolean areEqual = true;
    for (int i = 0; i < targetSize; i++) {
        if (current[i] != other[i]) {
            areEqual = false;
            break;
        }
    }
    return areEqual;
}

private static void printNaturalOrdered(char[] current) {
    int size = current.length;
    for (int j = 0; j < size; j++) {
        System.out.print(current[j] + " ");
    }
    System.out.println("----------------------------- is natural ordered\n");
}

private static boolean isNaturalOrdered(char[] current) {
    return areEqual(current, naturalOrderedNums);
}

private static char[] generateRandomDigits() {
    int targetSize = NUMBER_OF_DIGITS_TO_ORDER;
    int targetSizeMinusOne = targetSize - 1;
    StringBuilder sb = new StringBuilder(targetSize);
    Random random = new Random();
    char[] chars;
    boolean isUnique;
    while (sb.length() < targetSize) {
        //random.nextInt() WILL NEVER GIVE A NUMBER BEGINING WITH 0
        chars = Integer.toString(Math.abs(random.nextInt())).toCharArray();
        int numberOfChars = chars.length;
        //BY STARTING WITH i = 1 INSTEAD OF i = 0, THE FIRST CHAR IS ALWAYS THROWN OUT
        //THAT MATTERS SINCE, AS NOTED ABOVE: //random.nextInt() WILL NEVER GIVE A NUMBER BEGINING WITH 0
        for (int i = 1; i < numberOfChars; i++) {//WAS i = 0
            int currentValueOfChar = Integer.parseInt(String.valueOf(chars[i]));
            if (currentValueOfChar > targetSizeMinusOne) {//WILL ALWAYS FAIL WHEN NUMBER_OF_DIGITS_TO_ORDER = 10
                continue;
            }
            isUnique = true;
            for (int j = 0; j < sb.length(); j++) {
                if (sb.charAt(j) == chars[i]) {
                    isUnique = false;
                    break;
                }
            }
            if (isUnique && sb.length() < targetSize) {
                sb.append(chars[i]);
            }
        }
    }
    char[] randomNums = new char[targetSize];
    for (int i = 0; i < targetSize; i++) {
        randomNums[i] = sb.charAt(i);
    }
    return randomNums;
}

Now, I get ordered nums, on occasion.

edit:

Put whole app in instead of just method. Now has logging as per gnat. Hits are higher than I expected but good enough for now. Incidentally, I've run it many times and I no longer get the error noted in link above; don't have a clue what caused the change.

package numgen;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Random;

public class NumGen {

    private static char[] naturalOrderedNums = null;

    //change value as desired for any given run
    //reasonably quick results at <= 8
    private static final int NUMBER_OF_DIGITS_TO_ORDER = 8;//must be: 0 >= NUMBER_OF_DIGITS_TO_ORDER <= 10

    //change value as desired for any given run
    private static final int TRIALS = 2;

    private static int numberOfCharArrays;

    private static int attempts;

    private static int totalHits = 0;

    private static double totalPercentSuccess = 0;

    private static ArrayList<char[]> listOfArrays = null;

    //i already know it is within 8 decimal places, so good enough
    private static DecimalFormat df = new DecimalFormat("#.########");

    private static ArrayList<DuplicateSequence> dupSequenceList = new ArrayList<>();

    /**
    * @param args the command line arguments
    */
    public static void main(String[] args) {
        init();
        runTrials();
        printNaturalOrderSummaryData();
    }

    private static void init() {
        loadNaturalOrderedArray();
        calculateNumberOfCharArrays();
        calculateAttempts();
    }

    private static void runTrials() {
        for (int i = 0; i < TRIALS; i++) {
            loadListOfArrays();
            testForNaturalOrder(i);
            testForDuplication();
        }
    }

    private static void printNaturalOrderSummaryData() {
        totalPercentSuccess = ((double) totalHits / (double) attempts) * 100;
        System.out.println("----------------------------------------------------------");
        System.out.println("\nDATA FOR OCCURANCE OF NATURAL ORDERING ACROSS ALL TRIALS:\n");
        System.out.println("\ttotalHits = " + totalHits);
        double hitsPerTrial = (double) totalHits / (double) TRIALS;
        System.out.println("\thitsPerTrial = " + hitsPerTrial);
        System.out.println("\ttotalPercentSuccess = " + df.format(totalPercentSuccess));
        System.out.println("\n\n>>>>>>>>>>>>>>>>>>>>>>>>>> DONE <<<<<<<<<<<<<<<<<<<<<<<<<<");
    }

    private static void loadListOfArrays() {
        listOfArrays = new ArrayList<>(numberOfCharArrays);
        for (int j = 0; j < numberOfCharArrays; j++) {
            listOfArrays.add(j, generateRandomDigits());
        }
    }

    private static void calculateNumberOfCharArrays() {
        int value = 1;
        for (int i = 2; i < (NUMBER_OF_DIGITS_TO_ORDER + 1); i++) {
            value *= i;
        }
        numberOfCharArrays = value;
    }

    private static void calculateAttempts() {
        attempts = numberOfCharArrays * TRIALS;
    }

    private static void testForNaturalOrder(int trialNum) {
        int trialHits = 0;
        double trialPercentSuccess;
        for (int j = 0; j < numberOfCharArrays; j++) {
            char[] current = listOfArrays.get(j);
            if (isNaturalOrdered(current)) {
                totalHits++;
                trialHits++;
            }
        }
        trialPercentSuccess = ((double) trialHits / (double) numberOfCharArrays) * 100;
        System.out.println("----------------------------------------------------------\tTrial " + trialNum + " is done");
        System.out.println("\nTRIAL OCCURANCES OF NATURAL ORDERING:\n");
        System.out.println("\ttrialHits = " + trialHits);
        System.out.println("\ttrialPercentSuccess = " + df.format(trialPercentSuccess));
    }

    private static void updateDupSequenceList(char[] current) {
        int size = dupSequenceList.size();
        boolean isListed = false;
        DuplicateSequence currentDupSeq;
        for (int j = 0; j < size; j++) {
            currentDupSeq = dupSequenceList.get(j);
            char[] dupSeqArray = currentDupSeq.getSequence();
            if (areEqual(current, dupSeqArray)) {
                isListed = true;
                currentDupSeq.incrementCount();
                break;
            }
        }
        if (!isListed) {
            dupSequenceList.add(new DuplicateSequence(current));
        }
    }

    private static void testForDuplication() {
        //create copy because of copy.remove(j); below
        @SuppressWarnings("unchecked")
        ArrayList<char[]> copy = (ArrayList<char[]>) listOfArrays.clone();
        //(copy.size() - 1) because the last item has nothing after it to compare to
        for (int i = 0; i < (copy.size() - 1); i++) {
            char[] current = copy.get(i);

            //j = (i + 1) because j = i or j = 0 would test the current against itself
            for (int j = (i + 1); j < copy.size(); j++) {
                char[] other = copy.get(j);
                if (areEqual(current, other)) {
                    updateDupSequenceList(current);
                    copy.remove(j);//speeds things up - why let it become item at i and check it again?

                    //j-- because copy.remove(j) shifts items, then next unchecked item is now at current j
                    //and would not be checked without decrement.
                    j--;
                }
            }
        }
        System.out.println("\n\nTRIAL DUPLICATION DATA:");
        int totalInstancesOfduplicateNumbers = 0;
        int numberOfSequencesWithDuplicates = dupSequenceList.size();
        System.out.println("");

        for (int i = 0; i < numberOfSequencesWithDuplicates; i++) {
            totalInstancesOfduplicateNumbers += dupSequenceList.get(i).getCount();
            //System.out.println("\tsequence = " + String.valueOf(dupSequenceList.get(i).getSequence()));
            //System.out.println("\tduplicate count for this sequence = " + dupSequenceList.get(i).getCount());
            //System.out.println("\t-------------------------------------\n");
        }
        System.out.println("\tnumberOfSequencesWithDuplicates = " + numberOfSequencesWithDuplicates);

        //because count in DuplicateSequence is the count of duplicates of a given sequence
        //and does not count the original/reference sequence occurance itself
        totalInstancesOfduplicateNumbers += numberOfSequencesWithDuplicates;
        System.out.println("\ttotalInstancesOfduplicateNumbers = " + totalInstancesOfduplicateNumbers);
        //note: duplications seem high
        double percentDuplication = ((double) totalInstancesOfduplicateNumbers / (double) attempts) * 100;
        System.out.println("\tpercentDuplication = " + new DecimalFormat("#.##").format(percentDuplication));
        System.out.println("\n\n");

    }

    private static void loadNaturalOrderedArray() {
        naturalOrderedNums = new char[NUMBER_OF_DIGITS_TO_ORDER];
        for (int i = 0; i < NUMBER_OF_DIGITS_TO_ORDER; i++) {
            naturalOrderedNums[i] = Integer.toString(i).charAt(0);
        }
    }

    private static boolean areEqual(char[] current, char[] other) {
        int targetSize = NUMBER_OF_DIGITS_TO_ORDER;
        boolean areEqual = true;
        for (int i = 0; i < targetSize; i++) {
            if (current[i] != other[i]) {
                areEqual = false;
                break;
            }
        }
        return areEqual;
    }

    private static void printNaturalOrdered(char[] current) {
        int size = current.length;
        for (int j = 0; j < size; j++) {
            System.out.print(current[j] + " ");
        }
        System.out.println("----------------------------- is natural ordered\n");
    }

    private static boolean isNaturalOrdered(char[] current) {
        return areEqual(current, naturalOrderedNums);
    }

    private static char[] generateRandomDigits() {
        int targetSize = NUMBER_OF_DIGITS_TO_ORDER;
        int targetSizeMinusOne = targetSize - 1;
        StringBuilder sb = new StringBuilder(targetSize);
        Random random = new Random();
        char[] chars;
        boolean isUnique;
        while (sb.length() < targetSize) {
            //random.nextInt() WILL NEVER GIVE A NUMBER BEGINNING WITH 0
            //BUT IT WILL RETURN A SINGLE DIGIT AND IT CAN BE 0
            chars = Integer.toString(Math.abs(random.nextInt())).toCharArray();
            int numberOfChars = chars.length;

            char currentChar;
            //random.nextInt() SOMETIMES RETURNS A SINGLE DIGIT AND IT CAN BE 0
            //IN THAT CASE, chars[1] WOULD FAIL
            if (numberOfChars == 1) {
                currentChar = chars[0];
            } else {
                currentChar = chars[1];
            }
            int currentValueOfChar = Integer.parseInt(String.valueOf(currentChar));
            if (currentValueOfChar > targetSizeMinusOne) {//WILL ALWAYS FAIL WHEN NUMBER_OF_DIGITS_TO_ORDER = 10
                continue;
            }
            isUnique = true;
            for (int j = 0; j < sb.length(); j++) {
                if (sb.charAt(j) == currentChar) {
                    isUnique = false;
                    break;
                }
            }
            if (isUnique && sb.length() < targetSize) {
                sb.append(currentValueOfChar);
            }
        }
        char[] randomNums = new char[targetSize];
        for (int i = 0; i < targetSize; i++) {
            randomNums[i] = sb.charAt(i);
        }
        return randomNums;
    }
}

class DuplicateSequence {

    private char[] sequence = null;

    /**
    * @return the sequence
    */
    public char[] getSequence() {
        return sequence.clone();
    }

    //the number of duplications, not total occurances.
    //if one duplicate is found, count is 1 but total
    //occurances is 2. Basically total = count + 1,
    // (duplicates + referenced sequence).
    private int count = 0;

    /**
    * @return the count
    */
    public int getCount() {
        return count;
    }

    public DuplicateSequence(char[] sequence) {
        this.sequence = sequence;
        this.count = 1;
    }

    public void incrementCount() {
        this.count++;
    }
}


答:
Large projects often occur in large organizations. If you've never worked in a large organization, there is one thing that is guaranteed to kill performance and productivity: bureaucracy.

Surprisingly, many people do not know what bureaucracy is (it is often confused with politics), or even if/when they have a bureaucracy problem.

We recently concluded a project to implement smart card authentication. It was originally estimated at three months. It took 15 months. There were not any cost, budget, scope, or technical reasons for the delay. The scope was actually quite narrow - only for accounts with elevated privileges (administrator accounts), about 1,200 total accounts.

Another significant factor is your business partners. This would include vendors. If your partners have a problem that introduces a delay in your project, there aren't many options that will actually fix the delay problem.  They don't work directly for you, and you may not be able to fire that one person at a partner that may be the cause. The partner can be fired, or can be subject to financial penalties or disincentives, but that does not change the fact that the project has incurred a delay. This is precisely what occurred with Boeing when they undertook a mammoth sourcing strategy with the Boeing 787 Dreamliner.


答:
I have a shorter version for you:

Whatever is easy to do, or streamlined, we write a program to do it instead of us.

And then fight with the meta-process instead.

It's not that much true, per se, but every day thousands of blogs are set up, instead of writing blog engines. Every workday, thousands of Excel macros are written, instead of writing specially-designed database applications for these.

There are a lot of other factors - some of them mentioned here - but I wanted to add this point to the discussion.


答:
Software engineering and management is fundamentally different than a lot of other engineering areas. The deliverables aren't physical, and the production process is the design and development process. Creating another copy of a piece of software has essentially zero marginal cost; all the cost is found in developing the first copy.

Because of the relative youth of software engineering and management as a discipline, there is some misinformation and falsehoods out that are still taken as fact (see this reference) which hinders software development and engineering as a whole.


答:
Not all developers are created equally.  Some are good, others are, well, not.

Try reading other people's code all the time to get a feel of what I'm saying.  Too many extra logic statements can add risk.  These risks can lead to ill behavior or bugs.  Not enough logic statements and now you have null references.  The good programmer understands this and knows when to do what and where.  But no one is perfect.  Things are complex.  Add the poorly thought out work of others and it is easy to see how projects run away.


答:
I would explain, both in summary and in detail, the full domain of the system

I've worked on systems where I had no idea what the system was supposed to do, and also no context for where the system fitted in with other systems. While I expect my job to involve reverse engineering, some context goes a long way to ease the process

Those were systems where the staff would expertly only reveal slightly less than the minimum amount of information to get any one particular task done (probably for their own job security)


问:
Introducing Agile development after traditional project inception
About a year and a half ago, I entered a workplace that claimed to do Agile development. What I learned was that this place has adopted several agile practices (such as daily standups, sprint plannings and sprint reviews) but none of the principles (just in time / just good enough mentality, exposing failure early, rich communication).

I've now been tasked with making the team more agile and I've been assured that I have complete buy-in from the devs and the business team. As a pilot program, they've given me a project that just completed 15 months of requirements gathering, has a 110 page Analysis & Design document (to be considered as "written in stone"), and where I have no access to the end users (only to the committee made up of the users' managers who won't actually be using the product).

I started small, giving them a list of expected deliverables for the first 5 sprints (leaving the future sprints undefined), a list of goals for the first sprint, and I dissected the A&D doc to get enough user stories to meet the first sprint's goals.

Since then, they've asked why we don't have all the requirements for all the sprints, why I haven't started working on stuff for the third sprint (which they consider more important but is based off of the deliverables of the first 2 sprints) and are pressing for even more documentation that my entire IT team considers busy-work or un-related to us (such as writing the user manual up-front, documenting all the data fields from all the sprints up front, and more "up-front" work).

This has been pretty rough for me as a new project manager, but there are improvements I have effectively implemented such as scrumban for story management, pair programming, and having the business give us customer acceptance tests up front (as part of the requirements documentation).

So my questions are:

What can I do to more effectively introduce change to a resistant
business?

Are there other practices that I can introduce on the
IT side to help show the business the benefits of agile?

The burden of documentation is strangling us - the business still sees
it as a risk management strategy instead of as a risk. What can we
do to alleviate their documentation concerns and demands
(specifically the quantity of documentation and their need for all
of it up front)?

We are in a separate building from our business, about 3 blocks away and they refuse to have their people on the project co-habitate b/c that person "won't be able to work on their other projects while they're at our building." They expect us to always go over there and to bundle our questions so that we can ask them all at once and not waste that person's time with "constant interruptions." What can we do to get richer communication from them?

Any additional advice would also be appreciated.

Thanks!

答:
Since then, they've asked why we don't have all the requirements for all the sprints, why I haven't started working on stuff for the third sprint (which they consider more important but is based off of the deliverables of the first 2 sprints) and are pressing for even more documentation that my entire IT team considers busy-work or un-related to us (such as writing the user manual up-front, documenting all the data fields from all the sprints up front, and more "up-front" work).

That's your problem. They don't get it. Someone can't ask you to be more agile and not be willing to go along for the ride. They have the wrong expectations. Things are broken, up front, before you even start. Correct the expectations or you will fail. It's like me asking you to drive 150 MPH and I give you a Chevette in which to do that.


答:
Most large projects have a high degree of separability of sub-projects, where you can define a small number of design constraints; the whole project will work when those sub-projects each are completed.  If something goes wrong in a sub-project, the whole effort is not thrown into question; you just look for alternate ways to complete the sub-project (e.g. use a different engine).

This is possible but difficult, both practically and as a matter of human nature, in software projects.

In part, other industries have learned the hard way that this sort of separability is a good thing.  For example, if you're going to use Rolls Royce aircraft engines, you do not need to use special Rolls Royce bolts and attachment points that only work with wings with a particular design, and then if you try to switch to Pratt and Whitney, you have to redesign your entire wing from the ground up (which, in turn, requires a complete redesign of the fuselage, which in turn requires you to buy different seats, which in turn requires you to buy a different in-flight entertainment system, which...).  There may be a few linkages--you can't just swap engines without a care--but big projects generally work better when such things are minimized.

I postulate that big software projects designed as a cluster of small software projects with clean interfaces between each other will not fail particularly often, as long as the big project is actually solved by the cluster of small projects.  (It is possible to make a mistake in this regard.)


答:
Building software systems is very different from building physical structures. That is, the implementation is very much different. While for example building a huge tanker, you do lots of relatively simple (not easy though!) tasks, such as welding parts together by a robot or by hand, tightening all the nuts and bolts, painting, do the decoration by carrying in all the equipment and furniture and such. All of this is very simple stuff to do, really.

However, when it comes to software, it gets much more complex. For example, how exactly do you implement the secure login and user credential storing part of the product? What libraries and tools can you use? With what libraries and tools are you familiar with? How exactly do you go about writing the hashing + salting function and how do you ensure it is secure? You can do this in so many ways that it's impossible to set any actual practical design patterns for these kind of things. Yes, the said design patterns do exist on a smaller scale as "best practices", but every single software system is very different from the others, and the field advances and changes at so rapid pace that it's essentially impossible to keep up.

When building a house, you don't really run into such problems where you realize that the main supporting walls seem to be inadequate and need to be replaced, requiring you to demolish the progress so far and start from the base by redoing the support walls. You tackle such issues at the design phase, because it's relatively simple to predict what kind of support walls your building needs.

That is not the case with software though. You can't really design the whole product as a single entity and then implement it. The software design process is usually iterative, and the goals and requirements change as the product is being implemented and tested. Software development as a whole is an iterative process in which things usually change when least expected, and many times such changes impose challenges which require more work, more complexity and unfortunately and ultimately more money, time and hard work to get right.

So, in essence, the reason why it is hard to deliver big projects and estimate project timelines and roadmaps is that software development and especially working design are very complex fields. Complexity is the root problem.


问:
Software licensing particulars
I have spent a lot of time examining the various (major) software licenses and ultimately have decided upon using the MIT Licenses for my open source projects, and the Microsoft Reference License (MS-RSL) for my proprietary projects.

Not knowing much about IP law, I have three simple questions that I haven't been able to find answers to:

At the top of each source file that I want to protect, I need to place a copy of the appropriate license (MIT/MS-RSL), yes?

If so, then in this license notice, do I have to acknowledge that I am using the MIT or MS-RSL licenses? Or is it fine to just copy-n-paste the licenses in, as-is? In other words, do I need to say: SOFTWARE LICENSE NOTICE - MIT LICENSE or can I just write SOFTWARE LICENSE NOTICE?

Is it "okay" (legally enforceable) to just place a link to a URL (where an EULA lives) instead of pasting in the same software license over and over again, at the top of every single source file? It would be nice to just have this:

// SOFTWARE LICENSE NOTICE
// This software and associated files is licensed. Please visit:
//     http://www.example.com/my-license/latest
// for full details.
```

That way, http://www.example.com/my-license/latest could always contain the latest license I want the source file(s) to be protected by. So if I switch from MIT to, say, APL, no code changes/rollouts are necessary. Is this legally-sound? Thanks in advance!

答:
You should either

include a copy of the complete license in the source file (this is easy with short licenses like BSD or MIT), or

if the license is too long for inclusion, distribute a copy of the complete license together with your source files and link to it from your source files.
See here for how to do this with the GPL.

Title: Software licensing particulars


答:
Engineering standards and practices are very different in IT (as an independent industry) than in aerospace. This is perhaps most easily understood by considering how IT professionals react when encountering standards documents for IT in aerospace. For example, the Joint Strike Fighter C++ Standards that have made their way around the Internet in recent times.

Many express bemusement or wistful resignation (wish we could do that way); and many respond with ridicule, claiming there is no practical way to deliver consumer products in this way. This may even be right, given the expectations, not of consumers, but of management. There is a great deal of distrust for coders who just code and code for a few weeks, not demoing anything. God help the coder who merely designs something for two weeks. Not so with airplanes.

In software, people really expect to have something right now. Sure, the reasoning goes, it will take a little while to have it really solid; but can't we have some complex thing described in simple terms in a week? One learns, also, that complex things described in honest, complex terms rarely excite the imagination; and thus many engineers end up being complicit in an imagined world of really simple things being put together in creative ways (as opposed to a world of hard things being done really well).


答:
Some stuff from me:

1- Standards and parts: They are plane manufacturers, not developers. I am not entirely sure, but my guess is that a lot of parts are outsourced. They don't build their own electronic/instruments, they get seats from some company, the engines are probably developed elsewhere, etc.

Software projects, on the other hand, almost always start from scratch with just some small frameworks/helpers in place.

2- Time to hit the market: Time is not a critical issue for planes. I bet the design of the Airbus was finalized years before it was finished, and they did chose to neglect any major breakthroughs that might happen in that time. (Same for car manufacturers, for example, the cutting-edge technology they develop at the moment will hit the streets in 5-10 years.)

For software you need to be very agile, if I start a huge project now and take three years to develop it without any change the chances are pretty high that I am relying on technology that is not available anymore or my product is completely outdated. This in turn offers a lot of problems.

3- Release-cycle and versions. - A plane needs to be completely finished when it is "released". There are no stable beta versions, nightly builds or similar. Additionally, once it's done, it can only be modified in a small way. You can't add an additional level with 100 seats to an existing boeing, it's just not possible.

Software on the other hand has incremental changes that are often just "builds that work", but not necessarily finished products. Also, in IT it's not unusual to say "hey, let's add another luggage compartment to our plane which holds additional 50 tons".


答: It does sound like that there has been a strategic shift inside Microsoft, and at this time Adobe Flex/Flash will continue to be the leading technology to work with for RIA applications. It looks like HTML5 will be broadly adopted and I personally would switch over to experimenting with it. </p>

Title: Does Silverlight have a future?

Body:
Recently I have read some articles/blogs/comments about the development and history of WPF and Silverlight. In some forums many developers and users criticize the performance of WPF applications (for example Visual Studio 2010). Actually the market share of Silverlight in comparison to Flash is not very high. At PDC 2010 Bob Muglia said something like "our Silverlight strategy and focus going forward has shifted...." and Microsoft wants to push HTML5 in the future.

Additionally, Microsoft has announced HTML5 being a core part of the Windows 8 and Windows Phone 8 ("Mango") platforms.

Recently I have started learning Silverlight and now I must ask myself, if I should continue investing time in learning these (in my opinions) very nice and powerful technologies!? Does they have a future? Does (Windows) desktop (client) applications have a future? Does so called "Rich Internet Applications" have a future? Or will HTML5 become the "absolute truth" in software development?

What is your opinion and what do you think?

ContentLicense: CC BY-SA 2.5


答: Lack of accountability... People get sued when an aircraft crashes. The software industry declines any responsibility in any software defect, therefore creating a lack of incentive to create a robust and safe product.</p>


问:
Do some best practices depend on skill?
Is there evidence that some software development best practices depend on programming skill level? I mean, these methods are good, but maybe the way the are used or the extent might vary?

This question arose after I read Paul Graham's commentary about OOP, and the last bullet point of this accepted answer. It proposes that where, how, and how much to use unit tests might depend on your programming skill.

So do top programmers use different approaches than average programmers?

答:
I consider myself an experienced programmer, both in time and tasks. My style definitely has changed a lot over the years.

As I see, I am a strange kind of programmer/architect. I am never proud of what I have written, but the ability that I was able to accomplish that task. I do respect running code, but by the original meaning of the word: re-spect: check it again. And refactor, whenever it is not exactly what I want to see.

I change the name of a variable or a function several times, if it does not exactly mean what it does - until I don't have to roll up to the definition, because the name is evident. I move a function or data several times between layers of a system until they get to where they really belong. I always re-indent my codes, I never leave any () although I know the operator precedence, or the {} after an if for a single instruction.

I have a strong feeling that there is a good way to do a task - and far too many working, but structurally wrong solution. The structure (service layers, communication, responsibility, data) is much more important (because it affects the whole structure of a system), while the code should be "good enough" to run.

Programming for me is a constant search for that good answer, and I still have a lot to learn - but what seemed to be a whole field of many possible ways when I was a beginner, looks a map with a very few paths to try. It s fundamentally different.

Title: Do some best practices depend on skill?


问:
UML Actions with object and control flows
Consider a UML Action contained in a UML Activity defining the behavior of a classifier. Such Action has three input pins connected to other output pins of different action by means of object flow edges. It also has an incoming control flow.

My question is: does the action start when all the tokens _ those coming from all the input pins and that coming from the control flow _ are available? What if I have more than one control flows?

答:
As far as I remember, this was modeled after the Petri nets.

I remember that this part of the specification has changed between my PDF version of the specification (20003 january 6), and by the time the UML 2.0 was finalized in Rational Rose files (which I can't and won't handle)

Anyway, to summarize the specification, whilst there can be multiple actions that are able to fire at any single moment in time, UML does not deal with their concurrency. Quoting the spec:

However, the fact that the UML allows for concurrently executing objects does not necessarily imply a distributed software structure. Some implementations may group together objects into a single task and execute sequentially—so long as the behav- ior of the implementation conforms to the sequencing constraints of the specification.

Also, UML doesn't deal with passing of time, it only deals with requirements about sequence. Again, quote:

The UML does not provide for the specification of a time metric, but only describes sequences of executions.

That said, in a Petri network, when there are one or more executable actions, at least one will have to execute in the next step. The order of execution between these, just as in real life, is undeterminable. It can also be, that given two executable actions, firing one of them will make the other one impossible to fire.

Therefore, in case your action is the only action in the system which is executable (either because others don't have their sufficient input or because you only have a single control flow), it will be executed in the next step. When does that next step occur, nobody can, and nobody is willing to tell you.

In case you want to get guarantees, consider LTL modeling your UML actions. UML is formal in order to be modelable with LTL.


问:
Are some NOP codes treated differently than others?
I'm curious about this, let's say I have:

```<code>00000000001 90                              nop
00000000002 90                              nop
00000000003 90                              nop
</code>```

Is it executed exactly the same as this?

```<code>00000000001 0F1F00                          nop        dword [ds:rax]
</code>```

What effect would the second example have as opposed to the first?

答: It depends on the machine architecture.   The classic KA-10 (pdp-10) had lots of nop codes, probably a consequence of it's highly regular instruction set, and the fact that it was all implemented by descrete components, not by microcode.  Some NOPs referenced memory, some were skip tests that never skipped, but nonetheless tested the condition that might have caused a skip, and so on.  "JFCL 0," was advertised in the manual as the fastest nop.</p>


答:
I think the answer is quite simple:

1) Physical construction and implementation have been around for as long as people have - we've had thousands of years to develop our methods and techniques for implementing physical projects. Software 'construction', which requires an entirely new and different skill-set, is no more than 50 years old - we haven't had enough time figure it all out yet.

2) Virtual construction is harder - you have to 'see' things in you mind that have no physical reality whatsoever. It requires you to analyze and abstract a lot of information before you even know what your product is supposed to look like and the steps it will take to create it. Not so when building a bridge or a building.

3) It's often much more difficult to find the source of a software failure or bug than it is when doing physical engineering. If a girder buckles, you see where it's buckling and you see the supports that are holding it and failing, etc. Finding a software defect can entail examining a great deal of code and interacting processes - difficult, time consuming, and not bound to the laws of physics and math in the way that physical structures are.


答:
As someone with a mechanical engineering background working in IT, I've often wondered about the reasons of the low success rate in IT.

As others in this thread, I've also often attributed the failures to the immaturity of IT, the lack of detailed standards (yes I'm serious, have you ever checked the standard sheet of a simple bolt?) and the lack of standardized components and modules.

Other industries, like building construction or ship building also have much more "beaten paths": knowledge and experience of a particular solution prototype, which - in customized form - is re-used again and again. Ever wondered about why buildings, ships or airplanes of different size and purpose somehow look so similar? (there are exceptions to the rule of course...)

That is because those prototypes are well researched, well understood, generally used and have a proven track record. Not because it couldn't be done any other way. In IT standardization is rarely the case: (large) projects tend to re-invent components, doing research and delivery at the same time and with the same people!

These inevitably lead to one-off products, which are expensive to develop and service, are error-prone and fail in unpredictable ways under uncertain conditions. And because of this, of course, these products are much quicker obsolete, written down and replaced at equally great costs with only slightly better ones. What IT needs is the equivalent of the industrial revolution, which turned middle-age artisans into efficient factories.

That said, there are factors that make IT truly unique however. As opposed to those other mentioned industries, IT is truly ubiquitous: it is used in every aspect of our modern life. So it's a small miracle IT achieved this much progress and is capable of delivering the results it does.


问:
Who should participate in time estimation?
In an IT project:

Who should participate in time estimation? Developer, team leader, scrum master and etc?

Whose vote should be counted most?

答:
THE DEVELOPERS CHARGED WITH IMPLEMENTING THE PROJECT! NOBODY ELSE!

The developers doing the actual hands on work and the development team leaders are the only ones capable of properly estimating how much time it will really take. Only programmers familiar with the actual code base can understand the potential difficulties and pitfalls that may be encountered in the course of development. Everyone else is a 'spectator'.

In addition, the only way developers can be trusted to give accurate estimates is when business people trust them and rely on their expertise such that developers know they will not be penalized if their estimate doesn't meet business's expectations.

Rule of thumb: it will take at least 3 times as long as the estimate of any project manager or business person not intimately familiar with the challenges of hands on development and the code base in question.

As someone who has worked as a hands on developer both free-lance and as an employee in big corporations for nearly 20 years, I say this with utmost certaintly and the benefit of a great deal of bitter experience.


答:
Digital building blocks can be 1 or 0. There is no inbetween.

A mechanical design has a level of tollerance. I can put one less than perfect rivet into a bridge and it will most likely will not fall down, however, in code even just once instance of putting a 0 where a 1 should be can fail the entire program.

Due to the logical and interative nature of computing, any, even very small changes, can lead to drastic failure.


答:
I'm afraid that I disagree with your statement.

Airbus and Boeing are two examples of companies that build planes. How many companies that build planes are there? Very few, if you would compare it to how many companies build software.

It is equally easy to screw an airplane project as to screw a software project. If only the entry barrier was so low in the aircraft-building industry as it is in the software industry, you will certainly see many failed aircraft projects.

Look at cars; There are high-quality manufacturers that build very durable and highly advanced automobiles (think Land Rover, Mercedes) and there are ones that build cars that won't last a year without having to repair them (think Kia or Cherry). This is a perfect example of an industry with slightly lower entry barrier, were you start to have weaker players.

Software is no different. You have lots of buggy products, on the other hand, Windows, Office, Linux, Chrome, or Google Search are very high-quality projects that were delivered on time and had similar quality level as an aircraft.

The other point that many people miss is how much maintenance goes into maintaining a car, a tanker or an aircraft that we just take as a fact of life. Every plane has to undergo a technical check-up before every take off. You have to check-up your car every several k miles and do so regular stuff like change oil, change tires.

Software needs that too. If only people spent as much time on diagnostics, prevention or auditing software's state and quality as they do with mechanical/physical products, I would expect way less statements like these. Do you read your application's logs each time before you launch it? Well.. if it was an aircraft you would have to ;-)


答:
Skyscraper guy here. Not sure if I can answer your question but I can surely shed some light into various items in the thread. Buildings do indeed occur very fast. A major constraint is locale (regulations). But in general it takes 3 to 10 years for a tall building from start to finish.

I think comparing a new building with a new software project is not very accurate. A new building is closer to a new version of a kernel or OS. In this respect software development is much faster. We never build from zero as this will be a high risk task the client would never sign up for. Most design and development in buildings is derivative of proven and completed projects.

From personal experience only one in ten projects ever get built. The process is development-driven rather than design-driven, so the moment something like the price of steel goes up the whole project is out the window, or designed, as design is the cheap component of the process.

Design takes a month for concept to schematic, two to six months to design development, another six months to details and construction documents by a team of architects, planning consultants, structural engineers, wind engineers, services engineers, quantity and cost consultants, surveyors, accessibility engineers and the list goes on...

The argument of virtual versus physical is not very accurate. We also work mainly with virtual tools, and moreover we are both time- and scale-remote from our final product. In most cases we can not even test aspects of buildings in mockup scale and we use simulation to try predict what may come about.

Complexity-wise there are differences, but overall it is maybe about the same. We not only have interrelated units and multiple levels of tiered abstractions and interfaces but also people are very much specialized in small parts of the process that make communication very difficult.

As for the argument of design versus development, I think both processes are design-built. It sounds academically nice to keep these separated but it is not possible to design if you don't know how things work. You just increase the risk of failure.

Overall my (potentially wrong) estimation as per OP's question is that programming is more of an art than engineering. Why would people take pleasure and even do it for free, find expression and elegance in it? Computer science is also (as on the tin) more of a science than engineering. Why would you try to prove algorithms instead of just patching existing parts together and work to make things just work? Not sure if this makes any sense; I'm not a software guy.

One aspect that strikes me with software design and development is about the medium itself. Computers make human-centric work very unnatural. Everything is so very explicit and there are few tolerances. It's hard to mentally work your way around this, and some get away with it by dumping complexity within. If nothing else this may have something to do with it?


问:
Issues Tracker for both developers and end users
currently, we have a closed source project on hand. However, we would like to have a communication channel together with our end users.

We would like to have our end users to know, what features we are currently working on, and what features they are going to get in next release.

We would like to know users' thought, on our planned features. They may always provide input/suggestion on our planned features.

We do not planned to host on our own server. Hence, a ready-available service is welcomed.

But we would like to remain our source code in closed model

Is there any web based service available for this purpose? Free or commercial doesn't matter.

答:
FaultTrack will have this, but it won't be available until September 2013 and only if it gets funded. The bug tracker itself is a desktop application for developers, and the current customer submission feature will be through a web portal however. When its available though, there will also be hosted solutions so you don't have to set anything up.

I currently use this with my clients who I develop software for, they are provided an entire project management portal through my site, which includes a web portal hooked up to FaultTrack. Here's a screenshot.

And to ensure I'm following StackExchange guidelines, I must let you know that I'm the creator of the FaultTrack project.


答:
Cathedrals used to take up to 100 years to build.

Some Airbus airplane needs 1 million lines of code to work.

The more time you have been improving something, the more improvement you get, so give the software industry a couple of centuries of trial-error to get better, and we'll see how much it takes a to develop a solid huge project without bugs or flaws.


答:
Though it's hardly the only thing that could be mentioned, I think one basic thing is worth pointing out. Most products are intended to fit with existing behavior. Even a product that's a radical breakthrough (for example, the car) is generally built to fit with existing behavior, and simply make it a bit simpler/easier/cheaper/whatever to do that. Yes, there's often some side effect on existing behavior as well (for example, getting fuel for the car instead of food for the horses), but most of the latter tends to be a fairly minor side effect.

By contrast, almost any software that doesn't change the behavior of the users (for example, let them do their job considerably more easily) is basically guaranteed to be a complete failure from day 1. Worse, large software projects don't just involve the behavior of users on an individual level, but the behavior of large groups -- often the entirety of the organization.

In short, designing the software itself is often the easiest part of the job. The hard part is redesigning peoples' jobs for them. That's difficult to start with; doing it in a way that will not only work, but also be accepted is much more difficult still.


问:
Dynamic choice of compilers?
An application has the following logic:

client => created *.cpp => sent to the server => cl.exe + *.cpp =

*.exe

client => created *.cs => sent to the server => csc.exe + *.cs =

*.exe

client => created *.pas => sent to the server => PascalCompiler +

*.pas = *.exe

etc.

The language - C#. I hear that MSBUILD can help me, but I don't understand how to change compiler on server at runtime. Does anyone know of options other than Process class?

I'm trying to write an online system to test programs in programming contests. The programmer selects the compiler and sends the source code to the server for verification.

And I do not need to build the project, I just need to compile a single file.

答:
You are on a right track.

I would suggest to start with your MSBuild and continues integration process. Dealing with continues integration takes time and resource. I would advice to think twice on the goal that you are planning to achieve.

I have compiled a list of good resources that hopefully will help you to understand the build process itself:

Continues integration with MS Build and CruiseControl.Net

Continuous Integration – Why use MSBuild?

Continuous Integration and nightly build system for an ASP.Net application using MSBuild build scripts and Jenkins CI Server

Redefine Your Build Process with Continuous Integration

Title: Dynamic choice of compilers?