问:
How Immutable Sets are Manipulated
When working with an immutable set or map, like the ones found in many functional programming languages, operations that would otherwise modify the container generate a new container instead.

I know that most list operations in functional languages do not result in a copy of the list and just rearrange pointers. This is why working with lists is extremely efficient.

I am curious whether immutable maps are similar or if an entirely new map is created after each operation. I am asking because a library I wrote manipulates a lot of maps and I am curious whether I will see a performance boost if I switch over to immutable maps. Currently, I am just looping over my map adding or throwing away key/value pairs as I go.

答:
Sharing — referencing the same data block from several objects, so that several data structures end up with part of their memory in common — is one of the major points of immutable data structures. Immutable data structures automatically share the common pieces that they're built from. (Data structures built independently don't share anything — there are techniques for that, in particular hash consing.)

In many ways, the fundamental mutable data structure is the array, and the fundamental mutation operation is to modify one element of an array. A mutable data structure consists of arrays that contain pointers to (or into) each other.

In an immutable data structure, you have to decide all the elements of a data block when you build that block. That tends to drive towards small data blocks. When you need to store a large amount of data, you pretty much need to apply a divide-and-conquer strategy: unless the data is small enough to store in one lump, you divide it into several pieces, and store a lump of pointers to those pieces — which themselves may be again pointers to smaller pieces, and so on recursively. That makes the resulting data structure a tree. The tree is the basic immutable data stucture.

Any mutable data structure can be represented as an immutable data structure with a logarithmic loss of time and a linear increase in memory. That is, if you have an algorithm that operates in time N and uses M units of memory, you can convert it to use only immutable data structures with O(M) more memory used and operating in time O(N*log(N)). You can do this by encoding every array as a binary tree where the leaves are the elements of the tree. To access or modify an element costs O(1) time in an array and O(log(N)) in a tree with the same number of leaves. This is of course a maximum: often there is a less general but more efficient approach.

This means that there is a bound to the build-up caused by switching to immutable data structures. You'll never experience anything like a quadratic explosion.

In practice, every immutable data structure you'll find in any halfway-decent library will be written around such divide-and-conquer lines, often with copious tricks to compensate the logarithmic build-up. Sharing comes for free: most of the time it would take some work to avoid it. Building short-term data structures that are derived from another data structure, differing only in a few values, is something programmers do all the time; you can be confident that it will result in sharing under the hood. (You can test by checking physical equality of non-modified parts of the data structure, by keeping tracks of your program's memory consumption, or by looking at the program executing in a debugger).

Building a new data structure that differs in only a few places from an old one and discarding the old one is also something programmers do often, and you can often expect to find implementations of immutable data structures that are optimized for that case. Look at indications of amortized complexity.

Chris Okasaki's book Purely Functional Data Structures is a good reference if you need to write your own immutable data structure. Expect the implementers of immutable data structure libraries to have read this book.

Title: How Immutable Sets are Manipulated


问:
Will SSD make the distinction between column oriented DB and row oriented DB obsolete?
I had a discussion with a friend about row vs column oriented RDBMS.

From my understanding, these things are closely linked with the fact that there's a concrete drive head reading and writing the data. This head moves and reading/writing data is faster if the head moves are limited.

Still from my understanding, SSD drives drops those mechanical artifacts and accessing the data is now taking the same amount time regardless of where they are physically stored on the chip / device (don't know the right term).

Considering these two points, will the SSD drives (when they'll have reached their full potential) make the distinction between row oriented and column oriented either obsolete or pointless?

答:
The only time I've ever seen rotational latency mentioned in the same breath as a DBMS is with SQLite.  SQLite recommends that, if you have a lot of consecutive inserts, you should wrap them into a transaction, because if you don't, the database engine does a read after write to verify each record.  That takes about 1/60th of a second for each insert on a 7200 RPM drive, which is a lifetime in computer terms.

In any case, there's always a workaround in databases for this rotational latency; usually it's some sort of caching.  The only thing that changes when you switch to a solid state drive is that this caching becomes less important.  You still need the things like queries, joins and sets that databases provide; you'll just get them with a performance boost.

ContentLicense: CC BY-SA 3.0


答:
When dealing with sets and maps, a lot depends on the specific data structure. Trees are quite common for associative containers, including sets and maps, so I'll deal purely with those.

For unbalanced binary trees, an insert operation operation works in two phases - the top-down part to find the insert point and the bottom-up part to modify (or create) the new tree.

The point here is that for each node, only one of the two subtrees contains the insertion point, and only that one subtree needs to be duplicated for a pure-functional tree insert. So the only new nodes needed are in a chain from the insert point back up to the root.

This means that assuming the tree is (accidentally) balanced, you have O(log n) new nodes for a single insert - the number of new nodes depends on the depth of the tree, not the total size.

A key assumption here is that nodes only store pointers to their children. In imperative languages, it's common for nodes to store pointers back to their parents. This means there are cyclic references, so the data structure must be copied as a whole. There are similar issues with threaded binary trees. The general rule is that when creating a new state, every strongly connected component must be copied as a whole - in practice, these data structures are rarely used in functional programming.

Of course parent links can be stored outside of the tree data structure, and the functional way to handle this is using a zipper. One issue (sometimes advantage, sometimes disadvantage) is that the zippers, like externally-stored parent links generally, refer to the particular state they were created to refer to, not to any newer state.

With balanced binary tree schemes such as AVL trees and red-black trees, there will be more complex changes due to rebalancing, but you still generally get the same O(log n) nodes copied per single item insert - unless you have parent links again.

Digital trees or tries use a tree data structure, but base that on the binary (or digital, at least) representation of the keys, not the ordering. For example, using base 10 digits, you might find the item for key 123 by starting at the root node, following child link 1, then child link 2, then child link 3. The depth of these trees is logarithmic in the maximum possible size because if you have an n-digit number and k distinct digits, you can form k^n digit strings so the maximum possible size is k^n. For example, with three decimal digits, you can only have 1000 different keys, so the maximum size is 1000 - 3 is the base 10 logarithm of 1000.

The story is similar to binary trees, except that you tend to have better constants (the tree branches more ways at each node) and you can often claim O(1) because the keys all have a fixed number of bits. This structure, with hashes for keys, can even be used to give a kind of hash table - with both advantages and disadvantages over the usual array-based hash tables from imperative programming.

There's an in-between structure called a ternary tree - basically a tree of binary trees, so you binary search for the first character of the string, then the next and so on. Again, it's still a tree, and provided there are no parent pointers or other cyclic references each insert should only have to copy O(log n) nodes.

Title: How Immutable Sets are Manipulated

Body:
When working with an immutable set or map, like the ones found in many functional programming languages, operations that would otherwise modify the container generate a new container instead.

I know that most list operations in functional languages do not result in a copy of the list and just rearrange pointers. This is why working with lists is extremely efficient.

I am curious whether immutable maps are similar or if an entirely new map is created after each operation. I am asking because a library I wrote manipulates a lot of maps and I am curious whether I will see a performance boost if I switch over to immutable maps. Currently, I am just looping over my map adding or throwing away key/value pairs as I go.


问:
Entropy in large scale software systems
I work on a fairly large software system and over the years it has accumulated a lot of entropy. There is plenty of scope for refactoring but there is always pressures to build the next features upon what's already there. This adds to more entropy, because design choices for implementing new features are typically made by first accepting what's there and 'working-around' some earlier weaker design that is otherwise ripe for refactoring.

What are some ways to manage this kind of complexity and build functionality without substantially weakening the structure of the system further. I know this is a very broad question and the approaches/solutions depend on the particular software system at hand, but I am still hoping there are some generic ways to manage the problem I am highlighting.

答:
You can't. As you already acknowledge, every new feature built on the weak foundation makes that feature weaker, perpetuating the cycle.

What you need to do is spend the time to refactor things to at least not require hacks for new functionality. Maybe that means a heart-to-heart with management about tech debt and/or maintenance costs. Maybe it means having high estimates to make sure you get the time to do it right. Maybe it means having the pride at your craft to take the time to do it right, even if it doesn't get done 'on time'.

But you're the one writing the code - so you're the one who is going to have to fix it. How you do that will vary from place to place.

Title: Entropy in large scale software systems


问:
Is object-oriented conceptual thinking something you build with experience?
I know that the answer is pretty clear because you get better on everything with time and experience. But I'll tell you where I'm coming from:

A couple of months ago I decided to learn iOS development, so I studied C (read the C primer plus book, pretty good book). Recently I finished "Programming in Objective C" and lately I started following the Stanford course for Winter 2013 (I'm really enjoying it. I'm only at the beginning of the course, on lecture #3, and had to do only 2 homeworks).

I understand all the syntax and concepts so far, and I think Objective C is an amazing language. But something has been bothering me, I thought it might be because I'm new to OOP. For example when the instructor defines models (matching cards game for instance), I definitely understand the syntax and logic, but sometimes I'm trying to think if it as taking a task (card game for instance) and breaking it into the right logic. Is this something I will get used to with time? Because at this stage when I try to predict things I'm supposed to do, pretty often I go and see some of his logic and go back to code. Actually we haven't had to go from zero, he always tells us to follow the presentation with the code in this stage, but I really want to improve at taking a task and knowing how to break it into the right models, controllers, etc.

答:
In my opinion, object composition comes with time and experience.

When you are creating and designing an object, remember that you are modelling, whether you are basing it on a real world object or a specific domain concern.

From what you write I think you understand how to read the object, it's just the process of designing the object you are having problems with.

I suggest what you try and do is think abstract and where you have a problem work out what fields of information you need to represent your data structure.

Remember that in object orientation, subclassing, interfaces and abstract classes are your friends. They allow you do design your solutions elegantly and reuse code where appropriate.

Hope this helps.


问:
Do any LOP languages exist?
I have read a few of the articles related to the Language Oriented Programming paradigm. Therefore, I concluded that LOP paradigm can let programmers be more productive because of it's extensibility.

Are there any programming languages that are already implemented LOP or in development status?

答:
As was mentioned, language oriented programming will refer to a DSL.

This may summarize what you are trying to express:

When you have to solve a complex problem, first choose – or, if
  necessary, develop – a language that is most appropriate for the
  problem. Then, implement the solution in this language.

which I found in:

https://www.fbi.h-da.de/fileadmin/personal/b.humm/Publikationen/Humm_Engelschall_-_Language-Oriented_Programming_via_DSL_Stacking.pdf

There are many languages that will help you create a DSL, such as Groovy, Ruby, Scala and F#.

You can write internal and external DSLs in these languages, and these languages have constructs to help the programmer create a DSL more easily, such as using parser combinator so you can more easily create a compiler or interpreter for your language.

This will make it easier for the end-user to write their own programs, in the language they are used to, so they won't realize they are writing a program, just expressing what they want done.

So, you could have something like:

```<code>order 10 cartons of milk from Soya and deliver them to store 23 delivered on 4/1/2013.
</code>```

It would be obvious to the user what they are doing, and as long as they follow some rules you express the language can be very expressive.

You may want to read:

http://blogs.ethz.ch/copton/2009/07/23/language-oriented-programming/

Title: Do any LOP languages exist?

Body:
As was mentioned, language oriented programming will refer to a DSL.

This may summarize what you are trying to express:

When you have to solve a complex problem, first choose – or, if
  necessary, develop – a language that is most appropriate for the
  problem. Then, implement the solution in this language.

which I found in:

https://www.fbi.h-da.de/fileadmin/personal/b.humm/Publikationen/Humm_Engelschall_-_Language-Oriented_Programming_via_DSL_Stacking.pdf

There are many languages that will help you create a DSL, such as Groovy, Ruby, Scala and F#.

You can write internal and external DSLs in these languages, and these languages have constructs to help the programmer create a DSL more easily, such as using parser combinator so you can more easily create a compiler or interpreter for your language.

This will make it easier for the end-user to write their own programs, in the language they are used to, so they won't realize they are writing a program, just expressing what they want done.

So, you could have something like:

order 10 cartons of milk from Soya and deliver them to store 23 delivered on 4/1/2013.

It would be obvious to the user what they are doing, and as long as they follow some rules you express the language can be very expressive.

You may want to read:

http://blogs.ethz.ch/copton/2009/07/23/language-oriented-programming/


答:
Ah yes, this problem.

The first thing you have to do is to get management on board with the idea that the software needs to be made evolvable (my term).  The idea here is that instead of a system of fixed design and changing requirements, you have to get them on board with the idea of modifying the design as the requirements change.  Otherwise you invariably end with monsterous systems that are impossible to maintain.

The second thing (once you have management on board) is that you have to get a commitment from programmers to separate contract from implementation.  Then you have to be willing to write unit tests against contracts, not against implementation.

Now if this is a large-scale system (and it sounds like one) the next stage is actually to build a new framework.  New code goes on the new framework and eventually the old framework will be retired.  You should do this in a way that allows you to preserver old contracts (with external apps) in the new framework for as long as you can.

From there, the solution is what I call "refactor with a chainsaw" and remove well-defined blocks of functionality from the old framework and move it onto the new framework.  On a large scale system this can take years to move over everything.

Now if you have unit tests on contracts, then you can refactor your own implementations as you go without worrying as much about breaking things.

Title: Entropy in large scale software systems

Body:
I work on a fairly large software system and over the years it has accumulated a lot of entropy. There is plenty of scope for refactoring but there is always pressures to build the next features upon what's already there. This adds to more entropy, because design choices for implementing new features are typically made by first accepting what's there and 'working-around' some earlier weaker design that is otherwise ripe for refactoring.

What are some ways to manage this kind of complexity and build functionality without substantially weakening the structure of the system further. I know this is a very broad question and the approaches/solutions depend on the particular software system at hand, but I am still hoping there are some generic ways to manage the problem I am highlighting.


问:
When to pay for C++ compilers
Recently I have began to wonder when developers should pay for compilers. Compilers come for free with most platforms or there is a free version easily obtainable.

Example:

OS X - GCC and Clang/LLVM come with the developer tools. No limitations here for how and what you can turn out with them.

Linux - GCC and I am sure more. I dont know the current state of linux compilers. No limitations here for how and what you can turn out with them.

Windows - MinGW and Microsoft does offer a free version of Visual Studio. No limitations with MinGW but I think with the free Visual Studio there are severe limitations.

However, as an example, Intel produces C/C++ compilers. They are hefty in price. Educationally I think that one can get the OS X version for $49 and Windows/Linux for $129 each. They then offer a complete "Studio" product too. Obviously using the educational pricing there are imposed limitations.

But what I am wondering is when should one really considering paying for compilers. One example I can think of is a video game. If you are using a compiler that works on the major platforms there would be no more switching tools for the platform. It seems there would be a level of ease in switching among platforms if the tools were the same.

Can anyone shed some light on paying for compilers like the Intel compilers and the true cross-platform benefits one might get from using them? Does one's code become less portable even trying very hard to not do platform specific techniques?

答:
In my experience, cross host platform ability is a minor consideration for choosing a compiler.  In fact, quite the opposite.  People much more frequently choose a compiler for it's superior support for one specific target platform.

Take the Intel compiler for example.  People usually buy it when they want to eke every last ounce of performance out of the latest bleeding edge Intel chip.  After all, it's hard to design a compiler better than the guys who can walk down the hall and talk to the guys who designed the chips.

It's the same reason people buy tools from Microsoft to develop on Microsoft platforms.  That's who has the support first and foremost.

Title: When to pay for C++ compilers


答:
Having worked on a for-pay compiler, I believe the main reason to pay for a compiler is for the support contract. If the customer has a problem with their code and suspects a compiler bug, they can ask the compiler vendor to investigate possible solutions (on the vendor's dime, not their's), possibly with a deadline for a response/solution. This can be done without having to publicly release source code for projects which may contain sensitive information, and usually the contract binds the vendor into secrecy about any shared source code. Generally, larger companies are willing to pay for this level of support, while smaller shops don't view it as worth the money or just too expensive. </p>

<p>In addition, vendors want to please (high paying) customers, so feature requests are prioritized by which customers want them. It is also possible for customers to suggest features more tailored to their needs, things more company specific which would not be widely used. This is not possible for users of GCC or other opensource compilers where features get implemented by those willing to do it in whichever order they feel on their own schedule. </p>

Title: When to pay for C++ compilers

Body:
Recently I have began to wonder when developers should pay for compilers. Compilers come for free with most platforms or there is a free version easily obtainable.

Example:

OS X - GCC and Clang/LLVM come with the developer tools. No limitations here for how and what you can turn out with them.

Linux - GCC and I am sure more. I dont know the current state of linux compilers. No limitations here for how and what you can turn out with them.

Windows - MinGW and Microsoft does offer a free version of Visual Studio. No limitations with MinGW but I think with the free Visual Studio there are severe limitations.

However, as an example, Intel produces C/C++ compilers. They are hefty in price. Educationally I think that one can get the OS X version for $49 and Windows/Linux for $129 each. They then offer a complete "Studio" product too. Obviously using the educational pricing there are imposed limitations.

But what I am wondering is when should one really considering paying for compilers. One example I can think of is a video game. If you are using a compiler that works on the major platforms there would be no more switching tools for the platform. It seems there would be a level of ease in switching among platforms if the tools were the same.

Can anyone shed some light on paying for compilers like the Intel compilers and the true cross-platform benefits one might get from using them? Does one's code become less portable even trying very hard to not do platform specific techniques?

Body:
Having worked on a for-pay compiler, I believe the main reason to pay for a compiler is for the support contract. If the customer has a problem with their code and suspects a compiler bug, they can ask the compiler vendor to investigate possible solutions (on the vendor's dime, not their's), possibly with a deadline for a response/solution. This can be done without having to publicly release source code for projects which may contain sensitive information, and usually the contract binds the vendor into secrecy about any shared source code. Generally, larger companies are willing to pay for this level of support, while smaller shops don't view it as worth the money or just too expensive.

In addition, vendors want to please (high paying) customers, so feature requests are prioritized by which customers want them. It is also possible for customers to suggest features more tailored to their needs, things more company specific which would not be widely used. This is not possible for users of GCC or other opensource compilers where features get implemented by those willing to do it in whichever order they feel on their own schedule.


答:
One reason that systems get into this state is that there has not been anyone guiding the changes. Many successful long-term projects have associated steering committees and roadmaps to guide development. These are especially helpful when there are multiple development teams and stakeholders involved.

My suggestion is that your team develop a roadmap to refactor the system. First, define a goal. In your case, define the ideal architecture for the system. Remember, it doesn't have to be perfect, just workable and better than what you are working with. Take into account software, development tools, hardware platforms, major new features that may be added to the system. Do a cost analysis. If you have the desired architecture, what are the tangible benefits of performing the refactoring? (Benefits would include reduced test time, more reliable software products, more predictable development cycles, etc.) If you can show enough benefits to performing refactoring, you can get management support.

Once you have a roadmap and management support, Develop a series of steps that you need to take to get to this desired state. It may be a good idea to put together a steering committee that maintains the roadmap, trains and educates the development teams on the roadmap, and periodically reviews changes for architectural integrity.

Roadmaps are really useful, and perhaps the 13th question on the Joel Test should be "Do you have a roadmap?"

Here is a video of the first hour of a recent Red Hat Linux roadmap session.

Title: Entropy in large scale software systems


问:
What can a technically proficient senior software developer study to keep improving
Say you have been programming for over 10 years. You know many languages, with few of those at very detailed level. You have been designing architecture for solutions, worked on and delivered larger projects. You have been studying patterns, best practices, effective coding guidelines, unit testing, multi-threading, etc.

And then you slowly develop a feeling that most of the books you read, give less and less valuable information per 100 pages of text. So they start giving diminishing returns. You still learn, but you no longer improve by leaps and bounds.

Why does learning become less productive compared to how it was before?

Back then, it used to change your way of thinking, taught you new things and broadened your horizons that later improved either your current profession, or allowed to invent/manage/build something new. Why is it no longer the case?

答:
I think that software is always evolving and as such there is an emphasis on constant improvement. I understand where you're coming from, I've felt somewhat similar recently and I'm now pursuing an MCSM in SQL Server.

Learn the next new language, or framework, or what's currently "hot". Every year there is a technology, framework or language that comes out, or reaches critical mass that it becomes a buzz word in its own right. I can think a few of these over the past few years: node.js, Ruby, jQuery. This will also likely impact your way of thinking for other platforms, for example, look at what ROR did to Java with Grails.

There is always room for improvement. I think it is very unlikely that you can be an expert on everything, and I read a lot and I am always learning. I do agree with what you say about learning less and less per 100 pages, but this is to be expected when you're a subject matter expert.

In terms of what you can do, here are some suggestions:

Keep abreast of community changes and what people are "getting into". Learn the new stacks, at least so you have enough to recommend them where appropriate

Participate in Q&A sites such as this, where you can impart your knowledge on others. If you take the time to read other peoples contributions, you will likely learn something, and at the very least you will likely see the perspectives other people have.

Pick a hobby that has some relation to your work. There are plenty of hobbies with cross over, think AI, lego mindstorms, RaspPi, etc.

As well as trying to increase the width of your knowledge, look at increasing the depth. For example, learn how EF works under the cover, so you can diagnose those weird corner cases rather than just use the framework.

Pursue top level certification just to prove you know your stuff

Personally, I'll tell you what's opening my mind at the moment. I'm reading 97 Things Every Software Architect Should Know and I'm only partially though it but it's thrown up a lot of sage advice. The book is free to read online at the link I provided.

In terms of the hobby I ultimately took up, I got into vehicle diagnostics (with the computer, obviously) which got me fully maintaining my own car. I actually really enjoy the time I spend working with my hands.


答:
GNU free compiler (gcc) comes with GNU license (GPL) meaning you can use for Open source projects only. Supported by big names in software.

Clang (free) is an attempt to avoid GPL limitations creating a good compiler. Also, is supported by Apple, Google, and many others.

VC++ Express (free) is limited to Windows platform (by the way, they made it free in the last moment, because many people from Open Source community asked them about it) and lacks most of professional tools an features. Such as profiler, for example.

So, all these tools are free for us, but are supported by the industry.

Intel (commercial), as Karl mentioned, for projects that target most performance on Intel platforms.

Title: When to pay for C++ compilers


答:
First, despite the way your question is formulated, there is no end to any studying, especially not in our field, where new things pop up faster than you can read about them. That being said, when you want to improve, there are the following categories that I'd consider. For the most benefit/ROI you should choose something from your weakest area of course.

Foundational Knowledge

Despite knowing programming languages and having practical experience, one often has (esp. self-learned) areas where basic foundational issues are left incomplete. Think about things like data structures, algorithms, cache strategies, hash functions, ...

Note that this also includes the foundations of programming languages - everything from compilers, optimization techniques and type systems, up to category theory, monads, and the like.

If you are well taught, as in have persued a university level degree for several years, then you are likely to already be strong in this category (far from finished of course, but a solid basis). Otherwise, do try to read a few books in these areas to find out if there's anything you didn't even know was missing in your repertoire. This category is the easiest to over-estimate yourself in.

Paradigmatic Knowledge

I am always astounded when programmers show up who think they are know-it-alls, yet are completely ignorant on other than the mainstream paradigms. If you think object-orientation is the end of it, this is your category for improvement. If you think functional programming exists too and might even have heard of logic programming, then it's still a good choice. There are way more paradigms out there and learning about them has the profound effect of giving you something akin to a new view of the world of programming.

Just don't forget: there are often (rather philosophical in their nature) arguments about what can be considered a paradigm or not. Don't get side-tracked by these. Your goal should be to broaden your horizon and that means learning about these things, whether someone else considers X a paradigm on its own, or not, does not make any difference to that.

Specialist Knowledge

The easiest of them all - and the least useful at the same time. Of course, you can commit yourself to a single technology and get to know all its ins and outs, but you should be prepared to pay the price. Technologies age and they do so in an ever-increasing speed, which makes it almost a guarantee that time invested here will be worthless several years down the road.

Also the problem of diminishing return shines here. By the very nature being a specialist on something means you have to spend countless hours on that narrow subject, and hence, by definition it will take you a long time to learn something new and that new thing will be a tiny little puzzle piece that is not going to change anyone's views of anything.

Domain Knowledge

Be it because it's your work's domain, or simply based on your personal interest, but being an expert in computer science and a certain domain is very valuable and rewarding. I am not talking about side-areas of CS here, like computer graphics or AI. Instead notice that computers have taken a hold in everyone's life and that makes every other field subject to computers and an area you can get into.

This one clearly falls into the category of "outside your field", yet it is not a sharp mathematical "outside", but rather a field of application. Consider medicine: I am not advicing you to become a doctor. However, learning the foundations of medicine in order to apply your existing knowledge about computer science to that field's problems is indeed worthwhile. This ranges from visualization techniques, over robotics, to expert systems and mere data management for accounting/administration. While you have done all of that before, doing it in another domain can end up being a whole new experience.

Keep in mind though, that this is a way more radical change in your direction than the other categories. You may not have any contact to that field in your day-to-day work, which makes it extremely hard to pull off. It may even mean switching jobs. Plus, you will need some sort of certification about your new domain - you are a complete newbie to that domain after all, and you have to compete against graduates from interdisciplinary studies, which already began their journey to become experts in that niche.

Supplementary Knowledge

As Mike Brown added, there is also the area of knowledge which in some way accompanies your current job, but is not strictly necessary. You do not need to be a project manager to learn about project management, but as usual, additional knowledge will give you a larger insight on how the other side ticks. One could even generalize this to the point of focusing on soft skills. I guess everyone who worked on a real project with other people knows the value of these.

Title: What can a technically proficient senior software developer study to keep improving

Body:
Say you have been programming for over 10 years. You know many languages, with few of those at very detailed level. You have been designing architecture for solutions, worked on and delivered larger projects. You have been studying patterns, best practices, effective coding guidelines, unit testing, multi-threading, etc.

And then you slowly develop a feeling that most of the books you read, give less and less valuable information per 100 pages of text. So they start giving diminishing returns. You still learn, but you no longer improve by leaps and bounds.

Why does learning become less productive compared to how it was before?

Back then, it used to change your way of thinking, taught you new things and broadened your horizons that later improved either your current profession, or allowed to invent/manage/build something new. Why is it no longer the case?


问:
In a resume, what all constitutes a Programming Language
In your resume, what would you classify as a Programming Language? For instance, under Programming Languages (or a similarly titled section of your resume), do you list C#, Java, C and leave it at that or do you go and add XML (because, well it is eXtensible Markup Language) and XSLT and jQuery and all that too?

If you are not going to add jQuery under languages, where exactly would you put it?

One resolution to this dilemma would be put in the technologies you have used under the project, but that way, you are forcing the recruiter to go through the projects that you have done rather than giving a highlight of the technologies and languages you are familiar in.

What are your thoughts?

答:
If you need a technologies section, list languages and then list frameworks separately.

Better thing is to list your languages, frameworks, and other technologies inline with descriptions of your key project/work experiences.

ie, "Developed web application to do XYZ using PHP, Javascript (jQuery), and XSLT...."

ContentLicense: CC BY-SA 2.5


问:
When to use DI and when to create yourself in Java
I've a decent amount of OOP with various languages but am pretty new to Java.

I'm reading through a lot of tutorials where large numbers of objects are created within the code of a class, and I'm trying to run through them but build versions of the classes in the tutorials that do Dependency Injection instead of instantiating all the classes themselves.

But Java is not like other languages I've used in that pretty much everything is an object.  If I was to literally inject everything then the result would be very messy and hard to follow.

Obviously you wouldn't inject String objects, and I'm guessing there are other objects you wouldn't inject, but I'm not sure where the line should go.  At what point does DI stop being the right thing to do, and when does it start being a burden?  How do you decide pragmatically what to inject and what to just instantiate?

FYI, the tutorials I'm doing are http://edn.embarcadero.com/article/31995 and http://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html for building a simple client and server.  I'm not copying them line for line though, I'm trying to create equivalent classes that follow best practice

答:
Firstly, it's OK to use the new keyword, really!  DI is a fantastic technique, but there is a temptation to overuse it.  Times where you might want to use DI are:

Test Doubles - Often with unit tests you want to mock out / test double a 3rd party resource as you don't want to bring that 3rd party resource up (e.g. A full Oracle DB). For example, instead of a creating a new database connection to the big Oracle DB, you might want to replace that connection with one to an HSQL (in memory database) instead.

When you want to control the scope (~lifespan) of that object and the natural Java object lifecycle doesn't work for you. Many Java based DI frameworks allow you to do this.

When you want singletons.

Anytime you think you need a Factory, Service Locator or similar.  This includes if you need different factories (rare, but it happens).

At other times, simply create a new object, in fact if in doubt, create a new object - you can always DI it when you see the need later :-).


答:
I am with Karl Bielefeldt on this.

I won't actually trust compilers that offer cross-platform capabilities. Because, to be honest we all know native and targeted tools / compilers always have advantages like knowing the target platform better.

And I believe, when your software becomes complex and performance is needed you can start thinking about switching to paid compilers.

And on addition to that, I believe Microsoft's compilers are pretty damn good. And like everyone else said, they are free for ever.

Title: When to pay for C++ compilers


问:
Can commented-out code be valuable documentation?

I wrote the following code:

if (boutique == null) {
    boutique = new Boutique();

    boutique.setSite(site);
    boutique.setUrlLogo(CmsProperties.URL_FLUX_BOUTIQUE+fluxBoutique.getLogo());
    boutique.setUrlBoutique(CmsProperties.URL_FLUX_BOUTIQUE+fluxBoutique.getUrl());
    boutique.setNom(fluxBoutique.getNom());
    boutique.setSelected(false);
    boutique.setIdWebSC(fluxBoutique.getId());
    boutique.setDateModification(new Date());

    boutiqueDao.persist(boutique);
} else {
    boutique.setSite(site);
    boutique.setUrlLogo(CmsProperties.URL_FLUX_BOUTIQUE+fluxBoutique.getLogo());
    boutique.setUrlBoutique(CmsProperties.URL_FLUX_BOUTIQUE+fluxBoutique.getUrl());
    boutique.setNom(fluxBoutique.getNom());
    //boutique.setSelected(false);
    boutique.setIdWebSC(fluxBoutique.getId());
    boutique.setDateModification(new Date());

    boutiqueDao.merge(boutique);
}
```

There is a commented-out line here. But I think it makes the code clearer, by making obvious what the difference is between if and else. The difference is even more noticeable with color highlighting .

Can commenting out code like this ever be a good idea?

答:
This is an absolutely horrifying idea. It does not make clear what the intent is. Did the developer comment out the line by mistake? To test something? What's going on?!

Aside from the fact that I see 6 lines that are absolutely equal in both cases. Rather, you should prevent this code duplication. Then it will be clearer that in one case you additionally call setSelected.


答:
The biggest problem with this code is that you duplicated those 6 lines. Once you eliminate that duplication, that comment is useless.

If you create a boutiqueDao.mergeOrPersist method you can rewrite this as:

```<code>if (boutique == null) {
    boutique = new Boutique();
    boutique.setSelected(false);
}

boutique.setSite(site);
boutique.setUrlLogo(CmsProperties.URL_FLUX_BOUTIQUE+fluxBoutique.getLogo());
boutique.setUrlBoutique(CmsProperties.URL_FLUX_BOUTIQUE+fluxBoutique.getUrl());
boutique.setNom(fluxBoutique.getNom());
boutique.setIdWebSC(fluxBoutique.getId());
boutique.setDateModification(new Date());

boutiqueDao.mergeOrPersist(boutique);
</code>```

Code that either creates or updates a certain object is common, so you should solve it once, for example by creating a mergeOrPersist method. You certainly should not duplicate all the assignment code for those two cases.

Many ORMs have built in support for this in some way. For example they might create a new row if the id is zero, and update an existing row if the id is not zero. The exact form depends on the ORM in question, and since I'm not familiar with the technology you're using, I can't help you with that.

If you don't want to create a mergeOrPersist method, you should eliminate the duplication in some other way, for example by introducing a isNewBoutique flag. That may not be pretty, but it's still much better than duplicating the whole assignment logic.

```<code>bool isNewBoutique = boutique == null;
if (isNewBoutique) {
    boutique = new Boutique();
    boutique.setSelected(false);
}

boutique.setSite(site);
boutique.setUrlLogo(CmsProperties.URL_FLUX_BOUTIQUE + fluxBoutique.getLogo());
boutique.setUrlBoutique(CmsProperties.URL_FLUX_BOUTIQUE + fluxBoutique.getUrl());
boutique.setNom(fluxBoutique.getNom());
boutique.setIdWebSC(fluxBoutique.getId());
boutique.setDateModification(new Date());

if (isNewBoutique)
    boutiqueDao.persist(boutique);
else
    boutiqueDao.merge(boutique);
</code>```

Title: Can commented-out code be valuable documentation?

Body:
I wrote the following code:

if (boutique == null) {
    boutique = new Boutique();

    boutique.setSite(site);
    boutique.setUrlLogo(CmsProperties.URL_FLUX_BOUTIQUE+fluxBoutique.getLogo());
    boutique.setUrlBoutique(CmsProperties.URL_FLUX_BOUTIQUE+fluxBoutique.getUrl());
    boutique.setNom(fluxBoutique.getNom());
    boutique.setSelected(false);
    boutique.setIdWebSC(fluxBoutique.getId());
    boutique.setDateModification(new Date());

    boutiqueDao.persist(boutique);
} else {
    boutique.setSite(site);
    boutique.setUrlLogo(CmsProperties.URL_FLUX_BOUTIQUE+fluxBoutique.getLogo());
    boutique.setUrlBoutique(CmsProperties.URL_FLUX_BOUTIQUE+fluxBoutique.getUrl());
    boutique.setNom(fluxBoutique.getNom());
    //boutique.setSelected(false);
    boutique.setIdWebSC(fluxBoutique.getId());
    boutique.setDateModification(new Date());

    boutiqueDao.merge(boutique);
}
```

There is a commented-out line here. But I think it makes the code clearer, by making obvious what the difference is between if and else. The difference is even more noticeable with color highlighting .

Can commenting out code like this ever be a good idea?

Body:
The biggest problem with this code is that you duplicated those 6 lines. Once you eliminate that duplication, that comment is useless.

If you create a boutiqueDao.mergeOrPersist method you can rewrite this as:

if (boutique == null) {
    boutique = new Boutique();
    boutique.setSelected(false);
}

boutique.setSite(site);
boutique.setUrlLogo(CmsProperties.URL_FLUX_BOUTIQUE+fluxBoutique.getLogo());
boutique.setUrlBoutique(CmsProperties.URL_FLUX_BOUTIQUE+fluxBoutique.getUrl());
boutique.setNom(fluxBoutique.getNom());
boutique.setIdWebSC(fluxBoutique.getId());
boutique.setDateModification(new Date());

boutiqueDao.mergeOrPersist(boutique);

Code that either creates or updates a certain object is common, so you should solve it once, for example by creating a mergeOrPersist method. You certainly should not duplicate all the assignment code for those two cases.

Many ORMs have built in support for this in some way. For example they might create a new row if the id is zero, and update an existing row if the id is not zero. The exact form depends on the ORM in question, and since I'm not familiar with the technology you're using, I can't help you with that.

If you don't want to create a mergeOrPersist method, you should eliminate the duplication in some other way, for example by introducing a isNewBoutique flag. That may not be pretty, but it's still much better than duplicating the whole assignment logic.

bool isNewBoutique = boutique == null;
if (isNewBoutique) {
    boutique = new Boutique();
    boutique.setSelected(false);
}

boutique.setSite(site);
boutique.setUrlLogo(CmsProperties.URL_FLUX_BOUTIQUE + fluxBoutique.getLogo());
boutique.setUrlBoutique(CmsProperties.URL_FLUX_BOUTIQUE + fluxBoutique.getUrl());
boutique.setNom(fluxBoutique.getNom());
boutique.setIdWebSC(fluxBoutique.getId());
boutique.setDateModification(new Date());

if (isNewBoutique)
    boutiqueDao.persist(boutique);
else
    boutiqueDao.merge(boutique);


问:
What should every programmer know about programming?
Please, stay on technical issues, avoid behavior, cultural, career or political issues.

答: Floating point computations are not precise.


答:
No, it's a terrible idea. Based on that piece of code the following thoughts come up to my mind:

This line is commented out because the developer was debugging it and forgot restore the line to its former state

This line is commented out because it once was part of the business logic, but it is no longer the case

This line is commented out because it caused performance problems on production and the developer wanted to see what the impact was on a production system

After seeing thousands of lines of commented out code, I'm now doing the only sensible thing when I see it: I immediately remove it.

There is no sensible reason to check in commented out code into a repository.

Also, your code uses a lot of duplication. I suggest you optimize that away for human readability as soon as possible.


答:
From Wikipedia:

The primary purpose of the dependency injection pattern is to allow
  selection among multiple implementations of a given dependency
  interface at runtime, or via configuration files, instead of at
  compile time. The pattern is particularly useful for providing stub
  test implementations of complex components when testing, but is often
  used for locating plugin components, or locating and initializing

You should not need to inject strings, you can simply pass them as parameters to the relevant method. You should not need to inject any data, appart from config.

Good unit tests help you localise errors and therefore you should test your code independently from other units of code. DI can help you achieve this.

Title: When to use DI and when to create yourself in Java

Body:
I've a decent amount of OOP with various languages but am pretty new to Java.

I'm reading through a lot of tutorials where large numbers of objects are created within the code of a class, and I'm trying to run through them but build versions of the classes in the tutorials that do Dependency Injection instead of instantiating all the classes themselves.

But Java is not like other languages I've used in that pretty much everything is an object.  If I was to literally inject everything then the result would be very messy and hard to follow.

Obviously you wouldn't inject String objects, and I'm guessing there are other objects you wouldn't inject, but I'm not sure where the line should go.  At what point does DI stop being the right thing to do, and when does it start being a burden?  How do you decide pragmatically what to inject and what to just instantiate?

FYI, the tutorials I'm doing are http://edn.embarcadero.com/article/31995 and http://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html for building a simple client and server.  I'm not copying them line for line though, I'm trying to create equivalent classes that follow best practice


答:
In .Net (which is similar in this regard that everything is an object), I use DI mostly with my domain objects (entities, repositories and services) and application objects (controllers, view models), so repos/services get injected into controller/view models and similar. This means my business and application logic is fully testable, which is the primary reason I use DI.

Basically the objects that you inject and inject stuff into, are mostly objects that are specific to the solution you are building. If some object is "native" to the language or framework (like .Net), there's probably no need to inject it.
A lot of objects need string to represent data, and a string is basically a "language feature" that is not specific to your domain. The same thing applies to enumerables, lists, arrays and a whole lot of other stuff that does not need to change when you want to run your class in isolation from the rest of the system.

The most important thing to look at is coupling between your domain/application classes. If an object does not introduce tight coupling, then it's usually safe to just create it.
One of the ways to check for coupling is to try to run the methods in a class in isolation (which is basically unit testing). What needs to be DI-ed are all dependencies that you need to mock out, in order to make sure that the class you're testing is really running in isolation from the system.


问:
Is there a way to calculate whether to spawn a new thread or use current thread
I am building an interpret DSL in which parallelism is part of the language - the user simply states that a calculation can be done in parallel and the interpreter may decide whether to make the calculation in parallel or not. Since it is not always helpful to do parallel calculations, specially for very small jobs (context switch, memory copying between cores, etc may actually make the program slower).

I want to know if there are any "best practices" available that can calculate (with high degree of certainty) whether to do a new calculation in the current thread or spawn a new thread for the calculation. Note that since my language is interpreted, I can do all kinds of monitoring on the executed program and make this decision depending on how the program executes (kind of a JIT compiler).

Update By "Spawn" I didn't mean that I will create a new thread, but transfer the processing to a different thread, maybe from a thread pool. Note that even when using a thread pool there is overhead of possible memory transfer between processor cores and stuff like that, so even in this case the amount of work should be relatively high.

答:
Not to my knowledge, it seems extremely hard to get right. Even if you could do it, you still have to consider system load, number of cores, other os activities etc.

Some alternative approaches I can think of:

Have you considered a pool of threads or a dispatch queue? At least that allows you avoid some issues with context switching etc and you can balance the system as a whole dynamically based on the total amount of usage and jobs.

Can you model the calculations as map-reduce problems (or otherwise separate input data from code)? Then you could calculate how hard a problem is based on input data size and throughput for each item. After a bunch of samples you should be able to determine how much time it should take in total for the calculation to complete, and thus decide to run it locally or distributed.

Would it be possible to start the calculation and simply wait until a certain time has passed and then move it to a separate thread, once you realize this calculation is not trivial?


问:
How can a server initiate request in SIP protocol?
Either a client or a server can initiate request in SIP. How is it possible? How will the server know about the client?</p>

答: Since SIP entities have public addresses (e.g. user@example.org), a server may send an INVITE to the user's public server (example.org).  The client will usually REGISTER a private address (IP and port) with its public server when it starts up, so the public server will usually forward the INVITE request to that address.</p>


问:
Which design pattern is illustrated by inheriting IStructuralComparable interface?
We know that some design patterns are found so useful that they become features of the language itself.

For instance, the interface IEnumerator which is implemented by Array object.
This helps in separating the iterator from the collection object. The internal representation of the object is encapsulated.

The pattern: Iterator Pattern

I have just come across another interface IStructuralComparable(msdn). This is used to compare the structure of two collection types using StructuralComparisons(msdn) class.

The intent of this interface seems to be thus:

My understanding is that it's used for collection like types, and
  encapsulates the structural part of the comparison, but leaves the
  comparison of the elements to a comparer passed in by the user.
  (link)
  (Got from the comments section  of the question)

Is this an implementation of any familiar design pattern?
If yes, which pattern is it?

答:
I'd say this would be a strategy pattern.
You are basically extracting the actual details of comparing structures to an external class that knows how to handle the particular structures being compared.

For example, An implementation of IStructureComparable for a list would only need to scan a flat list whereas an implementation for a binary tree would also need to take into account the branching of the tree (e.g. it would perhaps use the depth of the trees as a way to order them.)

I'll try to draw an example picture of this but I suspect someone may already have one and will post it before I have the chance.


问:
Effective Ways to Introduce Agile into the Workplace?
In your experience (anecdotal or otherwise), what are some effective ways to introduce Agile into a non-Agile organization or company? </p>

<p>UPDATED: Can anyone speak to cases where you tried to introduce Agile but you were "shot down"? Also, do you now have a retrospective understanding why you were "shot down"? </p>

答:
We see it all the time. (full disclosure: I'm developing a project management application). The problem is that agile methodologies introduce an inherent tension into traditionally managed organizations. Typically, upper managements wants to be able to plan ahead. They want 3-year plans; they want properly estimated projects; they want to be able to budget hiring new people; they want to be able to commit to significant milestones when it comes to partners/customers.

But then the R&D department decides it's going to go agile. It's no longer about planning ahead for two months before writing code. Sprints are going to be short and beyond sprints you get very low-resolution estimates of the stuff that's in the backlog/roadmap. R&D realizes that requirements change way too frequently for classic waterfall to be effective, but product managers want a clear, thought-out and well budgeted vision of what the product will look like in 12 months.

The problem, then, is to reconcile the two. As I said, we see this all the time happening with our customers. Our solution is thus to unify the tools used to do both sprints and long-term planning. Okay, now here comes the part of the shameless plug, so feel free to take it with a grain of salt. One of our unique features is that we use a zoomable-user-interface for managing tasks. Meaning it's very easy to drill down into some user-story/task and elaborate on it. (you can see how it looks here). There's actually no concept of a "project" in our system at all. It's all tasks containing other tasks, linking to other tasks (a fractal, really). This creates a nice blur between user-stories, tasks, projects, epics, etc.

In practice, what many of our users who practice agile methodologies do, is create a telescopic plan that merges the long-term road map (or backlog) with managing the short term sprints (or iterations). Managers still get to see a nice, estimated road-map of major features waiting to be added, and developers simply zoom in more deeply and deal with actual work tasks. One advantage this has is that it reduces the amount of "haggling" that takes place when managers review the work-plan. Instead of the development team providing only very rough estimates (i.e. "4-6 weeks!"), they get a chance to zoom into each user-story in question and break it down to smaller chunks. When you do that there's suddenly less room for haggling. You spend 10 minute breaking down a 5 week user-story into chunks that are about 1-day in size, and all of the sudden the argument isn't "no, you can do it faster. no we can't. yes you can." but "here's what goes into this effort, including all the hidden work the initial estimate didn't consider. What do you suggest we eliminate? Quality assurance? Testing? Training the new guy? Setting up the build environment?".

This approach works as long as you're using a tool that lets you change plans as quickly as you initially draft them. Which is the real reason people these days detest waterfall. Most systems make it exceedingly hard to completely redo existing plans and people are very rationally refusing to waste time on this activity.

Okay, I feel like this is turning into a sales pitch, so I'll stop now. :)

OwnerDisplayName: Troy DeMonbreun


问:
What sort of questions drive the decision as to whether similar code is separate or common?
I have come across the following problem many times in various guises in my programming career. As a simple example, consider the following:

Let's say there is a method (B) that could differ depending on customer requirements. This could be for any number of reasons. Common sense tells you that as things are now, you should write them as a common method and add branching code in the future to handle any future edge cases.

```<code>Customer 1: A-->B-->C

Customer 2: A-->B-->C
</code>```

However, your experience tells you that this particular bit of code is likely to change so it would be easier to have separate methods (B1 & B2) and change the logic for one customer rather than continually add branching code making method (B) non-generic.

```<code>Customer 1: A-->B1-->C

Customer 2: A-->B2-->C
</code>```

Are there any rules of thumb that can be applied in such cases or does every case have to be taken on its merits?

As an aside, I've come across plenty of people who staunchly advocate one approach over the other and I can see the merits of both. But surely there is some middle ground that can be reached based on reasoned arguments?

答:
Are there any rules of thumb that can be applied in such cases or does every case have to be taken on its merits?

There are at least one or two dozen different kind of solutions for that kind of problem, and to choose the "best" one (whatever that means) depends on the details of the specific situation. That does not mean there are "no rules of thumb" - there are a lot, but I guess more than it would make sense trying to list them here in one posting.

Said that, here are some things which could influence your decision:

what "triggers" the branching? Do you need a compile time or a run-time switch?

how big are the differences between B1 and B2? Does one have to duplicate code in B1 and B2? Are you going to duplicate code by doing "A -> B1 -> C" and "A -> B2 -> C" (which would be a bad thing)?

is B getting "too big" or "too complex" (and why doesn't B just branch between B1 and B2)?

do you use OOP and are A, B and C parts of a class where applying "template method pattern" may be the right thing to do?

do you have a programming language at hand where instead of calling B1 or B2, you could inject a callback to either B1 or B2 into the code which has to call either B1 or B2?

must the decision "B1 vs. B2" be made at just one place in code, or are there many places where the result of that decision is evaluated (and the switch between B1 and B2 has to be done again)?


答:
Yes, each case needs to be taken on its own merit, as there is not general rule that says "all branches must be in their own methods".

The branching needs to be done in either case. It's just a matter of deciding if you want to put it in B per your first example, or in A as in your second. Deciding how to do boils down to two things:

Readability: Is the code more readable if you put branching in A vs. B?

Maintainability: Is the code easier to maintain if you put branching in A vs. B?

More often than not, these two goes hand in hand. Code that is easy to understand tend to be easier to change. Start with the simplest possible case (all code in one place) and then extract stuff out until you reach a point where the code is short and sweet, but still compact enough to make out the details.

When (if) you need to add B3 and B4, you have a candidate for introducing something a bit more flexible, like creating a common superclass and what not. But not before that.

Title: What sort of questions drive the decision as to whether similar code is separate or common?

Body:
I have come across the following problem many times in various guises in my programming career. As a simple example, consider the following:

Let's say there is a method (B) that could differ depending on customer requirements. This could be for any number of reasons. Common sense tells you that as things are now, you should write them as a common method and add branching code in the future to handle any future edge cases.

```<code>Customer 1: A-->B-->C

Customer 2: A-->B-->C
</code>```

However, your experience tells you that this particular bit of code is likely to change so it would be easier to have separate methods (B1 & B2) and change the logic for one customer rather than continually add branching code making method (B) non-generic.

```<code>Customer 1: A-->B1-->C

Customer 2: A-->B2-->C
</code>```

Are there any rules of thumb that can be applied in such cases or does every case have to be taken on its merits?

As an aside, I've come across plenty of people who staunchly advocate one approach over the other and I can see the merits of both. But surely there is some middle ground that can be reached based on reasoned arguments?


问:
How to deal with necessary workarounds in software?
Even with detailed specifications for exchanging data between computer programs, chances are that data generated by older versions of programs do not conform 100% to the specification, or that they use old obscure features which few people know how to implement them. As a result, companies have to keep a library of "odd specimens" for testing their software.

In good software design, these quirks can be confined into a small layer of libraries called "Abstraction Layer". However, most abstraction layers cut off too many functionalities (in order to prevent the higher level software from touching the unstable parts of the lower level software).

Sometimes it is not possible to completely hide away the unstable parts. What are the strategies for coping with such necessary workarounds?

((Please pardon my poor language skills.)

答:
Sometimes it is not possible to completely hide away the unstable parts. What are the strategies for coping with such necessary workarounds?

It's important to realize that the software will keep evolving in the future. One layer of obscure workarounds is tolerable, but real problems will emerge if you start building workarounds on top of workarounds. Therefore refactoring is absolutely required before the layer of workarounds is going to exceed one. Of course it would be better to do it cleanly in the first place, but it simply doesn't go like that in the real world.


答:
This doesn't look good buddy.

Commented code is...just not code. Code is for implementation of logic. Making a code more readable in itself is an art. As @CodesInChaos have suggested already that repetitive lines of code are not very good implementation of logic.

Do you really think that one true programmer will prefer readability over logical implementation. (by the way we have comments and 'complements' to put in our logical representation).

As far as I am concerned one should write a code for compiler and that's good - if 'it' understands that code. For human readability Comments are good, for the developers (in a long run), for people reusing that code (e.g. testers).

Otherwise you can try something more flexible here, something like

boutique.setSite(site) can be replaced with

setsiteof.boutique(site). There are different aspects and perspective of OOP through which you can increase readability.

While this code seems to be very appealing at first and one can think that he have found a way for human readability while compiler also does its job perfectly, and we all start following this practice it will lead to a fuzzy file which will become less readable in time and more complex as it will expand its way down.


问:
Should I use Dependency Injection or static factories?
When designing a system I am often faced with the problem of having a bunch of modules (logging, database acces, etc) being used by the other modules. The question is, how do I go about providing these components to other components. Two answers seem possible dependency injection or using the factory pattern. However both seem wrong:

Factories make testing a pain and don't allow easy swapping of implementations. They also don't make dependencies apparent (e.g. you're examining a method, oblivious to the fact that it calls a method that calls a method that calls a method that uses a database).

Dependecy injection massively swells constructor argument lists and it smears some aspects all over your code. Typical situation is where constructors of more than half classes look like this (....., LoggingProvider l, DbSessionProvider db, ExceptionFactory d, UserSession sess, Descriptions d)

Here's a typical situation I have a problem with:
I have exception classes, which use error descriptions loaded from the database, using a query which has parameter of user language setting, which is in user session object. So to create a new Exception I need a description, which requires a database session and the user session. So I'm doomed to dragging all these objects across all my methods just in case I might need to throw an exception.

How do I tackle such a problem??

答:
Use dependency injection, but whenever your constructor argument lists become too big, refactor it using a Facade Service. The idea is to group some of the constructor arguments together, introducing a new abstraction.

For example, you could introduce a new type SessionEnvironment encapsulating a DBSessionProvider, the UserSession and the loaded Descriptions. To know which abstractions make sense most, however, one has to know the details of your program.

A similar question was already asked here on SO.


答: From a high-level perspective, a thread probably shouldn't know enough about the system well enough to resolve this problem.  The usual solution to this problem is to use a thread pool (many languages and operating systems offer automated support for this).  You hand the thread pool tasks and it allocates threads as needed, reusing existing threads when reasonable.  This provides the performance benefit of avoiding wasted thread allocation without adding inappropriate responsibilities to your thread workers.</p>

Title: Is there a way to calculate whether to spawn a new thread or use current thread

Body:
I am building an interpret DSL in which parallelism is part of the language - the user simply states that a calculation can be done in parallel and the interpreter may decide whether to make the calculation in parallel or not. Since it is not always helpful to do parallel calculations, specially for very small jobs (context switch, memory copying between cores, etc may actually make the program slower).

I want to know if there are any "best practices" available that can calculate (with high degree of certainty) whether to do a new calculation in the current thread or spawn a new thread for the calculation. Note that since my language is interpreted, I can do all kinds of monitoring on the executed program and make this decision depending on how the program executes (kind of a JIT compiler).

Update By "Spawn" I didn't mean that I will create a new thread, but transfer the processing to a different thread, maybe from a thread pool. Note that even when using a thread pool there is overhead of possible memory transfer between processor cores and stuff like that, so even in this case the amount of work should be relatively high.


问:
In functional programming, does having most of the data structures immutable require more memory usage?
In functional programming since almost all data structure are immutable, when the state has to change a new structure is created. Does this mean a lot more memory usage? I know the object oriented programming paradigm well, now I'm trying to learn about the functional programming paradigm. The concept of everything being immutable confuses me. It would seem like the a program using immutable structures would require much more memory than a program with mutable structures. Am I even looking at this in the right way?</p>

答:
I only know a little about Clojure and it's Immutable Data Structures.

Clojure provides a set of immutable lists, vectors, sets and maps.
  Since they can't be changed, 'adding' or 'removing' something from an
  immutable collection means creating a new collection just like the old
  one but with the needed change. Persistence is a term used to describe
  the property wherein the old version of the collection is still
  available after the 'change', and that the collection maintains its
  performance guarantees for most operations. Specifically, this means
  that the new version can't be created using a full copy, since that
  would require linear time. Inevitably, persistent collections are
  implemented using linked data structures, so that the new versions can
  share structure with the prior version.

Graphically, we can represent something like this:

```<code>(def my-list '(1 2 3))

    +---+      +---+      +---+
    | 1 | ---> | 2 | ---> | 3 |
    +---+      +---+      +---+

(def new-list (conj my-list 0))

              +-----------------------------+
    +---+     | +---+      +---+      +---+ |
    | 0 | --->| | 1 | ---> | 2 | ---> | 3 | |
    +---+     | +---+      +---+      +---+ |
              +-----------------------------+
</code>```

Body:
I only know a little about Clojure and it's Immutable Data Structures.

Clojure provides a set of immutable lists, vectors, sets and maps.
  Since they can't be changed, 'adding' or 'removing' something from an
  immutable collection means creating a new collection just like the old
  one but with the needed change. Persistence is a term used to describe
  the property wherein the old version of the collection is still
  available after the 'change', and that the collection maintains its
  performance guarantees for most operations. Specifically, this means
  that the new version can't be created using a full copy, since that
  would require linear time. Inevitably, persistent collections are
  implemented using linked data structures, so that the new versions can
  share structure with the prior version.

Graphically, we can represent something like this:

(def my-list '(1 2 3))

    +---+      +---+      +---+
    | 1 | ---> | 2 | ---> | 3 |
    +---+      +---+      +---+

(def new-list (conj my-list 0))

              +-----------------------------+
    +---+     | +---+      +---+      +---+ |
    | 0 | --->| | 1 | ---> | 2 | ---> | 3 | |
    +---+     | +---+      +---+      +---+ |
              +-----------------------------+


答:
Use dependency injection. Using static factories is an employment of the Service Locator antipattern. See the seminal work from Martin Fowler here - http://martinfowler.com/articles/injection.html

If your constructor arguments become too large and you're not using a DI container by all means write your own factories for instantiation, allowing it to be configurable, either by XML or binding an implementation to an interface.

Title: Should I use Dependency Injection or static factories?

Body:
When designing a system I am often faced with the problem of having a bunch of modules (logging, database acces, etc) being used by the other modules. The question is, how do I go about providing these components to other components. Two answers seem possible dependency injection or using the factory pattern. However both seem wrong:

Factories make testing a pain and don't allow easy swapping of implementations. They also don't make dependencies apparent (e.g. you're examining a method, oblivious to the fact that it calls a method that calls a method that calls a method that uses a database).

Dependecy injection massively swells constructor argument lists and it smears some aspects all over your code. Typical situation is where constructors of more than half classes look like this (....., LoggingProvider l, DbSessionProvider db, ExceptionFactory d, UserSession sess, Descriptions d)

Here's a typical situation I have a problem with:
I have exception classes, which use error descriptions loaded from the database, using a query which has parameter of user language setting, which is in user session object. So to create a new Exception I need a description, which requires a database session and the user session. So I'm doomed to dragging all these objects across all my methods just in case I might need to throw an exception.

How do I tackle such a problem??


答:
Dependecy injection massively swells constructor argument lists and it smears some aspects all over your code.

From that, it doesn't seem like you understand DI proper - the idea is to invert the object instantiation pattern inside of a factory.

Your specific problem seems to be a more general OOP problem. Why can't the objects just throw normal, non-human-readable exceptions during their runtime, and then have something before the final try/catch that catches that exception, and at that point uses the session information to throw a new, prettier exception?

Another approach would be to have an exception factory, which is passed to the objects through their constructors. Instead of throwing a new exception, the class can throw on a method of the factory (e.g. throw PrettyExceptionFactory.createException(data).

Keep in mind that your objects, apart from your factory objects, should never use the new operator. Exceptions are generally the one special case, but in your case they might be an exception!


答:
I would just like to add to CodesInChaos's answer, by pointing out that you can refactor it further into small methods. Sharing common functionality by composition avoids the conditionals:</p>

```<code>function fill(boutique) {
  boutique.setSite(site);
  boutique.setUrlLogo(CmsProperties.URL_FLUX_BOUTIQUE+fluxBoutique.getLogo());
  boutique.setUrlBoutique(CmsProperties.URL_FLUX_BOUTIQUE+fluxBoutique.getUrl());
  boutique.setNom(fluxBoutique.getNom());
  boutique.setIdWebSC(fluxBoutique.getId());
  boutique.setDateModification(new Date());
}

function create() {
  boutique = new Boutique();
  fill(boutique);
  boutique.setSelected(false);
  return boutiqueDao.persist(boutique);
}

function update(boutique) {
  fill(boutiquie);
  return boutiquieDao.merge(boutique);
}

function createOrUpdate(boutique) {
  if (boutique == null) {
    return create();
  }
  return update(boutique);
}
</code>```

Body:
I would just like to add to CodesInChaos's answer, by pointing out that you can refactor it further into small methods. Sharing common functionality by composition avoids the conditionals:

function fill(boutique) {
  boutique.setSite(site);
  boutique.setUrlLogo(CmsProperties.URL_FLUX_BOUTIQUE+fluxBoutique.getLogo());
  boutique.setUrlBoutique(CmsProperties.URL_FLUX_BOUTIQUE+fluxBoutique.getUrl());
  boutique.setNom(fluxBoutique.getNom());
  boutique.setIdWebSC(fluxBoutique.getId());
  boutique.setDateModification(new Date());
}

function create() {
  boutique = new Boutique();
  fill(boutique);
  boutique.setSelected(false);
  return boutiqueDao.persist(boutique);
}

function update(boutique) {
  fill(boutiquie);
  return boutiquieDao.merge(boutique);
}

function createOrUpdate(boutique) {
  if (boutique == null) {
    return create();
  }
  return update(boutique);
}


答:
I would go as well with Dependency Injection. Remember that DI is not only done through constructors, but also through Property setters. For example, the logger could be injected as a property.

Also, you may want to use an IoC container that may lift some of the burden for you, for example by keeping the constructor parameters to things that are needed at runtime by your domain logic (keeping the constructor in a way that reveals the intention of the class and the real domain dependencies) and maybe inject other helper classes through properties.

A step further you may want to go is Aspect-Oriented Programmnig, which is implemented in many major frameworks. This can allow you to intercept (or "advise" to use AspectJ terminology) the constructor of the class and inject the relevant properties, maybe given a special attribute.


答:
In general, business logic tends to be similar by coincidence. On the other hand, program logic (meaning the structure and flow of your application) tends to be similar by convention.

If you think about different types of business entities, they're all going to have a fileTaxReturn method ('tis the season), but there's very little reason for them to use the same method because the way an LLC files its taxes is completely different from the way a C Corp files its taxes. This is business logic.

On the other hand, if you have some sort of behavior (maybe it's an event emitter that gets hooked for logging) that is part of the program logic, it's very likely that that's a convention of the application and can be reused.

There are two maintenance oriented aspects of this question.

Implicit polymorphism - for business logic, often times it makes a lot of sense to prematurely abstract, because otherwise as you add more base cases all of your methods are going to turn into ugly switch statements. By making business cases clear scenarios early on, it makes intent visible and prevents switch statement hell.

Premature abstraction - On the other hand, if you are saying to yourself "Maybe we'll want to log to the database, but sometimes to a flat file, and other times to an RSS feed, and maybe Twitter, or Facebook, or a serial port...", you're doing premature abstraction - creating unnecessary complexity in a system, and outright confusion for the maintenance programmer. Well-encapsulated code is easy to refactor, and will not suffer from a lack of abstraction.


问:
Dev approaches to complex JavaScript UI's
I am trying to understand the landscape of different approaches, and best practices, around the development of complex client-side JavaScript.

I'm not sure what to label this class of application, perhaps heavy AJAX or RIA (but not plugins like Flash/Silverlight).  I'm referring to web apps with these characteristics:

Emulate rich/native desktop UX in JavaScript

Contain most/all behavior in client-side JS, using the server as a data-API (JSON/Html-Templates).

This is in contrast to using the web-server for the UI rendering, producing all HTML in a page-refresh model.

Some examples are:

Google Docs / Gmail

Mindmeister

Pivotal Tracker

As we move forward into HTML5, I can see this style of RIA development, with heavy JavaScript, becoming ever more common and necessary to compete.

QUESTION: So what are the common approaches emerging around managing these kinds of heavy JS developments?

Client-side code, as an app grows in features, is fiendishly complicated.  There are problems scaling a development effort across multiple teams with raw JS (or so I hear, and can well believe it).

Google has approached the problem by building GWT that compiles from a higher level language (Java) to JS, leaning on the existing development infrastructure that the higher level language has (Eclipse, strong-typing, refactoring tools), along with abstracting browser compatibility and other issues away from the developer.

There are other tools, like Script# for C# that do something similar.  All this puts JS more in the role of an IL (Intermediate Language). ie. "You never really write in that 'low level language' anymore."

But this 'compile to JS' is not the only approach.  It's not apparent that GWT is the dominant approach...or indeed will become it.

What are people doing with rich-client JavaScript? Some orienting questions:

Are most shops crafting JS manually (atop libs like jQuery et al)?

Or are there many many different approaches, with no clear best-practice emerging?

Are most shops avoiding RIA scale development in favor of the simpler to developer server-side/page-redraw model?  If so, will this last?

Is compiling to JS perhaps an emerging future trend?  Or is this just wrong headed?

How do they manage the complexity and refactoring of client JS?

Modularization and distribution of work across teams?

The application, enforcement, and testing of client-side patterns like MVC/MVP etc.

So, what are the emerging trends in this heavy-JavaScript and HTML5 future of ours?

Thanks!

答:
Most of the Web apps I see (and Web devs I've talked to) who are moving in this direction are using jQuery as their base.

The whole reasoning behind GWT (and similar multi-level languages) is that JavaScript is too flakey/too fragile/too changeable for "real programmers" to use. But if you have a framework handling the flakey/fragile/changeable bits for you, then there's no reason to add on that extra layer of complexity.

Just my opinion…


问:
Is wrapping byte[] for stronger typing good practice?
I'm working on a Java-based library which makes use of PKCS #10 requests.  There are PKCS #10 libraries available for Java (Sun and IBM libraries that come with the respective JDKs), and the open-source Bouncy Castle library.

I'd rather not couple my library to another through the API, so my initial thought was to create a wrapper.  However, PKCS #10 is potentially complex, so the scope of the wrapper would expand quite quickly, and users of that wrapper would probably "unwrap" the wrapper and use one of the aforementioned libraries for any heavy-lifting, particularly if they use PKCS #10 in their own applications already.

My remaining option is to provide a simple wrapper around a byte array.  Is providing a very thin wrapper just for the sake of typing good practice?

答: Yes, it's a very good practice - you're leveraging the biggest strength of statically typed languages.</p>


问:
Algorithm for matching similar content text items
I am working on a website (C#, ASP.Net MVC 3) which reads some RSS feeds from multiple sources and put feed title and summary in a database table(Sql Server).

What I want to do is:
Put an algorithm in place which can relate multiple feeds. For example if each feed is a news item, I would like to relate all news which says in different grammar of English "Some has won some election".

Is there any standard algorithm for such kind of content matching logic?
If not, what kind of custom algorithm should be used?

If this logic can be written on Database side(e.g. Stored Procedure) it will be better.

答: As @Cosmin-Prund said, there's no trivial or good pre-existing way to do this.  My off-the-top-of-my-head suggestion would be to use a search engine like Lucene to tokenize and store the feed title.  Use a stemming tokenizer, so that you can match words even if they're in different forms (such as wins vs winning).  Then, when you process a new feed, you can search for the title as keywords, and see what you get back.  You'll have to play with it some to find out how to tune the results to do what you want (try dropping the two most common tokens?), but it ought to be in the right ballpark of what you're looking for.


答:
Generally speaking, code is only self-documenting to the person who wrote the code. If documentation is required, write documentation.  It is unacceptable to expect a developer new to a source-code base will sit down read thousands of lines of code to attempt to figure out from a high-level what is happening.

In this case, the purpose of the commented-out line-of-code is to show the difference between two instances of duplicate code.  Instead of attempting to subtely documenting the difference with a comment, rewrite the code so it makes sense. Then, if you still feel it is necessary to comment on the code, write an appropriate comment.


答:
B is behavior. So have an interface for it and introduce new implementations as needed. Equip different object instances with different implementations when instantiating them. This way you stick to the Open Closed Principle, because you just need to implement an interface and configure its usage. The owner of such an interface instance won't be affected by introductions of new interface implementations.

This way you are also separating the branching, which is a configuration issue, and the actual execution. The code will get a lot more readable, because there won't be any branches during the execution of the business logic.


答:
It can be in very rare cases, but not as you've done it.  The other answers have pretty well hashed out the reasons for that.

One of the rare cases is a template RPM spec we use in my shop as a starting point for all new packages, largely to make sure nothing important is left out.  Most, but not all of our packages have a tarball containing sources which has a standard name and is specified with a tag:

```<code>Name:           foomatic
Version:        3.14
 ...
Source0:        %{name}-%{version}.tar.gz
</code>```

For packages without sources, we comment out the tag and put another comment above it to maintain the standard format and indicate that someone has stopped and thought about the problem as part of the development process:

```<code>Name:           barmatic
Version:        2.71
 ...
# This package has no sources.
# Source0:        %{name}-%{version}.tar.gz
</code>```

You don't add code you know isn't going to be used because, as others have covered, it could be mistaken for something that belongs there.  It can. however, be useful to add a comment explaining why code one might expect to be there is missing:

```<code>if ( condition ) {
  foo();
  // Under most other circumstances, we would do a bar() here, but
  // we can't because the quux isn't activated yet.  We might call
  // bletch() later to rectify the situation.
  baz();
}
</code>```

Body:
It can be in very rare cases, but not as you've done it.  The other answers have pretty well hashed out the reasons for that.

One of the rare cases is a template RPM spec we use in my shop as a starting point for all new packages, largely to make sure nothing important is left out.  Most, but not all of our packages have a tarball containing sources which has a standard name and is specified with a tag:

Name:           foomatic
Version:        3.14
 ...
Source0:        %{name}-%{version}.tar.gz

For packages without sources, we comment out the tag and put another comment above it to maintain the standard format and indicate that someone has stopped and thought about the problem as part of the development process:

Name:           barmatic
Version:        2.71
 ...
# This package has no sources.
# Source0:        %{name}-%{version}.tar.gz

You don't add code you know isn't going to be used because, as others have covered, it could be mistaken for something that belongs there.  It can. however, be useful to add a comment explaining why code one might expect to be there is missing:

if ( condition ) {
  foo();
  // Under most other circumstances, we would do a bar() here, but
  // we can't because the quux isn't activated yet.  We might call
  // bletch() later to rectify the situation.
  baz();
}


答: I've used an approach based on Levenshtein distance to find similar phrases and words. It doesn't understand semantics, but it's used to find a concrete number telling "how similar are these two phrases". The algorithm itself are quick and easy and I know it's implemented in a few databases as well.</p>

Title: Algorithm for matching similar content text items

Body:
I am working on a website (C#, ASP.Net MVC 3) which reads some RSS feeds from multiple sources and put feed title and summary in a database table(Sql Server).

What I want to do is:
Put an algorithm in place which can relate multiple feeds. For example if each feed is a news item, I would like to relate all news which says in different grammar of English "Some has won some election".

Is there any standard algorithm for such kind of content matching logic?
If not, what kind of custom algorithm should be used?

If this logic can be written on Database side(e.g. Stored Procedure) it will be better.


问:
Web Developer or Software Engineer?
A question that I have been asking myself and really confused which path to take.

So I need your guys help as to the pros and cons of these 2 professions in today's world. I love web applications development as the Web is the best thing to happen in this age and nearly everyone gets by on the World Wide Web. And also tend to keep learning about new technologies and about web services.

On the other hand I like software engineering also for the desktop applications as I have had experience with development small scale software in VB.Net, Java, C++, etc.

Which path has more scope and better future? What's your view?

答:
Strictly speaking, software engineering is about designing software systems correctly - regardless of what platform (web, desktop, mobile, etc) they live on - how various subsystems of the solution interact with each other and external systems, etc.

I'd suggest getting some experience with desktop and enterprise applications, like web applications - they can be done just as badly for the novice and just as well for the expert. Being able to tell a prospective employer that you've got more extensive experience than 90% of the 'popularist' web dev crowd always helps!

Title: Web Developer or Software Engineer?


答:
KISS & YAGNI

...simple & intuitive systems are usually way easier to evolve/adapt than complex systems that try to cover all possible "potential evolutions" upfront.

If the differences are minor, go for a common method/object/whatever.

If the differences are big, implement them in distinct method/object/whatever.

My 2 cents


答:
I've actually been looking into doing something similar.  As a good starting point, I found an open source project called mahout which implements most of the algorithms you need, although it is far from a plug and play solution.

The three use cases you might be interested in are clustering, recommendation, and classification.  They all basically group items into related topics, but in subtly different ways.

Use recommendation when you have a bunch of news articles and are trying to determine which ones you are most likely to like based on your past reading habits and those of readers similar to you.

Use classification when you want to group the news articles into subjects, and you know beforehand what those subjects should be.  This is most useful for long term, ongoing topics, like the weather, for example.

Use clustering when you want to group the news articles into basic subjects, and you don't know beforehand what those subjects should be.  This is most useful for one-time events, like the death of Hugo Chavez, for example.

If you're looking for a more complete solution, check out Carrot2.  It is only able to handle around 1,000 documents, though.  Perhaps useful if you are only interested in clustering one day's worth of news from a few select rss feeds.


问:
In which order should I do comparisons?
I'm a strong proponent of writing if statements like this:

```<code>variable == constant
</code>```

Because to me it just makes sense, it is more readable than the inverted:

```<code>constant == variable
</code>```

Which seems to be used a lot by C-programmers. And I see the use, namely that the interpreter or compiler will throw an error and let you know if you're not doing a comparison. But still it is less readable, and for that reason alone I don't think comparisons should be written in the manner of the second example.

The actual question is:

Does it exist a general best practice for this, or is it different depending on language/religion/age/etc..?

I'm happy that so many seem to understand why you'd want to do as in the latter example, but that is not what I'm asking about.

答:
The second method you list (constant == variable) is done to be safe, and to make the intent clear. That way, if you see:

```<code>if(variable = constant)
</code>```

In the code, you know it was intentional and not a typo.

That said, I've never seen:

```<code>if(constant == variable)
</code>```

In any textbook or advocated in any style guide. There are static analysis tools that can detect assignment in conditionals and throw notices or errors.

Title: In which order should I do comparisons?

Body:
The second method you list (constant == variable) is done to be safe, and to make the intent clear. That way, if you see:

if(variable = constant)

In the code, you know it was intentional and not a typo.

That said, I've never seen:

if(constant == variable)

In any textbook or advocated in any style guide. There are static analysis tools that can detect assignment in conditionals and throw notices or errors.


问:
Why is Python recommended as an entry level programming language?
I've read here on P.SE more questions in which beginner programmers are advised to pick Python as their first programming language.

Don't get me wrong, I like Python. I like it a lot! But its philosophy revolves around "We are all consenting adults here".

From an experience/knowledge point of view, a beginner programmer is not an adult. Which then kinda means it is easier to shoot yourself in the foot and pick up some bad habits even if you survive the wound.

I'm thinking that in a "more static" language it would be harder to shoot yourself in the foot as it will be more restrictive.

Back to my question. Why is Python recommended as an entry level programming language?

What are the points that make it good for teaching a programming language. Or... is it personal preference of the adviser?

答:
The key issue with Python as a first language are the dynamic typing and lack of variable declaration. IMHO they are the only major issue with the language.

The simple addition of a line saying I am only going to store a string in the variable foo allows the programmer, the development environment, the language (and for "professional code" the poor fool who has to come in cold and support it afterwards) to work together. For normal developers and beginners especially it doesn't make sense to use a variable for more than one type. It is quite OK on the rare occasion when it does make sense to use an explicit var/object type that allows for dynamic typing.