问:
Managing Similar Code On Multiple Platforms (GIT)
My team and I have developed a Chrome extension which we are now porting into Firefox. The two versions share enough of a code base that it would be redundant to manage to separate depos. In fact theoretically the difference is within a few files and folder structure (once we unglue a lot of the platform specific code from the internals).

The Chrome extension houses all the files in the root directory, because all Chrome needs is the manifest file and the files can be located anywhere. This is different from the FireFox plugin, because FireFox requires a specific folder structure and where the files are located.

I haven't really found any discussions dealing specifically with managing multiple versions of the same project, yet maintaining a common shared code base. If you know of any articles/discussions, please let me know!

The structure for our Chrome extension is:

```<code> Root
   [House Extension Scripts]
</code>```

however the firefox requires the following structure:

```<code> Root
    |-Data
        |-[Houses Page Injected Scripts]
    |-Lib
        |-[Houses Plugin Side Scripts]
    |-package.json
</code>```

which makes merging and maintaining a common code base a little tricky. In those case Root in Chrome and Data in Firefox contain mostly common files (with a few exception). I am not sure how to do this in Git. In Perforce you can select which folders get merged into which folders. So I would merge the a common Dev folder into the root of the chrome extension folder and into the data folder of the FireFox plugin.

In my mind, the Git branching structure would be something like this:

```<code>      Firefox-Master/-----------------|-------------------------|---
                   /                 ↗                         ↗
      Firefox-Dev /-------------|---|--------|-------|---------|---
                 /             ↗            ↗        ↘
         Dev -----------------|-------------|----------|-----------
                 \             ↘          ↗            ↘
       Chrome-Dev \ ------------|---|----|---------------|----|----
                   \                 ↘                        ↘
     Chrome-Master  \-----------------|------------------------|----
</code>```

where the Dev branch houses the common code base. Each plugin has it's own dev folder, because each version needs it's own seperate code files to work. If there is something that get's developed in the FireFox-Dev branch that can be incorportated into Chrome, it will first be merged into Dev and then Dev will be merged into the Chrome-Dev branch. Each Master is independent as it is treated as a "release" branch.

I am wondering how this is managed on projects that have products ported across multiple platforms. For instance the Linux kernel for x86 and ARM must have a similar issue.

The biggest hurdle here is the fact that both require a different folder structure. I am wondering how this issue is tackled using Git. I want to be able to develop in one branch and be able to merge any non-platform specific code into the other versions while maintaining their unique folder structures.

Please let me know if this is a vague question and if I need to update any of the graph to be more clear. Any help is greatly appreciated!

答:
You might be trying to use git to handle a situation it was not intended to[citation needed], maybe a build script might be the answer.

If Chrome is flexible with the folder structure, you could just follow the folder structure required by Firefox. Have one branch for Chrome and another for Firefox to handle the distinct files, then later do a merged by a script to form a release version for each browser.


答:
I am not familiar with plugin development at all.

However, where your code is in the source control and how you present it to either browser can be separated by adding a build step.

With that model:

you have a single branch of development (you could have multiple, but you don't need to)

your source is wherever you like it to be

two distinct build steps assemble the source for chrome and firefox

ContentLicense: CC BY-SA 3.0

Title: Managing Similar Code On Multiple Platforms (GIT)

Body:
My team and I have developed a Chrome extension which we are now porting into Firefox. The two versions share enough of a code base that it would be redundant to manage to separate depos. In fact theoretically the difference is within a few files and folder structure (once we unglue a lot of the platform specific code from the internals).

The Chrome extension houses all the files in the root directory, because all Chrome needs is the manifest file and the files can be located anywhere. This is different from the FireFox plugin, because FireFox requires a specific folder structure and where the files are located.

I haven't really found any discussions dealing specifically with managing multiple versions of the same project, yet maintaining a common shared code base. If you know of any articles/discussions, please let me know!

The structure for our Chrome extension is:

```<code> Root
   [House Extension Scripts]
</code>```

however the firefox requires the following structure:

```<code> Root
    |-Data
        |-[Houses Page Injected Scripts]
    |-Lib
        |-[Houses Plugin Side Scripts]
    |-package.json
</code>```

which makes merging and maintaining a common code base a little tricky. In those case Root in Chrome and Data in Firefox contain mostly common files (with a few exception). I am not sure how to do this in Git. In Perforce you can select which folders get merged into which folders. So I would merge the a common Dev folder into the root of the chrome extension folder and into the data folder of the FireFox plugin.

In my mind, the Git branching structure would be something like this:

```<code>      Firefox-Master/-----------------|-------------------------|---
                   /                 ↗                         ↗
      Firefox-Dev /-------------|---|--------|-------|---------|---
                 /             ↗            ↗        ↘
         Dev -----------------|-------------|----------|-----------
                 \             ↘          ↗            ↘
       Chrome-Dev \ ------------|---|----|---------------|----|----
                   \                 ↘                        ↘
     Chrome-Master  \-----------------|------------------------|----
</code>```

where the Dev branch houses the common code base. Each plugin has it's own dev folder, because each version needs it's own seperate code files to work. If there is something that get's developed in the FireFox-Dev branch that can be incorportated into Chrome, it will first be merged into Dev and then Dev will be merged into the Chrome-Dev branch. Each Master is independent as it is treated as a "release" branch.

I am wondering how this is managed on projects that have products ported across multiple platforms. For instance the Linux kernel for x86 and ARM must have a similar issue.

The biggest hurdle here is the fact that both require a different folder structure. I am wondering how this issue is tackled using Git. I want to be able to develop in one branch and be able to merge any non-platform specific code into the other versions while maintaining their unique folder structures.

Please let me know if this is a vague question and if I need to update any of the graph to be more clear. Any help is greatly appreciated!


问:
How do you decide your side projects
At any given time, I usually have a bunch of ideas for weekend/side projects that I can work on. The ideas can be generally be categorized into these:

Self Learning: Learning a new language/ technology/ framework

Work related: Learning/Doing something that would help you at work

Money: Projects that (you think) can make some money

Fun/Utility projects

These are just the rough categories that I can think of and there can be more/other ways of classification.

My question is based on your experience what should drive the decision of what kind of project to work on. What parameters apart from the type of project should impact this decision (time, effort, money...)

答:
I actually wrote a blogpost about this a while back.  To summarize, the major guidelines I try to stick to in coming up with side projects is:

Have fun

Learn something

Make it timeless (in other words, make it something you can come back to later)

Don't limit yourself to just code (I learn a lot from my blog)

Write something I'll actually use (because I personally am more likely to stick with it that way).

To answer your question a bit more directly, I generally try to do #1 and #4 almost exclusively with my side projects.  That said, I gave having fun the number 1 spot for a reason.  If you aren't having fun, it isn't a side project.  It's work.

Title: How do you decide your side projects

ContentLicense: CC BY-SA 2.5


问:
Why the recent shift to removing/omitting semicolons from Javascript?
It seems to be fashionable recently to omit semicolons from Javascript. There was a blog post a few years ago emphasising that in Javascript, semicolons are optional and the gist of the post seemed to be that you shouldn't bother with them because they're unnecessary. The post, widely cited, doesn't give any compelling reasons not to use them, just that leaving them out has few side-effects.

Even GitHub has jumped on the no-semicolon bandwagon, requiring their omission in any internally-developed code, and a recent commit to the zepto.js project by its maintainer has removed all semicolons from the codebase. His chief justifications were:

it's a matter of preference for his team;

less typing

Are there other good reasons to leave them out?

Frankly I can see no reason to omit them, and certainly no reason to go back over code to erase them. It also goes against (years of) recommended practice, which I don't really buy the "cargo cult" argument for. So, why all the recent semicolon-hate? Is there a shortage looming? Or is this just the latest Javascript fad?

答:
There are good reasons to keep them in.

They are not really optional, JS can add them back in with automatic semicolon insertion when they are missing but that is not the same thing.

Douglas Crockford's JavaScript: The Good Parts says on two separate occasions that it is a bad idea. The automatic semicolon insertion can hide bugs in your program and creates ambiguity.

JSLint doesn't approve.


问:
What exactly makes the Haskell type system so revered (vs say, Java)?
I'm starting to learn Haskell. I'm very new to it, and I am just reading through a couple of the online books to get my head around its basic constructs.

One of the 'memes' that people familiar with it have often talked about, is the whole "if it compiles, it will work*" thing - which I think is related to the strength of the type system.

I'm trying to understand why exactly Haskell is better than other statically typed languages in this regard.

Put another way, I assume in Java, you could do something heinous like bury
ArrayList<String>() to contain something that really should be ArrayList<Animal>(). The heinous thing here is is that your string contains elephant, giraffe, etc, and if someone puts in Mercedes - your compiler won't help you.

If I did do ArrayList<Animal>() then, at some later point in time, if I decide my program isn't really about animals, it's about vehicles, then I can change, say, a function that produces ArrayList<Animal> to produce ArrayList<Vehicle> and my IDE should tell me everywhere there is a compilation break.

My assumption is that this is what people mean by a strong type system, but it's not obvious to me why Haskell's is better. Put another way, you can write good or bad Java, I assume you can do the same in Haskell (i.e stuff things into strings/ints that should really be first-class data types).

I suspect I'm missing something important/basic.

I would very happy to be shown the error of my ways!

答:
Full type inference.  You can actually use complex types ubiquitously without feeling like, "Holy crap, all I ever do is write type signatures."

Types are fully algebraic, which makes it very easy to express some complex ideas.

Haskell has type classes, which are sort of like interfaces, except you don't have to put all the implementations for one type in the same place.  You can create implementations of your own type classes for existing third-party types, without needing access to their source.

Higher-order and recursive functions have a tendency to put more functionality into the purview of the type checker. Take filter, for example.  In an imperative language, you might write a for loop to implement the same functionality, but you won't have the same static type guarantees, because a for loop has no concept of a return type.

Lack of subtypes greatly simplifies parametric polymorphism.

Higher-kinded types (types of types) are relatively easy to specify and use in Haskell, which lets you create abstractions around types that are completely unfathomable in Java.


答:
```<code>a :: Integer
b :: Maybe Integer
c :: IO Integer
d :: Either String Integer
</code>```

In Haskell: an integer, an integer that might be null, an integer whose value came from the outside world, and an integer that might be a string instead, are all distinct types - and the compiler will enforce this. You cannot compile a Haskell program which fails to respect these distinctions.

(You can, however, omit the type declarations. In most cases, the compiler can determine the most general type for your variables which will result in a successful compilation. Isn't that neat?)

Title: What exactly makes the Haskell type system so revered (vs say, Java)?

Body:
I'm starting to learn Haskell. I'm very new to it, and I am just reading through a couple of the online books to get my head around its basic constructs.

One of the 'memes' that people familiar with it have often talked about, is the whole "if it compiles, it will work*" thing - which I think is related to the strength of the type system.

I'm trying to understand why exactly Haskell is better than other statically typed languages in this regard.

Put another way, I assume in Java, you could do something heinous like bury
ArrayList<String>() to contain something that really should be ArrayList<Animal>(). The heinous thing here is is that your string contains elephant, giraffe, etc, and if someone puts in Mercedes - your compiler won't help you.

If I did do ArrayList<Animal>() then, at some later point in time, if I decide my program isn't really about animals, it's about vehicles, then I can change, say, a function that produces ArrayList<Animal> to produce ArrayList<Vehicle> and my IDE should tell me everywhere there is a compilation break.

My assumption is that this is what people mean by a strong type system, but it's not obvious to me why Haskell's is better. Put another way, you can write good or bad Java, I assume you can do the same in Haskell (i.e stuff things into strings/ints that should really be first-class data types).

I suspect I'm missing something important/basic.

I would very happy to be shown the error of my ways!

Body:
a :: Integer
b :: Maybe Integer
c :: IO Integer
d :: Either String Integer

In Haskell: an integer, an integer that might be null, an integer whose value came from the outside world, and an integer that might be a string instead, are all distinct types - and the compiler will enforce this. You cannot compile a Haskell program which fails to respect these distinctions.

(You can, however, omit the type declarations. In most cases, the compiler can determine the most general type for your variables which will result in a successful compilation. Isn't that neat?)


答:
JavaScript hasn't needed semi-colons to terminate statements in over a decade.  That's because newline characters are considered statement terminators(I believe this is also mentioned in early ECMAScript specs).  It really makes a lot of sense, especially since there really is no good reason [that I know of] why JavaScript would need frequent use of semi-colons but not other interpreted declarative languages like Ruby or Python.

Requiring semi-colons may make it easier to write a parser for a language, but if every interpreter out there supports the omission of semi-colons then what exactly is the point?

What it comes down to is how knowledgeable a programmer is: if you know that you can omit a semi-colon, feel free to do so understanding that there may or may not be a consequence.  Human beings are decision-making machines and nearly all decisions require some compromise or trade-off.  The trade-off to just throwing semi-colons all around your code(even in places where they aren't needed) is that your code becomes less read-able(depending on who you ask) and JSLint won't complain(who cares).  On the other hand, the trade-off to omitting semi-colons is the fact that 90% of JavaScript programmers will chastise you for it, but you may end up enjoying writing JavaScript more because of it.

What sounds better to you; making informed decisions or blind decision-making / herd-mentality?

Title: Why the recent shift to removing/omitting semicolons from Javascript?

Body:
It seems to be fashionable recently to omit semicolons from Javascript. There was a blog post a few years ago emphasising that in Javascript, semicolons are optional and the gist of the post seemed to be that you shouldn't bother with them because they're unnecessary. The post, widely cited, doesn't give any compelling reasons not to use them, just that leaving them out has few side-effects.

Even GitHub has jumped on the no-semicolon bandwagon, requiring their omission in any internally-developed code, and a recent commit to the zepto.js project by its maintainer has removed all semicolons from the codebase. His chief justifications were:

it's a matter of preference for his team;

less typing

Are there other good reasons to leave them out?

Frankly I can see no reason to omit them, and certainly no reason to go back over code to erase them. It also goes against (years of) recommended practice, which I don't really buy the "cargo cult" argument for. So, why all the recent semicolon-hate? Is there a shortage looming? Or is this just the latest Javascript fad?


问:
What default features is Windows missing that are required for programmers?
What features is Windows missing that can improve the productivity of a programmer. I know a lot of people would want some features from Linux and OSX ported or being created for Windows as well. What is missing for you ?

An example would be the option to have multiple workspaces. When not having the possibility to use dual monitors that can come in handy.

答:
The Unix file processing tools (wc, sort, uniq, awk, cat, grep, find, et cetera), including-- as others have mentioned-- a good shell (e.g., bash).

In order to be productive in Windows, when I'm working with anything text related, eventually I'll need to go into the Unix command toolbox. Fortunately, Cygwin is an excellent resource just for that purpose.

That said, you do need to "tame" Cygwin to work nicely with the Windows file system; unless you override some default settings, you can get files with nasty permissions that are difficult to delete. Anything too far above the basic needs and you're better off with a VM or dual booting, but for my purposes I'm quite satisfied with Cygwin.


问:
How to reduce the number of bugs when coding?
No one's perfect, and no matter what we do, we are going to produce code that has bugs in it from time to time. What are some methods/techniques for reducing the number of bugs you produce, both when writing new software and changing/maintaining existing code?</p>

答:
Surprisingly, the following three very important points have not been mentioned yet:

Use assertions liberally. The question you should always be asking yourself is not "should I assert this?" but "is there anything I forgot to assert?"

Opt for immutability. (Use final/readonly liberally.) The less mutable state you have, the fewer things can go wrong.

Do not optimize prematurely. Many programmers get side tracked with performance concerns, causing them to unnecessarily convolute their code and bastardize their designs without even knowing beforehand whether performance is going to be an issue. First, build your software product the academic way, disregarding performance; then, see if it performs poorly; (It probably won't.)  If there are any performance issues, go find the one or two places where you can provide nice and formal algorithmic optimizations that will make your product meet its performance requirements instead of tweaking and hacking your entire code base to squeeze clock cycles here and there.


问:
How minor of a case is a class appropriate for?
I'm trying to use composition in an Entity class of mine. So far, an Entity "is" Displayable(inherited an ABC), and "has" a Position(contains a point-like class). I know I will want my Entity to "have" a/some health, so I started defining a Health class to be composed into Entity. It was super-simplistic though, and only ended up containing 2 methods: hurt, and heal that modify its single field: hp.

If I intended to inherit from Health, I guess this would be OK, as it wouldn't require any boilerplate inside of Entity; it would just inherit the methods.

If I'm going to compose with it though, so for me to hurt an Entity, I'll have to route the hurt/heal call to their Health member and call their own hurt/heal method. With a class this simple, that means I'll basically have all of Health's methods duplicated in Entity.

In a case like this, is there any point in defining Health? The simpler alternative would be to just give Entity a hp field, and give it the hurt and heal methods directly.

答:
As long as the underlying hp value is not public, it doesn't matter too much either way. Having Entity::hurt()/heal() directly access a private hp member is fine, and making them wrappers for a Health::hurt()/heal() call is also fine.

Assuming it's not public, I would base the decision on what you expect to happen in the future. Will health probably be a simple integer forever? Or do you think it'll turn into a non-trivial class with methods like getTimesHurt(), getLastHealValue() or getPoisonTicksRemaining()? You may not know for sure, but you can make a well-educated guess based on what kind of game you're making.


问:
What is a good frequency for merging up feature branches to a main line?
We have a very large code base in mercurial.  We have about a 6 month release cadence with 2 week sprints.   For each release we have about 10 feature branches and maybe 5 or so people working per branch.

Now whether or not feature branches are a good idea is a question for another day.

Currently we do merge-downs/copy-ups from feature branches into the main QA line twice during that 6 months - once about 1/2 way through and once a few weeks before the end of the release.  (specifically, merge-down from qa, then feature branch copies up).

The reason seems not to keep in sync with each other, but to enable some testing about half-way through the release.

This has caused a lot of angst about looming merges and a few nasty merge conflicts, but not as many as one might expect.

So I guess my questions are:

Would having more frequent merges just for the sole purpose of keeping things in sync and preventing surprises create more churn or less churn?

If so, what would be a good schedule?    I've thought about this a bit - more frequent merges would require teams to have their code in good shape more often, which might not be a bad thing.  Too often though might spread bugs around to all feature branches before they get a chance to be fixed.

We're using Hg, but I'm adding git as a tag because I think the issues are pretty much the same.

答:
The good schedule is to merge only stable code (or "likely to be stable" code).

If you merge half-way just to begin tests, and you know that some of the features you're currently coding are not finished, you surely will get some testing feedback about these features.

The question you have to ask is "Am I confident with the completeness of what I already built ?"

If the answer is Yes, you can test it. If not, there is no point testing it, just keep coding.

EDIT : Actually, you could start testing partially each time one of your devs tells you that he finished a feature that could be ok by itself.

OwnerDisplayName: Caillou


问:
Time-complexity of nested for loop
I have loops like this:

```<code>for(int i = 0; i < n; i++) {
    for(int j = 0; j < i; j++) {
        sum += 1;
    }
}
</code>```

It's O(n * ), but I'm not sure what the j < i loop is.

I have some tests that I ran,

```<code>n = 10, runs = 45

n = 20, runs = 190

n = 40, runs = 780

n = 80, runs = 3160

n = 10, runs = 12720
</code>```

It seems to be converging onto .5*n^2, but I'm not quite sure.

答:
On the 1st iteration of the outer loop (i = 0), the inner loop will iterate 0 times
On the 2nd iteration of the outer loop (i = 1), the inner loop will iterate 1 time
On the 3rd iteration of the outer loop (i = 2), the inner loop will iterate 2 times

.

.

On the FINAL iteration of the outer loop (i = n ‐ 1), the inner loop will
iterate n ‐ 1 times

So, the total number of times the statements in the inner loop will be executed
will be equal to the sum of the integers from 1 to n ‐ 1, which is:

```<code>((n ‐ 1)*n) / 2 = (n^2)/2 ‐ n/2 = O(n^2) times
</code>```

Title: Time-complexity of nested for loop

Body:
On the 1st iteration of the outer loop (i = 0), the inner loop will iterate 0 times
On the 2nd iteration of the outer loop (i = 1), the inner loop will iterate 1 time
On the 3rd iteration of the outer loop (i = 2), the inner loop will iterate 2 times

.

.

On the FINAL iteration of the outer loop (i = n ‐ 1), the inner loop will
iterate n ‐ 1 times

So, the total number of times the statements in the inner loop will be executed
will be equal to the sum of the integers from 1 to n ‐ 1, which is:

((n ‐ 1)*n) / 2 = (n^2)/2 ‐ n/2 = O(n^2) times


问:
Why was the Itanium processor difficult to write a compiler for?
It's commonly stated that Intel's Itanium 64-bit processor architecture failed because the revolutionary EPIC instruction set was very difficult to write a good compiler for, which meant a lack of good developer tools for IA64, which meant a lack of developers creating programs for the architecture, and so no one wanted to use hardware without much software for it, and so the platform failed, and all for the want of a horseshoe nail good compilers.

But why was the compiler stuff such a difficult technical problem?  It seems to me that if the explicit parallelism in EPIC was difficult for compiler vendors to implement... why put that burden on them in the first place?  It's not like a good, well-understood solution to this problem didn't already exist: put that burden on Intel instead and give the compiler-writers a simpler target.

Itanium came out in 1997.  By this point, the UCSD P-Code bytecode system was nearly 20 years old, the Z-machine just slightly younger, and the JVM was the hot new rising star in the world of programming languages.  Is there any reason why Intel didn't specify a "simple Itanium bytecode" language, and provide a tool that converts this bytecode into optimized EPIC code, leveraging their expertise as the folks who designed the system in the first place?

答:
As I recall at the time, the issue was not just the particulars of IA64, it was the competition with AMD's x86-64 instruction set. By making their architecture backwards compatible with the x86 instruction set, AMD was able to leverage the existing tools and developer skill sets. AMD's move was so successful that Intel (and Via) were essentially forced to adopt the x86-64 architecture.

The big barrier at the time was 4 GB RAM on desktop PCs (more realistically ~3.4GB usable on Windows). x86-64 smashed that barrier and opened up higher power computing to everyone. Had AMD never come up with x86-64, I'm sure Intel would have been happy to have everyone who wanted to jump to 4GB+ RAM pay a hefty premium for years for that privilege. Demonstrating how slowly markets move, it has taken years for applications to catch up to 64-bit, multi-threaded programming, and even now 4GB RAM is standard on low-end PCs.

In short, Intel tried to make a revolutionary leap with the IA64 architecture, and AMD made an evolutionary step with x86-64. In an established market, evolutionary steps that allow knowledge workers to leverage existing skills will win over revolutionary steps that require everyone to learn new skills. Regardless of the qualitative differences between the architectures, IA64 could not overcome the momentum of its own x86 platform once AMD added the x86-64 extensions.

I don't buy the explanation that IA64 was too difficult to program for. It was only difficult relative to the alternatives. @delnan's point about low-level IR is smack on, I just don't think it would have made a difference.

As to why Intel didn't try to shoulder that burden themselves, who knows? They were the market power at the time. AMD was something of a threat but Intel was the king of the hill. Maybe they thought that IA64 would be so much better than anything else that they could move the entire market. Maybe they were trying to make a premium tier and leave AMD, VIA, etc. in the second tier fighting over low-margin commodity hardware - a strategy that both Intel and Apple have employed quite successfully.

Was Itanium a deliberate attempt to make a premium platform and pull the rug out from under AMD, VIA, etc.? Of course, that's how business works.


问:
Rich object model in the context of a good REST API and of an existing rich object model on the server-side
First off, let's frame this question in the context of a good REST API and an existing rich object model on the server-side, as well as modern web architecture (MVC frameworks like angularjs).

I'm debating whether or not to use a rich object model with my next project. The alternative is just using very light-weight POJO objects (pretty much whatever the API gives me) and using these in a non-persistent (between views) manner, i.e. no "application state". Just load what you need for the current operations and then get rid of it when you don't.

The risks of a rich object model that are giving me pause are:

1. Testability - it could be harder to unit test a complex object model

2. Performance - with a large object graph, the performance of the app could suffer. Contrast that with lightweight POJO's that get created and destroyed as needed, the app stays nimble.

3. Complexity - a complex object model could be orders of magnitude more complex than a lightweight app that just loads what it needs at the moment. This could also make it harder to modify...

4. Harder to modify - a rich object model creates a multitude of dependencies. This makes it harder to change things down the road.

I'm leaning towards a lean, light-weight web app that just loads what it needs at the moment and destroys what it doesn't.

答:
You can have a lean, lightweight app and still have a rich object model.

If you're using Angular, that means you're probably writing a single-page application and driving the UI from web services.  Those web services should provide you with the data you need for the UI.  On the server, you can have a data model and application layer as complex as your domain requires.

ViewModel objects are the layer of abstraction that allows you to have your complex object model, while still keeping the UI as lean as you need it to be.

OwnerDisplayName: Richard DesLonde


问:
Does grouping threads by task improve performance?
This is kind of a lazy question on my part, since I gave up after trying only a few google terms.

But when I read about multi-threaded performance, I read about context switching being bad for performance since the cache is thrashed or whatever.

My question is, is the cache always rendered useless after a context switch? What about when the context being switched to shares much of the stack and maybe even data which was being processed in the previous context? Would grouping thread pools by task or category of task help performance because it increased this effect?

Or is the cache always flushed no matter what because of a possible (inherent?) switch of address space or something like that?

答:
Is the cache always rendered useless after a context switch?

No, not at all.

Context switches are actually a concept of the software that runs on a CPU, not one of the CPU itself.  When the software decides to do a context switch, the state of the CPU is saved somewhere convenient, a new or previously-saved state is loaded and execution jumps to the address where the switched-to process was interrupted.  That's a bit oversimplified, but the major point is that the CPU is just following whatever instructions it's told to execute and doesn't know or care that the effect of those instructions is a context switch.

The cache is the domain of the CPU, which has its own rules for what it keeps in which cache and when evictions or commits to other caches or RAM happen.  Say you have a single-core, single-cache CPU running a supervisor and two processes.  If the code and data for all three fit in the cache, all three could context switch among themselves forever without ever having to reach outside the processor.  This is because what's in the cache remains valid between time slices.  The only reason RAM would ever have to be touched is to make data visible off the processor, such as for peripherals doing I/O.

What about when the context being switched to shares much of the stack and maybe even data which was being processed in the previous context?

Contexts may operate in the same code and data space if they're threads of the same process.  One thing they can't share is a stack, so each gets its own and the stack pointer is changed during a context switch.  If there is data in common that's being used frequently enough, it will remain in the cache.  This effect is leveraged when designing software for very high performance, but it has the drawback of depending on CPU-specific features.

Would grouping thread pools by task or category of task help performance because it increased this effect?

It can, depending on the machine architecture, the workload and how you manage it.  You want to run the same context on the same core as often as possible because it increases the odds of a cache hit, and cache hits improve performance.  That doesn't mean misses are automatically bad, but the cost has to be balanced with that of waiting in line for the same core, which may have already evicted what the context was using to socket-wide cache that can be accessed just as quickly by other cores.

You see this sort of thing on a macro scale in NUMA systems, where operating systems will try to assign contexts to the same socket to avoid cache invalidation and data transfer between the sockets.


问:
Django urls.py runs only once. Why? How does it call views on next request?
While testing django cashing on our development server, one of our senior asked if is it possible to change the value of caching timeout on urls.py without restarting the http service.

On first note, I was 100% sure it can be done by changing the timeout value dynamically.

For example - As suggested by my other colleague, If we save the timeout value in separate xml file and read this file value in urls.py and assign that value on the caching command, then by changing the value in the xml file, caching timeout will be updated without restarting the http service.

But when we tested this, we came to an understanding that it works only on first hit as the urlpattern object is passed to django server and urls.py never runs again unless the http service is restarted.

In the end to get our requirement done, we had to write few more script inside the view function to load the urls.py again so that it reads the new caching timeout value.

So my question is why this urls.py is not loaded every time on every url hit but only once on first time?, where does this urlpattern object goes?, Any Idea!

答:
Looking through the documentation, I found this after searching the Django repository for re.compile. Look through django.core.urlresolvers. RegexURLResolver is called on the root urlconf unless it's set by whatever calls get_resolver. The output of get_resolver, and therefore the result of building the URL resolver, is cached:

```<code>@lru_cache.lru_cache(maxsize=None)
def get_resolver(urlconf):
if urlconf is None:
    from django.conf import settings
    urlconf = settings.ROOT_URLCONF
return RegexURLResolver(r'^/', urlconf)
</code>```

re.compile is called twice in the RegexURLResolver class. You may want to look further into that, and the @lru_cache decorator, for whatever it is you want to do.

Body:
Looking through the documentation, I found this after searching the Django repository for re.compile. Look through django.core.urlresolvers. RegexURLResolver is called on the root urlconf unless it's set by whatever calls get_resolver. The output of get_resolver, and therefore the result of building the URL resolver, is cached:

@lru_cache.lru_cache(maxsize=None)
def get_resolver(urlconf):
if urlconf is None:
    from django.conf import settings
    urlconf = settings.ROOT_URLCONF
return RegexURLResolver(r'^/', urlconf)

re.compile is called twice in the RegexURLResolver class. You may want to look further into that, and the @lru_cache decorator, for whatever it is you want to do.


问:
Porting Silverligtht application to web application with Asp.net and HTML 5
I work as internal software developer. We used Silverlight to build our application, but we have been asked to start considering their replacement.

Currently our set-up is:

Silverlight application for client side.

Asp.Net soap web service. Deployed in two servers with a load
balancer.

MS SQL server 2008. Also Deployed in two servers with a load
balancer.

Our application as as a sort of suite, performing several different functions, included but not restricted to:

Reporting.

Data analysis.

Front-end for several database tables that are used both for other
processes in the application, and for other applications in the
company.

Our constraints:

Limited development resources: We are a small team, a dozen or so developers, and while we have already hired more people to be able to cope with a increasing work load, getting more reinforcements is unlikely. Time also is constrained, as new projects, bug fixes,requests for new features in existing application and changes in the business logic are quite frequent.

Slow technology update: Our company changed from Windows XP to Windows 7 last year, and only because the support ended. We started considering to upgrade database servers to SQL server 2010 recently. Official browser is Internet Explorer 9 and Chrome. New Servers,licenses and tools can be requested, but they often take time.

Big, slow data: Some of our data come from tables big, clunky tables with million of rows and many columns, with only the bare minimum indexing, because they are updated frequently. We have little control over those specific big tables because they are feeds from other systems and requesting changes in those feeds is possible, but, as before, it takes time.

User mentality: The managers appreciate the fancy interfaces and dashboards to show in meetings. All users appreciate responsiveness and general UI smoothness. Also, many of our users come from a Excel background, which means that they are accustomed to take big chunks of data and filter them, perform analysis, make statistics, generate charts, etc, and they expect to be able to do it in the application too.

Our own experience: Most of our developers have backgrounds related to .net, asp.net, Windows Forms and Silverlight. Only a few of us have Java experience (non android). Only a few of us have experience with web applications besides some small projects.

Our past: The first iteration  of our application was a windows forms application who suffered an acute case of installer bloating. Some of the IT heads decided that this could be solved by turning it into a web application. Since this was before HTML5 and we were still using IE6 as our official browser, we decided to go with Silverlight as it offered us the best compromise.

Our advantages:

Homogenized hardware: Most users use exactly the same type of laptop with the same specifications. Available screen size range is not very wide, so we should not have to struggle with different resolutions.

Intranet: We work in a controlled environment.

Reasonable budget: Most request for  Servers,licenses and the like will be approved if a  sufficiently good reason is given.

Recently, the higher ups has started to fear that Silverlight support may end abruptly. And they have suggested that we update the application to a more stable technology, hinting that HTML5 would be a good idea. They have asked us how feasible would be, and how much time it would take. We have next to 0 experience in this type of projects, so we are researching a bit to be able to give them an answer. This is my question:

Given this situation and set-up, would be feasible to port this kind of application to a web application with HTML5 and asp.net while keeping most of its functionality?

If not, why? Which of the above would need to be changed in order to make it possible?.

答:
First rule of thumb - never start over if you can avoid it. That's a Joel Spolsky rule of software development. So that's automatically a strike against re-writing your app in HTML5. Fortunately, you really only have to re-write the client. You can update the server app incrementally, but you don't need to replace it wholesale.

However, moving from Silverlight to HTML5 is hardly a slam-dunk. I wrote Flex apps for a few years before switching to JavaScript as the front end of my apps. Like most folks, I had written a decent amount of JavaScript, but never an end-to-end app like a Silverlight app, and it took quite a bit of re-education to get me up to speed. Here is what I learned in no particular order.

JavaScript/HTML5 is only just now getting to the point where Flex was in 2010. Maybe older JavaScript devs will argue that point with me, but to my experience, the tooling, libraries, UI elements, etc. have taken quite a bit of time to catch up to what Flex/Silverlight could offer out of the box. In this sense I still miss how easy certain things, like data binding and customized component view handlers, are in Flex.

Unlike Flex/Silverlight, where there is a small ecosystem of well-thought-out tools, libraries, etc., the JavaScript ecosystem is gigantic, scattered, and not easy to navigate. Gituhub, npm and bower help organize things to some extent, but there are literally hundreds of thousands of projects in JavaScript registered and who knows which of them is going to apply to what you need.

jQuery/jQueryUI are your friends. jQuery takes a lot of the old cross-browser nightmare out of JavaScript on the client. jQueryUI provides a base of UI elements from which to choose.

I don't know your specific needs, but there are commercial JavaScript libraries for graphing/charting that you might be very well advised to use.

Frameworks in JavaScript are like sunrises - there is a new one everyday. Pick a mainstream framework you like and stick with it.

So, is it feasible, re-writing your app? That depends on your project functionality, time and resource constraints. I suggest you look at the visualization packages available in JavaScript to see if they fit your needs. Given that you need advanced functionality, finding a match there will be your biggest challenge. Give yourself a month - research available packages, maybe try to implement a couple of functional items and see where your gaps are. That will give you a sense of what you are facing. Then you can make an informed decision about whether the tools exist (yet) to achieve your goals in a reasonable time frame. If the answer is no, re-visit the issue in another year to see how things have advanced.


答:
I would say it depends greatly on how 'hobbyist' of a programmer you are. Personally, I am not. I rarely create things for 'fun' though I do love programming with or without a monetary incentive.

I would say #1 to learn something new would determine what I worked on. Along with that, I'd say #3: something which I believe could make lots of money. 3 doesn't come up all that often as it usually requires a ton of work I don't have time to do.

To me, heaven is developing something yourself and making a living off of it's distribution, thereby being in a position to completely dedicate your work to it. Isn't that what everyone wants?

I read an article the other week about a indie games programmer who developed a highly acclaimed title and he is now living off the sales comfortably while being able to apply constant updates.

Being paid to do something you love is bliss. It's not work. And if you also own the final product, that's a huge bonus.

EDIT:

Would also like to add, if took out #3, then the ONLY reason I would have any side projects would be #1. That is, to learn something new.

Title: How do you decide your side projects

Body:
At any given time, I usually have a bunch of ideas for weekend/side projects that I can work on. The ideas can be generally be categorized into these:

Self Learning: Learning a new language/ technology/ framework

Work related: Learning/Doing something that would help you at work

Money: Projects that (you think) can make some money

Fun/Utility projects

These are just the rough categories that I can think of and there can be more/other ways of classification.

My question is based on your experience what should drive the decision of what kind of project to work on. What parameters apart from the type of project should impact this decision (time, effort, money...)


问:
TDD Red-Green-Refactor and if/how to test methods that become private
as far as I understand it, most people seem to agree that private methods should not be tested directly, but rather through whatever public methods call them. I can see their point, but I have some problems with this when I try to follow the "Three Laws of TDD", and use the "Red - green - refactor" cycle. I think it's best explained by an example:

Right now, I need a program that can read a file (containing tab-separated data) and filter out all columns that contain non-numerical data. I guess there's probably some simple tools available already to do this, but I decided to implement it from scratch myself, mostly because I figured it could be a nice and clean project for me to get some practice with TDD.

So, first, I "put the red hat on", that is, I need a test that fails. I figured, I'll need a method that finds all the non-numerical fields in a line. So I write a simple test, of course it fails to compile immediately, so I start writing the function itself, and after a couple of cycles back and forth (red/green) I have a working function and a complete test.

Next, I continue with a function, "gatherNonNumericColumns" that reads the file, one line at a time, and calls my "findNonNumericFields"-function on each line to gather up all the columns that eventually must be removed. A couple of red-green-cycles, and I'm done, having again, a working function and a complete test.

Now, I figure I should refactor. Since my method "findNonNumericFields" was designed only because I figured I would need it when implementing "gatherNonNumericColumns", it seems to me that it would be reasonable to let "findNonNumericFields" become private. However, that would break my first tests, since they would no longer have access to the method they were testing.

So, I end up with a private methods, and a suite of test that test it. Since so many people advice that private methods should not be tested, it feels like I've painted myself into a corner here. But where exactly did I fail?

I gather I could have started out at a higher level, writing a test that tests what will eventually become my public method (that is, findAndFilterOutAllNonNumericalColumns), but that feels somewhat counter to the whole point of TDD (at least according to Uncle Bob): That you should switch constantly between writing tests and production code, and that at any point in time, all your tests worked within the last minute or so. Because if I start out by writing a test for a public method, there will be several minutes (or hours, or even days in very complex cases) before I get all the details in the private methods to work so that the test testing the public method passes.

So, what to do? Is TDD (with the rapid red-green-refactor cycle) simply not compatible with private methods? Or is there a fault in my design?

答:
it feels like I've painted myself into a corner here. But where exactly did I fail?

There's an old adage.

When you fail to plan, you plan to fail.

People seem to think that when you TDD, you just sit down, write tests, and the design will just magically happen. This isn't true. You need to have a high level plan going in. I've found that I get my best results from TDD when I design the interface (public API) first. Personally, I create an actual interface that defines the class first.

gasp I wrote some "code" before writing any tests! Well, no. I didn't. I wrote a contract to be followed, a design. I suspect you could get similar results by jotting down a UML diagram on graph paper. The point is, you must have a plan. TDD isn't a license to go willy nilly hacking at a piece of code.

I really feel like "Test First" is a misnomer. Design First then test.

Of course, please follow the advice others have given about extracting more classes out of your code. If you strongly feel the need to test the internals of a class, extract those internals into an easily tested unit and inject it.


答:
Here's an unordered list of type system features available in Haskell and either unavailable or less nice in Java (to my knowledge, which is admittedly weak w.r.t. Java)

Safety. Haskell's types have pretty good "type safety" properties. This is pretty specific, but it essentially means that values at some type cannot wantonly transform into another type. This is sometimes at odds with mutability (see OCaml's value restriction)

Algebraic Data Types. Types in Haskell have essentially the same structure as high school mathematics. This is outrageously simple and consistent, yet, as it turns out, as powerful as you could possibly want. It's simply a great foundation for a type system.

Datatype-generic programming. This is not the same as generic types (see generalization). Instead, due to the simplicity of the type structure as noted before it's relatively easy to write code which operates generically over that structure. Later I talk about how something like Equality might be auto-derived for a user-defined type by a Haskell compiler. Essentially the way that it does this is walk over the common, simple structure underlying any user-defined type and match it up between values—a very natural form of structural equality.

Mutually recursive types. This is just an essential component of writing non-trivial types.

Nested types. This allows you to define recursive types over variables which recurse at different types. For instance, one type of balanced trees is data Bt a = Here a | There (Bt (a, a)). Think carefully about the valid values of Bt a and notice how that type works. It's tricky!

Generalization. This is almost too silly to not have in a type system (ahem, looking at you, Go). It's important to have notions of type variables and the ability to talk about code which is independent of the choice of that variable. Hindley Milner is a type system which is derived from System F. Haskell's type system is an elaboration of HM typing and System F is essentially the hearth of generalization. What I mean to say is that Haskell has a very good generalization story.

Abstract types. Haskell's story here is not great but also not non-existent. It's possible to write types which have a public interface but a private implementation. This allows us to both admit changes to the implementation code at a later time and, importantly since it's the basis of all operation in Haskell, write "magic" types which have well-defined interfaces such as IO. Java probably actually has a nicer abstract type story, to be honest, but I don't think until Interfaces became more popular was that genuinely true.

Parametricity. Haskell values do not have any universal operations. Java violates this with things like reference equality and hashing and even more flagrantly with coercions. What this means is that you get free theorems about types which allow you to know the meaning of an operation or value to a remarkable degree entirely from its type---certain types are such that there can only be a very small number of inhabitants.

Higher-kinded types show up all the type when encoding trickier things. Functor/Applicative/Monad, Foldable/Traversable, the entire mtl effect typing system, generalized functor fixpoints. The list goes on and on. There are a lot of things which are best expressed at higher kinds and relatively few type systems even allow the user to talk about these things.

Type classes. If you think of type systems as logics—which is useful—then you often are demanded to prove things. In many cases this is essentially line noise: there may be only one right answer and it's a waste of time and effort for the programmer to state this. Typeclasses are a way for Haskell to generate the proofs for you. In more concrete terms, this lets you solve simple "type equation systems" like "At which type are we intending to (+) things together? Oh, Integer, ok! Let's inline the right code now!". At more complex systems you might be establishing more interesting constraints.

Constraint calculus. Constraints in Haskell—which are the mechanism for reaching into the typeclass prolog system—are structurally typed. This gives a very simple form of subtyping relationship which lets you assemble complex constraints from simpler ones. The entire mtl library is based on this idea.

Deriving. In order to drive the canonicity of the typeclass system it's necessary to write a lot of often trivial code to describe the constraints user-defined types must instantiate. Do to the very normal structure of Haskell types, it is often possible to ask the compiler to do this boilerplate for you.

Type class prolog. The Haskell type class solver—the system which is generating those "proofs" I referred to earlier—is essentially a crippled form of Prolog with nicer semantic properties. This means you can encode really hairy things in type prolog and expect them to be handled all at compile time. A good example might be solving for a proof that two heterogenous lists are equivalent if you forget about the order—they're equivalent heterogenous "sets".

Multi-parameter type classes and functional dependencies. These are just massively useful refinements to base typeclass prolog. If you know Prolog, you can imagine how much the expressive power increases when you can write predicates of more than one variable.

Pretty good inference. Languages based on Hindley Milner type systems have pretty good inference. HM itself has complete inference which means that you never need to write a type variable. Haskell 98, the simplest form of Haskell, already throws that out in some very rare circumstances. Generally, modern Haskell has been an experiment in slowly reducing the space of complete inference while adding more power to HM and seeing when users complain. People very rarely complain—Haskell's inference is pretty good.

Very, very, very weak subtyping only. I mentioned earlier that the constraint system from typeclass prolog has a notion of structural subtyping. That is the only form of subtyping in Haskell. Subtyping is terrible for reasoning and inference. It makes each of those problems significantly harder (a system of inequalities instead of a system of equalities). It's also really easy to misunderstand (Is subclassing the same as subtyping? Of course not! But people very frequently confuse that and many languages aid in that confusion! How did we end up here? I suppose nobody ever examines the LSP.)

Note recently (early 2017) Steven Dolan published his thesis on MLsub, a variant of ML and Hindley-Milner type inference which has a very nice subtyping story (see also). This doesn't obviate what I've written above—most subtyping systems are broken and have bad inference—but does suggest that we just today may have discovered some promising ways to have complete inference and subtyping play together nicely. Now, to be totally clear, Java's notions of subtyping are in no way able to take advantage of Dolan's algorithms and systems. It requires a rethinking of what subtyping means.

Higher rank types. I talked about generalization earlier, but more than just mere generalization it's useful to be able to talk about types which have generalized variables within them. For instance, a mapping between higher order structures which is oblivious (see parametricity) to what those structures "contain" has a type like (forall a. f a -> g a). In straight HM you can write a function at this type, but with higher-rank types you demand such a function as an argument like so: mapFree :: (forall a . f a -> g a) -> Free f -> Free g. Notice that the a variable is bound only within the argument. This means that the definer of the function mapFree gets to decide what a is instantiated at when they use it, not the user of mapFree.

Existential types. While higher-rank types allow us to talk about universal quantification, existential types let us talk about existential quantification: the idea that there merely exists some unknown type satisfying some equations. This ends up being useful and to go on for longer about it would take a long while.

Type families. Sometimes the typeclass mechanisms are inconvenient since we don't always think in Prolog. Type families let us write straight functional relationships between types.

Closed type families. Type families are by default open which is annoying because it means that while you can extend them at any time you cannot "invert" them with any hope of success. This is because you cannot prove injectiveness, but with closed type families you can.

Kind indexed types and type promotion. I'm getting really exotic at this point, but these have practical use from time to time. If you'd like to write a type of handles which are either open or closed then you can do that very nicely. Notice in the following snippet that State is a very simple algebraic type which had its values promoted into the type-level as well. Then, subsequently, we can talk about type constructors like Handle as taking arguments at specific kinds like State. It's confusing to understand all the details, but also so very right.

```<code>data State = Open | Closed

data Handle :: State -> * -> * where
  OpenHandle :: {- something -} -> Handle Open a
  ClosedHandle :: {- something -} -> Handle Closed a
</code>```

Runtime type representations that work. Java is notorious for having type erasure and having that feature rain on some people's parades. Type erasure is the right way to go, however, as if you have a function getRepr :: a -> TypeRepr then you at the very least violate parametricity. What's worse is that if that's a user-generated function which is used to trigger unsafe coercions at runtime... then you've got a massive safety concern. Haskell's Typeable system allows the creation of a safe coerce :: (Typeable a, Typeable b) => a -> Maybe b. This system relies on Typeable being implemented in the compiler (and not userland) and also could not be given such nice semantics without Haskell's typeclass mechanism and the laws it is guaranteed to follow.

More than just these however the value of Haskell's type system also relates to how the types describe the language. Here are a few features of Haskell which drive value through the type system.

Purity. Haskell allows no side effects for a very, very, very wide definition of "side effect". This forces you to put more information into types since types govern inputs and outputs and without side effects everything must be accounted for in the inputs and outputs.

IO. Subsequently, Haskell needed a way to talk about side effects—since any real program must include some—so a combination of typeclasses, higher kinded types, and abstract types gave rise to the notion of using a particular, super-special type called IO a to represent side-effecting computations which result in values of type a. This is the foundation of a very nice effect system embedded inside of a pure language.

Lack of null. Everyone knows that null is the billion dollar mistake of modern programming languages. Algebraic types, in particular the ability to just append a "does not exist" state onto types you have by transforming a type A into the type Maybe A, completely mitigate the problem of null.

Polymorphic recursion. This lets you define recursive functions which generalize type variables despite using them at different types in each recursive call in their own generalization. This is difficult to talk about, but especially useful for talking about nested types. Look back to the Bt a type from before and try to write a function to compute its size: size :: Bt a -> Int. It'll look a bit like size (Here a) = 1 and size (There bt) = 2 * size bt. Operationally that isn't too complex, but notice that the recursive call to size in the last equation occurs at a different type, yet the overall definition has a nice generalized type size :: Bt a -> Int. Note that this is a feature which breaks total inference, but if you provide a type signature then Haskell will allow it.

I could keep going, but this list ought to get you started-and-then-some.

Body:
Here's an unordered list of type system features available in Haskell and either unavailable or less nice in Java (to my knowledge, which is admittedly weak w.r.t. Java)

Safety. Haskell's types have pretty good "type safety" properties. This is pretty specific, but it essentially means that values at some type cannot wantonly transform into another type. This is sometimes at odds with mutability (see OCaml's value restriction)

Algebraic Data Types. Types in Haskell have essentially the same structure as high school mathematics. This is outrageously simple and consistent, yet, as it turns out, as powerful as you could possibly want. It's simply a great foundation for a type system.

Datatype-generic programming. This is not the same as generic types (see generalization). Instead, due to the simplicity of the type structure as noted before it's relatively easy to write code which operates generically over that structure. Later I talk about how something like Equality might be auto-derived for a user-defined type by a Haskell compiler. Essentially the way that it does this is walk over the common, simple structure underlying any user-defined type and match it up between values—a very natural form of structural equality.

Mutually recursive types. This is just an essential component of writing non-trivial types.

Nested types. This allows you to define recursive types over variables which recurse at different types. For instance, one type of balanced trees is data Bt a = Here a | There (Bt (a, a)). Think carefully about the valid values of Bt a and notice how that type works. It's tricky!

Generalization. This is almost too silly to not have in a type system (ahem, looking at you, Go). It's important to have notions of type variables and the ability to talk about code which is independent of the choice of that variable. Hindley Milner is a type system which is derived from System F. Haskell's type system is an elaboration of HM typing and System F is essentially the hearth of generalization. What I mean to say is that Haskell has a very good generalization story.

Abstract types. Haskell's story here is not great but also not non-existent. It's possible to write types which have a public interface but a private implementation. This allows us to both admit changes to the implementation code at a later time and, importantly since it's the basis of all operation in Haskell, write "magic" types which have well-defined interfaces such as IO. Java probably actually has a nicer abstract type story, to be honest, but I don't think until Interfaces became more popular was that genuinely true.

Parametricity. Haskell values do not have any universal operations. Java violates this with things like reference equality and hashing and even more flagrantly with coercions. What this means is that you get free theorems about types which allow you to know the meaning of an operation or value to a remarkable degree entirely from its type---certain types are such that there can only be a very small number of inhabitants.

Higher-kinded types show up all the type when encoding trickier things. Functor/Applicative/Monad, Foldable/Traversable, the entire mtl effect typing system, generalized functor fixpoints. The list goes on and on. There are a lot of things which are best expressed at higher kinds and relatively few type systems even allow the user to talk about these things.

Type classes. If you think of type systems as logics—which is useful—then you often are demanded to prove things. In many cases this is essentially line noise: there may be only one right answer and it's a waste of time and effort for the programmer to state this. Typeclasses are a way for Haskell to generate the proofs for you. In more concrete terms, this lets you solve simple "type equation systems" like "At which type are we intending to (+) things together? Oh, Integer, ok! Let's inline the right code now!". At more complex systems you might be establishing more interesting constraints.

Constraint calculus. Constraints in Haskell—which are the mechanism for reaching into the typeclass prolog system—are structurally typed. This gives a very simple form of subtyping relationship which lets you assemble complex constraints from simpler ones. The entire mtl library is based on this idea.

Deriving. In order to drive the canonicity of the typeclass system it's necessary to write a lot of often trivial code to describe the constraints user-defined types must instantiate. Do to the very normal structure of Haskell types, it is often possible to ask the compiler to do this boilerplate for you.

Type class prolog. The Haskell type class solver—the system which is generating those "proofs" I referred to earlier—is essentially a crippled form of Prolog with nicer semantic properties. This means you can encode really hairy things in type prolog and expect them to be handled all at compile time. A good example might be solving for a proof that two heterogenous lists are equivalent if you forget about the order—they're equivalent heterogenous "sets".

Multi-parameter type classes and functional dependencies. These are just massively useful refinements to base typeclass prolog. If you know Prolog, you can imagine how much the expressive power increases when you can write predicates of more than one variable.

Pretty good inference. Languages based on Hindley Milner type systems have pretty good inference. HM itself has complete inference which means that you never need to write a type variable. Haskell 98, the simplest form of Haskell, already throws that out in some very rare circumstances. Generally, modern Haskell has been an experiment in slowly reducing the space of complete inference while adding more power to HM and seeing when users complain. People very rarely complain—Haskell's inference is pretty good.

Very, very, very weak subtyping only. I mentioned earlier that the constraint system from typeclass prolog has a notion of structural subtyping. That is the only form of subtyping in Haskell. Subtyping is terrible for reasoning and inference. It makes each of those problems significantly harder (a system of inequalities instead of a system of equalities). It's also really easy to misunderstand (Is subclassing the same as subtyping? Of course not! But people very frequently confuse that and many languages aid in that confusion! How did we end up here? I suppose nobody ever examines the LSP.)

Note recently (early 2017) Steven Dolan published his thesis on MLsub, a variant of ML and Hindley-Milner type inference which has a very nice subtyping story (see also). This doesn't obviate what I've written above—most subtyping systems are broken and have bad inference—but does suggest that we just today may have discovered some promising ways to have complete inference and subtyping play together nicely. Now, to be totally clear, Java's notions of subtyping are in no way able to take advantage of Dolan's algorithms and systems. It requires a rethinking of what subtyping means.

Higher rank types. I talked about generalization earlier, but more than just mere generalization it's useful to be able to talk about types which have generalized variables within them. For instance, a mapping between higher order structures which is oblivious (see parametricity) to what those structures "contain" has a type like (forall a. f a -> g a). In straight HM you can write a function at this type, but with higher-rank types you demand such a function as an argument like so: mapFree :: (forall a . f a -> g a) -> Free f -> Free g. Notice that the a variable is bound only within the argument. This means that the definer of the function mapFree gets to decide what a is instantiated at when they use it, not the user of mapFree.

Existential types. While higher-rank types allow us to talk about universal quantification, existential types let us talk about existential quantification: the idea that there merely exists some unknown type satisfying some equations. This ends up being useful and to go on for longer about it would take a long while.

Type families. Sometimes the typeclass mechanisms are inconvenient since we don't always think in Prolog. Type families let us write straight functional relationships between types.

Closed type families. Type families are by default open which is annoying because it means that while you can extend them at any time you cannot "invert" them with any hope of success. This is because you cannot prove injectiveness, but with closed type families you can.

Kind indexed types and type promotion. I'm getting really exotic at this point, but these have practical use from time to time. If you'd like to write a type of handles which are either open or closed then you can do that very nicely. Notice in the following snippet that State is a very simple algebraic type which had its values promoted into the type-level as well. Then, subsequently, we can talk about type constructors like Handle as taking arguments at specific kinds like State. It's confusing to understand all the details, but also so very right.

data State = Open | Closed

data Handle :: State -> * -> * where
  OpenHandle :: {- something -} -> Handle Open a
  ClosedHandle :: {- something -} -> Handle Closed a

Runtime type representations that work. Java is notorious for having type erasure and having that feature rain on some people's parades. Type erasure is the right way to go, however, as if you have a function getRepr :: a -> TypeRepr then you at the very least violate parametricity. What's worse is that if that's a user-generated function which is used to trigger unsafe coercions at runtime... then you've got a massive safety concern. Haskell's Typeable system allows the creation of a safe coerce :: (Typeable a, Typeable b) => a -> Maybe b. This system relies on Typeable being implemented in the compiler (and not userland) and also could not be given such nice semantics without Haskell's typeclass mechanism and the laws it is guaranteed to follow.

More than just these however the value of Haskell's type system also relates to how the types describe the language. Here are a few features of Haskell which drive value through the type system.

Purity. Haskell allows no side effects for a very, very, very wide definition of "side effect". This forces you to put more information into types since types govern inputs and outputs and without side effects everything must be accounted for in the inputs and outputs.

IO. Subsequently, Haskell needed a way to talk about side effects—since any real program must include some—so a combination of typeclasses, higher kinded types, and abstract types gave rise to the notion of using a particular, super-special type called IO a to represent side-effecting computations which result in values of type a. This is the foundation of a very nice effect system embedded inside of a pure language.

Lack of null. Everyone knows that null is the billion dollar mistake of modern programming languages. Algebraic types, in particular the ability to just append a "does not exist" state onto types you have by transforming a type A into the type Maybe A, completely mitigate the problem of null.

Polymorphic recursion. This lets you define recursive functions which generalize type variables despite using them at different types in each recursive call in their own generalization. This is difficult to talk about, but especially useful for talking about nested types. Look back to the Bt a type from before and try to write a function to compute its size: size :: Bt a -> Int. It'll look a bit like size (Here a) = 1 and size (There bt) = 2 * size bt. Operationally that isn't too complex, but notice that the recursive call to size in the last equation occurs at a different type, yet the overall definition has a nice generalized type size :: Bt a -> Int. Note that this is a feature which breaks total inference, but if you provide a type signature then Haskell will allow it.

I could keep going, but this list ought to get you started-and-then-some.


问:
best practices for packaging in Scala projects?
Scala runs on the JVM, but that doesn't mean we have to write it like Java.  Eclipse discourages use of the default package.  What are some considerations (e.g. size of project) that determine how code ought to be packaged in Scala?</p>

答:
Scala package best practices are generally the same as Java conventions, according to the Style Guide.</p>

```<code>// wrong!
package coolness
// right!
package com.novell.coolness
// right, for package object com.novell.coolness
package com.novell
/**
 * Provides classes related to coolness
 */
package object coolness {
}
</code>```

Body:
Scala package best practices are generally the same as Java conventions, according to the Style Guide.

// wrong!
package coolness
// right!
package com.novell.coolness
// right, for package object com.novell.coolness
package com.novell
/**
 * Provides classes related to coolness
 */
package object coolness {
}


问:
What are the best resources for learning about concurrency and multi-threaded applications?
I realised I have a massive knowledge gap when it comes to multi-threaded applications and concurrent programming. I've covered some basics in the past, but most of it seems to be gone from my mind, and it is definitely a field that I want, and need, to be more knowledgeable about.

What are the best resources for learning about building concurrent applications? I'm a very practical oriented person, so if said book contains concrete examples the better, but I'm open to suggestions. I personally prefer to work in pseudocode or C++, and a slant toward game development would be best, but not required.

答:
To learn about concurrency, use a language that was designed for concurrency. Golang is a good choice since it has built-in support for concurrency and a C-like syntax which makes the language easy to learn for most programmers.

It has message passing, mutexes etc which cover almost all of your concurrency needs and which have more complicated equivalents in other languages.

For example, receiving an int from another thread into variable a using MPI in C:

```<code>MPI_Recv(&a, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,MPI_STATUS_IGNORE);
</code>```

Receiving an int into variable a from another (user) thread in go:

```<code>a := <-c
</code>```

To learn go in practice, check out the go tour, where you can write, compile and run go code in your browser.

tour.golang.org

To skip to the concurrency part

http://tour.golang.org/concurrency/1

My former professor held a very popular short course for first year CS students on the topic of concurrency. For a quick, but thorough, introduction to what concurrency is, I definitely recommend reading the this.

Fundamentals of concurrent programming

Body:
To learn about concurrency, use a language that was designed for concurrency. Golang is a good choice since it has built-in support for concurrency and a C-like syntax which makes the language easy to learn for most programmers.

It has message passing, mutexes etc which cover almost all of your concurrency needs and which have more complicated equivalents in other languages.

For example, receiving an int from another thread into variable a using MPI in C:

MPI_Recv(&a, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,MPI_STATUS_IGNORE);

Receiving an int into variable a from another (user) thread in go:

a := <-c

To learn go in practice, check out the go tour, where you can write, compile and run go code in your browser.

tour.golang.org

To skip to the concurrency part

http://tour.golang.org/concurrency/1

My former professor held a very popular short course for first year CS students on the topic of concurrency. For a quick, but thorough, introduction to what concurrency is, I definitely recommend reading the this.

Fundamentals of concurrent programming


答:
Packages on the JVM have a very important job – to provide a globally unique namespace for all your classes. It doesn't matter whether you write your code with Scala or Java or Clojure; in the end all get compiled to .class files or JAR archives. Note that Scala is not the Anti-Java, instead interoperability with Java was a primary design goal.

So the package naming convention applies not only to Java but essentially to anything that runs on the JVM and wants to interoperate with Java. Using the Domain Name System as a basis for package names allows you to easily register a globally unique namespace for your code.

I've written code in enough languages that feature no similar convention, and the name clashes that invariably arise are bloody annoying. Who would have guessed two projects would both publish The One And Only template system? Clearly no one else could write a better http client. In particular, the conventions in C++, Python, Perl, and NodeJS are not satisfactory, while Java surprisingly gets this right.

Title: best practices for packaging in Scala projects?

Body: Scala runs on the JVM, but that doesn't mean we have to write it like Java.  Eclipse discourages use of the default package.  What are some considerations (e.g. size of project) that determine how code ought to be packaged in Scala?</p>


问:
What are perspective fields and options for self-employed, one-man team developer?
my wish is to get self-employed as one-men team, being a part of IT industry, not bound to anything, anyone and being able to work from anywhere, anytime...kinda freelancer job. However, making this happen doesn't seem to be that easy. I have just graduated  as electrical engineer and I'm also employed in software developing company which is creating tools for engineers, and I'm mostly doing API programming in .net. It's an OK job, but it's not a long term stuff that I would see some personal interest and satisfation in it. As I said, I want to go self-employed route and I want to do something different.

[rant]
I was thinking to try with game developing as this used to be one of my former hobbies. I created some stuff for flash portals and android market, but those were one of the worst projects ever had in the means of time invested and money generated. In previous years I invested a lot of time to learn programming, art,game design and also some audio engineering, but all this has to be done, just to create an application, which technically can be called a game and is still light years away from a state of finished product. Then I had to learn how to make polished art (in my case vector graphics),so that my product looks proffessional and that can be taken seriously (yes, yes I know, there are successfull games with shitty graphics, but they are exceptions), a game market, which is almost definition for oversaturation. It turned out that on game market 90% of developers doesn't make a dime, while others take almost all income and they're more or less all teams. Me as a lone wolf, couldn't stand a chance against highly skilled and professional teams. Some people even told me: "If your primary concern is money, just don't bother with game developing where multiple needed skills are just a ticket into an oversaturated market, where success is based on luck"
[/rant]

So what could I try as well?Web page design and web tech seem to be also out of question, since there are so many developers who do that, and I'm not into web tech that much. The idea is that projects are small and managable by one person and that market is not full of this profession. I don't know, just give some ideas.. [yeah I know, I sound like a semi-frustrated college boy, who just graduated and this actually is true] What are some specific jobs, that they may not b

答:
Hard to answer, because I do not know you, your skillset or your location. Generally, I don't think its wise to go self-employed "out of the blue", just because "I feel to".

I am a normal employer, also graduation not too long ago. I work with some freelancers, and those started their career mostly in small steps. They built up their network of companies and persons when they were employers. And someday (maybe a little luck involved), they got some project over that network. Just resigning your job and change your door bell nameplate to "freelancer" may not work.

Maybe you could persuade your employer in allowing you to have a small business beside your normal fulltime job (check that you do not work in the same field as your employer/steal him cusomers!). When you get more contracts and things start to go straight up for your business, you can switch your emphasis on that.

As I understand you, you tried to write and distribute your own software. I can not cover that topic, as I do not know much about that. But If you try to sell your stuff by yourself, you also have to evaluate if you feel up to the task of being your own marketing department. Engineers like me mostly look down on marketing, but without it, even the best software is nothing.


问:
How can I argue convincingly against duplicating database columns?
I've started working at a new organization and one of the patterns I've been seeing in the database is duplicating fields to make writing queries easier for the business analysts. We're using Django and its ORM.

In one case, we keep a MedicalRecordNumber object with a unique string identifying a patient in a certain context. We have Registration objects which track patients and have associated MedicalRecordNumbers, but rather than using a foreign key relationship, they duplicate the string so they can avoid writing a join (not for performance reasons). This pattern is common throughout the database.

For me the importance of a data model being clean is just so I can think about it well. Needless complexity is a waste of my limited cognitive processing time. It's a systematic problem. Not being comfortable writing joins is a rectifiable skills issue. I don't necessarily want to advocate going back and changing the schema, but I'd love to be able to convincingly articulate the problems with this type of duplication.

答:
To add to what the other guys have suggested above.
This is a data governance issue. You need to work with relevant stakeholders: data architects and data stewards to develop data principles, policies and naming conventions.

Be patient and work methodically. Change won't happen over night.


问:
Which things instantly ring alarm bells when looking at code?
I attended a software craftsmanship event a couple of weeks ago and one of the comments made was "I'm sure we all recognize bad code when we see it" and everyone nodded sagely without further discussion.

This sort of thing always worries me as there's that truism that everyone thinks they're an above average driver. Although I think I can recognize bad code I'd love to learn more about what other people consider to be code smells as it's rarely discussed in detail on people's blogs and only in a handful of books. In particular I think it'd be interesting to hear about anything that's a code smell in one language but not another.

I'll start off with an easy one:

Code in source control that has a high proportion of commented out
  code - why is it there? was it meant
  to be deleted? is it a half finished
  piece of work? maybe it shouldn't have
  been commented out and was only done
  when someone was testing something
  out? Personally I find this sort of
  thing really annoying even if it's just the odd line here and there, but when you see large blocks interspersed with the rest of the code it's totally unacceptable. It's
  also usually an indication that the rest of
  the code is likely to be of dubious
  quality as well.

答:
Peephole optimizations on code that could be optimized with better structure, e.g. linear searches implemented in inline assembly when a binary search in plain C/C++/Java/C# would be appropriate (and faster).

Either the person is missing some fundamental concepts, or has no sense of priorities. The latter is much more worrying.


问:
Are any side effects not concrete side effects?
In Chapter 23 of "Object Oriented Software Construction" (1988), Betrand Meyer makes a distinction between side effects, concrete side effects, and abstract side effects.

Meyer defines a side effect in the following quote:

A change performed by a function is known as a side effect to indicate that it is ancillary to the function’s official purpose of answering a query."

And he defines a concrete side effect in a definition box as:

A function produces a concrete side effect if its body contains any of the following: an assignment, assignment attempt or creation instruction whose target is an attribute, or a procedure call.

This distinction is hard for me to understand though, since I cannot think of an examples of functions which produce side effects but which do not produce concrete side effects. Meyer does not give us any either.

Would Meyer say that side effect and concrete side effect are synonymous? Or are there a class of side effects which are not concrete side effects?

(Note, the answer is not abstract side effects, since abstract side effects are themselves concrete side effects.)

答: From the comments we discussed the following: it could be a side effect that is not actually directly in the function called, but in a function called by that function? So function A is called. It calls function B and function B has a concrete side effect and function A is then sad to have a side effect, because it calls function B.</p>


问:
Is it reasonable to insist on reproducing every defect before diagnosing and fixing it?
I work for a software product company. We have large enterprise customers who implement our product and we provide support to them. For example, if there is a defect, we provide patches, etc. In other words, It is a fairly typical setup.

Recently, a ticket was issued and assigned to me regarding an exception found by a customer in a log file that has to do with concurrent database access in a clustered implementation of our product. So this customer's specific configuration may well be critical in the occurrence of this bug. All we got from the customer was their log file.

The approach I proposed to my team was to attempt to reproduce the bug in a configuration setup similar to that of the customer and get a comparable log. However, they disagree with my approach saying that I don't need to reproduce the bug as it's overly time-consuming and will require simulating a server cluster on VMs. My team suggests I simply "follow the code" to see where the thread- and/or transaction-unsafe code is and put in the change working off of a simple local development, which is not a cluster implementation like the environment from which the occurrence of the bug originates.

To me, working out of an abstract blueprint (program code) rather than a tangible, visible manifestation (runtime reproduction) seems difficult, so I wanted to ask a general question:

Is it reasonable to insist on reproducing every defect and debug it before diagnosing and fixing it?

Or:

If I am a senior developer, should I be able to read multithreaded code and create a mental picture of what it does in all use case scenarios rather than require to run the application, test different use case scenarios hands-on, and step through the code line by line? Or am I a poor developer for demanding that kind of work environment?

Is debugging for sissies?

In my opinion, any fix submitted in response to an incident ticket should be tested in an environment simulated to be as close to the original environment as possible. How else can you know that it will really remedy the issue? It is like releasing a new model of a vehicle without crash testing it with a dummy to demonstrate that the air bags indeed work.

Last but not least, if you agree with me:

How should I talk with my team to convince them that my approach is reasonable, conservative and more bulletproof?

答:
Sounds to me like you need more detailed logging.

While adding more logging cannot guarantee that you won't need to debug (or, in this case, reproduce the situation), it will give  you a far better insight into what actually went wrong.

Especially in complicated/threading situations, or anything where you can't use a debugger, falling back on "debug by printf()" might be your only recourse. In which case, log as much as you can (more than you expect to need) and have some good tools for filtering the wheat from the chaff.


答:
Let's take it to the extreme, and assume that you found the bug much earlier: in your code, as you were writing it. Then you wouldn't have any qualms about fixing it right there -- you see a logic flaw in the code you just wrote, it doesn't do what you wanted it to do. You wouldn't feel a need to setup a whole environment to show that it's actually a bug.

Now a bug report comes in. There are several things you can do. One of them is to go back to the code and re-read it. Now suppose that on this second reading, you immediately find the bug in the code -- it simply doesn't do what you intended it to do, and you failed to notice when you wrote it. And, it perfectly explains the bug that just came in! You make the fix. It took you twenty minutes.

Did that fix the bug that caused the bug report? You can't be 100% sure (there may have been two bugs causing this same thing), but it probably did.

Another thing you could do is reproduce the customer's configuration as well as you can (a few days' work), and eventually reproduce the bug. In many cases, there are timing and concurrency issues that mean you can't reproduce the bug, but you can try a lot of time and sometimes see the same thing happen. Now you start debugging, find the error in the code, put it in the environment, and you try a lot of times again. You don't see the bug occurring anymore.

Did that fix the bug that caused the bug report? You still can't be 100% sure -- one, you may actually have seen a completely different bug that the customer did, two, maybe you didn't try often enough, and three, maybe the configuration is still slightly different and it's fixed on this system, but not the customer's.

So certainty is impossible to get in any case. But the first method is way faster (you can give the customer a patch faster too), is way cheaper and, if you find a clear coding bug that explains the symptom, is actually more likely to find the problem too.

So it depends. If it's cheap to setup a testing environment (or better: an automated test that shows the problem), then do that. But if it's expensive and/or the circumstances in which the bug shows are unpredictable, then it's always better to try to find the bug by reading the code first.

Title: Is it reasonable to insist on reproducing every defect before diagnosing and fixing it?

Body:
I work for a software product company. We have large enterprise customers who implement our product and we provide support to them. For example, if there is a defect, we provide patches, etc. In other words, It is a fairly typical setup.

Recently, a ticket was issued and assigned to me regarding an exception found by a customer in a log file that has to do with concurrent database access in a clustered implementation of our product. So this customer's specific configuration may well be critical in the occurrence of this bug. All we got from the customer was their log file.

The approach I proposed to my team was to attempt to reproduce the bug in a configuration setup similar to that of the customer and get a comparable log. However, they disagree with my approach saying that I don't need to reproduce the bug as it's overly time-consuming and will require simulating a server cluster on VMs. My team suggests I simply "follow the code" to see where the thread- and/or transaction-unsafe code is and put in the change working off of a simple local development, which is not a cluster implementation like the environment from which the occurrence of the bug originates.

To me, working out of an abstract blueprint (program code) rather than a tangible, visible manifestation (runtime reproduction) seems difficult, so I wanted to ask a general question:

Is it reasonable to insist on reproducing every defect and debug it before diagnosing and fixing it?

Or:

If I am a senior developer, should I be able to read multithreaded code and create a mental picture of what it does in all use case scenarios rather than require to run the application, test different use case scenarios hands-on, and step through the code line by line? Or am I a poor developer for demanding that kind of work environment?

Is debugging for sissies?

In my opinion, any fix submitted in response to an incident ticket should be tested in an environment simulated to be as close to the original environment as possible. How else can you know that it will really remedy the issue? It is like releasing a new model of a vehicle without crash testing it with a dummy to demonstrate that the air bags indeed work.

Last but not least, if you agree with me:

How should I talk with my team to convince them that my approach is reasonable, conservative and more bulletproof?


问:
What are messages in FHIR?
I am trying to get my head around Fast Healthcare Interoperability Resources (FHIR) specification, but I can't  understand what Messages are used for.

The exact mechanism of transfer is irrelevant to this specification, but may include file transfer, http based transfer, MLLP (HL7 minimal lower layer protocol), MQ series messaging or anything else.
http://hl7.org/fhir/messaging.html

Isn't it the whole point of FHIR that it uses REST? And that:

Events mostly correspond to things that happen in the real world.

  http://hl7.org/fhir/messaging.html

Is this a way of saying it is for real-time systems?

This is probably easy question, but I do not have any background in HL7. What are these messages and what are they used for?

答:
A message in this case is a stream of data that is sent from one system to the other. If you make a request to a REST service you would pass in a stream of data (for example, a JSON object) so that the service can perform an action. In FHIR, this data is called a message.

There is no requirement for FHIR to use REST, it is simply one of the ways it can be implemented. You could write a FHIR-conforming application using file shares by writing a message to a file from the sending application and have the receiving application read the files from the share. But the basic architecture of FHIR also defines a RESTful API, so you could implement communication between the applications using a REST API and have them call each other directly.

It is not for real-time systems per se, but it can be. In HL7, messages mostly respond to real-life events. For example, there is a 'MedicationAdministration-Complete'-event that changes the status of a medication administration to complete. When a user in an application checks off the administration of medication, this event will be raised. Events in HL7 are mostly the result of a physical action in the real world.

Title: What are messages in FHIR?


问:
How to mark next version in the source code?
We are developing a software that gets released every few months, and it is either a major version (1.0.x -> 2.0.0) or a minor version (-> 1.1.x). This version is visible in the software, say that we have a variable for it like this:

```<code>var version = '1.0.0';
</code>```

and then it's displayed somehow:

```<code>print(version);
</code>```

When we release 1.0.0 and start working on "vNext", it just feels wrong to leave 1.0.0 there because all the developers and testers will see a "wrong" version in the app. However, at that point we are not sure what the next version will be called - it might be 1.1 or 2.0. I've thought about possibly just marking the next version as "DEV" so that there is no expectation of a certain version number but am not sure this is a good idea (and it's certainly not in semver format so some other code may be broken if it works with the version number in any way). Another idea was to just call it "post-1.0" but that's not a proper version format, too.

Have you ever run into this situation, and how did you deal with it?

答:
You use your build setup to populate the var.

Most build engines allow a search-replace pass of a file and compile in the resulting file.

So the actual line in the repo would be

```<code>var version = @VERSION@;
</code>```

And then through the builder's config settings @VERSION@ would be replaced with the actual version when building (possibly adding debug postfixes and commit ID for test builds).

Body:
You use your build setup to populate the var.

Most build engines allow a search-replace pass of a file and compile in the resulting file.

So the actual line in the repo would be

var version = @VERSION@;

And then through the builder's config settings @VERSION@ would be replaced with the actual version when building (possibly adding debug postfixes and commit ID for test builds).