问:
How should I handle using two databases with a legacy PHP application?
I have a legacy PHP application that was written in 2004 and uses MSSQL as a database backend.

At this stage MSSQL is still supported by PHP but only just via a Microsoft driver.  I have looked at converting to mysql via automated tools, which work quite well, but I have quite complex views which need a lot of individual work to convert.  I don't have a great deal of time to do this.

Many tools I wish to use and frameworks I would like to move the application to, don't support MSSQL, so I was considering adding new features using a new mysql database and wondered if anyone had opinions on the pros and cons of using two seperate database backends in a single application?

答: Since I don't know what platforms, frameworks, and tools you want to use, it's tough to present an easy answer. The first thought that comes to mind is some middleware that can map between the MSSQL interface and the data model the tool/framework is using. It's likely that this wheel has already been invented, but requires more specifics to locate.</p>


问:
How do I get up-to-date on web development technologies?
I'm a regular user here, but linking my screen name to my real identity is dirt simple, and the question I'm about to ask would lead to a very unpleasant conversation with my current employer were they to see it.  So, my apologies for this sock-puppet account; I promise Socky and I won't be voting on each other's stuff, and Socky won't be doing much of anything other than voting on answers to his own questions.

I may have an opportunity to work with somebody I've worked with in the past.  Short, extremely understated summary:  It went well.  This time he's looking to bring me on as a partner to a fledgling web venture.  My job title isn't defined, but I'd basically be "the guy" in terms of the tech side of the company.  One of the first things I'd be doing is fleshing out the current and future requirements of the site and determining the best way to meet them -- overhaul the existing site?  Scrap the existing site entirely and replace it with something like Drupal?  I'd also be tasked with making sure that the site is not only a pleasant user experience, but that it looks and feels like a modern, professional website.

One problem:  I'm not qualified.

At least, not yet.

I wasn't really qualified for the last time we worked together, but I taught myself what I needed to know and ... like I said.  It Went Well.  However, I was a lower-level code wrangler that time around, and a lot of key decisions had already been made.  I had more room for error and time to learn as I was going.

This outing, not so much.  It's been a long damn time since I was completely up-to-date on web programming; my current gig has a healthy dash of web stuff, but the web interface isn't the main business and it's built on old technology.  (Technology it honestly doesn't use particularly well.)  I just don't spend a lot of time playing with new tech when I'm not at work; I generally spend that time on hobbies and passions I don't get paid to do.

But I want this to happen.  And I want to do it right.  So my question is:  what resources would you recommend I use to both get myself up-to-date and stay up-to-date on professional-caliber web programming?

I know I need to beef-up my jQuery-fu; I've been exposed to it a little, and holy crap does it make hard jobs easy.  I also know I need to acquaint myself with Drupal and other content management systems so that I can accurately gauge whether using one as the foundation for the site would be a good idea or a waste of time.  But I'm certain there are other technologies out there that would help me do that job that I don't yet know anything about.  What are some good resources for helping me figure out what I don't know?

Websites, magazines, podcasts, whatever.  I need to figure out how to get back into the game properly.

This is scary as hell, but it also feels like it could be a huge step forward in my career.  (Assuming it's not a step into a pool filled with laser sharks.)  My thanks in advance for any assistance anybody can offer in curing my ignorance.

答:
There is so much going on in web technology nowadays you can not possibly be up to speed with everything.

It is literally not possible for a single individual to know everything at the cutting edge of web development: HTML5, CSS3, the latest jQuery, pubsubhubbub, Node.js, Google APIs, Yahoo YUI stuff,whichever MVC framework you like, whichever javascript framework you like... are all in a constant state of rapid flux.

Repeat after me: You can not know it all.

Now, breath a sigh of relief, and learn the stuff you need to for the new project. You have done it before and you will do it again.

The secret is not in the knowing but the learning. To do that, read the web, listen to relevant podcasts, and start building prototypes. There is no better way to learn than starting the doing.

Aside: I personally don't generally bother with books. Web technology moves so fast now that by the time anything gets to print it will probably be, to some extent, out of date.

ContentLicense: CC BY-SA 2.5


问:
I've inherited 200K lines of spaghetti code -- what now?
I hope this isn't too general of a question; I could really use some seasoned advice.

I am newly employed as the sole "SW Engineer" in a fairly small shop of scientists who have spent the last 10-20 years cobbling together a vast code base. (It was written in a virtually obsolete language: G2 -- think Pascal with graphics). The program itself is a physical model of a complex chemical processing plant; the team that wrote it have incredibly deep domain knowledge but little or no formal training in programming fundamentals. They've recently learned some hard lessons about the consequences of non-existant configuration management. Their maintenance efforts are also greatly hampered by the vast accumulation of undocumented "sludge" in the code itself. I will spare you the "politics" of the situation (there's always politics!), but suffice to say, there is not a consensus of opinion about what is needed for the path ahead.

They have asked me to begin presenting to the team some of the principles of modern software development. They want me to introduce some of the industry-standard practices and strategies regarding coding conventions, lifecycle management, high-level design patterns, and source control. Frankly, it's a fairly daunting task and I'm not sure where to begin.

Initially, I'm inclined to tutor them in some of the central concepts of The Pragmatic Programmer, or Fowler's Refactoring ("Code Smells", etc). I also hope to introduce a number of Agile methodologies. But ultimately, to be effective, I think I'm going to need to hone in on 5-7 core fundamentals; in other words, what are the most important principles or practices that they can realistically start implementing that will give them the most "bang for the buck".

So that's my question: What would you include in your list of the most effective strategies to help straighten out the spaghetti (and prevent it in the future)?

答:
I don't know if this is an option to you, but I would start trying to convincing them to hire more professional developers. This way they could concentrate in domain problems (I'm sure they have enough there).

I believe they are very smart people, but becoming a good developer demands a lot of time. Are they ready to spend so much time in a activity that isn't their main business? IMHO, this isn't the way to achieve the best results.

ContentLicense: CC BY-SA 3.0


问:
Quality of Code in unit tests?
When writing unit tests, is it worth spending the extra time to make the code have good quality and readability?

When writing tests I often break the Law of Demeter, for faster writing and to avoid using so many variables. Technically, unit tests are not reused directly - they are strictly bound to the code so I do not see any reason for spending much time on them; they only need to be functional.

答:
The most important practical reason is that every time you change code, you change unit tests. And if you're doing TDD, you're even changing the unit tests first.

Do either of these things in your tests:

Duplicate code

Diminish readability

Tight coupling

Temporal coupling

High cyclomatic complexity (lots of dependencies)

And you're in for a whole lot of work when a change is needed.

Treat your tests like you suggested, and you'll end up regretting it. You'll probably even reach the false conclusion that "TDD doesn't work".

Title: Quality of Code in unit tests?


问:
Is running "milli"-benchmarks a good idea?
I just came across the Caliper project and it looks very nice.
Reading the introduction to microbenchmarks, one gets the feeling that the developers would not suggest to use the framework if the benchmark takes longer than a second or so. I looked at the code and it looks like a RuntimeOutOfRangeException is actually thrown if a scenario takes longer than 10s to execute.

Could you explain to me what the problems are with running larger benchmarks?

My motivation for using Caliper was to compare two join-algorithm implementations. Those will definitely run for quite some time and will do some disk IO, yet running the entire database would make it hard to do the comparison, because the configuration of the algorithms and the visualization of the results would be a pain.

答:
One of the reasons for using caliper rather than just naively writing your own benchmarking code is that caliper goes a long way to avoid some of the pitfalls of writing micro-benchmarks. For example, a good benchmark should first run code in a warmup phase that ensures all relevant code gets JITed. It should also ensure that doing twice as many iterations takes twice as long; if not, it suggests that the JVM is optimizing away the work.

All of this means that to properly benchmark code, caliper needs to run lots of iterations. For a task that should take something on the order of microseconds, this is reasonable. But if a single iteration will take more than 10 seconds, this means that the caliper run will take a very long time indeed. My assumption is that the Caliper team decided that because of this, a task that takes more than 10 seconds to run was far more likely to be the result of programmer error than an intentional choice to write a benchmark that would take hours to run. By bailing early, it helps programmers realize quickly that they need to fix a bug, rather than having their machine spin away for hours.

OwnerDisplayName: Konstantin Weitz


答: I just got done doing a series of presentations on Robert Martin's SOLID principles for my co-workers. I don't know how well these principles translate to G2, but since you're looking for 5-7 core fundamentals, these seem like a well-established set to start out with. If you want to round it up to 7, you could start with DRY and throw in Fail-Fast.</p>

Title: I've inherited 200K lines of spaghetti code -- what now?

Body:
I hope this isn't too general of a question; I could really use some seasoned advice.

I am newly employed as the sole "SW Engineer" in a fairly small shop of scientists who have spent the last 10-20 years cobbling together a vast code base. (It was written in a virtually obsolete language: G2 -- think Pascal with graphics). The program itself is a physical model of a complex chemical processing plant; the team that wrote it have incredibly deep domain knowledge but little or no formal training in programming fundamentals. They've recently learned some hard lessons about the consequences of non-existant configuration management. Their maintenance efforts are also greatly hampered by the vast accumulation of undocumented "sludge" in the code itself. I will spare you the "politics" of the situation (there's always politics!), but suffice to say, there is not a consensus of opinion about what is needed for the path ahead.

They have asked me to begin presenting to the team some of the principles of modern software development. They want me to introduce some of the industry-standard practices and strategies regarding coding conventions, lifecycle management, high-level design patterns, and source control. Frankly, it's a fairly daunting task and I'm not sure where to begin.

Initially, I'm inclined to tutor them in some of the central concepts of The Pragmatic Programmer, or Fowler's Refactoring ("Code Smells", etc). I also hope to introduce a number of Agile methodologies. But ultimately, to be effective, I think I'm going to need to hone in on 5-7 core fundamentals; in other words, what are the most important principles or practices that they can realistically start implementing that will give them the most "bang for the buck".

So that's my question: What would you include in your list of the most effective strategies to help straighten out the spaghetti (and prevent it in the future)?


答:
Foreword

This is a daunting task indeed, and there's a lot of ground to
cover. So I'm humbly suggesting this as somewhat comprehensive guide
for your team, with pointers to appropriate tools and educational
material.

Remember: These are guidelines, and that as such are meant to
adopted, adapted, or dropped based on circumstances.

Beware: Dumping all this on a team at once would most likely
fail. You should try to cherry-pick elements that would give you the
best bang-for-sweat, and introduce them slowly, one at a time.

Note: not all of this applies directly to Visual Programming
Systems like G2. For more specific details on how to deal with these,
see the Addendum section at the end.

Executive Summary for the Impatient

Define a rigid project structure, with:

project templates,

coding conventions,

familiar build systems,

and sets of usage guidelines for your infrastructure and tools.

Install a good SCM and make sure they know how to use it.

Point them to good IDEs for their technology, and make sure they know how to use them.

Implement code quality checkers and automatic reporting in the build system.

Couple the build system to continuous integration and continuous inspection systems.

With the help of the above, identify code quality "hotspots" and refactor.

Now for the long version... Caution, brace yourselves!

Rigidity is (Often) Good

This is a controversial opinion, as rigidity is often seen as a force
working against you. It's true for some phases of some projects. But
once you see it as a structural support, a framework that takes away
the guesswork, it greatly reduces the amount of wasted time and
effort. Make it work for you, not against you.

Rigidity = Process / Procedure.

Software development needs good process and procedures for exactly the
same reasons that chemical plants or factories have manuals,
procedures, drills and emergency guidelines: preventing bad outcomes,
increasing predictability, maximizing productivity...

Rigidity comes in moderation, though!

Rigidity of the Project Structure

If each project comes with its own structure, you (and newcomers) are
lost and need to pick up from scratch every time you open them. You
don't want this in a professional software shop, and you don't want
this in a lab either.

Rigidity of the Build Systems

If each project looks different, there's a good chance they also
build differently. A build shouldn't require too much research or
too much guesswork. You want to be able to do the canonical thing and
not need to worry about specifics: configure; make install, ant,
mvn install, etc...

Re-using the same build system and making it evolve over the time also
ensures a consistent level of quality.

You do need a quick README to point the project's specifics, and
gracefully guide the user/developer/researcher, if any.

This also greatly facilitates other parts of your build
infrastructure, namely:

continuous integration,

continuous inspection.

So keep your build (like your projects) up to date, but make it
stricter over time, and more efficient at reporting violations and bad
practices.

Do not reinvent the wheel, and reuse what you have already done.

Recommended Reading:

Continuous Integration: Improving Software Quality and Reducing Risk (Duval, Matyas, Glover, 2007)

Continuous Delivery: Release Sotware Releases through Build, Test and Deployment Automation (Humble, Farley, 2010)

Rigidity in the Choice of Programming Languages

You can't expect, especially in a research environment, to have all
teams (and even less all developers) use the same language and
technology stack. However, you can identify a set of "officially
supported" tools, and encourage their use. The rest, without a good
rationale, shouldn't be permitted (beyond prototyping).

Keep your tech stack simple, and the maintenance and breadth of
required skills to a bare minimum: a strong core.

Rigidity of the Coding Conventions and Guidelines

Coding conventions and guidelines are what allow you to develop both
an identity as a team, and a shared lingo. You don't want to err
into terra incognita every time you open a source file.

Nonsensical rules that make life harder or forbid actions explicity
to the extent that commits are refused based on single simple
violations are a burden. However:

a well thought-out ground ruleset takes away a lot of the whining
and thinking: nobody should break under no circumstances;

and a set of recommended rules provide additional guidance.

Personal Approach: I am aggressive when it comes to coding
  conventions, some even say nazi, because I do believe in having a
  lingua franca, a recognizable style for my team. When crap code
  gets checked-in, it stands out like a cold sore on the face of an
  Hollywood star: it triggers a review and an action automatically.
  In fact, I've sometimes gone as far as to advocate the use of
  pre-commit hooks to reject non-conforming commits. As mentioned, it
  shouldn't be overly crazy and get in the way of productivity: it
  should drive it. Introduce these slowly, especially at the
  beginning. But it's way preferable over spending so much time fixing
  faulty code that you can't work on real issues.

Some languages even enforce this by design:

Java was meant to reduce the amount of dull crap you can write with
it (though no doubt many manage to do it).

Python's block structure by indentation is another idea in this
sense.

Go, with its gofmt tool, which completely takes away any debate
and effort (and ego!!) inherent to style: run gofmt before
you commit.

Make sure that code rot cannot slip through. Code
conventions, continuous integration and continuous
inspection, pair programming and code reviews are your
arsenal against this demon.

Plus, as you'll see below, code is documentation, and that's
another area where conventions encourage readability and clarity.

Rigidity of the Documentation

Documentation goes hand in hand with code. Code itself is
documentation. But there must be clear-cut instructions on how to
build, use, and maintain things.

Using a single point of control for documentation (like a WikiWiki or
DMS) is a good thing. Create spaces for projects, spaces for more
random banter and experimentation. Have all spaces reuse common rules
and conventions. Try to make it part of the team spirit.

Most of the advice applying to code and tooling also applies to
documentation.

Rigidity in Code Comments

Code comments, as mentioned above, are also documentation. Developers
like to express their feelings about their code (mostly pride and
frustration, if you ask me). So it's not unusual for them to express
these in no uncertain terms in comments (or even code), when a more
formal piece of text could have conveyed the same meaning with less
expletives or drama. It's OK to let a few slip through for fun and
historical reasons: it's also part of developing a team
culture. But it's very important that everybody knows what is
acceptable and what isn't, and that comment noise is just that:
noise.

Rigidity in Commit Logs

Commit logs are not an annoying and useless "step" of your SCM's
lifecycle: you DON'T skip it to get home on time or get on with the
next task, or to catch up with the buddies who left for lunch.  They
matter, and, like (most) good wine, the more time passes the more valuable
they become. So DO them right. I'm flabbergasted when I see co-workers
writing one-liners for giant commits, or for non-obvious hacks.

Commits are done for a reason, and that reason ISN'T always clearly
expressed by your code and the one line of commit log you
entered. There's more to it than that.

Each line of code has a story, and a history. The diffs can tell
its history, but you have to write its story.

Why did I update this line? -> Because the interface changed.

Why did the interface changed? -> Because the library L1 defining it
  was updated.

Why was the library updated? -> Because library L2, that we need for
  feature F, depended on library L1.

And what's feature X? -> See task 3456 in issue tracker.

It's not my SCM choice, and may not be the best one for your lab
either; but Git gets this right, and tries to force you to write
good logs more than most other SCMs systems, by using short logs and
long logs. Link the task ID (yes, you need one) and a leave a
generic summary for the shortlog, and expand in the long log: write
the changeset's story.

It is a log: It's here to keep track and record updates.

Rule of Thumb: If you were searching for something about this
  change later, is your log likely to answer your question?

Projects, Documentation and Code Are ALIVE

Keep them in sync, otherwise they do not form that symbiotic entity
anymore. It works wonders when you have:

clear commits logs in your SCM, w/ links to task IDs in your
issue tracker,

where this tracker's tickets themselves link to the changesets in
your SCM (and possibly to the builds in your CI system),

and a documentation system that links to all of these.

Code and documentation need to be cohesive.

Rigidity in Testing

Rules of Thumb:

Any new code shall come with (at least) unit tests.

Any refactored legacy code shall come with unit tests.

Of course, these need:

to actually test something valuable (or they are a waste of time
and energy),

to be well written and commented (just like any other code you check in).

They are documentation as well, and they help to outline the contract
of your code. Especially if you use TDD. Even if you don't, you
need them for your peace of mind. They are your safety net when you
incorporate new code (maintenance or feature) and your watchtower
to guard against code rot and environmental failures.

Of course, you should go further and have integration tests, and
regression tests for each reproducible bug you fix.

Rigidity in the Use of the Tools

It's OK for the occasional developer/scientist to want to try some new
static checker on the source, generate a graph or model using another,
or implement a new module using a DSL. But it's best if there's a
canonical set of tools that all team members are expected to know
and use.

Beyond that, let members use what they want, as long as they are ALL:

productive,

NOT regularly requiring assistance

NOT regularly adjusting to your general infrastructure,

NOT disrupting your infrastructure (by modifying common
areas like code, build system, documentation...),

NOT affecting others' work,

ABLE to timely perform any task requested.

If that's not the case, then enforce that they fallback to defaults.

Rigidity vs Versatility, Adaptability, Prototyping and Emergencies

Flexibility can be good. Letting someone occasionally use a hack, a
quick-n-dirty approach, or a favorite pet tool to get the job done
is fine. NEVER let it become a habit, and NEVER let this code
become the actual codebase to support.

Team Spirit Matters

Develop a Sense of Pride in Your Codebase

Develop a sense of Pride in Code

Use wallboards

leader board for a continuous integration game

wallboards for issue management and defect counting

Use an issue tracker / bug tracker

Avoid Blame Games

DO use Continuous Integration / Continuous Inspection games: it
fosters good-mannered and productive competition.

DO keep track defects: it's just good house-keeping.

DO identifying root causes: it's just future-proofing processes.

BUT DO NOT assign blame: it's counter productive.

It's About the Code, Not About the Developers

Make developers conscious of the quality of their code, BUT make them
see the code as a detached entity and not an extension of
themselves, which cannot be criticized.

It's a paradox: you need to encourage ego-less programming for a
healthy workplace but to rely on ego for motivational purposes.

From Scientist to Programmer

People who do not value and take pride in code do not produce good
code. For this property to emerge, they need to discover how valuable
and fun it can be. Sheer professionalism and desire to do good is not
enough: it needs passion. So you need to turn your scientists into
programmers (in the large sense).

Someone argued in comments that after 10 to 20 years on a project and
its code, anyone would feel attachment. Maybe I'm wrong but I assume
they're proud of the code's outcomes and of the work and its legacy,
not of the code itself or of the act of writing it.

From experience, most researchers regard coding as a necessity, or at
best as a fun distraction. They just want it to work. The ones who are
already pretty versed in it and who have an interest in programming
are a lot easier to persuade of adopting best practices and switching
technologies. You need to get them halfway there.

Code Maintenance is Part of Research Work

Nobody reads crappy research papers. That's why they are
peer-reviewed, proof-read, refined, rewritten, and approved time and
time again until deemed ready for publication. The same applies to a
thesis and a codebase!

Make it clear that constant refactoring and refreshing of a codebase
prevents code rot and reduces technical debt, and facilitates future
re-use and adaptation of the work for other projects.

Why All This??!

Why do we bother with all of the above? For code quality. Or is it
quality code...?

These guidelines aim at driving your team towards this goal. Some
aspects do it by simply showing them the way and letting them do it
(which is much better) and others take them by the hand (but that's
how you educate people and develop habits).

How do you know when the goal is within reach?

Quality is Measurable

Not always quantitatively, but it is measurable. As mentioned, you
need to develop a sense of pride in your team, and showing progress
and good results is key. Measure code quality regularly and show
progress between intervals, and how it matters. Do retrospectives to
reflect on what has been done, and how it made things better or worse.

There are great tools for continuous inspection. Sonar being
a popular one in the Java world, but it can adapt to any technologies;
and there are many others. Keep your code under the microscope and
look for these pesky annoying bugs and microbes.

But What if My Code is Already Crap?

All of the above is fun and cute like a trip to Never Land, but it's
not that easy to do when you already have (a pile of steamy and
smelly) crap code, and a team reluctant to change.

Here's the secret: you need to start somewhere.

Personal anecdote: In a project, we worked with a codebase
  weighing originally 650,000+ Java LOC, 200,000+ lines of JSPs,
  40,000+ JavaScript LOC, and 400+ MBs of binary dependencies.

After about 18 months, it's 500,000 Java LOC (MOSTLY CLEAN),
  150,000 lines of JSPs, and 38,000 JavaScript LOC, with dependencies
  down to barely 100MBs (and these are not in our SCM anymore!).

How did we do it? We just did all of the above. Or tried hard.

It's a team effort, but we slowly inject in our process
  regulations and tools to monitor the heart-rate of our product,
  while hastily slashing away the "fat": crap code, useless
  dependencies... We didn't stop all development to do this: we have
  occasional periods of relative peace and quiet where we are free to
  go crazy on the codebase and tear it apart, but most of the time we
  do it all by defaulting to a "review and refactor" mode every chance
  we get: during builds, during lunch, during bug fixing sprints,
  during Friday afternoons...

There were some big "works"... Switching our build
  system from a giant Ant build of 8500+ XML LOC to a
  multi-module Maven build was one of them. We then had:

clear-cut modules (or at least it was already a lot better, and we
  still have big plans for the future),

automatic dependency management (for easy maintenance and updates, and
  to remove useless deps),

faster, easier and reproduceable builds,

daily reports on quality.

Another was the injection of "utility tool-belts", even though we
  were trying to reduce dependencies: Google Guava and Apache Commons
  slim down your code and and reduce surface for bugs in your code
  a lot.

We also persuaded our IT department that maybe using our new tools
  (JIRA, Fisheye, Crucible, Confluence, Jenkins) was better than the
  ones in place. We still needed to deal with some we despised (QC,
  Sharepoint and SupportWorks...), but it was an overall improved
  experience, with some more room left.

And every day, there's now a trickle of between one to dozens of
  commits that deal only with fixing and refactoring things. We
  occasionally break stuff (you need unit tests, and you better write
  them before you refactor stuff away), but overall the benefit
  for our morale AND for the product has been enormous. We get there
  one fraction of a code quality percentage at a time. And it's fun
  to see it increase!!!

Note: Again, rigidity needs to be shaken to make room for new and
better things. In my anecdote, our IT department is partly right in
trying to impose some things on us, and wrong for others. Or maybe
they used to be right.  Things change. Prove that they are better
ways to boost your productivity. Trial-runs and prototypes are
here for this.

The Super-Secret Incremental Spaghetti Code Refactoring Cycle for Awesome Quality

```<code>       +-----------------+      +-----------------+
       |  A N A L Y Z E  +----->| I D E N T I F Y |
       +-----------------+      +---------+-------+
                ^                           |
                |                           v
       +--------+--------+      +-----------------+
       |    C L E A N    +<-----|      F I X      |
       +-----------------+      +-----------------+
</code>```

Once you have some quality tools at your toolbelt:

Analyze your code with code quality checkers.

Linters, static analyzers, or what have you.

Identify your critical hotspots AND low hanging fruits.

Violations have severity levels, and large classes with a large number
 of high-severity ones are a big red flag: as such, they appear as
 "hot spots" on radiator/heatmap types of views.

Fix the hotspots first.

It maximizes your impact in a short timeframe as they have
 the highest business value. Ideally, critical violations should
 dealt with as soon as they appear, as they are potential security
 vulnerabilities or crash causes, and present a high risk of inducing a
 liability (and in your case, bad performance for the lab).

Clean the low level violations with automated codebase sweeps.

It improves the signal-to-noise ratio so you are be able to
 see significant violations on your radar as they appear. There's often
 a large army of minor violations at first if they were never taken care
 of and your codebase was left loose in the wild. They do not present a
 real "risk", but they impair the code's readability and maintainability.
 Fix them either as you meet them while working on a task, or by large
 cleaning quests with automated code sweeps if possible. Do be
 careful with large auto-sweeps if you don't have a good test suite
 and integration system. Make sure to agree with co-workers
 the right time to run them to minimize the annoyance.

Repeat until you are satisfied.

Which, ideally, you should never be, if this is still an
 active product: it will keep evolving.

Quick Tips for Good House-Keeping

When in hotfix-mode, based on a customer support request:

It's usually a best practice to NOT go around fixing other issues,
as you might introduce new ones unwillingly.

Go at it SEAL-style: get in, kill the bug, get out, and ship your
patch. It's a surgical and tactical strike.

But for all other cases, if you open a file, make it your duty to:

definitely: review it (take notes, file issue reports),

maybe: clean it (style cleanups and minor violations),

ideally: refactor it (reorganize large sections and their neigbors).

Just don't get sidetracked into spending a week from file to file and
ending up with a massive changeset of thousands of fixes spanning multiple
features and modules - it makes future tracking difficult. One issue in
code = one ticket in your tracker. Sometimes, a changeset can impact multiple
tickets; but if it happens too often, then you're probably doing something wrong.

Addendum: Managing Visual Programming Environments

The Walled Gardens of Bespoke Programming Systems

Multiple programming systems, like the OP's G2, are different beasts...

No Source "Code"

Often they do not give you access to a textual representation of
your source "code": it might be stored in a proprietary binary
format, or maybe it does store things in text format but hides
them away from you. Bespoke graphical programming systems are
actually not uncommon in research labs, as they simplify the
automation of repetitive data processing workflows.

No Tooling

Aside from their own, that is. You are often constrained by their
programming environment, their own debugger, their own
interpreter, their own documentation tools and formats. They are
walled gardens, except if they eventually capture the interest
of someone motivated enough to reverse engineer their formats and
builds external tools - if the license permits it.

Lack of Documentation

Quite often, these are niche programming systems, which are used
in fairly closed environments. People who use them frequently sign NDAs
and never speak about what they do. Programming
communities for them are rare. So resources are scarce. You're
stuck with your official reference, and that's it.

The ironic (and often frustrating) bit is that all the things these
systems do could obviously be achieved by using mainstream and general
purpose programming languages, and quite probably more
efficiently. But it requires a deeper knowledge of programming,
whereas you can't expect your biologist, chemist or physicist (to name
a few) to know enough about programming, and even less to have the
time (and desire) to implement (and maintain) complex systems, that
may or may not be long-lived. For the same reason we use DSLs, we have
these bespoke programming systems.

Personal Anecdote 2: Actually, I worked on one of these
  myself. I didn't do the link with the OP's request, but my the
  project was a set of inter-connected large pieces of
  data-processing and data-storage software (primarily for
  bio-informatics research, healthcare and cosmetics, but also for
  business intelligence, or any domain implying the tracking of
  large volumes of research data of any kind and the preparation of
  data-processing workflows and ETLs). One of these applications was,
  quite simply, a visual IDE that used the usual bells and whistles:
  drag and drop interfaces, versioned project workspaces (using text
  and XML files for metadata storage), lots of pluggable drivers to
  heterogeneous datasources, and a visual canvas to design pipelines
  to process data from N datasources and in the end generate M
  transformed outputs, and possible shiny visualizations and complex
  (and interactive) online reports. Your typical bespoke visual
  programming system, suffering from a bit of NIH syndrome under the
  pretense of designing a system adapted to the users' needs.

And, as you would expect, it's a nice system, quite flexible for its
  needs though sometimes a bit over-the-top so that you wonder "why
  not use command-line tools instead?", and unfortunately always
  leading in medium-sized teams working on large projects to a lot of
  different people using it with different "best" practices.

Great, We're Doomed! - What Do We Do About It?

Well, in the end, all of the above still holds. If you cannot extract
most of the programming from this system to use more mainstream tools
and languages, you "just" need to adapt it to the constraints of your
system.

About Versioning and Storage

In the end, you can almost always version things, even with the
most constrained and walled environment. Most often than not, these
systems still come with their own versioning (which is unfortunately
often rather basic, and just offers to revert to previous versions
without much visibility, just keeping previous snapshots). It's not
exactly using differential changesets like your SCM of choice might,
and it's probably not suited for multiple users submitting changes
simultaneously.

But still, if they do provide such a functionality, maybe your
solution is to follow our beloved industry-standard guidelines above,
and to transpose them to this programming system!!

If the storage system is a database, it probably exposes export
functionalities, or can be backed-up at the file-system level. If it's
using a custom binary format, maybe you can simply try to version it
with a VCS that has good support for binary data. You won't have
fine-grained control, but at least you'll have your back sort of
covered against catastrophes and have a certain degree of disaster
recovery compliance.

About Testing

Implement your tests within the platform itself, and use external
tools and background jobs to set up regular backups. Quite probably,
you fire up these tests the same that you would fire up the programs
developed with this programming system.

Sure, it's a hack job and definitely not up to the standard of what is
common for "normal" programming, but the idea is to adapt to the
system while trying to maintain a semblance of professional software
development process.

The Road is Long and Steep...

As always with niche environments and bespoke programming systems, and
as we exposed above, you deal with strange formats, only a limited (or
totally inexistant) set of possibly clunky tools, and a void in place
of a community.

The Recommendation: Try to implement the above guidelines outside
of your bespoke programming system, as much as possible. This ensures
that you can rely on "common" tools, which have proper support and
community drive.

The Workaround: When this is not an option, try to retrofit this
global framework into your "box". The idea is to overlay this
blueprint of industry standard best practices on top of your
programming system, and make the best of it. The advice still applies:
define structure and best practices, encourage conformance.

Unfortunately, this implies that you may need to dive in and do a
tremendous amount of leg-work. So...

Famous Last Words, and Humble Requests:

Document everything you do.

Share your experience.

Open Source any tool your write.

By doing all of this, you will:

not only increase your chances of getting support from people in
similar situations,

but also provide help to other people, and foster discussion
around your technology stack.

Who knows, you could be at the very beginning of a new vibrant
community of Obscure Language X. If there are none, start one!

Ask questions on Stack Overflow,

Maybe even write a proposal for a new StackExchange Site in the
Area 51.

Maybe it's beautiful inside, but nobody has a clue so far, so
help take down this ugly wall and let others have a peek!

Body:
Foreword

This is a daunting task indeed, and there's a lot of ground to
cover. So I'm humbly suggesting this as somewhat comprehensive guide
for your team, with pointers to appropriate tools and educational
material.

Remember: These are guidelines, and that as such are meant to
adopted, adapted, or dropped based on circumstances.

Beware: Dumping all this on a team at once would most likely
fail. You should try to cherry-pick elements that would give you the
best bang-for-sweat, and introduce them slowly, one at a time.

Note: not all of this applies directly to Visual Programming
Systems like G2. For more specific details on how to deal with these,
see the Addendum section at the end.

Executive Summary for the Impatient

Define a rigid project structure, with:

project templates,

coding conventions,

familiar build systems,

and sets of usage guidelines for your infrastructure and tools.

Install a good SCM and make sure they know how to use it.

Point them to good IDEs for their technology, and make sure they know how to use them.

Implement code quality checkers and automatic reporting in the build system.

Couple the build system to continuous integration and continuous inspection systems.

With the help of the above, identify code quality "hotspots" and refactor.

Now for the long version... Caution, brace yourselves!

Rigidity is (Often) Good

This is a controversial opinion, as rigidity is often seen as a force
working against you. It's true for some phases of some projects. But
once you see it as a structural support, a framework that takes away
the guesswork, it greatly reduces the amount of wasted time and
effort. Make it work for you, not against you.

Rigidity = Process / Procedure.

Software development needs good process and procedures for exactly the
same reasons that chemical plants or factories have manuals,
procedures, drills and emergency guidelines: preventing bad outcomes,
increasing predictability, maximizing productivity...

Rigidity comes in moderation, though!

Rigidity of the Project Structure

If each project comes with its own structure, you (and newcomers) are
lost and need to pick up from scratch every time you open them. You
don't want this in a professional software shop, and you don't want
this in a lab either.

Rigidity of the Build Systems

If each project looks different, there's a good chance they also
build differently. A build shouldn't require too much research or
too much guesswork. You want to be able to do the canonical thing and
not need to worry about specifics: configure; make install, ant,
mvn install, etc...

Re-using the same build system and making it evolve over the time also
ensures a consistent level of quality.

You do need a quick README to point the project's specifics, and
gracefully guide the user/developer/researcher, if any.

This also greatly facilitates other parts of your build
infrastructure, namely:

continuous integration,

continuous inspection.

So keep your build (like your projects) up to date, but make it
stricter over time, and more efficient at reporting violations and bad
practices.

Do not reinvent the wheel, and reuse what you have already done.

Recommended Reading:

Continuous Integration: Improving Software Quality and Reducing Risk (Duval, Matyas, Glover, 2007)

Continuous Delivery: Release Sotware Releases through Build, Test and Deployment Automation (Humble, Farley, 2010)

Rigidity in the Choice of Programming Languages

You can't expect, especially in a research environment, to have all
teams (and even less all developers) use the same language and
technology stack. However, you can identify a set of "officially
supported" tools, and encourage their use. The rest, without a good
rationale, shouldn't be permitted (beyond prototyping).

Keep your tech stack simple, and the maintenance and breadth of
required skills to a bare minimum: a strong core.

Rigidity of the Coding Conventions and Guidelines

Coding conventions and guidelines are what allow you to develop both
an identity as a team, and a shared lingo. You don't want to err
into terra incognita every time you open a source file.

Nonsensical rules that make life harder or forbid actions explicity
to the extent that commits are refused based on single simple
violations are a burden. However:

a well thought-out ground ruleset takes away a lot of the whining
and thinking: nobody should break under no circumstances;

and a set of recommended rules provide additional guidance.

Personal Approach: I am aggressive when it comes to coding
  conventions, some even say nazi, because I do believe in having a
  lingua franca, a recognizable style for my team. When crap code
  gets checked-in, it stands out like a cold sore on the face of an
  Hollywood star: it triggers a review and an action automatically.
  In fact, I've sometimes gone as far as to advocate the use of
  pre-commit hooks to reject non-conforming commits. As mentioned, it
  shouldn't be overly crazy and get in the way of productivity: it
  should drive it. Introduce these slowly, especially at the
  beginning. But it's way preferable over spending so much time fixing
  faulty code that you can't work on real issues.

Some languages even enforce this by design:

Java was meant to reduce the amount of dull crap you can write with
it (though no doubt many manage to do it).

Python's block structure by indentation is another idea in this
sense.

Go, with its gofmt tool, which completely takes away any debate
and effort (and ego!!) inherent to style: run gofmt before
you commit.

Make sure that code rot cannot slip through. Code
conventions, continuous integration and continuous
inspection, pair programming and code reviews are your
arsenal against this demon.

Plus, as you'll see below, code is documentation, and that's
another area where conventions encourage readability and clarity.

Rigidity of the Documentation

Documentation goes hand in hand with code. Code itself is
documentation. But there must be clear-cut instructions on how to
build, use, and maintain things.

Using a single point of control for documentation (like a WikiWiki or
DMS) is a good thing. Create spaces for projects, spaces for more
random banter and experimentation. Have all spaces reuse common rules
and conventions. Try to make it part of the team spirit.

Most of the advice applying to code and tooling also applies to
documentation.

Rigidity in Code Comments

Code comments, as mentioned above, are also documentation. Developers
like to express their feelings about their code (mostly pride and
frustration, if you ask me). So it's not unusual for them to express
these in no uncertain terms in comments (or even code), when a more
formal piece of text could have conveyed the same meaning with less
expletives or drama. It's OK to let a few slip through for fun and
historical reasons: it's also part of developing a team
culture. But it's very important that everybody knows what is
acceptable and what isn't, and that comment noise is just that:
noise.

Rigidity in Commit Logs

Commit logs are not an annoying and useless "step" of your SCM's
lifecycle: you DON'T skip it to get home on time or get on with the
next task, or to catch up with the buddies who left for lunch.  They
matter, and, like (most) good wine, the more time passes the more valuable
they become. So DO them right. I'm flabbergasted when I see co-workers
writing one-liners for giant commits, or for non-obvious hacks.

Commits are done for a reason, and that reason ISN'T always clearly
expressed by your code and the one line of commit log you
entered. There's more to it than that.

Each line of code has a story, and a history. The diffs can tell
its history, but you have to write its story.

Why did I update this line? -> Because the interface changed.

Why did the interface changed? -> Because the library L1 defining it
  was updated.

Why was the library updated? -> Because library L2, that we need for
  feature F, depended on library L1.

And what's feature X? -> See task 3456 in issue tracker.

It's not my SCM choice, and may not be the best one for your lab
either; but Git gets this right, and tries to force you to write
good logs more than most other SCMs systems, by using short logs and
long logs. Link the task ID (yes, you need one) and a leave a
generic summary for the shortlog, and expand in the long log: write
the changeset's story.

It is a log: It's here to keep track and record updates.

Rule of Thumb: If you were searching for something about this
  change later, is your log likely to answer your question?

Projects, Documentation and Code Are ALIVE

Keep them in sync, otherwise they do not form that symbiotic entity
anymore. It works wonders when you have:

clear commits logs in your SCM, w/ links to task IDs in your
issue tracker,

where this tracker's tickets themselves link to the changesets in
your SCM (and possibly to the builds in your CI system),

and a documentation system that links to all of these.

Code and documentation need to be cohesive.

Rigidity in Testing

Rules of Thumb:

Any new code shall come with (at least) unit tests.

Any refactored legacy code shall come with unit tests.

Of course, these need:

to actually test something valuable (or they are a waste of time
and energy),

to be well written and commented (just like any other code you check in).

They are documentation as well, and they help to outline the contract
of your code. Especially if you use TDD. Even if you don't, you
need them for your peace of mind. They are your safety net when you
incorporate new code (maintenance or feature) and your watchtower
to guard against code rot and environmental failures.

Of course, you should go further and have integration tests, and
regression tests for each reproducible bug you fix.

Rigidity in the Use of the Tools

It's OK for the occasional developer/scientist to want to try some new
static checker on the source, generate a graph or model using another,
or implement a new module using a DSL. But it's best if there's a
canonical set of tools that all team members are expected to know
and use.

Beyond that, let members use what they want, as long as they are ALL:

productive,

NOT regularly requiring assistance

NOT regularly adjusting to your general infrastructure,

NOT disrupting your infrastructure (by modifying common
areas like code, build system, documentation...),

NOT affecting others' work,

ABLE to timely perform any task requested.

If that's not the case, then enforce that they fallback to defaults.

Rigidity vs Versatility, Adaptability, Prototyping and Emergencies

Flexibility can be good. Letting someone occasionally use a hack, a
quick-n-dirty approach, or a favorite pet tool to get the job done
is fine. NEVER let it become a habit, and NEVER let this code
become the actual codebase to support.

Team Spirit Matters

Develop a Sense of Pride in Your Codebase

Develop a sense of Pride in Code

Use wallboards

leader board for a continuous integration game

wallboards for issue management and defect counting

Use an issue tracker / bug tracker

Avoid Blame Games

DO use Continuous Integration / Continuous Inspection games: it
fosters good-mannered and productive competition.

DO keep track defects: it's just good house-keeping.

DO identifying root causes: it's just future-proofing processes.

BUT DO NOT assign blame: it's counter productive.

It's About the Code, Not About the Developers

Make developers conscious of the quality of their code, BUT make them
see the code as a detached entity and not an extension of
themselves, which cannot be criticized.

It's a paradox: you need to encourage ego-less programming for a
healthy workplace but to rely on ego for motivational purposes.

From Scientist to Programmer

People who do not value and take pride in code do not produce good
code. For this property to emerge, they need to discover how valuable
and fun it can be. Sheer professionalism and desire to do good is not
enough: it needs passion. So you need to turn your scientists into
programmers (in the large sense).

Someone argued in comments that after 10 to 20 years on a project and
its code, anyone would feel attachment. Maybe I'm wrong but I assume
they're proud of the code's outcomes and of the work and its legacy,
not of the code itself or of the act of writing it.

From experience, most researchers regard coding as a necessity, or at
best as a fun distraction. They just want it to work. The ones who are
already pretty versed in it and who have an interest in programming
are a lot easier to persuade of adopting best practices and switching
technologies. You need to get them halfway there.

Code Maintenance is Part of Research Work

Nobody reads crappy research papers. That's why they are
peer-reviewed, proof-read, refined, rewritten, and approved time and
time again until deemed ready for publication. The same applies to a
thesis and a codebase!

Make it clear that constant refactoring and refreshing of a codebase
prevents code rot and reduces technical debt, and facilitates future
re-use and adaptation of the work for other projects.

Why All This??!

Why do we bother with all of the above? For code quality. Or is it
quality code...?

These guidelines aim at driving your team towards this goal. Some
aspects do it by simply showing them the way and letting them do it
(which is much better) and others take them by the hand (but that's
how you educate people and develop habits).

How do you know when the goal is within reach?

Quality is Measurable

Not always quantitatively, but it is measurable. As mentioned, you
need to develop a sense of pride in your team, and showing progress
and good results is key. Measure code quality regularly and show
progress between intervals, and how it matters. Do retrospectives to
reflect on what has been done, and how it made things better or worse.

There are great tools for continuous inspection. Sonar being
a popular one in the Java world, but it can adapt to any technologies;
and there are many others. Keep your code under the microscope and
look for these pesky annoying bugs and microbes.

But What if My Code is Already Crap?

All of the above is fun and cute like a trip to Never Land, but it's
not that easy to do when you already have (a pile of steamy and
smelly) crap code, and a team reluctant to change.

Here's the secret: you need to start somewhere.

Personal anecdote: In a project, we worked with a codebase
  weighing originally 650,000+ Java LOC, 200,000+ lines of JSPs,
  40,000+ JavaScript LOC, and 400+ MBs of binary dependencies.

After about 18 months, it's 500,000 Java LOC (MOSTLY CLEAN),
  150,000 lines of JSPs, and 38,000 JavaScript LOC, with dependencies
  down to barely 100MBs (and these are not in our SCM anymore!).

How did we do it? We just did all of the above. Or tried hard.

It's a team effort, but we slowly inject in our process
  regulations and tools to monitor the heart-rate of our product,
  while hastily slashing away the "fat": crap code, useless
  dependencies... We didn't stop all development to do this: we have
  occasional periods of relative peace and quiet where we are free to
  go crazy on the codebase and tear it apart, but most of the time we
  do it all by defaulting to a "review and refactor" mode every chance
  we get: during builds, during lunch, during bug fixing sprints,
  during Friday afternoons...

There were some big "works"... Switching our build
  system from a giant Ant build of 8500+ XML LOC to a
  multi-module Maven build was one of them. We then had:

clear-cut modules (or at least it was already a lot better, and we
  still have big plans for the future),

automatic dependency management (for easy maintenance and updates, and
  to remove useless deps),

faster, easier and reproduceable builds,

daily reports on quality.

Another was the injection of "utility tool-belts", even though we
  were trying to reduce dependencies: Google Guava and Apache Commons
  slim down your code and and reduce surface for bugs in your code
  a lot.

We also persuaded our IT department that maybe using our new tools
  (JIRA, Fisheye, Crucible, Confluence, Jenkins) was better than the
  ones in place. We still needed to deal with some we despised (QC,
  Sharepoint and SupportWorks...), but it was an overall improved
  experience, with some more room left.

And every day, there's now a trickle of between one to dozens of
  commits that deal only with fixing and refactoring things. We
  occasionally break stuff (you need unit tests, and you better write
  them before you refactor stuff away), but overall the benefit
  for our morale AND for the product has been enormous. We get there
  one fraction of a code quality percentage at a time. And it's fun
  to see it increase!!!

Note: Again, rigidity needs to be shaken to make room for new and
better things. In my anecdote, our IT department is partly right in
trying to impose some things on us, and wrong for others. Or maybe
they used to be right.  Things change. Prove that they are better
ways to boost your productivity. Trial-runs and prototypes are
here for this.

The Super-Secret Incremental Spaghetti Code Refactoring Cycle for Awesome Quality

       +-----------------+      +-----------------+
       |  A N A L Y Z E  +----->| I D E N T I F Y |
       +-----------------+      +---------+-------+
                ^                           |
                |                           v
       +--------+--------+      +-----------------+
       |    C L E A N    +<-----|      F I X      |
       +-----------------+      +-----------------+

Once you have some quality tools at your toolbelt:

Analyze your code with code quality checkers.

Linters, static analyzers, or what have you.

Identify your critical hotspots AND low hanging fruits.

Violations have severity levels, and large classes with a large number
 of high-severity ones are a big red flag: as such, they appear as
 "hot spots" on radiator/heatmap types of views.

Fix the hotspots first.

It maximizes your impact in a short timeframe as they have
 the highest business value. Ideally, critical violations should
 dealt with as soon as they appear, as they are potential security
 vulnerabilities or crash causes, and present a high risk of inducing a
 liability (and in your case, bad performance for the lab).

Clean the low level violations with automated codebase sweeps.

It improves the signal-to-noise ratio so you are be able to
 see significant violations on your radar as they appear. There's often
 a large army of minor violations at first if they were never taken care
 of and your codebase was left loose in the wild. They do not present a
 real "risk", but they impair the code's readability and maintainability.
 Fix them either as you meet them while working on a task, or by large
 cleaning quests with automated code sweeps if possible. Do be
 careful with large auto-sweeps if you don't have a good test suite
 and integration system. Make sure to agree with co-workers
 the right time to run them to minimize the annoyance.

Repeat until you are satisfied.

Which, ideally, you should never be, if this is still an
 active product: it will keep evolving.

Quick Tips for Good House-Keeping

When in hotfix-mode, based on a customer support request:

It's usually a best practice to NOT go around fixing other issues,
as you might introduce new ones unwillingly.

Go at it SEAL-style: get in, kill the bug, get out, and ship your
patch. It's a surgical and tactical strike.

But for all other cases, if you open a file, make it your duty to:

definitely: review it (take notes, file issue reports),

maybe: clean it (style cleanups and minor violations),

ideally: refactor it (reorganize large sections and their neigbors).

Just don't get sidetracked into spending a week from file to file and
ending up with a massive changeset of thousands of fixes spanning multiple
features and modules - it makes future tracking difficult. One issue in
code = one ticket in your tracker. Sometimes, a changeset can impact multiple
tickets; but if it happens too often, then you're probably doing something wrong.

Addendum: Managing Visual Programming Environments

The Walled Gardens of Bespoke Programming Systems

Multiple programming systems, like the OP's G2, are different beasts...

No Source "Code"

Often they do not give you access to a textual representation of
your source "code": it might be stored in a proprietary binary
format, or maybe it does store things in text format but hides
them away from you. Bespoke graphical programming systems are
actually not uncommon in research labs, as they simplify the
automation of repetitive data processing workflows.

No Tooling

Aside from their own, that is. You are often constrained by their
programming environment, their own debugger, their own
interpreter, their own documentation tools and formats. They are
walled gardens, except if they eventually capture the interest
of someone motivated enough to reverse engineer their formats and
builds external tools - if the license permits it.

Lack of Documentation

Quite often, these are niche programming systems, which are used
in fairly closed environments. People who use them frequently sign NDAs
and never speak about what they do. Programming
communities for them are rare. So resources are scarce. You're
stuck with your official reference, and that's it.

The ironic (and often frustrating) bit is that all the things these
systems do could obviously be achieved by using mainstream and general
purpose programming languages, and quite probably more
efficiently. But it requires a deeper knowledge of programming,
whereas you can't expect your biologist, chemist or physicist (to name
a few) to know enough about programming, and even less to have the
time (and desire) to implement (and maintain) complex systems, that
may or may not be long-lived. For the same reason we use DSLs, we have
these bespoke programming systems.

Personal Anecdote 2: Actually, I worked on one of these
  myself. I didn't do the link with the OP's request, but my the
  project was a set of inter-connected large pieces of
  data-processing and data-storage software (primarily for
  bio-informatics research, healthcare and cosmetics, but also for
  business intelligence, or any domain implying the tracking of
  large volumes of research data of any kind and the preparation of
  data-processing workflows and ETLs). One of these applications was,
  quite simply, a visual IDE that used the usual bells and whistles:
  drag and drop interfaces, versioned project workspaces (using text
  and XML files for metadata storage), lots of pluggable drivers to
  heterogeneous datasources, and a visual canvas to design pipelines
  to process data from N datasources and in the end generate M
  transformed outputs, and possible shiny visualizations and complex
  (and interactive) online reports. Your typical bespoke visual
  programming system, suffering from a bit of NIH syndrome under the
  pretense of designing a system adapted to the users' needs.

And, as you would expect, it's a nice system, quite flexible for its
  needs though sometimes a bit over-the-top so that you wonder "why
  not use command-line tools instead?", and unfortunately always
  leading in medium-sized teams working on large projects to a lot of
  different people using it with different "best" practices.

Great, We're Doomed! - What Do We Do About It?

Well, in the end, all of the above still holds. If you cannot extract
most of the programming from this system to use more mainstream tools
and languages, you "just" need to adapt it to the constraints of your
system.

About Versioning and Storage

In the end, you can almost always version things, even with the
most constrained and walled environment. Most often than not, these
systems still come with their own versioning (which is unfortunately
often rather basic, and just offers to revert to previous versions
without much visibility, just keeping previous snapshots). It's not
exactly using differential changesets like your SCM of choice might,
and it's probably not suited for multiple users submitting changes
simultaneously.

But still, if they do provide such a functionality, maybe your
solution is to follow our beloved industry-standard guidelines above,
and to transpose them to this programming system!!

If the storage system is a database, it probably exposes export
functionalities, or can be backed-up at the file-system level. If it's
using a custom binary format, maybe you can simply try to version it
with a VCS that has good support for binary data. You won't have
fine-grained control, but at least you'll have your back sort of
covered against catastrophes and have a certain degree of disaster
recovery compliance.

About Testing

Implement your tests within the platform itself, and use external
tools and background jobs to set up regular backups. Quite probably,
you fire up these tests the same that you would fire up the programs
developed with this programming system.

Sure, it's a hack job and definitely not up to the standard of what is
common for "normal" programming, but the idea is to adapt to the
system while trying to maintain a semblance of professional software
development process.

The Road is Long and Steep...

As always with niche environments and bespoke programming systems, and
as we exposed above, you deal with strange formats, only a limited (or
totally inexistant) set of possibly clunky tools, and a void in place
of a community.

The Recommendation: Try to implement the above guidelines outside
of your bespoke programming system, as much as possible. This ensures
that you can rely on "common" tools, which have proper support and
community drive.

The Workaround: When this is not an option, try to retrofit this
global framework into your "box". The idea is to overlay this
blueprint of industry standard best practices on top of your
programming system, and make the best of it. The advice still applies:
define structure and best practices, encourage conformance.

Unfortunately, this implies that you may need to dive in and do a
tremendous amount of leg-work. So...

Famous Last Words, and Humble Requests:

Document everything you do.

Share your experience.

Open Source any tool your write.

By doing all of this, you will:

not only increase your chances of getting support from people in
similar situations,

but also provide help to other people, and foster discussion
around your technology stack.

Who knows, you could be at the very beginning of a new vibrant
community of Obscure Language X. If there are none, start one!

Ask questions on Stack Overflow,

Maybe even write a proposal for a new StackExchange Site in the
Area 51.

Maybe it's beautiful inside, but nobody has a clue so far, so
help take down this ugly wall and let others have a peek!


问:
Are proofs worth the effort?
I bought the de-facto book for learning about data structures and algorithms (CLRS). The book is though quite good but the singularity is in the proofs. The book is filled with Lemmas, theorems, peculiar symbols and unimaginable recurrence relations which are very hard to understand. I am able to somehow get the algorithms but the discrete mathematics just not for me.

So should I leave them out and just concentrate on algorithims?

答:
Here is a great example of why proofs are necessary and why you should be able to understand and come up with them: https://stackoverflow.com/q/11320423/811001

Many times while programming, you'll have to come up with your own ad-hoc algorithms. Or perhaps you need to make an optimization to an existing algorithm. In those cases, you better be able to back up your algorithm/optimization with a proof of why it works.

Title: Are proofs worth the effort?


问:
What is meant by "Now you have two problems"?
There is a popular quote by Jamie Zawinski:

Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.

How is this quote supposed to be understood?

答: In addition to ChrisF's answer - that regular expressions "are difficult to code, understand and maintain", there's worse: they're just powerful enough to trick people into trying to use them to parse things they can't, like HTML. See the numerous questions on SO on "how do I parse HTML?" For instance, the single most epic answer in all of SO!</p>


问:
Debugger for file I/O development?
Okay, the question title may be a bit cryptic. But it aptly describes what I'm looking for:

I think every experienced coder went through this numerous times: You get a binary file format specification, you implement the reader for it, and… nothing works like expected. So you run your code in the debugger, go execute through the code line by line, every header field is read in seemingly correct, but when it comes to the bulk data, offset and indices no longer match up.

What would really help in this situation was a binary file viewer, that shows you the progress of your file pointer, as you step through the code, and ideally would also highlight all memory maps. Then you could see the context of the current I/O operations, most notably those darn "off-by-one" mistakes, which are even more annoying when reading a file.

Implementing such a debugger should not be too hard. traces on the process' file descriptors/handles and triggers on the I/O functions, to update the display.

Only: I don't know of such a kind of debugger to exist. Do I just lack knowledge about the existance of such a tool, or is there really no such thing?

答:
As every binary file format (Just like text files) is different, there cannot be a single tool that does it for everyone.  Unless you write one yourself, or the writer of the spec has one for you, you will be out of luck. A decent editor that support binary viewing of files is mandatory, as a an ability and willingness to do Hex math.

Binary files are not hard, the only difference to a text file is that programmers every where seem to quake in their boots when the hear the term.

My experience (coming from embedded systems) is most people have problems because of bad assumptions - things like a Byte is 8 bits and a word is 32. A methodical approach and no assumptions are the best way to deal with your problems.

Title: Debugger for file I/O development?


答:
Suggestion #1: GUI tools:

Process Monitor is exactly such a tool available for free, on Microsoft Windows x86 and x64.
http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx

Suggestion #2: Build your own tools:

A complex file format can often be thought of as a deeply nested tree structure of "containers". The actual data on the file may be linked with offset pointers, but this doesn't prevent you from building a conceptual, hierarchical view of the file's structure.

What's the easiest way to display such a structure? XML.

Suggestion #3: implement your decoder to an interface that's debugger-friendly

Take a look at the IStream interface (COM), and consider refactoring your code to work with these elementary file operations:

Seek

Read

Write

SetSize

Along with a bunch of Decorator classes (implementing the IStream interface), you can implement readers for very sophisticated file formats.

As an example, the image encoders and decoders in Windows Imaging Component are implemented with such architecture.

This approach will not lead to great I/O performance; but if you can't get a correct implementation, focusing on performance will be futile.

Title: Debugger for file I/O development?

Body:
Okay, the question title may be a bit cryptic. But it aptly describes what I'm looking for:

I think every experienced coder went through this numerous times: You get a binary file format specification, you implement the reader for it, and… nothing works like expected. So you run your code in the debugger, go execute through the code line by line, every header field is read in seemingly correct, but when it comes to the bulk data, offset and indices no longer match up.

What would really help in this situation was a binary file viewer, that shows you the progress of your file pointer, as you step through the code, and ideally would also highlight all memory maps. Then you could see the context of the current I/O operations, most notably those darn "off-by-one" mistakes, which are even more annoying when reading a file.

Implementing such a debugger should not be too hard. traces on the process' file descriptors/handles and triggers on the I/O functions, to update the display.

Only: I don't know of such a kind of debugger to exist. Do I just lack knowledge about the existance of such a tool, or is there really no such thing?


问:
How to verify that all files are intact prior to install?
I'm working on my CMS (in PHP platform) for a long time now. The main program is done and I'm currently developing the Installer part. Installation itself will be fairly simple:

Upload all files

Verify that the "content/" dir has correct permissions

Check if ALL files are intact and not modified [This is the subject of this question]

Insert the config data and first settings

Run install (Generate all DB tables and insert sample data etc.)

Now the question-mark is at step 3. How do I verify ALL files? Verification itself should compare all CMS root-directories files against a list from remote location. List should contain filename, filesize and filetype. This way the user can check, that there are no unnecessary or corrupted files, that could indicated a breach in the software.

I have seen some software installers do that, but I cannot find any right now and there for I'm clueless on the most optimal method for this. Of course there always is a simple array trick, but there surely must be a better and faster method?!

答:
First of all, I'd say checking for 'unnecessary' files is not really a good idea. The user might have installed your CMS in a common folder with another piece of software.
On the other hand, if you confirm your own files are not corrupt, it should be OK, since a user has to edit your files in order to introduce something else in your CMS (otherwise your design is suboptimal, but it can happen if you import all files that fit a pattern; you shouldn't depend on this).

Another thing: in PHP (to my knowledge) you can't really make sure your files don't get edited to include a 'crack' to your security mechanism. This in turn means everything you do in the installer is theoretically useless, since it can be defeated by a smart enough adversary.

So, on the topic.
If possible, use Public-key cryptography instead of hashing.

You can easily include a list of files and check them with sha1_file (hash) or a better equivalent (PKC).
Then compare the computed values with the proper values and generate error messages if there are discrepancies.

If you really want to make sure only your files are on the server, use readdir to generate the list of files and check it against your bundle. This is all pretty straight-forward IMO.


答:
To check file integrity, generate and compare hashes of your files with the originals. For protecting against corrupted downloads, CRC-32 or MD5 would suffice. However if you want to ensure the files weren't altered by a malicious third-party, for whatever reason, look into SHA-1. All three are widely used and implemented and should be available for PHP.

Also, as K.Steff already noted, you can't prevent changes to be made to your software that way. Due to PHP being interpreted, files can easily be altered after installation.

Title: How to verify that all files are intact prior to install?

Body:
I'm working on my CMS (in PHP platform) for a long time now. The main program is done and I'm currently developing the Installer part. Installation itself will be fairly simple:

Upload all files

Verify that the "content/" dir has correct permissions

Check if ALL files are intact and not modified [This is the subject of this question]

Insert the config data and first settings

Run install (Generate all DB tables and insert sample data etc.)

Now the question-mark is at step 3. How do I verify ALL files? Verification itself should compare all CMS root-directories files against a list from remote location. List should contain filename, filesize and filetype. This way the user can check, that there are no unnecessary or corrupted files, that could indicated a breach in the software.

I have seen some software installers do that, but I cannot find any right now and there for I'm clueless on the most optimal method for this. Of course there always is a simple array trick, but there surely must be a better and faster method?!


答:
The only production problem sounds like a change management issue.  If that is the case and the software otherwise performs it purpose the first advice I would give is to resist the urge to do too much too quickly.

Source control, refactoring, more trained devs are all good suggestions, but if this is the first time you have had to deal with this sort of issue moving slowly and making controlled changes cannot be emphasized enough.

The urge to shred through the mess will be great at times, but until you have reverse engineered enoughof it that you know you can test your replacement version adequately you need to be very careful.


问:
What is the difference between Windows 8, WinRT, and Windows RT?
I just read that there will be two versions of Windows available: Windows RT and Windows 8.

Could someone please describe what the differences between Windows RT and Windows 8 are? And how these differences may affect developers creating apps for one or the other?

Also, what is WinRT?

答:
In Brief...

WinRT (Windows Runtime, unlikely to be what you meant) is a software layer on top of which Metro apps are built, while Windows 8 is the whole operating system;

Windows RT (most likely the one you meant), this is a version of Windows 8 for devices using processors based on the ARM achitecture and instruction set.

You got the names a bit mixed up apparently - granted they made them confusingly similar -  so I just addressed both and edited your question accordingly.

WinRT / Windows Runtime

WinRT a software layer that sits on top of the OS, and that is at the base of the new Metro design language approach. It's primarily a set of APIs to build Metro apps for all Metro-supported platforms (including for Windows 8 for ARM).

See the image below for a general approximation of the Windows 8 Platform:

Windows RT / Windows 8 for ARM

Windows RT (where RT also means "runtime", to make things as confused as possible), used to be known as Windows 8 for ARM. It is a version targeting hardware manufacturers (mostly aiming at the tablet market).

See this post Announcing the Windows 8 Editions (Archived, July 2012) of the Windows Team's Blogging Windows blog (emphasis mine):

Windows RT is the newest member of the Windows family – also known as Windows on ARM or WOA, as we’ve referred to it previously. This single edition will only be available pre-installed on PCs and tablets powered by ARM processors and will help enable new thin and lightweight form factors with impressive battery life. Windows RT will include touch-optimized desktop versions of the new Microsoft Word, Excel, PowerPoint, and OneNote. For new apps, the focus for Windows RT is development on the new Windows runtime, or WinRT, which we unveiled in September and forms the foundation of a new generation of cloud-enabled, touch-enabled, web-connected apps of all kinds.

See the original post for a table listing the major differences between the versions, or Wikipedia's Windows 8 Editions article for more details and sources.

Note that only software written using Win RT (the APIs) can run on Windows RT (the OS version).


问:
Is this a decent use-case for goto in C?
I really hesitate to ask this, because I don't want to "solicit debate, arguments, polling, or extended discussion" but I'm new to C and want to gain more insight into common patterns used in the language.

I recently heard some distaste for the goto command, but I've also recently found a decent use-case for it.

Code like this:

```<code>error = function_that_could_fail_1();
if (!error) {
    error = function_that_could_fail_2();
    if (!error) {
        error = function_that_could_fail_3();
        ...to the n-th tab level!
    } else {
        // deal with error, clean up, and return error code
    }
} else {
    // deal with error, clean up, and return error code
}
</code>```

If the clean-up part is all very similar, could be written a little prettier (my opinion?) like this:

```<code>error = function_that_could_fail_1();
if(error) {
    goto cleanup;
}
error = function_that_could_fail_2();
if(error) {
    goto cleanup;
}
error = function_that_could_fail_3();
if(error) {
    goto cleanup;
}
...
cleanup:
// deal with error if it exists, clean up
// return error code
</code>```

Is this a common or acceptable use-case of goto in C? Is there a different/better way to do this?

答:
Take a look at the MISRA (Motor Industry Software Reliability Association) C coding guidelines that allow goto under strict criteria (Which your example meets)

Where I work the same code would be written - no goto needed - Avoiding needless religious debate about them is a big plus in any software house.

```<code>error = function_that_could_fail_1();
if(!error) {
  error = function_that_could_fail_2();
}
if(!error) {
  error = function_that_could_fail_3();
}
if(!error) {
...
if (error) {
  cleanup:
}
</code>```

or for "goto in drag" - something even more dodgy than goto, but gets around the "No goto Ever!!!" camp) "Surely it must be OK, does not use Goto" ....

```<code>do {
  if (error = function_that_could_fail_1() ){
    break
  }
  if (error = function_that_could_fail_2() ){
    break
  }
  .......
} while (0)
cleanup();
....
</code>```

If the functions have the same parameter type, put them into a table and use a loop -

Body:
Take a look at the MISRA (Motor Industry Software Reliability Association) C coding guidelines that allow goto under strict criteria (Which your example meets)

Where I work the same code would be written - no goto needed - Avoiding needless religious debate about them is a big plus in any software house.

error = function_that_could_fail_1();
if(!error) {
  error = function_that_could_fail_2();
}
if(!error) {
  error = function_that_could_fail_3();
}
if(!error) {
...
if (error) {
  cleanup:
}

or for "goto in drag" - something even more dodgy than goto, but gets around the "No goto Ever!!!" camp) "Surely it must be OK, does not use Goto" ....

do {
  if (error = function_that_could_fail_1() ){
    break
  }
  if (error = function_that_could_fail_2() ){
    break
  }
  .......
} while (0)
cleanup();
....

If the functions have the same parameter type, put them into a table and use a loop -


问:
How is programming affected by spatial aptitude?

Background

The longer I work on a project, the less clear it becomes. It's like I cannot seperate various classes/objects anymore in my head. Everything starts mixing up, and it's extremely hard to take it all apart again. I start putting functions in classes where they really don't belong, and make silly mistakes such as writing code that I later find was 100% obsolete; things are no longer clearly mappable in my head. It isn't until I take a step back for several hours (or days sometimes!) that I can actually see what's going on again, and be productive.

I usually try to fight through this, I am so passionate about coding that I wouldn't for the life of me know what else I could be doing. This is when stuff can get really weird, I get so up in my head that I sort of lose touch with reality (to some extent) in that various actions, such as pouring a glass of water, no longer happen on a concious level. It happens on auto pilot, during which pretty much all of my concious concentration (is that even a thing?) is devoted to borderline pointless problem solving (trying to seperate elements of code). It feels like a losing battle.

So I took an IQ test a while ago (Wechsler Adult Intelligence Scale I believe it was) and it turned out my Spatial Aptitude was quite low. I still got a decent total score, just above average, so I won't have to poke things with a stick for a living, but I am a little worried that this is such a handicap when writing/engineering computer programs that I won't ever be able to do it seriously or professionally.

Question

I am very much interested in what other people think of this...

Could a low spatial aptitude be the cause of the above described problems?

How is programming affected by spatial aptitude?

Maybe I should be looking more along the lines of ADD or something similar, because I did get diagnosed with ADD at the age of 17 (5 years ago) but the medicine I received didn't seem to affect me that much so I never took it all that serious.

As far as I know people are born with low/med/high spatial aptitude, so I think it's interesting to find out if the more fortunate are better programmers by birth right.

答:
There's actually some hard research data on this, mostly collected over the past 35 years, and I also have experienced a few similar phenomenons, though not on a regular basis. See below for more.

Research Data

There appears to be some but minor correlation based on research performed and summarized in the following works. As often with research though, the study models differ between studies and they should be closely reviewed to understand why results present differences in conclusions.

Exploring the psychological predictors of programming achievement [PDF] (Erdogan, Aydin, Kabaca, 2008)

Unfortunately this one is vague on details. It points to the "high-impact" of "aptitudes" in general, but then only points to other research without giving the results for each aptitude test, so we don't know how spatial ability fares. It's mostly a litterature review more than actual research.

Spatial ability and learning to program [PDF] (Jones, 2008)

From the results of this analysis, there is evidence that spatial ability
  is important when learning to program. [...] While spatial ability has
  been shown to be relevant, we do not feel that mental rotation capacity
  should be used as a means of predetermining programming aptitude, but
  should be considered while devising pedagogical interventions. Thought
  needs to be given to teaching methods and software visualizations that
  help students with low spatial ability to envisage abstract concepts
  and build better mental models (Wiedenbeck et al., 2004).

Predictors of Success in a First Programming Course [PDF] (Simon, Fincher & al., 2006)

Only a small positive correlation  was found between
  scores in the spatial visualisation (paper folding) task and
  programming marks. This suggests that components of
  IQ other than spatial skills may account for most of the
  effect of IQ on programming success (Mayer et al 1989).

Who is likely to acquire programming skills? (Shute, 1991)

Hemispheric Lateralization and Programming Ability, (Gasen, Morecroft, 1990)

Correlates of problem-solving in programming [PDF] (Choi-man, 1988)

Interesting one... Nice study model, and quantified results with several study groups and accounting for the reliability of study factors. It yields that:

[...] it could be
  seen that, for the males, mathematics alone
  could account for 30.90% of variance on
  programming ability, and that spatial test
  could account for 8.00%. [...]

[...] it could
  also be seen that, for females, only the
  performance of mathematics and spatial
  tests had significant effect in predicting the
  programming ability.

Results of this study revealed that
  students who scored high in mathematics
  test and spatial test would score high in
  programming ability test.

Learning, research, and the graphical representation of programming (Taylor, Cunniff, Uchiyama, 1986)

Cognitive Requirements of Learning Computer Programming in Group and Individual Settings (Webb, 1985)

Cognitive correlates of programming tasks in novice programmers (Irons, 1982)

Research on aptitude for learning: A progress report [PDF] (RE Snow, 1976)

Take it with a pinch of salt: Some are relatively dated, IQ tests might have changed since. I haven't done an in-depth search to find citations of each article to see if they were confirmed or debunked later on.

Some links (especially the [PDF] kind) may not work for you if you don't have an affiliation to a library giving access to these online contents.

Personal Opinion

Warning and disclosure: I am NEITHER a psychologist NOR a neurologist, but I have been studying and teaching programming to both small kids (starting 6) and university students (up to 60!).

Having studied with AND taught students as university teacher myself, including some students affected by spatial problems (and others with stronger disabilities), I have to say that while it could have been (I didn't keep track of my students based on disabilities, obviously) that some would have registered in a lower part of the general curve, I still remember clearly some scoring high (and even one in particular being the class' major for at least 2 years).

My point is, while it may have an effect, and as shown by some of the research above, it doesn't account for the largest part of your ability to learn to program and think like a programmer. It's inconsequential, in that it won't stop you to learn if you really want to, and won't prevent you from working in the general case, though it could (as might be your case) make it slightly harder for you.

There's virtually no limit to what and how fast you can learn.

After all, no programmer doesn't like a good challenge, right? (I'm looking at you, RSI)

Personal (Possibly Unrelated) Experience

It might be that you are too passionate. How many hours do you work per day and per week? Do you take regular breaks?

A Similar Case?

At a period in my life, I worked days of at least 14 hours every day of the week, the whole year, to a point where it culminated to record weeks of 120 hours of work in front of a computer screen. Yes, that's only 48 hours left per week to eat, sleep, travel to and from work (tip: avoid driving!!), shower and other vital functions. At this particular point, I could pretty much go to sleep in a heart-beat (though usually having sleeping problems), but I would almost always keep dreaming of code, and I would also suddenly realize in the shower or even when walking or running or doing menial tasks that my mind went back to it in auto-pilot, as you said it yourself. Unfortunately, I wouldn't magically solve problems in my sleep; it would be closer to what you seem to describe and experience: a giant maelstrom of confused thoughts turning around in my head, which would sort of (seem to) make sense on a grander scale, but not clearly express any solution and without much success in grabbing one of these thoughts to focus on it, dissect it clearly and turn it into something useful. And this was usually rather tiresome and distressing.

Relaxation Might Help

Maybe you need to calm down just a bit, and relax and work less. Try to find something to take your mind off. Back then, I ended up often renouncing some precious hours of sleeping time to instead do something that would really stop this mad train of thought. It seems counterproductive, but I actually preferred to do a few thing where I would really relax than to sleep more and not be rested. The distraction for the nervous batteries, and the sleep for the physical batteries, in a sense.

Identifying Triggers

If that's not your case, then maybe there's something else involved in triggering this state for you. Try to isolate elements that are present in these situations, and see if you can reproduce this condition in other environments, to see if you find these elements as well. Does it happen more at work or at home, etc...

Isolation

Also, you may already have heard and tried this, but I have a friend with a minor spatial disability, and usually it helps for him, if working on computers, to be a in darker room, to avoid having too many complex views and windows open (to avoid distraction), and in general to keep things rather minimalistic (both in terms of design and colors, and in terms of content and representation).

Try also to take regular breaks, and to let your mind run free for short periods of time every 1 or 2 hours, based on what works best for you. Maybe adopt the Pomodoro technique or something similar (I don't have research on a correlation with this, but it could be helpful in forcing you to take breaks).


答:
How many hours do you work for before starting to see this blurring?  Many average to good programmers I know of work 4, may be 5 hours before taking a coffee or lunch or something.  The longest of such sprints I have read of is when Guy L Steele and Richard M Stallman did a 10 or so hour sprint when writing Emacs.  Steele goes on to say that he would not want to do such a long sprint again.

If you are fairly new to (less than, say, 5000 hours (that number came from Peter Norvig's post on learning to program in ten years, by halving the 10000 hours that he recommends to become an expert programmer)) programming, this sounds very normal except for the part where you say you need days of break.  Perhaps you are burning out yourself to make yourself need such a long break?

Body:
Background

The longer I work on a project, the less clear it becomes. It's like I cannot seperate various classes/objects anymore in my head. Everything starts mixing up, and it's extremely hard to take it all apart again. I start putting functions in classes where they really don't belong, and make silly mistakes such as writing code that I later find was 100% obsolete; things are no longer clearly mappable in my head. It isn't until I take a step back for several hours (or days sometimes!) that I can actually see what's going on again, and be productive.

I usually try to fight through this, I am so passionate about coding that I wouldn't for the life of me know what else I could be doing. This is when stuff can get really weird, I get so up in my head that I sort of lose touch with reality (to some extent) in that various actions, such as pouring a glass of water, no longer happen on a concious level. It happens on auto pilot, during which pretty much all of my concious concentration (is that even a thing?) is devoted to borderline pointless problem solving (trying to seperate elements of code). It feels like a losing battle.

So I took an IQ test a while ago (Wechsler Adult Intelligence Scale I believe it was) and it turned out my Spatial Aptitude was quite low. I still got a decent total score, just above average, so I won't have to poke things with a stick for a living, but I am a little worried that this is such a handicap when writing/engineering computer programs that I won't ever be able to do it seriously or professionally.

Question

I am very much interested in what other people think of this...

Could a low spatial aptitude be the cause of the above described problems?

How is programming affected by spatial aptitude?

Maybe I should be looking more along the lines of ADD or something similar, because I did get diagnosed with ADD at the age of 17 (5 years ago) but the medicine I received didn't seem to affect me that much so I never took it all that serious.

As far as I know people are born with low/med/high spatial aptitude, so I think it's interesting to find out if the more fortunate are better programmers by birth right.


问:
Do companies care about university grades when hiring programmers?
Most of my fellow students that I've talked to claim that aiming for good grades is useless as the companies don't care about them when hiring programmers. To them, it's enough to have simply attended courses which may be important, and that's that.

Is this true? Are university grades useless when leaving campus, or do employers ask to see them for an interview?

答:
It depends a lot on the type of company where you are applying. A large organization is more likely to have a screening process that uses objective metrics and is done before the hiring manager sees the resumes. Smaller organizations may value different things. Grades demonstrate that you are good at the university game. That doesn't necessarily correlate with the professional game.

It matters most for your first job if you have no experience. But what matters more is if you can demonstrate that you've accomplished something relevant. This could be an internship that gave you real development tasks, meaningful contributions to open source projects, released software (shareware, mobile apps, etc.).


问:
Are there any limitations to using WinRT instead of .Net?
From my understanding creating an application that runs on multiple architectures requires virtualization, and virtualization reduces performance since it creates a layer of abstraction.

With Windows 8 supporting both Intel and ARM architectures should we expect slower performance with a WinRT app versus a .Net app running on an Intel device?

Also, will WinRT support database connectivity and active directory access?

答:
From what I've seen, WinRT is actually an "unmanaged" software layer based on native COM objects, so I would NOT expect to see a big performance impact when invoking the APIs. In fact, it's quite likely that these will perform better than .NET apps on the CLR, as they are likely to be "closer to the metal" than pure .NET apps.

Note also that you can implement invoke WinRT APIs from .NET apps (or, as they want the buzz to pick up and attract web hipsters, in shiny HTML5 + JavaScript), but are free to implement your application entirely in C++ if you prefer and are concerned about additional layers.

WinRT is essentially a COM-based API, although relying on an enhanced COM.
  [...] WinRT allows relatively easy interfacing from
  multiple languages, [...] it's essentially an unmanaged,
  native API. This common [.NET-based ECMA 335] metadata format
  allows for significantly less overhead when invoking WinRT from
  .NET applications compared to a P/Invoke, and much simpler syntax.

      - From Wikipedia's WinRT (emphasis mine)

Also, consider looking at the C++/CX Component Extensions Language:

The new C++/CX (Component Extensions) language,
  which borrows some C++/CLI syntax, allows the authoring and consumption of
  WinRT components with less glue visible to the programmer compared to
  classic COM programming in C++ [...]. Regular C++ [...]
  can also be used to program with WinRT components, with [a] library called
  Windows Runtime C++ Template Library (WRL), which is
  similar in purpose to what Active Template Library provides for COM.
  The MSDN Library, however, recommends using C++/CX instead of WRL.

      - From Wikipedia's WinRT (emphasis mine)

The Guardian also provides an interesting article on the apparent rebuff of .NET in favor of C++ to develop WinRT-based apps.

The same article points to a great explanation of WinRT compared to Silverlight and WPF on StackOverflow.com.

Regarding your other points, WinRT in itself certainly doesn't limit you or prevent you from interfacing to a database or AD. It just doesn't make it easy, and the question is more how you want to do it.