问:
Did C++11 address concerns passing std lib objects between dynamic/shared library boundaries? (ie dlls and so)?
One of my major complaints about C++ is how hard in practice it is to pass std library objects outside of dynamic library (ie dll/so) boundaries.

The std library is often header-only. Which is great for doing some awesome optimizations. However, for dll's, they are often built with different compiler settings that may impact the internal structure/code of a std library containers. For example, in MSVC one dll may build with iterator debugging on while another builds with it off. These two dlls may run into issues passing std containers around. If I expose std::string in my interface, I can't guarantee the code the client is using for std::string is an exact match of my library's std::string.

This leads to hard to debug problems, headaches, etc. You either rigidly control the compiler settings in your organization to prevent these issues or you use a simpler C interface that won't have these problems. Or specify to your clients the expected compiler settings they should use (which sucks if another library specifies other compiler settings).

My question is whether or not C++11 tried to do anything to solve these issues?

答:
You are correct that anything STL - actually, anything from any third party library which is templated - is best avoided in any public C++ API. You also want to follow the long list of rules at http://www.ros.org/reps/rep-0009.html#definition to inhibit ABI breakage which makes programming public C++ APIs a chore.

And the answer regarding C++11 is no, this standard isn't touching that. More interesting is why not? The answer is because C++17 is very much touching that, and for C++ Modules to be implemented we need exported templates to work, and for that we need a LLVM type compiler such as clang which can dump the full AST to disc and then do caller-dependent lookups to handle the many ODR violating cases in any large C++ project - which, by the way, includes lots of GCC and ELF code.

Lastly, I see a lot of MSVC hate and pro-GCC comments. These are very misinformed - GCC on ELF is fundamentally, and irretrievably, incapable of producing valid and correct C++ code. The reasons for this are many and legion, but I'll quickly quote one case example: GCC on ELF cannot safely produce Python extensions written using Boost.Python where more than one extension based on Boost.Python is loaded into Python. That's because ELF with its global C symbol table is simply incapable by design of preventing ODR violations causing segfaults, whereas PE and MachO and indeed the proposed C++ Modules specification all use per-module symbol tables - which incidentally also means vastly faster process init times. And there are plenty more problems: see a StackOverflow I answered recently at https://stackoverflow.com/questions/14268736/symbol-visibility-exceptions-runtime-error/14364055#14364055 for example where C++ exception throws are irretrievably fundamentally broken on ELF.

Last point: regarding interoping different STLs, this is a big pain for many large corporate users trying to mix third party libraries which are tightly integrated to some STL implementation. The only solution is a new mechanism for C++ to handle STL interop, and while they're at it you might as well fix compiler interop too so you can (for example) mix MSVC, GCC and clang compiled object files and it all just works. I'd watch the C++17 effort and see what turns up there in the next few years - I'd be surprised if nothing does.


问:
Categories of 'for' loops
I remember once reading some research where a body of C code had been analysed, and the findings were that the vast majority of for loops could be categorised into about five categories, corresponding to the functional equivalents of map, filter, fold, etc.

I can't seem to find this paper/article anymore. Can anyone point me to it?

答:
I think I've heard it too. Somewhere in the SICP-videos or the book i think I heard that most (if not all) programs/algorithms can be expressed using streams and filters. Streams starts at lecture 6A.

As for all loops (for, while, do-while and so on) they all are implemented with label, compare and conditional jump so they are just syntactic sugar to make it easier to read and understand.

ContentLicense: CC BY-SA 3.0

Title: Categories of 'for' loops


问:
What "version naming convention" do you use?
Are different version naming conventions suited to different projects? What do you use and why?

Personally, I prefer a build number in hexadecimal (e.g 11BCF), this should be incremented very regularly. And then for customers a simple 3 digit version number, i.e. 1.1.3.

```<code>1.2.3 (11BCF) <- Build number, should correspond with a revision in source control
^ ^ ^
| | |
| | +--- Minor bugs, spelling mistakes, etc.
| +----- Minor features, major bug fixes, etc.
+------- Major version, UX changes, file format changes, etc.
</code>```

答:
git describe provides a nice extension to whatever numbering convention you've chosen. It's easy enough to embed this in your build/packaging/deployment process.

Suppose you name your tagged release versions A.B.C (major.minor.maintenance). git describe on a given commit will find the most recent tagged ancestor of the commit, then tack on the number of commits since then, and the abbreviated SHA1 of the commit:

```<code>1.2.3-164-g6f10c
</code>```

If you're actually at one of the versions, of course, you'll just get the tag (1.2.3).

This has the nice benefit of letting you know exactly what source you built from, while not having to number every single build yourself.

Body:
git describe provides a nice extension to whatever numbering convention you've chosen. It's easy enough to embed this in your build/packaging/deployment process.

Suppose you name your tagged release versions A.B.C (major.minor.maintenance). git describe on a given commit will find the most recent tagged ancestor of the commit, then tack on the number of commits since then, and the abbreviated SHA1 of the commit:

1.2.3-164-g6f10c

If you're actually at one of the versions, of course, you'll just get the tag (1.2.3).

This has the nice benefit of letting you know exactly what source you built from, while not having to number every single build yourself.

ContentLicense: CC BY-SA 2.5


问:
Is it a good idea to provide different function signatures that do the same thing?
Here is a C++ class that gets constructed with three values.

```<code>class Foo{

    //Constructor
    Foo(std::string, int, char);

private:
    std::string foo;
    char bar;
    int baz;
};
</code>```

All of the parameter types are different.

I could overload the constructor so that order doesn't matter.

```<code>class Foo{

    //Constructors
    Foo(std::string, char, int);
    Foo(std::string, int, char);
    Foo(char, int, std::string);
    Foo(char, std::string, int);
    Foo(int, std::string, char);
    Foo(int, char, std::string);

private:
    std::string foo;
    char bar;
    int baz;
};
</code>```

But is that a good idea?

I started doing it because I knew what things a class/function needed;

I didn't always remember what order it took them in.

I've been assuming that the compiler optimizes this as if I called the same constructor.

```<code>//compiler will implement this with the same code?
//maybe not.. I could call a function to get a parameter,
//and that function could change the state of the program, before calling
//a function to get another parameter and the compiler would have to
//implement both
Foo foo1("hello",1,'a');
Foo foo2('z',0,"world");
</code>```

What are your opinions on overloading a function so that the order doesn't matter?

Also, If I'm writing some utility functions,

Is it a good idea to provide different function names that do the same thing?

eg.

```<code>void Do_Foo();
void DoFoo();
void do_foo();
//etc..
</code>```

I don't often see these two but similar conventions.

Should I break or embrace the habit?

答:
Sometimes supporting commutation among arguments is necessary. For instance:

```<code>double operator *(int, double);
double operator *(double, int);
</code>```

We do not want multiplication of an int and double to compute something different if the operands are reversed. Nor do we want to force programmers to remember that when multiplying ints and doubles, the double goes on the left!

It doesn't matter that this is an operator because the same goes for:

```<code>footype plus(const footype &, const bartype &);
footype plus(const bartype &, const footype &);
</code>```

It really depends on the kinds of function. Whereas most programmers probably want support for commutativity in arithmetic libraries, they don't necessarily want, say, an I/O library functions to support all possible argument orders.

The concern probably hinges around the expected nesting in which the function calls are going to be involved. The flexibility in the arithmetic operators allows us to change the overall structure of the syntax tree to clarify the overall expression: group together similar terms and such.

Body:
Sometimes supporting commutation among arguments is necessary. For instance:

double operator *(int, double);
double operator *(double, int);

We do not want multiplication of an int and double to compute something different if the operands are reversed. Nor do we want to force programmers to remember that when multiplying ints and doubles, the double goes on the left!

It doesn't matter that this is an operator because the same goes for:

footype plus(const footype &, const bartype &);
footype plus(const bartype &, const footype &);

It really depends on the kinds of function. Whereas most programmers probably want support for commutativity in arithmetic libraries, they don't necessarily want, say, an I/O library functions to support all possible argument orders.

The concern probably hinges around the expected nesting in which the function calls are going to be involved. The flexibility in the arithmetic operators allows us to change the overall structure of the syntax tree to clarify the overall expression: group together similar terms and such.


问:
Should OAuth token be shared to implement SSO?
What's a commonly accepted way of implementing SSO using a third party OAuth provider?

I have a server with user resources associated with server's user ID, the user ID also has a Facebook user ID associated. Would it be a good approach to authenticate a client to the server if the login was redirected to, say, Facebook where it would return an OAuth token and the token is then shared with the client?

Suppose SSL is implemented, the OAuth token would then act in the same way as a session cookie that gives permission to user resources on the server.

The same user an different client can then reauthenticate with Facebook which would return the same Facebook ID, which gives access to the same user's resources and a different OAuth token which expires independently and removing the app on Facebook can callback the server with a deauthenticate request to keep things synchronised.

Is this a good policy to use? Is it safe against attacks like session sidejacking, cross site reference etc?

答:
I think you are getting a little confused there.

SSO comes into question when there are two or more apps involved(ex: gmail, google drive and google plus are three different apps that have SSO, you sign in into one of them, the others will have signed in automatically). Are there two applications in this question?

You don't share the oAuth access token with the client. By client, I believe you mean the browser anyway. You keep the oAuth access token in the server tied to the user session or persist in the database. The oAuth access token will expire after some time(exact time is specified in the response). When the access token expires, you get a new access token with the refresh token that you saved when the user first authorized your application at the provider. You have to keep the refresh token forever by persisting in the database. By any means, if you lose the refresh token, you should have the user sign-in into the oAuth provider site and get the authorization done again so you'll get the refresh token.


问:
How much time a week do you spend on extracurricular programming?
Background: I'm a microsoft DBA/IT type person by day, an iOS and Mac developer by night. I have one app in the App Store and another one in the works. I try to spend as much time as possible working on my two apps, but with a new daughter and other (non computer) hobbies, I find it hard to spend more than a few hours every week programming.

I'm wondering how this compares to other developers. I see a lot of apps out there written by single developers who don't do iOS development as their main job. Are they spending 4 hours a night working on their projects, or do they just plug away for a year or two before releasing anything?

答:
If I can squeak in 2-3 hours then that is a good week for me.  Unfortunately my aspirations require MUCH more time than I can give them currently, due to a number of factors.

Ideally though, I'd be able to take 1-2 evenings a week and spend 4 hours + each time in large chunks.  If I know I only have an hour to work, it's hard to get into the 'zone' and get the really hard work done.


问:
Unit testing markup building logic
I'm currently writing a library of helper functions to produce some repetitive markup. I have a reference to the markup the functions should produce, but I'm curious about how I should go about unit testing this?

There are a lot of unit tests needed to get full coverage of the number of different variations of output from each function. Currently, I have a T4 template for each function which builds unit tests for every combination of inputs to that function.

Each unit test does a single assert against a string containing the reference markup. However, writing out these individual bits of markup by hand would take a long time so I wrote another small helper function which basically replicates the same logic I'm testing, but in a less flexible manner, to produce the expected string.

It occurs to me that this may not be the best idea? Or is this an OK approach to this kind of problem? What are the best practices surrounding this?

Example unit test

```<code>[TestMethod]
public void Function_P1_P2_P3()
{
    string markup = HelperLib.MakeMarkup(P1, P2, P3);
    Assert.AreEqual(this.MakeExpectedString(P1, P2, P3), markup);
}
</code>```

答:
You could parse the generated mark-up and make sure that the structure/content matches what should result from the arguments that you passed in when you ran the method.

It seems like this could be used evaluate all the different variations somewhat programatically (depending on how much your markup changes for different arguments), but I'm betting it'll be a bit more work than comparing strings. ;)

Title: Unit testing markup building logic


问:
How do I evaluate an IDE?
I don't want to know which IDE is best, because that's subjective. I'd like to know how to evaluate an IDE. I'm primarily a vim user, and realistically happy there, but occasionally look at languages that have powerful IDE's and I consider using them.

The problem I run into is that they mostly seem the same to me. Certainly any of them will work, but when trying to decide which IDE to invest time in how do I decide?

What features should I be testing to see if I like the way A or B works better? Obviously some IDE's are specifically tailored to a language, but given a choice between say Netbeans, Eclipse, and Intellij IDEA, how would I decide? as a novice they seem the same.

When evaluating I generally try the editor, a few configuration options, file browser. I think my colleagues all basically the same as me and don't use IDE. I also doubt I'd end up using the IDE for work, because Perl shop, and I'm happy with vim for that, I'm simply trying to figure out how to use them in the context of languages that aren't day job and have solid IDE support.

答:
An IDE is supposed to increase your productivity. That should be your criteria.

Whatever IDE's you wanted to try, download and install them first. Try coding in each of them, one by one. Or try one a day. By the end, I'm sure you will figure out by yourself which one could make you more productive.

Each IDE has its own settings, keyboard shortcuts, behaviors, etc and if you keep using them regularly, you will get comfortable around them and get used to them. Here are some other factors you might want to consider when evaluating IDE's:

If it is in active development

If it has good community support(and wide adoption as well)

If it has a good and growing number of plugins/extensions

Might not be relevant - but if it is free or paid

I have been using eclipse for 3 years until my colleague asked me to try IntelliJ IDEA. I have been very comfortable with eclipse for 3 years. However, I liked IntelliJ better as it is as they have advertised - more intelligent. Plus, they have a community edition that is open sourced and free. So, I switched to IntelliJ as it improved my productivity, but whenever I am helping other colleagues who are using Eclipse, I won't have trouble with that.

I personally find myself trying every IDE I get across, because, the IDE's have a lot of scope for improvement and they will keep getting better and intelligent.

Title: How do I evaluate an IDE?


问:
Handling table name collisions in Django
Django creates a table name by joining the app label with the model name. A project can have many apps. If two have the same label, how can both be used in the same database?

I'm currently using very long app names to minimize that risk (such as foo_bar_baz instead of nesting modules like foo.bar.baz - app label baz). That might be overkill for an internal app (i.e. not meant for reuse), but I have also some modules that are generic and could be used in different projects (which I'm making freely available on the internet, so the possibility of name clashing is greater). If someone downloads my modules, finds a name collision with another third-party app, but doesn't want to change either code (it would be a maintainance hell) what could he do about it?

I thought of "monkey patching" the apps to add a custom db_table to each model, or Django, to change the way the default table name is derived, or maybe ensuring every app uses dependency injection to refer to other apps (so one could freely rename/symlink the app without breaking others that depend on it), but all options seem a lot of work and/or too easily broken. Is there an easier way? Should I drop all this altogether and just keep using fully-qualified names?

答: Let others monkeypatch your models' table names. This is really better solved at the framework level. I wish schema/table naming was pluggable in Django (like Hibernate does, for instance).</p>


答:
What I might consider is decomposing the logic that generates the markup into smaller units, which you can test in more granular fashion.  It really sounds like you're describing more of a conceptual integration test -- "here's a scheme for generating big hunk of markup that I want to generate and I'm testing that it's the same as this slightly different scheme for generating that big hunk of markup."

What I'd suggest that you want to test with a unit test has more of a narrative like "I want to test that when I pass in x for P1, this specific thing happens."  Now doing that might involve decomposing.  For instance, if I have a GenerateTable() method and a GenerateTableRow() method, and a GenerateTableCell() method, I might have a test that says "when I pass foo to GenerateTableCell() I get back foo	".  Then you have another method that assembles cells into rows and rows into tables and you're testing at each growing layer of abstraction.

Title: Unit testing markup building logic

Body:
I'm currently writing a library of helper functions to produce some repetitive markup. I have a reference to the markup the functions should produce, but I'm curious about how I should go about unit testing this?

There are a lot of unit tests needed to get full coverage of the number of different variations of output from each function. Currently, I have a T4 template for each function which builds unit tests for every combination of inputs to that function.

Each unit test does a single assert against a string containing the reference markup. However, writing out these individual bits of markup by hand would take a long time so I wrote another small helper function which basically replicates the same logic I'm testing, but in a less flexible manner, to produce the expected string.

It occurs to me that this may not be the best idea? Or is this an OK approach to this kind of problem? What are the best practices surrounding this?

Example unit test

```<code>[TestMethod]
public void Function_P1_P2_P3()
{
    string markup = HelperLib.MakeMarkup(P1, P2, P3);
    Assert.AreEqual(this.MakeExpectedString(P1, P2, P3), markup);
}
</code>```

Body:
What I might consider is decomposing the logic that generates the markup into smaller units, which you can test in more granular fashion.  It really sounds like you're describing more of a conceptual integration test -- "here's a scheme for generating big hunk of markup that I want to generate and I'm testing that it's the same as this slightly different scheme for generating that big hunk of markup."

What I'd suggest that you want to test with a unit test has more of a narrative like "I want to test that when I pass in x for P1, this specific thing happens."  Now doing that might involve decomposing.  For instance, if I have a GenerateTable() method and a GenerateTableRow() method, and a GenerateTableCell() method, I might have a test that says "when I pass foo to GenerateTableCell() I get back <td>foo</td>".  Then you have another method that assembles cells into rows and rows into tables and you're testing at each growing layer of abstraction.


问:
Copyrighting simple JavaScript code
Googling around I found a particular page:

PCB Via Calculator

Looking the page code I found in the JavaScript code:

//copyright circuitcalculator.com

//please do not copy without permission

Taking in account the simplicity of this code, can I write my own JavaScript function for this? I think some related links can be useful.

UPD: So, talking more specifically this code cannot be accused in any sense?

答:
Their About page pretty much sums it up:  No, you can't directly copy their code.

That doesn't preclude you from writing your own version of those calculations though.  It's their expression of how those calculations are performed that is copyrighted, not the calculations themselves.

So Yes, you can write your own version of those calculations.

You are also allowed to look at their implementation to provide guidance with creating your implementation so long as you are not performing a direct copy or equivalent.  You need to have some originality to your code, which could consist of different variable or method names; different invocations; handling of units in a different fashion; etc....  The originality is what makes your code "new work" instead of a derivative of theirs.

Copyrights

The web calculator scripts on this site are copyrighted and may not be
  used outside of this site without permission. Copying and re-posting
  on another site without licensing is strictly prohibited. Contact us
  if you would like to license a script or if you are in need of a
  custom script.

The Excel files, Excel VBA code, and SPICE models may be freely used
  as desired.

Title: Copyrighting simple JavaScript code


问:
Considerations on which Java version to run in Production
Some people run the bleeding edge of technologies - updating the day that something is updated.  In production, this isn't as appropriate.

Researching about if the current (Java 7) version is ready for production produces a significant amount of old material that might not be correct anymore (at the time of this writing Java 7 has been out for a year and a half which seems plenty long).

What considerations do I need to make to determine if it is appropriate to upgrade the production environment to a later version of Java?

答:
The first question to ask is "Is the version of Java supported on the machine?"  While updating the JRE is one thing, it may be that the underlying OS is not supported running the new version of Java (supported certifications and support contracts and the like that many enterprise environments like to have).

Many java production environments are actually running on top of an application server.  This would be the next consideration.  Wikipedia comparison of Java EE App Servers shows what version of Java EE is supported.  This can be further seen in Oracle's JavaEE compatibility overview.  The tested configuration for JBoss Enterprise Application Platform 6 is against Java SE 6.0 update 6u30.  Java SE 6.0 update 6u30 is also the tested configuration for JBoss Application Server 7.1.0 Final.  These may work in Java 7, but they are not tested configurations.

Expanding on the application server, there are live code analysis tools that are used to do debug after the fact.  Omniscient Debugger (see also) and Dynatrace are two examples of this.  These applications work by instrumenting (modifying) the live byte code of java running to report back to it.  As these applications work by modifying the byte code, if the byte code changes in a way they are not capable of working with (such as in a new JRE), they won't work.

Next down the line is the frameworks.  One example of this is JAXB that comes with java and Spring which uses it.  Changing to Java 7 updated JAXB which generated code that was incompatible with some frameworks (which requires them to be updated and their dependencies would need to be updated...).

Build tools are next on the list.  One would need to make sure that the build environment is using the proper version of Java.  Writing code for Java 7 but not updating the version that Maven or Ant uses would then cause problems.  There are times when the build tools themselves are strongly tied to one version with particular plugins.

Testing tools.  Things such as PMD, findbugs, and checkstyle may not recognize new structures in a new version of Java - these may get very confused with string switch statements or compound catches.  Tools that get into instrumentation such as code coverage may not work in the new JVM.  In the context of Java 7, Cobertura and Emma have not been updated to the new JRE (again, these applications modify the byte code to see which code is run and which isn't) (see open source code coverage libraries for jdk7).  This could require a change to the build scripts to switch from one to another.

Then there is the IDE.  One would need to update the IDE to a version that is aware of the new structures in the language.  Eclipse's announcement of support for Java 7 shows these issues.

Last and certainly not least is the developer.  It is up to the developer to write the new code and be aware of how code can be restructured.  Going from Java 1.4 to 1.5, templates and annotations were introduced and it took time for the developers to get into the mindset of the new structures available.  Likewise the collections rework back in 1.2 and getting developers away from using HashTable and Vector.  Updating the version should be accompanied with some amount of training in the new language structures.


答:
For every major version you release, it's not uncommon to have a working version you call it internally.  For instance, at my last job, we referred to a major version with the following Ubuntu-inspired naming convention:

[sickly condition] [alliterative animal name]

Which gave such names as "Limp Lamprey", "Wounded Wombat" and "Asthmatic Anteater".

Make sure unless it's a truly cool name that it doesn't leak to your customers.

Title: What "version naming convention" do you use?

Body:
Are different version naming conventions suited to different projects? What do you use and why?

Personally, I prefer a build number in hexadecimal (e.g 11BCF), this should be incremented very regularly. And then for customers a simple 3 digit version number, i.e. 1.1.3.

```<code>1.2.3 (11BCF) <- Build number, should correspond with a revision in source control
^ ^ ^
| | |
| | +--- Minor bugs, spelling mistakes, etc.
| +----- Minor features, major bug fixes, etc.
+------- Major version, UX changes, file format changes, etc.
</code>```


问:
What is the business cost of anemic domain model
I am looking to quantify the cost or problems of bad software development practices. Specifically can software that has been developed resulting in an anemic domain model be quantifiable in terms of business cost or risk?

My initial thoughts (which are all nearly impossible to generically quantify) are: -

Reduced flexibility.

Potential for increased support costs.

Any assistance you can offer would be greatly appreciated.

答:
It's difficult to do, but it can be done if you have been keeping metrics regarding your development process.  You'll also need a comparison to base your presumed costs against.  Ideally, you would have an identical team / project without an anemic domain model to compare against.  Obviously, that's not realistic so a one-off project built by the same team but without the drag of the domain model would suffice.

From there, you simply have to compare the rate of development between the two projects.  Lines of code written is one method, but I don't think it's very meaningful.  Similar feature requests would be a better comparison, in my opinion.  And you'll want to measure the amount of time in both calendar and developer time that it took in order to deliver the features.  If your metrics allow you to dig into requirements discovery and QA, those aspects of the SDLC can present helpful, supplementary information.

In an ideal case, you'll have requirements -> dev -> test / QA measured.  A perfect feature comparison would have similar times for requirements and test, but an increased amount of development time.  Since you've effectively controlled for other likely factors (different teams, ...) you can then point to the anemic domain model as the culprit for the increased development time.

Translating increased development time into money is equally "easy".  There are two major factors to consider here - first is raw development dollars based upon internal rate of overhead * amount of increase in time.  The second is opportunity cost.  Add up your product's annual revenue and divide that by your developer time.  That will provide a somewhat crude but valid measure of potential revenues lost once you multiply the hourly opportunity cost against the increase in dev time.

You mention support costs as well.  A similar approach of documenting time spent on product ABC vs. XYZ with support calls will provide the basis of your analysis.

Realistically speaking, you're going to have a hard time coming up with ideal numbers like that.  If you don't have any metrics at all, I'm not sure you're going to be able make a case.  Document your assumptions, refine the numbers a bit to make them more manageable, and run your assessment by a trusted confidant within the business to make sure the message is clear.


问:
Why does DirectX use a left-handed coordinate system?
I considered posting on Stack Overflow, but the question strikes me as being far too subjective since I can't think of a reasonable technical explanation for Microsoft's choice in this matter. But this question has bugged me for so long and the issue keeps coming up in one of my projects, and I have never actually seen an attempt at explaining this:

OpenGL uses a right-handed coordinate system, where the +Z part of the world coordinate system extends toward the viewer.

DirectX uses a left-handed system where the +Z part of the world coordinate extends into the screen, away from the viewer.

I never used the Glide API, so I don't know how it worked, but from what I can gather, it uses a left-handed system as well.

Is there a technical reason for this? And if not, is there some conceptual advantage to a particular handedness of a coordinate system? Why would one choose one over the other?

答:
The real answer to Direct3D's early left handedness is a lot less sinister than some of you are speculating.  DirectX got its start when Microsoft bought RenderMorphics back in 1995.

At that time the standard graphics text used in the RenderMorphics offices was "Principles of Interactive Computer Graphics" by Newmann and Sproul which does everything using left handed coordinates.  It's the same book that I used in college.  Looking at the D3D code you could even see them using variable names which matched the equations in the book.

It's not some Microsoft conspiracy.  The decision was made before Microsoft even came into the picture.


问:
Is it necessary to learn Makefiles when you have an IDE?
I have recently began studying Makefiles in Linux. I have ample experience developing applications with advanced IDEs, such as Visual Studio.

My first impression and query after reading a few tutorials: is there any need to study Makefiles? Perhaps the IDEs are using it internally, but is this something everyone should learn eventually?

答: Yes, even if you don't use them often, it's good to know how and why things work the way they do. Some environments may not support IDEs as such or the IDE for a new language might be immature or non-existent. You can also make a script that triggers a makefile, thereby allowing code that can autocompile without human intervention. Thus knowing how to make fully working programs out of many pieces is a good skill to have; even if you mostly use the autopilot version.</p>


问:
Starting Up Code Review Process Where there Previously Was None?
Any tips for a group needing to start code reviews? We have no real software engineering processes currently. I have been working as software engineer for 7 years and have never seen any real processes implemented at the various places I have worked, though many books espouse all kinds of engineering methodologies. The management supports the idea of enabling new processes, though there is some resistance from the senior engineer who has over 20 years of software engineering experience.

We are a set of two programmers, with no software engineering manager. We report direct to the managing director of the Company. But we work on numerous software projects. The real reason why we have to begin performing code reviews is because of PA-DSS requirements. Therefore, I am pushing for us to do code reviews all around - not just on the payment application software.

答:
You want code reviews to be a positive exercise!  Here are some tips:

Code review early by pair programming!  Even if this is only for 30 minutes a day.

Use static code analysis tools, style checkers and templates to get rid of the fluff.  You can then concentrate on the meatier issues (SRP, design patterns, exception handling, coding to interfaces etc etc) which is what code reviews should be really about (IMHO).

Get an agreed checklist between you on what's important and what's not

Some sort of Test Driven approach (forces better upfront design) is recommended further down the track

There are some really good code review tools out there - I use Crucible personally

Make sure that an attitude of 'improve the code' as opposed to 'crticise the coder'.  This is vital in keeping everyone's egos happy.

Do it regularly, don't skimp on it. Either after a group of commits or 1/day or whatever you agree on.

Good luck!


答:
There are an unlimited number of things to learn with an unlimited depth to which they can be learned.

Since you will </life> far before you learn it all, you need to prioritize which you will focus on.

If you are a windows developer using windows tools, then learning unix makefiles may not be a big advantage.  If you are a c developer on any platform, it is probably a good idea.

Keep in mind different platforms and languages have different approaches to the same problem, eg apache ant with java.

So it really depends on where you are headed in your career/learning.  IMO, becoming an expert at version control software (eg, git) is one of the best things any software engineer can do, if they haven't already.

Title: Is it necessary to learn Makefiles when you have an IDE?

Body:
I have recently began studying Makefiles in Linux. I have ample experience developing applications with advanced IDEs, such as Visual Studio.

My first impression and query after reading a few tutorials: is there any need to study Makefiles? Perhaps the IDEs are using it internally, but is this something everyone should learn eventually?


答:
I don't believe what you are asking is actually possible to do. The reason I say this is simply because you are asking whether it is possible to justify one particular design over another when there are too many variables effecting it.

Firstly the debate over the anaemic domain model is not finalised. I've heard arguments from both sides as to whether it is good or bad. I think the reality is that "good" vs "bad" is completely dependant on the technologies you are employing and the application being developed. If you try to exclude those then there are too many "Yes - But"s to have such as answer.

The second consideration is that when comparing developing a product using X vs Y there are a whole host of factors that can mess with any numbers you try and come up with. Mostly because the idea of being able to compare project A with project B and deducing a comparison result on one factor is like comparing Boeing to Airbus and saying Arbus is better because they use titanium bolts where Boeing uses Hi Tensile Steel. I don't know if they do, but you get the idea.

The factors that will place question marks over your values are such things as the team members skills, design philosophies, experience and personal preferences and coding habits. The projects goals, technologies, time lines, customers and any prior history. Management support, funding, influence and control. No two projects will every be exactly the same in any of these factors and therefore any "quantifiable" results are at best questionable when it comes to "this" vs "that".

Various highly knowledgable people in the industry have used stats from large numbers of projects to make various generalisations about project development. These people are very smart and experienced. If you look into some of the background material on the waterfall vs agile debate you will see some of this data. I think that you request is far to macro to be able to make similar "factual" statements. Because of the complexities involved, you can only work at the large scale with these sorts of things.

Title: What is the business cost of anemic domain model

Body:
I am looking to quantify the cost or problems of bad software development practices. Specifically can software that has been developed resulting in an anemic domain model be quantifiable in terms of business cost or risk?

My initial thoughts (which are all nearly impossible to generically quantify) are: -

Reduced flexibility.

Potential for increased support costs.

Any assistance you can offer would be greatly appreciated.


问:
Descriptive naming vs. 80 character lines
I frequently hear these two valuable programming practices: (1) lines of code should be 80 characters or less and (2) use descriptive names for variables, methods, classes, etc. I understand the reasoning for both of these words of advice, however, they seem to often be tradeoffs of each other. If I keep my code below 80 chars/line I end up using less descriptive names (esp. in Python in which each indentation counts as 4 characters) but if I use more descriptive names, I end up with lines over 80 characters.

So, my question is which of these two pieces of advice is more important to abide by if the choice must be made? I am wondering this as an independent (hobbyist) programmer, but more importantly from the perspective of a software engineer working for a larger company.

答: Descriptive naming is by FAR more important. In most interfaces we can scroll to see longer lines. In no instance can the system help you translate poorly named variables and functions. </p>


答:
None

There are a few side projects I'd love to do but honestly, I don't have the time. I'm lucky I have a job that keeps me learning new things regularly or I'd probably never keep up on new technology!

Actually I do have some time to myself, but I prefer to use it to do things other then coding.

Title: How much time a week do you spend on extracurricular programming?

Body:
Background: I'm a microsoft DBA/IT type person by day, an iOS and Mac developer by night. I have one app in the App Store and another one in the works. I try to spend as much time as possible working on my two apps, but with a new daughter and other (non computer) hobbies, I find it hard to spend more than a few hours every week programming.

I'm wondering how this compares to other developers. I see a lot of apps out there written by single developers who don't do iOS development as their main job. Are they spending 4 hours a night working on their projects, or do they just plug away for a year or two before releasing anything?


答:
80 characters per line is not difficult to meet even naming are long because there are many ways to break a single line of long code into multiple short code, e.g., I can break a condition statement in C into multiple lines to fit in less than 40 characters,

```<code>if ( a == b || c == d  || d == e
    || c == e || c == a || c == k
    || c == l)
</code>```

you can also split a line of functions call into multiple lines too.

Therefore, both rules of descriptive naming and 80 character lines have no contradiction, they can coexist to improve readability.

Title: Descriptive naming vs. 80 character lines

Body:
I frequently hear these two valuable programming practices: (1) lines of code should be 80 characters or less and (2) use descriptive names for variables, methods, classes, etc. I understand the reasoning for both of these words of advice, however, they seem to often be tradeoffs of each other. If I keep my code below 80 chars/line I end up using less descriptive names (esp. in Python in which each indentation counts as 4 characters) but if I use more descriptive names, I end up with lines over 80 characters.

So, my question is which of these two pieces of advice is more important to abide by if the choice must be made? I am wondering this as an independent (hobbyist) programmer, but more importantly from the perspective of a software engineer working for a larger company.

Body:
80 characters per line is not difficult to meet even naming are long because there are many ways to break a single line of long code into multiple short code, e.g., I can break a condition statement in C into multiple lines to fit in less than 40 characters,

if ( a == b || c == d  || d == e
    || c == e || c == a || c == k
    || c == l)

you can also split a line of functions call into multiple lines too.

Therefore, both rules of descriptive naming and 80 character lines have no contradiction, they can coexist to improve readability.


答:
Keep your indents few, your names descriptive, and don't be afraid to break a line.

Keep your indents few.

Often when I find myself in a struggle between indents vs descriptive naming, I take a step back and look at my indention level. If you're indenting further than 3 or 4 levels (2 levels is automatic and unavoidable in many instances. Read: class method definition), you may want to restructure your code, abstracting functionality out to a function or method.

Your names descriptive

You should always keep your names descriptive. Descriptive names create self-documenting code. You can try to shorten the names in some instances, but readability comes first.

Don't be afraid to break a line

Shit happens. If you go over 80 characters, and you don't see anyway to reclaim any space in the line - break it. Most languages don't care about line breaks, so break the line into multiple. Don't just pick a random location. Keep things grouped logically, and indent another level when you do break the line.


答:
Yes. Because IDE's may not be helpful if you want to do automation. One of the Joel's test is one button automatic build. Makefiles can produce that. Also such build can also be fired from the remote machine, without much hassles. <br>
I am not aware of power of IDEs on linux, but Makefile also helps in doing more stuffs than pure compile. They can also be used for installation, dependency check, and pre-compile installation. You can also combine them with shell scripts, and do multiple builds. </p>

Body:
Yes. Because IDE's may not be helpful if you want to do automation. One of the Joel's test is one button automatic build. Makefiles can produce that. Also such build can also be fired from the remote machine, without much hassles.

I am not aware of power of IDEs on linux, but Makefile also helps in doing more stuffs than pure compile. They can also be used for installation, dependency check, and pre-compile installation. You can also combine them with shell scripts, and do multiple builds.


答:
An IDE and an Automated Build System have different purposes. An IDE is useful when your are developing the software and want to compile the code ect. An Automated Build System is useful when you want to Automate the building and compiling.

There are many situations in which an Automated System would help you out:

Do you have a large project with a large number of developers contributing to your source control? How do you create a latest compiled build? Do you expect someone to be in-charge of compiling the latest version in their IDE?

Does your project depend on some library that is developed by someone else on a different timeline? How do you manage their updates? Do you have to update that reference in your project manually and then build?

Very often a project will have several different components. For example a web service and a Desktop and Mobile Client. What if you have some resources, say string values, or images that are common in all of them? How will you manage the updates in them? You wouldn't want to hunt down all of the references in your different projects and update them manually.

Makefiles in linux, are only one example of Automated Build system. There are several option for this even in the .NET world.

Though using and configuring such systems are strictly not necessary, you'll organize and streamline your development a lot if you learn and use these systems.


答:
I don't think there's going to be some peer reviewed study that you can rely on or a simple empirical model to draw from; even to the extent that such a thing might exist, proving that the data fits your situation might be pretty hard. The fact that such model fitting is so impractical is the reason that business tends to rely so much on surveying "case studies" of what is usually a single company or team that changes practice x to y (or supplier a to b). The narrative fallacy is often at work, but it's one of the few tools that have any sort of traction outside of pseudoscientific neo-Taylorism, because people have an incredibly good pattern matching ability and have an intuition (whether justified or not by other data) whether a given case study has any lesson transferable to their situation. I think this sort of case study dependence can be as intellectually bankrupt as "scientific management" was, but that won't stop people from using them.

The thing to measure really is development friction. You won't be able to predict exactly how a strong domain model can affect velocity, but if you start with an anemic domain model and start encouraging moving more business logic from service layers into the domain layer, and encourage frequent refactoring as you gain a better understanding of the domain, you can at least draw comparisons of velocity (if you're using something like story points to approximately measure task complexity), or customer satisfaction, or fragility of the system, or test coverage, or whatever resonates with your organization.

Based on my experience, I'd guess you'll find some initial hurdles as you start changing practices, as you'll likely have to deal with some nasty side effects and existing technical debt, but that you'll have a long term payoff if you make progressive investments in a real domain layer.

If you're trying to make the case that you need to move away from an anemic domain model, the best thing to do is provide data on what's hard to change now, what customer requests take longer than they should because you have to change code in four different places instead of one, for example. As I frequently argue, the best case for change is identifying the pain points of the existing system; working code will start winning any arguments about whether you're on the right path. Rather than focusing on delivering cost estimates, focus on a narrow scenario that you need to deliver near term business value on, and start attacking the problem by firming up the domain model.

To be case-study-ish without naming specific companies that I've dealt with this problem in, here are some problems that projects I've worked on with anemic domain models had:

Duplicated or slightly divergent business logic in multiple layers of the system, not enforced at the domain layer.

Poor developer understanding of business rules, because the actual business logic is spread around the system. This alone tends to result in lots of bugs.

Slow turnaround time on feature enhancements, or major functional regressions and bugs as a result of new feature work.

Unexpected side effects of code changes. (Typically, some bit of code assumes that some other part of the system kicks off some sort of asynchronous process or autonomous transaction, but doesn't have a way of verifying that it occurred, and a new developer doesn't know about this behavior or an existing developer forgets about it).

A big divergence between the way developers talk about the system and the way users talk about it, resulting in cognitive friction when trying to make sense of new requirements.


答:
Yes, if you need advanced build options.

Visual Studio autogen project files, such as .csproj.

.csproj itself is a kind of XML-style makefile.

You can use a text editor to edit and customize .csproj if you need advanced options.

If you study MSBuild carefully, you will find that there are similar concepts to Makefile.

Build targets, include list of files, define properties, etc ...


问:
Are there technical reasons for an immediate update following a fresh download/install?
I've had this happen in all sorts of software products: You purchase a software product, download it, install it, and then after the install, the program immediately begins downloading an update or a patch.

Ideally, I would imagine that the download package would somehow be linked to the product's repository so that stable releases could be pushed to the product site rather than having to force the user to wait through an update after install.

Are there any technical reasons for the install/update process or is it just a case of poor deployment infrastructure on the part of a lot of companies?

答:
They don't want to rebuild the installer for the whole program every time there is a new security hole or bug found.  For one thing, the download would end up a lot bigger, and I assume it's easier to create a patch than to rebuild the whole installer.  And with installations on disk, there's a lot of money that goes into the making of those disks that would be wasted if they had to throw away the millions of them sitting in the warehouse every week just for a 5kb change to one file.

Also like the other answers state, it can be difficult to update all the different distribution sites.  I've seen old versions of games on some sites, when other sites have had updated versions for 6 months.


问:
Shorter release cycle with DVCS
Does the choice of using a DVCS over a CVCS actually make for shorter release cycles?  If so, what makes software release cycles shorter and what are the arguments for this?

Related to pull request? Does easier submission of patches play a role here?

Related to people factor? Are project teams that use CVCS act more conservative with release schedules?

Any other factors?

答:
Good question!

The CVCS believe in the primary principle that everything must keep merging/syncing back to 'the trunk'. Also, we expect that as we evolve, trunk should be the most stable points before release is made. So people put their work in working copy, take update and test before check-in. Or alternatively, you work on private/feature branches and then merge other trunk changes, test before you reintegrate.

The DVCS pattern can be significantly different. You keep branching and forking yourself. You may experiment, and then finally merge branches which make sense. Occasionally you heard of some security fix that must go out immediately, so you want that patch to be in your branch as well, but you don't want many other stuff of trunk! So by default, you keep working in your space, keep taking and integrating things - and the time comes for release you all sit an decide what to take what to drop.

See this: http://nvie.com/posts/a-successful-git-branching-model/

So the essential difference is this: CVCS asks what mother says to their of young children -don't go far away beyond a point where I can find you i.e. - keep synchronizing to trunk.  The DVCS works assuming that all work is design to be independent unless there is explicit need to merge (e.g. creating a release).

Now coming to your question -

The above explanation actually sounds more contrary to what you observed/asked. The real challenge is, defining what is stable! when the number of user base is very large, and while people keep pouring their deltas - each of them might have counter breaking with respect to other parallel changes till everyone is settled to their individual best as well as the entire integration and dependencies are ok. So when you are trying to make release, one need to really shake things up, stop people from pouring new features - identify any integration issues when things merge up and so on. All this, implies that CVCS always ask you to take 'release breaks' between the development!

When number of contributors become large, getting to this point of 'release breaks' becomes difficult and fewer; and hence CVCS will actually force you to make 'release creation festivals' after a very significant one.

In DVCS - you keep working, testing, working testing on your own space. The release creation and integration is quite a parallel activity and it can also afford to do try and error by seeing what patch-sets work together and what won't (hence will be taken or dropped from releases). In DVCS - you can decouple individual development and then once in a while just sneak in a release if that make sense.

Title: Shorter release cycle with DVCS


问:
How do you handle multiple users editing the same piece of data in a webapp?
There's a project I'm working on that is looking to produce a web application that will manage a task list between multiple users.  This is a master task list whose task items get distributed by an authorized user.  Each user has his/her own account to login and view the tasks they are assigned; it is possible for multiple users to have a single task in-common.

I am trying to leave details of the project out of this as I'm grappling more with the overall concept of how to handle the following situations, but if it helps, I'm using Java, EclipseLink, and GWT with RequestFactory implemented.  The database is PostgreSQL.

So the conceptual problems I am attempting to reconcile are the following:

If a single task that is common to multiple users changes in any way e.g. task completed, deleted, etc., the task list of all the users who have this task will be updated.  What design patterns are there that assist in implementing this function?

Some patterns I have looked at are Observer and Mediator - are there others that should be considered over these?

Say there are two users changing the same task at the same time.

First, should I allow that situation to happen or should I put a lock on it until one or the other person is done making changes?

Second, if I don't put a lock on it, how do I reconcile whose changes to accept?  This involves the situation in 1 because user 1 could submit the data and before user 2 receives the updated data, he/she may have gone ahead and submitted his/her's changes.

I am really looking for any guiding points, advice, or tips you can provide on how to properly sync data between multiple instances of this web app.  I would very much appreciate it!

答:
for 1. you should see if the publish/subscribe pattern is better suited.

for 2. it depends on your situation:

how frequent will this situation be?

how bad is a situation in which one of your users will be unable to update a task because it is locked or someone else has changed it in the meantime?

personally I prefer an  approach (used e.g. in pivotaltracker) in which there are:

no locks,

you see all changes in real-time, and

the UI invites doing frequent minor updates instead of bigger ones on multiple attributes.

you keep a history of all changes that have been made. if the history is visible to the users, eventually arising conflicts or overwrites can be resolved with comments, annotations or messages.


问:
How do you interview someone with more experience than you?
The company I'm working for is looking to hire a senior developer with more experience than me, and they expect me to do the technical part of the interview. I've only been programming a few years and am not sure I have the knowledge needed to evaluate the coding skills of someone who has greater understanding/experience than I do.

Can anyone recommend some technical interview questions to ask that are a good means for evaluating higher-level programming skills, but still be ones I can understand?

I would say I'm past the jr. programmer level, but nowhere near senior. Most of what I've done is built small apps (web and desktop), some of them fairly complicated, but all of them have been meant to be used by no more then a handful of users. I feel I have a decent understanding of most programming concepts and am capable of learning/teaching myself just about anything, however I lack experience. As my boss is fond of telling me, "You don't know what you don't know".

In particular, things we'd like the person we hire to have experience with (that I don't have) is: Multi-tier development, multi-user environment, large-scale application development, two-way messaging, shared sessions, and Multi-threading/BackgroundWorkers.

UPDATE:

In response to Thor's comment below, we hired someone a few months ago and I think it has been working out great. I am learning a lot, not just about coding but also about things like design patterns, software architecture, documentation, and how other larger programming teams get stuff done. Its not always easy having someone come in and point out better ways to do things you have done, but if you can swallow your pride and be willing to try out new things you can learn a lot.

The interview process went better than I expected. I started asking questions about things I was familiar with, then asked some questions about some things I was struggling with. Whenever the interviewee said something I didn't understand, I'd ask them to explain it to me and then write it down so I could look it up later on. Overall, I felt I was able to get a pretty good idea of the applicant's skill level, intelligence, and what they'd be like to work with.

答:
Use your age as an advantage.

I've interviewed a ton of people who are older than me.  I pick a technology that I do know pretty well and tell them that I've heard of Technology X, but never used it.  I ask the candidate to give me an overview of the technology and how they've used it in a project.

This works surprisingly well.  First of all, if the candidate is only using that Technology X as a buzzword on their resume, then their explanation will suck/not make sense.  Also, if they can't give you a good, concrete example of how they used a that technology in their past projects, you have a big red flag right there.

I interviewed someone who had java Spring experience.  I had used Spring in my previous job, and one of the big features of spring is Dependency Injection.  I told the candidate I interviewed that I had heard about Spring and never used it.  He started blabbing on and on, but couldn't tell me where he had used Spring AOP and couldn't explain Dependency Injection to me, even after I explicitly asked after seeing those things called out on his resume.  He just told me that they were really cool, and there's so much to learn out there, etc, etc.  It really turns out he didn't know jack...and I was the only to figure that out b/c I was a younger member of the dev team.

So use your age as an advantage!  Go in, be confident, and ask some questions about technology you know well.


答:
Anemic data models usually comes with public setters. So you got something like this:

```<code>public class Order
{
    public string Id { get; set; }
    public string UserId { get; set; }
    public OrderState State { get; set; }
    public DateTime StateChangedAt { get; set; }
    public List<OrderLine> Products { get; set; }
}
</code>```

Let's say that you have a routine which will scan all orders which will report orders have been in state WaitingOnStock for two weeks. Then in one place where that state is set you got

```<code>var order = _repository.Get(orderId);
if (product.StockCount == 0)
{
    order.Products.Add(new OrderLine(4, product));
    order.State == OrderState.WaitingOnStock;
}
_repository.Save();
</code>```

See? Since the developer do not know / forgot about the StateChangedAt field the notification routine wont work.

If you instead have let the Order class control it's behavior that wouldn't have happened:

```<code>public class Order
{
    public string Id { get; private set; }
    public string UserId { get; private set; }
    public OrderState State { get; private set; }
    public DateTime StateChangedAt { get; private set; }
    public IEnumerable<IOrderLine> Products { get; private set; }

    public void Add(int quantity, Product product)
    {
        Products.Add(new OrderLine(quantity, product);

        if (product.Quantity < quantity)
        {
            StateChangedAt = DateTime.Now;
            State = OrderState.WaitingOnStock;
        }
    }
}
</code>```

So what you basically do is to follow the fundamental OOP principle encapsulation. As a bonus you get all business logic related to the order in one place which greatly simplifies any bug tracking.

I've also blogged about it: http://blog.gauffin.org/2012/06/protect-your-data/

Body:
Anemic data models usually comes with public setters. So you got something like this:

public class Order
{
    public string Id { get; set; }
    public string UserId { get; set; }
    public OrderState State { get; set; }
    public DateTime StateChangedAt { get; set; }
    public List<OrderLine> Products { get; set; }
}

Let's say that you have a routine which will scan all orders which will report orders have been in state WaitingOnStock for two weeks. Then in one place where that state is set you got

var order = _repository.Get(orderId);
if (product.StockCount == 0)
{
    order.Products.Add(new OrderLine(4, product));
    order.State == OrderState.WaitingOnStock;
}
_repository.Save();

See? Since the developer do not know / forgot about the StateChangedAt field the notification routine wont work.

If you instead have let the Order class control it's behavior that wouldn't have happened:

public class Order
{
    public string Id { get; private set; }
    public string UserId { get; private set; }
    public OrderState State { get; private set; }
    public DateTime StateChangedAt { get; private set; }
    public IEnumerable<IOrderLine> Products { get; private set; }

    public void Add(int quantity, Product product)
    {
        Products.Add(new OrderLine(quantity, product);

        if (product.Quantity < quantity)
        {
            StateChangedAt = DateTime.Now;
            State = OrderState.WaitingOnStock;
        }
    }
}

So what you basically do is to follow the fundamental OOP principle encapsulation. As a bonus you get all business logic related to the order in one place which greatly simplifies any bug tracking.

I've also blogged about it: http://blog.gauffin.org/2012/06/protect-your-data/


问:
Aggressive Auto-Updating?
What do you guys think is best practice regarding auto-updating? Google Chrome for instance seems to auto-update itself as soon as it get's a chance without asking and I'm fine with it. I think most "normal" users benefits from updates being a transparent process.

Then again, some more technical users might be miffed if you update their app without permission, as I see it there's 3 options:

1) Have a checkbox when installing that  says "allow automatic updates"

2) Just have a preference somewhere that allows you to "disable automatic updates" so that you have to "check for updates manually"

I'm leaning towards 2) because 1) feels like it might alienate non-technical users and I'd rather avoid installation queries if possible. Also I'm thinking about making it easy to downgrade if an upgrade (heaven forbid) causes trouble, what are your thoughts?

Another question, even if auto-updates are automatically, perhaps they should be announced. If there's new features for example otherwise you might not realize and use them

One thing that kinda scares me though is the security implications, someone could theorically hack my server and push out spyware/zombieware to all my customers. It seems that using digital signatures to prevent man-in-the-middle attacks is the least you could do otherwise you might be hooked up to a network that spoofs the address of of update server.

答:
I feel like there should always be the option to turn off automatic updates, as I - like a lot of users in rural areas - am on dialup and there's nothing I hate more than having something start downloading causing me to not have enough bandwidth to surf the internet anymore, or to not be able to disconnect from the internet to make a phone call because this 10mb update is taking 2-3 hours to download.  Much better to be able to choose to update when I take my laptop to a wi-fi hotspot and don't have to worry about a dropped connection either.

Of course, being able to turn of automatic updates also makes it harder to kill illegal copies of a program, but in my opinion it's worth it to not alienate a bunch of users.

Title: Aggressive Auto-Updating?


答:
In our company we have a very high security standard. Our internal IT department doesn't allow any applications which update themselves, because then there is no way for them to control what they do and which version is installed where. They want to roll out any software updates manually (through our own software update system) so that they can examine them for potential security problems beforehand.

Lots of additional work for them? Certainly.

They won't find anything anyway? Maybe.

Counter-productive because it leaves us vulnerable to zero-day exploits for a lot longer? Not my department.

But fact is, many companies work that way. And when your product doesn't allow this update workflow, they won't consider it.

Title: Aggressive Auto-Updating?

Body:
What do you guys think is best practice regarding auto-updating? Google Chrome for instance seems to auto-update itself as soon as it get's a chance without asking and I'm fine with it. I think most "normal" users benefits from updates being a transparent process.

Then again, some more technical users might be miffed if you update their app without permission, as I see it there's 3 options:

1) Have a checkbox when installing that  says "allow automatic updates"

2) Just have a preference somewhere that allows you to "disable automatic updates" so that you have to "check for updates manually"

I'm leaning towards 2) because 1) feels like it might alienate non-technical users and I'd rather avoid installation queries if possible. Also I'm thinking about making it easy to downgrade if an upgrade (heaven forbid) causes trouble, what are your thoughts?

Another question, even if auto-updates are automatically, perhaps they should be announced. If there's new features for example otherwise you might not realize and use them

One thing that kinda scares me though is the security implications, someone could theorically hack my server and push out spyware/zombieware to all my customers. It seems that using digital signatures to prevent man-in-the-middle attacks is the least you could do otherwise you might be hooked up to a network that spoofs the address of of update server.


答:
What makes software release cycle shorter with DVCS, compared to CVCS?

I don't think there is necessarily a difference between DVCS and CVCS here, but rather a difference in the branching model that people adhere to.

From what I have gathered here and from my experience, people using DVCS tend to use more branches than people using CVCS. And if you develop each feature in a branch of its own, it is easier to start preparing a release with new feature X in it, but not feature Y, whose development has started but which is not yet ready for a release.

Title: Shorter release cycle with DVCS

Body:
Does the choice of using a DVCS over a CVCS actually make for shorter release cycles?  If so, what makes software release cycles shorter and what are the arguments for this?

Related to pull request? Does easier submission of patches play a role here?

Related to people factor? Are project teams that use CVCS act more conservative with release schedules?

Any other factors?


问:
What is Context Diagram in a SRS?
I am learning how to write a System Requirements Specifications, and most of templates I have seen talk of a Context Diagram.

What exactly is a Context Diagram?

答:
A Context diagram is used to depict the "environment" in which the system under design has to operate. It is usually drawn as a bubble for the system and the entities that interact with the system (both human and computers) around it, connected to the system with lines.

Sometimes, the context diagram also shows (in keywords) what kind of interaction there is between the system and an external entity (for example, that a Customer might 'place an order').

Title: What is Context Diagram in a SRS?


问:
Do I need to understand algorithms and data structures to be called a programmer?
It has been six years since I have been coding. Coding into all kinds of things like ActionScript, JavaScript, Java, PHP, Ajax, XML HTML, ASP, etc. I have used arrays, maps, linked lists, sets, etc and wherever I worked people like me. But whenever I am interviewed it is very likely that people ask me question on hashes, trees, stacks, and queues. Some questions are on juggling some sorting algorithms.  I don't know if I should really know them or should I stop calling myself a programmer. There is something in me which also tells me even if people who are asking all these questions select me, they will never be making me work of these things. Am I really required to know all this?</p>

答:
It depends what the jobs are for.  This sort of things are fairly standard interview questions but they're also fairly unimaginative and probably don't relate to the job at all - certainly not a job using the technologies you list.

For me as interview questions go they're a good judge of whether you did a Computer Science degree (and can remember it) rather than any measure of general programming ability or knowledge.

I'd suggest that either you learn this stuff so you can get through the interview, or you just accept that anywhere asking these things isn't for you, but no, you don't need to know them to call yourself a programmer.


问:
Documentation Generation - FiM++
This is a question I originally asked on Stack Overflow, but as a conceptual design question as opposed to a technical issue, I believe it may be more appropriate, or possibly have alternate parallel value, on this board.

The structure of a FiM++ program requires that it end with the closing of a letter and the code author's name in a specific manner.

```<code>Dear Princess Celestia and Stack Exchange and String: A Sample:
    ...
Your faithful student, Southpaw Hare!
</code>```

According to the language specification, the keyword "Your faithful student," (including the comma and following space) is used as an end tag for class definitions, and the following name is a comment with no syntactical effect.

The fact that the author is automatically included (if not strictly required) in every file makes me wonder if it can be used as a form of interpretable documentation akin to Java Docs.  In other words, that other programs or editors would be able to parse out this name and use it in some manner.

What is the requirement of such internal comment-based documentation?  Is there anything in this particular type of syntax that would cause problems?

Is the keyword sufficient to fit with the theme?  It occurs to me that the lack of ability to use "Your faithful students," for a plural form (or possibly "Yours faithful," or "Yours truly," for an ambiguous version) would make listing multiple authors look awkward and unnatural (and looking like a natural human-written letter is one of the core design paradigms).

If creating a Java Docs methodology was considered, then what other features should be included?  For one, a date seems common.  Including some form of date comment at the top of the letter would probably look natural and not defy the design paradigm.

Since the language is new, unfamiliar to most, and honestly quite silly, here are a few resources to consider:

Original Release Announcement

October Followup

Wiki

答:
What is the requirement of such internal comment-based documentation? Is there anything in this particular type of syntax that would cause problems?

The basic requirement is that the documentation parser knows what that piece of program-text means. This is independent of what a compiler would do with it.

In this case, it helps that the grammar specifies it as a student name.

Is the keyword sufficient to fit with the theme? It occurs to me that the lack of ability to use "Your faithful students," for a plural form (or possibly "Yours faithful," or "Yours truly," for an ambiguous version) would make listing multiple authors look awkward and unnatural (and looking like a natural human-written letter is one of the core design paradigms).

If the documentation must be able to distinguish between one author and multiple authors, then the current keyword alone is not sufficient. The documentation parser would have to infer the presence of multiple authors in a different way (for example by the use of commas or the word 'and').

Title: Documentation Generation - FiM++


答:
What makes software release cycle shorter with DVCS, compared to CVCS?

I agree with Bart that the primary reason is the branching model used, but the type of version control system directly affects which branching models are viable. So we have two sub-questions. What branching model the distributed systems support better and why it makes release cycle faster?

The fundamental difference between centralized and distributed version control is, that without central authority you can't enforce linear timeline. So to make distributed version control possible, these systems necessarily had to define history as directed acyclic graph, where each revision simply has unique identifier, one or more parent revisions and may have arbitrary many child revisions that you might not even be aware of, because you didn't synchronize with the system where they were created yet.

It turns out that this approach lends itself very well to branching. You don't have to do anything to get a branch, you simply always have one. So you can dive straight to work head first and leave deciding when and where to merge it or even where to keep it and under which name until you know whether it's actually going the way you need.

In contrast all centralized systems maintain history as set of branches with linear sequence of revisions. So you have to decide in advance whether you'll need a branch, give it a name and explicitly created it. This is quite pain in the butt when you don't yet know what the idea is worth and you often simply don't know that before you start programming. Complicated by the fact that in most centralized systems the branch names are global, significant, often persistent and not easily changed, while in all the major distributed systems they are just local monikers that can be changed at whim and recycled freely. And by the fact, that all the branching and merging operations are usually quite a bit slower in CVCS.

Thus DVCS makes branches easier and therefore teams using DVCS branches all the time while teams using CVCS will be avoiding them most of the time.

Now why using branches allows more frequent releases? Well, every team will underestimate a task now and then, often when hard to track bug appears. Teams using centralized systems usually do all debugging, and most development, on trunk, because branches are inconvenient. So they can't release until they flushed out most bugs and they have to interleave development and debugging phases.

In contrast in distributed systems where all work is done on branches these can be merged together for test, tested, bugs fixed and only the work that passes tests merged separately to trunk. Resulting in trunk that has very few bugs and thus can be released more often, usually whenever an important feature lands.

It also helps that whenever there is a change in priorities, the work in progress can be trivially shelved with the branching approach used with distributed systems. In most real projects, changes in priorities happen all the time.

Title: Shorter release cycle with DVCS


问:
Schema.org vs microformats
They both serve the same purpose: Providing a vocabulary for semantic markup. Schema is recognized and standardized… but the microformats standard is by an open community process.

Schema exploits microdata in documentation, while microformats go on classes. (Of note: microdata means that an element must be of a single itemtype, while microformats allow several classes to apply to the same element. I can markup xFolk+hAtom with classes, but not with microdata.)

Is this a black-and-white situation? Google says I can't use both "because it may confuse the parser".

What's the consensus on these?

答:
Google's structured data tester shows how well its parsers recognize both their presence together. Schema.org documentation is biased to microdata- invented within Google by WHATWG HTML5 editor. It prefixes RDFa lite reseved words with "item", eg. property=itemprop and so forth. Also it is unsupported outside HTML5.

RDFa initial context http://www.w3.org/2011/rdfa-context/rdfa-1.1 allows schema: prefix, so rest assured as RDFa despite lacking any bias favoring schema treats it as well as any vocab for semantic web.

vocabs address semantic aspects from domains outside W3's jurisdiction. The initial context illustrates this by recognizing cc and license for legal matters, og for social networks, and so forth. Search is more cross-cutting concern than aspect specific to domain, so aspects covered by schema vocab range from webPagElement to geographic maps and taxIDs. Its sameas giving dictionary meaning to machine for every word targeted to human user. Despite consensus on the vocab aspects by major search players, commitment on how which of such structured data will be pushed to user querys' results is absent. So far only ratings are seen on Google results and they are mostly misleading.

Microformats solve indivisible recurring use-cases. For larger use-cases RDFa works on both HTML5 and non-HTML5 pages. And if XHTML is used the same semantic content can be transformed through xslt or grddl or so on.

Title: Schema.org vs microformats


答:
Why Not Both?

First of all, "descriptive" and "verbose" are not the same. For example, if you're writing a fairly local loop, i is a very good variable name for the loop variable; current_iteration_index, while arguably more descriptive and definitely more verbose, is much worse and does not add any information at all, because the use of i as a loop variable is pretty much universally accepted, and there is no other meaning to i than that.

Good variable names are descriptive, in that a programmer familiar with the language's idiom and the codebase's conventions can easily guess what their role is, but they are also concise enough to keep things compact.

The 80-character limit, while originally a consequence of technical limitations of 1970's text terminals, is still valued by many today, and even though there are still technical reasons (maximum line lengths in some network protocols, most notably e-mail related), the more compelling reasons are psychological and social ones. It turns out that line lengths around the 66 character mark make for the most comfortable reading experience for natural-language prose (the font size interestingly doesn't make much of a difference, and consequently, neither does the screen or paper size); 80-character line limits are pretty close to that, but since the bulk of a typical piece of code is usually indented at least one or two levels (which means between 4 and 16 characters, depending on indentation settings), we end up with something that is pretty close to 66 (between 64 and 76 characters).

Another effect of sticking to 80-character lines is that it's a pretty good indicator of when things are too complicated. Lines that long are usually caused by one of the following:

Functions with a long list of arguments; this is not a nice thing to have, because they impede readability and can easily cause subtle bugs, e.g. when people swap argument order in a way that the compiler doesn't catch.

Complex expressions, often found in conditionals (e.g. if ((user.isLoggedIn && user.hasPermission(page.getRequiredPermission()) && !user.isBanned) || page.getRequiredPermission() == null)); this, too is usually rather hard to decipher, and the code should be rewritten into something more structured. Most likely, the expression does too much and should be factored out into a method or function.

Long literals used in function calls or expressions, e.g. print(translate(LANG_EN, LANG_ES, "This is the home page. Feel welcome to click around and see what we have."));. Move the literal into a variable or constant; it might still exceed the line length, but if you do it consistently, the reader can at least safely ignore the invisible part of the line, assuming that only the remainder of the literal follows. Or better yet, move the literals out of the code and into an external data store (file, database, whatever).

Deeply nested statements, e.g. six levels of if statements in a class method (that's 32 columns of indentation for typical settings). Again, deep nesting makes for complex and hard-to-read code, and should be avoided like the plague - put simply, deep nesting overflows the human brain's stack while reading.

All these are ultimately symptoms of things you rather wouldn't have in your code base in the long run, and enforcing 80-character limits is a nice and simple way that helps keep complexity down and readability up. (That's not to say you can't write perfectly unreadable code in 80 columns: the various obfuscated-something-code contests are a clear counter-example).


问:
Is initializing a char[] with a string literal bad practice?
I was reading a thread titled "strlen vs sizeof" on CodeGuru, and one of the replies states that  "it's anyways [sic] bad practice to initialie [sic] a char array with a string literal."

Is this true, or is that just his (albeit an "elite member") opinion?

Here is the original question:

```<code>#include <stdio.h>
#include<string.h>
main()
{
    char string[] = "october";
    strcpy(string, "september");

    printf("the size of %s is %d and the length is %d\n\n", string, sizeof(string), strlen(string));
    return 0;
}
</code>```

right. the size should be the length plus 1 yes?

this is the output

the size of september is 8 and the length is 9

size should be 10 surely. its like its calculating the sizeof string before it is changed by strcpy but the length after.

Is there something wrong with my syntax or what?

Here is the reply:

It's anyways bad practice to initialie a char array with a string literal. So always do one of the following:

```<code>const char string1[] = "october";
char string2[20]; strcpy(string2, "september");
</code>```

答:
The only problem I recall is assigning string literal to char *:

```<code>char var1[] = "september";
var1[0] = 'S'; // Ok - 10 element char array allocated on stack
char const *var2 = "september";
var2[0] = 'S'; // Compile time error - pointer to constant string
char *var3 = "september";
var3[0] = 'S'; // Modifying some memory - which may result in modifying... something or crash
</code>```

For example take this program:

```<code>#include <stdio.h>

int main() {
  char *var1 = "september";
  char *var2 = "september";
  var1[0] = 'S';
  printf("%s\n", var2);
}
</code>```

This on my platform (Linux) crashes as it tries to write to page marked as read-only. On other platforms it might print 'September' etc.

That said - initialization by literal makes the specific amount of reservation so this won't work:

```<code>char buf[] = "May";
strncpy(buf, "September", sizeof(buf)); // Result "Sep"
</code>```

But this will

```<code>char buf[32] = "May";
strncpy(buf, "September", sizeof(buf));
</code>```

As last remark - I wouldn't use strcpy at all:

```<code>char buf[8];
strcpy(buf, "very long string very long string"); // Oops. We overwrite some random memory
</code>```

While some compilers can change it into safe call strncpy is much safer:

```<code>char buf[1024];
strncpy(buf, something_else, sizeof(buf)); // Copies at most sizeof(buf) chars so there is no possibility of buffer overrun. Please note that sizeof(buf) works for arrays but NOT pointers.
buf[sizeof(buf) - 1] = '\0';
</code>```

Body:
The only problem I recall is assigning string literal to char *:

char var1[] = "september";
var1[0] = 'S'; // Ok - 10 element char array allocated on stack
char const *var2 = "september";
var2[0] = 'S'; // Compile time error - pointer to constant string
char *var3 = "september";
var3[0] = 'S'; // Modifying some memory - which may result in modifying... something or crash

For example take this program:

#include <stdio.h>

int main() {
  char *var1 = "september";
  char *var2 = "september";
  var1[0] = 'S';
  printf("%s\n", var2);
}

This on my platform (Linux) crashes as it tries to write to page marked as read-only. On other platforms it might print 'September' etc.

That said - initialization by literal makes the specific amount of reservation so this won't work:

char buf[] = "May";
strncpy(buf, "September", sizeof(buf)); // Result "Sep"

But this will

char buf[32] = "May";
strncpy(buf, "September", sizeof(buf));

As last remark - I wouldn't use strcpy at all:

char buf[8];
strcpy(buf, "very long string very long string"); // Oops. We overwrite some random memory

While some compilers can change it into safe call strncpy is much safer:

char buf[1024];
strncpy(buf, something_else, sizeof(buf)); // Copies at most sizeof(buf) chars so there is no possibility of buffer overrun. Please note that sizeof(buf) works for arrays but NOT pointers.
buf[sizeof(buf) - 1] = '\0';


答: Take a bunch of the problems you have already solved.  Describe to him what was done to solve the problem (keep it third-person; you don't want to put your personal ego at stake here).  Ask him what he would have done "differently".  You should be able to, based on what he is suggesting, figure out if that would have been better or worse, conceptually, than what you did.</p>

Title: How do you interview someone with more experience than you?

Body:
The company I'm working for is looking to hire a senior developer with more experience than me, and they expect me to do the technical part of the interview. I've only been programming a few years and am not sure I have the knowledge needed to evaluate the coding skills of someone who has greater understanding/experience than I do.

Can anyone recommend some technical interview questions to ask that are a good means for evaluating higher-level programming skills, but still be ones I can understand?

I would say I'm past the jr. programmer level, but nowhere near senior. Most of what I've done is built small apps (web and desktop), some of them fairly complicated, but all of them have been meant to be used by no more then a handful of users. I feel I have a decent understanding of most programming concepts and am capable of learning/teaching myself just about anything, however I lack experience. As my boss is fond of telling me, "You don't know what you don't know".

In particular, things we'd like the person we hire to have experience with (that I don't have) is: Multi-tier development, multi-user environment, large-scale application development, two-way messaging, shared sessions, and Multi-threading/BackgroundWorkers.

UPDATE:

In response to Thor's comment below, we hired someone a few months ago and I think it has been working out great. I am learning a lot, not just about coding but also about things like design patterns, software architecture, documentation, and how other larger programming teams get stuff done. Its not always easy having someone come in and point out better ways to do things you have done, but if you can swallow your pride and be willing to try out new things you can learn a lot.

The interview process went better than I expected. I started asking questions about things I was familiar with, then asked some questions about some things I was struggling with. Whenever the interviewee said something I didn't understand, I'd ask them to explain it to me and then write it down so I could look it up later on. Overall, I felt I was able to get a pretty good idea of the applicant's skill level, intelligence, and what they'd be like to work with.


问:
Why don't languages include implication as a logical operator?
It might be a strange question, but why there is no implication as a logical operator in many languages (Java, C, C++, Python Haskell - although as last one have user defined operators its trivial to add it)? I find logical implication much clearer to write (particularly in asserts or assert-like expressions) then negation with or:</p>

```<code>encrypt(buf, key, mode, iv = null) {
    assert (mode != ECB --> iv != null);
    assert (mode == ECB || iv != null);
    assert (implies(mode != ECB, iv != null)); // User-defined function
}
</code>```

答:
I can only guess, but a reason might be that there are workarounds which are quite simple and readable. Let's consider your example:

```<code>if (mode != ECB) assert (iv != null);

assert (mode != ECB --> iv != null);  // <-- that's only one character shorter
</code>```

If you need an expression, the inline-if operator available in most languages (often called the ternary operator) can be used. Granted, this is not as elegant as A --> B, but the number of use cases might not justify adding (and maintaining!) another operator:

```<code>assert (mode != ECB ? iv != null : true);
</code>```

Body:
I can only guess, but a reason might be that there are workarounds which are quite simple and readable. Let's consider your example:

if (mode != ECB) assert (iv != null);

assert (mode != ECB --> iv != null);  // <-- that's only one character shorter

If you need an expression, the inline-if operator available in most languages (often called the ternary operator) can be used. Granted, this is not as elegant as A --> B, but the number of use cases might not justify adding (and maintaining!) another operator:

assert (mode != ECB ? iv != null : true);


答:
It could be useful to have sometimes, no doubt. Several points argue against such an operator:

The characters - and > are valuable, both in isolation and combined. Many languages already use them to mean other things. (And many can't use unicode character sets for their syntax.)

Implication is very counter-intuitive, even to logic-minded people such as programmers. The fact that three out of the four truth table entries are true surprises many people.

All other logical operators are symmetrical, which would make -> an exception to orthogonality.

At the same time, there is an easy workaround: use operators ! and ||.

Implication is used vastly less often than logical and/or.

This is probably why the operator is rare today. Certainly it could become more common, as new dynamic languages use Unicode for everything and operator overloading becomes more fashionable again.

Title: Why don't languages include implication as a logical operator?

Body:
It might be a strange question, but why there is no implication as a logical operator in many languages (Java, C, C++, Python Haskell - although as last one have user defined operators its trivial to add it)? I find logical implication much clearer to write (particularly in asserts or assert-like expressions) then negation with or:</p>

```<code>encrypt(buf, key, mode, iv = null) {
    assert (mode != ECB --> iv != null);
    assert (mode == ECB || iv != null);
    assert (implies(mode != ECB, iv != null)); // User-defined function
}
</code>```


答:
80 limit is something that should have been increased long time ago. Note that this limit is used since age when length of every identifier was limited to 8 characters and only one font on the screen/printer. No possibility to change font size.

God, we have different screen and printing technology now. We have very different programming languages. There's no reason to use 80 characters anymore. Increase it to 120 chars at least.

Even then it shouldn't be a hard limit. You go one character over the line? Well, nothing happens!

Edit:

Detailed answers about the history of 80-char limit

Characters Per Line on Wikipedia

A study at Wichita State University found that CPL had only small effects on readability, including factors of speed and comprehension. When asked for preferences, however, 60% of respondents indicated a preference for either the shortest (35 CPL) or longest (95 CPL) lines used in the study. At the same time, 100% of respondents selected either one of these quantities as being the least desirable.


答:
I'd like to point out that on-by-default aggressive automatic updating, when you grow over a certain scale, (or when you rent really absymal servers) might also trigger denial of services if you're not handling it trough p2p/torrent solutions. You might take that into consideration while implementing the functionality.

Also: are you planning painless automatic updating? I hope so.

IMHO the dilemma you present revolts around it. In fact asking to the user, with a little box, at each update, if he wishes to get on the bandwagon, is almost always fine, UI-wise. If the actual update process is swift.

(And ok, you have to provide an option in the menus to turn updates off, as, there are concerned users around, ok, but what you should really consider are enterprise scenarios where people isn't allowed to update stuff)

But the real problem surfaces when the little "how about updating?" box redirects you to the author's site (sometimes even to the wrong url) where you can have the pleasure of:

sifting trough the downloads,

finding the right link for your platform,

starting the download, waiting for it to finish,

start the installer,

realize you should close the program you where trying to work with to let it update,

closing it - blocking your workflow,

re-start the installer,

mindlessy click "OK," 5 to 8 times

(all this hoping you didn't chose a non standard installation path, last time)

starting the freshly installed copy of the program

wondering what you where up to, before joining all of this joyous update dance.

So, my theory is that it's not that popup that nags the user, but the actual not-really-automatic update process.

It's a pretty widespread defect, and there are reasons for that, but still: bad UX. Some examples that pop to mind: (those also update A LOT, amplifying the symptom)

LibreOffice (it has unobtrusive update notifications and allows you to download updates as a torrent, but it really doesn't want to handle its own updates)

Filezilla

PDF Creator

Sumatra PDF Reader

μTorrent, instead, is a good example of a painless update process. (and yes it has it easy, having a small footprint to start and the main focus on downloading stuff)

Title: Aggressive Auto-Updating?


答:
With an anaemic domain model, testing becomes more expensive, because logic tends to be more coupled with persistence. One great benefit for the Domain Model Pattern is the possibility to test key features in a Unit Test fashion. Faster and cheaper.

As a result of an anaemic approach, some teams spend (or waste) a lot of time in test. Test need to include cleanups and to guarantee idempotency. They're more expensive, and usually do not provide the same degree of confidence that a test suite should provide. Some other teams, test less. Test doesn't look so appealing due to the big time investment, and so ...no confidence. Both approaches lead to bigger costs when it comes to further evolutions.

Confidence might not look like an appealing term for the management, but it badly influence the ability for an IT department to respond (or anticipate) evolving business needs.

However, not all portions of the software have the same expectations for the future. Some components might respond to a temporary need, and no evolution is on the horizon. Some others might need continuous evolution due to many factors.

Evolving business requirements.

Dependencies with external tools and libraries.

Continuous Learning of the domain.

Frequently changing regulations.

For software whose life expectancy is to include a lot of maintenance/evolution, it is pointless to focus on optimization of writing time (which is the most appealing marketing approach for most frameworks, by the way). For software whose expectation is different, more short-term strategies might be reasonable.
Clearly, we can be wrong. :-)