问:
ThreadPool.QueueUserWorkItem is this example a valid use case?
I need to send out a batch of reminder emails, never more than 100 emails per batch, using authenticated SMTP. This is happening on a WindowsService (no GUI).

The SMTP library we're using raises a Sent event. In the Sent eventlistener, we grab some info from the Sent event's args and write some data to a SqlServer database via SqlClient library, to note the fact that the particular email has been sent to the recipient, and when it went out.

Is there any concern or issue for the Sent eventlistener when the emails are being sent out on multiple threads managed by ThreadPool?

pseudocode:

```<code>  for each record in batch
     {
       var email = buildEmail(record);
       ThreadPool.QueueUserWorkItem( a =>
            {
               if (!SmtpClient.Connected) SmtpClient.Connect();
               if (!SmtpClient.Authenticated) SmtpClient.Authenticate();
               if (SmtpClient.Authenticated) SmtpClient.Send(email);
            });
     }

   SmtpClient.Sent += (sender, args) =>
  {
          //get info from args
          // populate SqlCommand parameters

        ThreadPool.QueueUserWorkItem(b =>
           {
               UpdateDatabase(info);
           });
  };
</code>```

答:
From the code it looks like it should work.  Spinning off queued threads to the thread pool from an event listener should not cause issues (and I use a similar pattern is some of my code).

You will want to stress test the code to make sure that through put is enough to keep up and I would read up on error handling in multi threaded code (https://stackoverflow.com/questions/5218080/c-sharp-threadpool-queueuserworkitem-exception-handling for example).

Another pain point you will want to look out for is Connection Pool exhaustion.  When you queue up your background threads if you have enough cpu capacity (or code UpdateDatabase using async to release the thread while waiting) you can try to open more connections to the database than there are in the connection pool.  When I was writing code very similar to yours I ran into issues with this and had to batch the actual updates to the database.


问:
Can "return this" pattern be optimized to no cost performance?
return this (or similar construct) allows method chaining. Lack of it is painful, because you have to write such code (C#):

```<code>var list = new List<string>();
list.Add("hello");
list.Add("world");
</code>```

instead of

```<code>list.Add("hello").Add("world");
</code>```

Elixir solves it nicely for function chaining, instead of relying on callee it relies on caller (forgive me my mistakes, I don't know Elixir):

```<code>list |> add("hello") |> add("world");
</code>```

But now I have just read this sentence at wikipedia:

Returning an object of built-in type from a function usually carries
  little to no overhead, since the object typically fits in a CPU
  register.

On one hand callee does not know if the result will be used or not, on the other hand caller cannot stop callee from setting the result value. So I am skeptical about this "little", but "no overhead"?

Thus MY QUESTION for this very particular pattern (i.e return this with method chaining) -- can it be optimized with no overhead? How?

Question by example -- say I will write a framework and sprinkle every possible method with return this just to give ability for method chaining. The question arise -- will user who does not use method chaining will pay the price of lowered performance? How compiler could optimize code that this feature will have zero cost.

Update after first 2 comments -- "cheap"!="free", so maybe another perspective for my question, why the difference "little" vs. "no cost". If it can be guaranteed it is at no cost, we write "no cost", period. So I assume it cannot be guaranteed, thus "little".

Clarification I am not asking how to make another Elixir-like syntax in other language. I am asking how it is possible for compiler to optimize callee-caller interaction on return this + method chaining (or lack of it, when not used).

答:
At least in C#, your desired construct is entirely unnecessary.

You can write something like

```<code>var mylist = new List<string>(new[] {"Hello", "World"});
...
mylist.AddRange(new[] {"Add", "Some", "More", "Items"});
</code>```

which is about as concise as you can get, while still being perfectly readable.

If you really want method chaining in a class, even one that you don't have the source for, you can use extension methods.

```<code>public static class ListExtender
{
    public static IList<T> ChainedAdd<T>(this IList<T> list, T item)
    {
        list.Add(item);
        return list;
    }
}
</code>```

then

```<code> mylist.ChainedAdd("x").ChainedAdd("y").ChainedAdd("z");
</code>```

ContentLicense: CC BY-SA 3.0

Body:
At least in C#, your desired construct is entirely unnecessary.

You can write something like

var mylist = new List<string>(new[] {"Hello", "World"});
...
mylist.AddRange(new[] {"Add", "Some", "More", "Items"});

which is about as concise as you can get, while still being perfectly readable.

If you really want method chaining in a class, even one that you don't have the source for, you can use extension methods.

public static class ListExtender
{
    public static IList<T> ChainedAdd<T>(this IList<T> list, T item)
    {
        list.Add(item);
        return list;
    }
}

then

 mylist.ChainedAdd("x").ChainedAdd("y").ChainedAdd("z");


问:
Should we avoid language features that C++ has but Java doesn't?
Suppose I am limited to use C++ by the environment in the project. Is it good to prevent the use of some language features that C++ has but Java doesn't have (e.g.: multiple inheritance, operator overloading)?

I think the reasons are:

As Java is newer than C++, if Java doesn't provide a feature that C++ has, it means that the feature is not good, so we should avoid using it.

C++ code with C++ specific features (e.g.: friend functions, multiple inheritance) can only be maintained or reviewed by C++ programmers, but if we just write C++ like Java (without C++ language specific feature), the code can be maintained or reviewed by both C++ and Java programmers.

You may be asked to convert the code to Java some day

Code without C++ specific features is usually more maintainable

Every C++ language specific feature (e.g.: multiple inheritance) should have alternatives to be implemented in Java. If it doesn't, that means the design pattern or code architecture is problematic.

Is that true?

答:
There are already some good points in other answers, but I'd like to provide a more complete answer, addressing your questions and statements individually.

If Java doesn't provide a feature that C++ has, it means that the feature is not good, so we should prevent using it.

This has been pretty well answered: Java isn't "the good parts" of C++, nor is there any reason to think so.

In particular, though the merits of each individual C++ feature are debatable, many of the features of C++11/C++14 that are not part of Java aren't necessarily excluded because the Java designers thought they were a poor idea. As an example case, until version 8, Java didn't have lambdas, but they were introduced to C++ in the C++11 standard. Prior to Java 8, your assumption that C++ features missing from Java were missing by design because they are "not good" would have implied that lambdas as a language feature are "not good" (to the horror of LISPers everywhere, though they're probably horrified enough to hear that you apparently actually like Java). But now the Java designers have put their Stamp of Approval (TM) on lambdas, so they're now A Good Thing.

To dig a little deeper, even in Java 8, lambdas-as-closures are not as flexible as C++14's lambdas, but this may be due to JVM architecture limitations rather than a conscious decision that the more flexible approach is bad from a language-design perspective.

C++ code with C++ specific features (e.g.: friend functions, multiple inheritance) can only be maintained or reviewed by C++ programmers, but if we just write C++ like Java (without C++ language specific feature), the code can be maintained or reviewed by both C++ and Java programmers.

This is the main thing I wanted to respond to.

Broadly speaking, there may be some value to getting code reviews from programmers who aren't intimately familiar with the language you're using. They can give you valuable feedback about the clarity of your function/method names and comments, and (as your question correctly implies) if the language is similar to one or more languages they already know, they may be able to follow the basic program flow and potentially catch logic errors.

However, it is not the case that this sort of review will ever be "as good as" or "equivalent to" review from developers who actually know the language you're using. Essentially, this is because making one language look like another will typically hide subtle differences, while making one language behave like another (especially in the case of C++ and Java) may be un-idiomatic for the language and/or might still be too confusing for the reviewers.

First, let's think about what it would mean to make C++ "look like" Java. As a simple case, you can use new to instantiate objects, just like in Java:

```<code>Foo foo = new Foo();
</code>```

But objects instantiated this way use -> instead of . to call methods, so if you want method calls to look like Java, you must instead write:

```<code>Foo& foo = *new Foo();
</code>```

But this is un-idiomatic; in particular, the memory must later be cleaned up using delete &foo, which some experienced C++ devs might not even realize is legal code. Either way, there are funny non-Java-like symbols sprinkled throughout, so we can't quite make the language "look like" Java. (You could eliminated *new using #define New *new, or, worse, #define new *new, but then you're just begging for your fellow developers to hate you.) And, as mentioned above, delete doesn't exist in Java, so in any case (as mentioned in another answer) you can't really ever make object-usage "look" the way it does in Java without memory leaks.

But modern C++ includes smart shared pointers, which behave a lot like Java's memory-managed variable-references. So everywhere in Java that you could write Foo foo = new Foo();, you could instead write:

```<code>std::shared_ptr<Foo> foo = std::make_shared<Foo>();
</code>```

Now you're using a language feature that's actually a lot like Java's under the hood. But suddenly you have a lot to explain to non-C++ reviewers: what is this shared_ptr stuff? What are the subtle tricky "gotchas" of make_shared? (It uses perfect-forwarding, which has some failure cases and can lead to the "wrong" constructor being called.) Why do methods need to be called with ->, but using . with some methods is permitted by the compiler? (shared_ptr has its own methods.) If the method Foo::reset(void) exists, an unwary developer might try to call it with foo.reset(), which (if there is only one shared pointer pointing to that instance of Foo when the call occurs) will delete the underlying memory and nullify foo, and Java developers aren't likely to catch this problem.

Moreover, C++ has a lot of pitfalls that are specific to the language. As best I can tell, most C++ developers learn to deal with these pitfalls by gradually developing their own idiom for "safe" C++ practices, which is often somewhat unique to them or to their development team (see for example the existing answer that mentions the Google coding practices and the comment on it saying that "Seasoned C++ veterans usually reject Google coding guidelines"). All claims that the language might be too complicated, it seems (in my experience, at least), are typically met with some variation of "well, stop using it wrong." I realize this is a highly negative view of the C++ community, and there are certainly experienced developers more willing to help out language-learners, but there does seem to be a certain defensiveness about e.g. undefined behavior (see for instance much of the discussion in my 'pitfalls' link above).

Java developers simply won't be helpful in finding and correcting these pitfalls via code review.

You may be asked to convert the code to Java some day.

It's entirely valid--commendable, even--to try to take into account what might happen to your code in the future while you're in the design phase.

But, first, this particular consideration seems like a remote possibility: code is typically either re-used as is (for instance you could plug some or all of the working C++ code into some future Java software using a JNI interface) or rewritten entirely rather than directly manually "transcribed".

And, second, you later say,

Every C++ language specific feature (e.g.: multiple inheritance) should have alternatives to be implemented in Java....

This essentially cancels out your "convert to Java" point. If software is written in idiomatic C++ and then converted to idiomatic Java, there's no reason to expect that this conversion would (or could!) be done by applying a precise one-to-one mapping of C++ features to Java features.

Code without C++ specific features is usually more maintainable.

It's not clear what you mean here, but I actually somewhat agree with part of this: unless you're very careful, and even when you are careful, C++ features can lead to maintainability problems. The C++ FQA Lite (a website critical of the language and its adherents from someone who at least appears to actually understand it fairly well) states that

... 80% of the developers understand at most 20% of the language. It is not the same 20% for different people, so don't count on them to understand each other's code.

PLEASE NOTE: If you're a C++ fan and you get to this point in my answer and feel inclined to jump down to the comments to argue that the author of the FQA doesn't actually understand C++ or is disingenuous in most of his arguments, note that (1) exactly two sentences after I cite him I acknowledge that the FQA is a very biased source, and (2) it doesn't really matter for what I'm trying to say whether or not the FQA author understands C++, and I'm not trying to bash C++, and you should read the rest of the post without assuming that I'm anti-C++ just because I've quoted the FQA. End of note.

Similarly, Linus Torvalds hates C++ for essentially this reason (warning: link involves lots of swearing, in true infamous Linus style).

Obviously, these are very biased takes on the matter, but even C++ proponents often say that you shouldn't use the entirety of the language feature-set (once again, see the Google coding guidelines; also, Bjarne Stroustrup, the creator of C++, has publicly stated, "Within C++, there is a much smaller and cleaner language struggling to get out").

So I think there's some merit to the idea that C++ features might be too easy to misuse, especially if you're coming from a Java background. Furthermore, there's merit to the idea of alleviating these problems by restricting yourself to some subset of the language.

However, deciding which subset to use based on a different language does not seem like the right approach, unless the "different language" is C, since there really is a C-like subset of the C++ language. (Linus refers to this in his rant above, and Scott Meyers even refers to this subset as a "sub-language.") Java's run-time paradigm (garbage-collected, running on a VM) is so fundamentally different from C++'s that it's not clear there are any useful lessons to draw about C++ usage from it, and as noted above, trying to draw lessons about C++ directly from Java can lead to very non-idiomatic code.

Instead, try to define your "acceptable subset" of the language on an understanding of how the language can be used idiomatically. If you want a fairly restrictive subset that still takes advantage of many of C++'s features beyond what C offers, the aforementioned Google Coding guideline might be a good place to start. Sure, you'll get developers who say that there is "no rational argument" for some of Google's restrictions, but unless you're looking to hire Alexandrescu away from his work on the D language (which itself should tell you something), that's probably okay. It's certainly better than trying to turn C++ into Java.

Another good starting-point for a set of code guidelines is the new C++ Core Guidelines, a work-in-progress by Bjarne Stroustrup and Herb Sutter.

The only other way to deal with the shortcomings of C++ is to pick a different language. It sounds like you like Java, and you think there's a chance this project might be converted into Java eventually. As noted in another answer, you could just...start with Java.

There are two reasons why you might really truly need to use something other than Java:

You really need the run-time performance. In this case, treating C++ like it's Java probably won't actually help you, because Java-like techniques such as shared-pointers degrade your run-time performance.

You need the software to work on an obscure platform that doesn't yet support the JVM. In this case, you are probably stuck with languages that have GCC or Clang frontends. C and C++ are obvious candidates, but you could also look into something like Rust. (Quick plug: I haven't used Rust extensively, but it looks awesome and I am eager to work on a major Rust project as soon as I can, and I think everyone considering starting a C++ project should consider Rust as an alternative.)

Every C++ language specific feature (e.g.: multiple inheritance) should have alternatives to be implemented in Java. If it doesn't, that means the design pattern or code architecture is problematic.

I've already addressed this somewhat, but I intentionally left out your second sentence.

I'm not convinced that something like constexpr, which wouldn't make any sense in a partially-JIT language like Java, is an indication of invalid architecture. I'm more open to the idea that excessive use of template meta-programming might be more trouble than it's worth, especially now that constexpr exists for doing compile-time function evaluation, but it's clear from the case of constexpr that there's no design flaw if you're using it: you're simply ensuring that some calculations occur prior to even running the code, which is an awesome performance boost (see for instance this entry for The Benchmark Game's n-body problem, which outperforms every other entry except another one written in C++, and is over twice as fast as the fastest Java implementation).

Body:
There are already some good points in other answers, but I'd like to provide a more complete answer, addressing your questions and statements individually.

If Java doesn't provide a feature that C++ has, it means that the feature is not good, so we should prevent using it.

This has been pretty well answered: Java isn't "the good parts" of C++, nor is there any reason to think so.

In particular, though the merits of each individual C++ feature are debatable, many of the features of C++11/C++14 that are not part of Java aren't necessarily excluded because the Java designers thought they were a poor idea. As an example case, until version 8, Java didn't have lambdas, but they were introduced to C++ in the C++11 standard. Prior to Java 8, your assumption that C++ features missing from Java were missing by design because they are "not good" would have implied that lambdas as a language feature are "not good" (to the horror of LISPers everywhere, though they're probably horrified enough to hear that you apparently actually like Java). But now the Java designers have put their Stamp of Approval (TM) on lambdas, so they're now A Good Thing.

To dig a little deeper, even in Java 8, lambdas-as-closures are not as flexible as C++14's lambdas, but this may be due to JVM architecture limitations rather than a conscious decision that the more flexible approach is bad from a language-design perspective.

C++ code with C++ specific features (e.g.: friend functions, multiple inheritance) can only be maintained or reviewed by C++ programmers, but if we just write C++ like Java (without C++ language specific feature), the code can be maintained or reviewed by both C++ and Java programmers.

This is the main thing I wanted to respond to.

Broadly speaking, there may be some value to getting code reviews from programmers who aren't intimately familiar with the language you're using. They can give you valuable feedback about the clarity of your function/method names and comments, and (as your question correctly implies) if the language is similar to one or more languages they already know, they may be able to follow the basic program flow and potentially catch logic errors.

However, it is not the case that this sort of review will ever be "as good as" or "equivalent to" review from developers who actually know the language you're using. Essentially, this is because making one language look like another will typically hide subtle differences, while making one language behave like another (especially in the case of C++ and Java) may be un-idiomatic for the language and/or might still be too confusing for the reviewers.

First, let's think about what it would mean to make C++ "look like" Java. As a simple case, you can use new to instantiate objects, just like in Java:

Foo foo = new Foo();

But objects instantiated this way use -> instead of . to call methods, so if you want method calls to look like Java, you must instead write:

Foo& foo = *new Foo();

But this is un-idiomatic; in particular, the memory must later be cleaned up using delete &foo, which some experienced C++ devs might not even realize is legal code. Either way, there are funny non-Java-like symbols sprinkled throughout, so we can't quite make the language "look like" Java. (You could eliminated *new using #define New *new, or, worse, #define new *new, but then you're just begging for your fellow developers to hate you.) And, as mentioned above, delete doesn't exist in Java, so in any case (as mentioned in another answer) you can't really ever make object-usage "look" the way it does in Java without memory leaks.

But modern C++ includes smart shared pointers, which behave a lot like Java's memory-managed variable-references. So everywhere in Java that you could write Foo foo = new Foo();, you could instead write:

std::shared_ptr<Foo> foo = std::make_shared<Foo>();

Now you're using a language feature that's actually a lot like Java's under the hood. But suddenly you have a lot to explain to non-C++ reviewers: what is this shared_ptr stuff? What are the subtle tricky "gotchas" of make_shared? (It uses perfect-forwarding, which has some failure cases and can lead to the "wrong" constructor being called.) Why do methods need to be called with ->, but using . with some methods is permitted by the compiler? (shared_ptr has its own methods.) If the method Foo::reset(void) exists, an unwary developer might try to call it with foo.reset(), which (if there is only one shared pointer pointing to that instance of Foo when the call occurs) will delete the underlying memory and nullify foo, and Java developers aren't likely to catch this problem.

Moreover, C++ has a lot of pitfalls that are specific to the language. As best I can tell, most C++ developers learn to deal with these pitfalls by gradually developing their own idiom for "safe" C++ practices, which is often somewhat unique to them or to their development team (see for example the existing answer that mentions the Google coding practices and the comment on it saying that "Seasoned C++ veterans usually reject Google coding guidelines"). All claims that the language might be too complicated, it seems (in my experience, at least), are typically met with some variation of "well, stop using it wrong." I realize this is a highly negative view of the C++ community, and there are certainly experienced developers more willing to help out language-learners, but there does seem to be a certain defensiveness about e.g. undefined behavior (see for instance much of the discussion in my 'pitfalls' link above).

Java developers simply won't be helpful in finding and correcting these pitfalls via code review.

You may be asked to convert the code to Java some day.

It's entirely valid--commendable, even--to try to take into account what might happen to your code in the future while you're in the design phase.

But, first, this particular consideration seems like a remote possibility: code is typically either re-used as is (for instance you could plug some or all of the working C++ code into some future Java software using a JNI interface) or rewritten entirely rather than directly manually "transcribed".

And, second, you later say,

Every C++ language specific feature (e.g.: multiple inheritance) should have alternatives to be implemented in Java....

This essentially cancels out your "convert to Java" point. If software is written in idiomatic C++ and then converted to idiomatic Java, there's no reason to expect that this conversion would (or could!) be done by applying a precise one-to-one mapping of C++ features to Java features.

Code without C++ specific features is usually more maintainable.

It's not clear what you mean here, but I actually somewhat agree with part of this: unless you're very careful, and even when you are careful, C++ features can lead to maintainability problems. The C++ FQA Lite (a website critical of the language and its adherents from someone who at least appears to actually understand it fairly well) states that

... 80% of the developers understand at most 20% of the language. It is not the same 20% for different people, so don't count on them to understand each other's code.

PLEASE NOTE: If you're a C++ fan and you get to this point in my answer and feel inclined to jump down to the comments to argue that the author of the FQA doesn't actually understand C++ or is disingenuous in most of his arguments, note that (1) exactly two sentences after I cite him I acknowledge that the FQA is a very biased source, and (2) it doesn't really matter for what I'm trying to say whether or not the FQA author understands C++, and I'm not trying to bash C++, and you should read the rest of the post without assuming that I'm anti-C++ just because I've quoted the FQA. End of note.

Similarly, Linus Torvalds hates C++ for essentially this reason (warning: link involves lots of swearing, in true infamous Linus style).

Obviously, these are very biased takes on the matter, but even C++ proponents often say that you shouldn't use the entirety of the language feature-set (once again, see the Google coding guidelines; also, Bjarne Stroustrup, the creator of C++, has publicly stated, "Within C++, there is a much smaller and cleaner language struggling to get out").

So I think there's some merit to the idea that C++ features might be too easy to misuse, especially if you're coming from a Java background. Furthermore, there's merit to the idea of alleviating these problems by restricting yourself to some subset of the language.

However, deciding which subset to use based on a different language does not seem like the right approach, unless the "different language" is C, since there really is a C-like subset of the C++ language. (Linus refers to this in his rant above, and Scott Meyers even refers to this subset as a "sub-language.") Java's run-time paradigm (garbage-collected, running on a VM) is so fundamentally different from C++'s that it's not clear there are any useful lessons to draw about C++ usage from it, and as noted above, trying to draw lessons about C++ directly from Java can lead to very non-idiomatic code.

Instead, try to define your "acceptable subset" of the language on an understanding of how the language can be used idiomatically. If you want a fairly restrictive subset that still takes advantage of many of C++'s features beyond what C offers, the aforementioned Google Coding guideline might be a good place to start. Sure, you'll get developers who say that there is "no rational argument" for some of Google's restrictions, but unless you're looking to hire Alexandrescu away from his work on the D language (which itself should tell you something), that's probably okay. It's certainly better than trying to turn C++ into Java.

Another good starting-point for a set of code guidelines is the new C++ Core Guidelines, a work-in-progress by Bjarne Stroustrup and Herb Sutter.

The only other way to deal with the shortcomings of C++ is to pick a different language. It sounds like you like Java, and you think there's a chance this project might be converted into Java eventually. As noted in another answer, you could just...start with Java.

There are two reasons why you might really truly need to use something other than Java:

You really need the run-time performance. In this case, treating C++ like it's Java probably won't actually help you, because Java-like techniques such as shared-pointers degrade your run-time performance.

You need the software to work on an obscure platform that doesn't yet support the JVM. In this case, you are probably stuck with languages that have GCC or Clang frontends. C and C++ are obvious candidates, but you could also look into something like Rust. (Quick plug: I haven't used Rust extensively, but it looks awesome and I am eager to work on a major Rust project as soon as I can, and I think everyone considering starting a C++ project should consider Rust as an alternative.)

Every C++ language specific feature (e.g.: multiple inheritance) should have alternatives to be implemented in Java. If it doesn't, that means the design pattern or code architecture is problematic.

I've already addressed this somewhat, but I intentionally left out your second sentence.

I'm not convinced that something like constexpr, which wouldn't make any sense in a partially-JIT language like Java, is an indication of invalid architecture. I'm more open to the idea that excessive use of template meta-programming might be more trouble than it's worth, especially now that constexpr exists for doing compile-time function evaluation, but it's clear from the case of constexpr that there's no design flaw if you're using it: you're simply ensuring that some calculations occur prior to even running the code, which is an awesome performance boost (see for instance this entry for The Benchmark Game's n-body problem, which outperforms every other entry except another one written in C++, and is over twice as fast as the fastest Java implementation).


问:
Zero Downtime Deployment - Transitional Db Schema
Achieving Zero Downtime Deployment touched on the same issue but I need some advice on a strategy that I am considering.

Context

A web-based application with Apache/PHP for server-side processing and MySQL DB/filesystem for persistence.

We are currently building the infrastructure. All networking hardware will have redundancy and all main network cables will be used in bonded pairs for fault-tolerance. Servers are being configured as high-availability pairs for hardware fault-tolerance and will be load-balanced for both virtual-machine fault-tolerance and general performance.

It is my intent that we are able to apply updates to the application without any down-time. I have taken great pains when designing the infrastructure to ensure that I can provide 100% up-time; it would be extremely disappointing to then have 10-15 minutes downtime every time an update was applied. This is particularly significant as we intend to have a very rapid release cycle (sometimes it may reach one or more releases per day.

Network Topology

This is a summary of the network:

```<code>                      Load Balancer
             |----------------------------|
              /       /         \       \
             /       /           \       \
 | Web Server |  DB Server | Web Server |  DB Server |
 |-------------------------|-------------------------|
 |   Host-1   |   Host-2   |   Host-1   |   Host-2   |
 |-------------------------|-------------------------|
            Node A        \ /        Node B
              |            /            |
              |           / \           |
   |---------------------|   |---------------------|
           Switch 1                  Switch 2

   And onward to VRRP enabled routers and the internet
</code>```

Note: DB servers use master-master replication

Suggested Strategy

To achieve this, I am currently thinking of breaking the DB schema upgrade scripts into two parts. The upgrade would look like this:

Web-Server on node A is taken off-line; traffic continues to be processed by web-server on node B.

Transitional Schema changes are applied to DB servers

Web-Server A code-base is updated, caches are cleared, and any other upgrade actions are taken.

Web-Server A is brought online and web-server B is taken offline.

Web-server B code-base is updated, caches are cleared, and any other upgrade actions are taken.

Web-server B is brought online.

Final Schema changes are applied to DB

'Transitional Schema' would be designed to establish a cross-version compatible DB. This would mostly make use of table views that simulate the old version schema whilst the table itself would be altered to the new schema. This allows the old version to interact with the DB as normal. The table names would include schema version numbers to ensure that there won't be any confusion about which table to write to.

'Final Schema' would remove the backwards compatibility and tidy the schema.

Question

In short, will this work?

more specifically:

Will there be problems due to the potential for concurrent writes at the specific point of the transitional schema change? Is there a way to make sure that the group of queries that modify the table and create the backwards-compatible view are executed consecutively? i.e. with any other queries being held in buffer until the schema changes are completed, which will generally only be milliseconds.

Are there simpler methods that provide this degree of stability whilst also allowing updates without down-time? It is also preferred to avoid the 'evolutionary' schema strategy as I do not wish to become locked into backwards schema compatibility.

答:
It sounds like what you are really looking for is not so much High Availability as you would need Continuous Availability.

Essentially your plan will work but you seem to have noticed that the major flaw in your setup is that database schema changes in a release could result in either downtime or failure of still available node to operate correctly.  Continuous Availability approach solves this by essentially creating a number of Production environments.

Production One

This environment is your current live version of the software being utilized by users.  It has its own web servers, application servers, and database servers and tablespace.  It operates independently of any other environment.  The Load Balancer which owns the domain resolution endpoint for these services is currently pointing to these web servers.

Production Two

This is basically release staging environment that is identical to Production One.  You can perform your release upgrades here and do your sanity tests before your go live event.  This also affords you to safely perform your database changes on this environment.  The Load Balancer does not point to this environment currently.

Production DR

This is another duplicate at a separate data center that is located in a different region of the world.  This allows you to fail over in the event of catastrophic event by doing a DNS switch at the Load Balancer.

Go Live

This event is essentially updating the DNS record to cycle to Production Two from Production One or vice-versa.  This takes a while to propagate throughout the DNS servers of the world so you leave both environments running for a while.  Some users MAY be working in existing sessions on the old version of your software.  Most users will be establishing new sessions on the upgraded version of your software.

Data Migration

The only drawback here is that not all data during that window is available to all users at that time.  There is clearly important user data in the previous version database that now needs to be migrated safely to the new database schema.  This can be accomplished with a well tested data export and migration script or batch job or similar ETL process.

Conclusion

Once you have fully completed your release event, Production Two is now your primary and you begin working on installing the next release to Production One for the next deployment cycle.

Drawbacks

This is a complex environment setup and it requires a large amount of system resources, often times two to three times the system resources to do successfully.  Operating this way can be expensive, especially if you have very large heavy use systems.


问:
Neat way on passing interface parameter to a constructor
Having lots of Interface that needs to pass in a constructor looks messy, is there any neat way of doing it?

Code snippet:

```<code>public class Foo
{
    private readonly IRepository1 _repository1;
    private readonly IRepository2 _repository2;
    private readonly IRepository3 _repository3;
    private readonly IRepository4 _repository4;

    public Foo(IRepository1 repository1, IRepository2 repository2,
               IRepository3 repository3, IRepository4  repository4)
    {
        repository1 = repository1;
        repository2 = repository2;
        repository3 = repository3;
        repository4 = repository4;
    }
}
</code>```

答:
Primary Constructors would have helped, but they were pulled from C# 6.

You could use certain IOC container black magic to make it look neater.

But neither remove the underlying problem: your class is awkward because it has a bunch of dependencies. If it has a bunch of dependencies, it's probably trying to do too much, since few problems require 4 completely indpendent things as inputs. You can shuffle things around, but without addressing the core problem, you're going to get code smells of some sort.


问:
How do I do TDD on embedded devices?
I'm not new to programming and I've even worked with some low level C and ASM on AVR, but I really can't get my head around a larger-scale embedded C project.

Being degenerated by the Ruby's philosophy of TDD/BDD, I'm unable to understand how people write and test code like this. I'm not saying it's a bad code, I just don't understand how this can work.

I wanted to get more into some low level programming, but I really have no idea how to approach this, since it looks like a completely different mindset that I'm used to. I don't have trouble understanding pointer arithmetics, or how allocating memory works, but when I see how complex C/C++ code looks compared to Ruby, it just seems impossibly hard.

Since I already ordered myself an Arduino board, I'd love to get more into some low level C and really understand how to do things properly, but it seems like none of the rules of high level languages apply.

Is it even possible to do TDD on embedded devices or when developing drivers or things like custom bootloader, etc.?

答:
Yes it is possible to do TDD on embedded software. The people telling it is not possible, not relevant, or not applicable are not correct. There is serious value to be gained from TDD in embedded as with any software.

They best way to do it though is not to run your tests on the target but to abstract your hardware dependencies and compile and run on your host PC.

When you're doing TDD, you'll be creating and running a lot of tests. You need software to help you do this. You want a test framework to that makes it quick and easy to do this, with automatic test discovery and mock generation.

The best option for C right now is Ceedling. Here is a post about I wrote about it:

http://www.electronvector.com/blog/try-embedded-test-driven-development-right-now-with-ceedling

And it's built in Ruby! You don't need to know any Ruby to use it though.

OwnerDisplayName: Darth

Title: How do I do TDD on embedded devices?


问:
When to use ANTLR and when to use a parsing library
I've always wanted to learn how to write a compiler - I've decided to use ANTLR, and am currently reading through the book (its very good by the way)

I'm pretty new to this, so go easy, but the jist seems to be that you write your grammar, transform this into a data structure (usually an AST) and then walk this one or more times actually executing the 'meat' of whatever you want your program to do.

If my input "language" was something like JSON or XML, i.e something that probably has a library that can turn it into a graph of pojos - does this negate the need to do the lexing and parsing with a compiler compiler like ANTLR? clearly if my input is very bespoke then I need to write my own lexer/parser - but could I and should I short-cut this if my input language is already broadly used.

Would be fair to say you could parse, say json, with Jackson,into POJO's and then drive your code of the resulting pojos? - or in this case, does a 'proper' compiler compiler offer some advantage?

Edited (based on the answers) to add

I probably should have pointed out that my question was slightly hypothetical - I wouldn't ever try and build a programming language in XML!

So I guess the deal is that AST != Pojo - and the tree walkers that antlr give you are more useful in the case where you need to 'walk' the data structure and execute code.

答:
I'm actually in the process of debating exactly this. My issue is that I want to give our users really pretty YAML documents to edit by-hand and then load back into our software --something akin to what CircleCI does with their circle.yml file.

We're on the JVM and SnakeYAML is a very nice YAML serializer/deserializer, so I can simply add it to my project and get started, yet that means I have to bridge from our domain's various model objects to serializer-friendly POJO ('surrogates') objects and back again. And that has some fairly disastrous consequences, including 300 or so lines to handle null checks alone (its a lot of null checks, and I'm sure I've missed some and will continue to miss them as I add features).

If I go with ANTLR and a make our configuration document not a true YAML document but instead a strict subset of YAML I can bake those null checks into the parser. But now I get a new set of problems: will my grammar properly handle YAML's references? will I have bugs in my whitespace handling (YAML is a whitespace sensitive document language like the python programming language).

I'm really torn. Right now the winds are favoring the latter since the amount of buggy validation we're doing is just getting too extensive.

Some questions/thoughts I've asked/had myself that have been reasonably helpful:

What specific problems are you going to encounter with using a Serializer?

How complex is your target language? What kind've gotchas does it have for your parser (eg preprocesor directives, comments (with semantics?), whitespace handling)

Experience with grammars, parsers and visitors is experience with sophisticated and reusable tools, experience writing null-checks and domainType.x = surrogateType.x is not. Getting to know a serializer intimately can also be helpful, but is generally not transferable out of your current language/tech-stack.

You can get started with both serializers and parser-generators reasonably easily, meaning its not impossible to try both. See how sophisticated your POJO classes can be before your serializer buckles and see what kind of parse tree gets generated by a simple grammar on a subset of the langauge you're looking at.


问:
In UML, can a component be placed inside a node?
in UML deployment diagrams, the node element is used to represent a "computational resource" (in other words, something that can run software).

I know that nodes may have other nodes placed inside them (to imply nesting), and that they may have artifacts placed inside them (to imply the deployment relationship, i. e. the artifact being deployed to the node).

However, I've also found a couple of illustrations that had component elements placed inside a node, which I'm not sure how to interpret.

Here's what I'd like to know:

Is it legal to place a component inside a node?

If so, what exactly does it imply - the component being deployed to the node (which I'm not sure is allowed), or the node consisting of the component?

If not, does the specification explicitly say so at any point?

答:
Strictly speaking, no, it is not legal to place a component inside a node.
The specification does not explicitly say so, but it would not be feasible for the spec to explicitly forbid every mistake one could possibly make.

Personally, I think it is acceptable to draw a component inside a node. I would interpret it as a deployed artifact implementing that component.

Some relevant quotes from the UML 2.5 specification:

11.6.3.1: A Component may be manifested by one or more Artifacts, and in turn, that Artifact may be deployed to its execution environment.

19.4.3: A Node is computational resource upon which Artifacts may be deployed. Nodes may be further sub-typed as Devices and ExecutionEnvironments.

19.2.4: System elements deployed on a DeployedTarget, and Deployments that connect them, may be drawn inside the perspective cube.

I think DeployedTarget is a typo or a synonym for DeploymentTarget, which is a superclass of Node. "System elements" is not well defined in the spec. I found this sentence:

19.2.3: System elements are represented as DeployedTargets

But I think this should not be treated as a formal definition of the word 'system element' as used in 19.2.4. I think it is clear that anything drawn inside a node should be something deployed on that node and the only deployments mentioned are the deployments of artifacts.


答: If the implementation uses a calling convention that uses the same register to pass the this pointer to a function that it does to return a value from the function, then return this is a zero-cost operation (because the return value is already there).

Title: Can "return this" pattern be optimized to no cost performance?

Body:
return this (or similar construct) allows method chaining. Lack of it is painful, because you have to write such code (C#):

```<code>var list = new List<string>();
list.Add("hello");
list.Add("world");
</code>```

instead of

```<code>list.Add("hello").Add("world");
</code>```

Elixir solves it nicely for function chaining, instead of relying on callee it relies on caller (forgive me my mistakes, I don't know Elixir):

```<code>list |> add("hello") |> add("world");
</code>```

But now I have just read this sentence at wikipedia:

Returning an object of built-in type from a function usually carries
  little to no overhead, since the object typically fits in a CPU
  register.

On one hand callee does not know if the result will be used or not, on the other hand caller cannot stop callee from setting the result value. So I am skeptical about this "little", but "no overhead"?

Thus MY QUESTION for this very particular pattern (i.e return this with method chaining) -- can it be optimized with no overhead? How?

Question by example -- say I will write a framework and sprinkle every possible method with return this just to give ability for method chaining. The question arise -- will user who does not use method chaining will pay the price of lowered performance? How compiler could optimize code that this feature will have zero cost.

Update after first 2 comments -- "cheap"!="free", so maybe another perspective for my question, why the difference "little" vs. "no cost". If it can be guaranteed it is at no cost, we write "no cost", period. So I assume it cannot be guaranteed, thus "little".

Clarification I am not asking how to make another Elixir-like syntax in other language. I am asking how it is possible for compiler to optimize callee-caller interaction on return this + method chaining (or lack of it, when not used).


答:
@Groostav, answering rather than commenting so I can say a bit more.

Interesting post. Since I asked my question, I made a bit more progress, so have a bit more perspective.

I think Id try to initially use something standard like YAML or JSON. Then if you feel you are stretching the boundary of what the config management system can do, only then would I make a DSL.

What does 'stretching the boundary' mean? - well I think it's things like trying to form programming idioms into things like JSON - e.g if you try and stuff a for loop into a json document, you probably went past the point where it should be a DSL rather than a standard config file solution.

You touch on the second point with your 'Null checks' observation. if you do a DSL and a grammar, you can enforce some schema constraints like

```<code>node 'shape' should always have a subnode called 'edges'
</code>```

which alleviates you from some of this burden as the grammar will do this for you - although you may have to do some work to get nice 'user friendly' error messages out of it.

Having said that - JSON has schema validators, and I'd bet someone has done one for YAML as well.

TL;DR is that I think its more art than science... for your use case, with the information you provided... I'd stick to YAML.

Title: When to use ANTLR and when to use a parsing library

Body:
I've always wanted to learn how to write a compiler - I've decided to use ANTLR, and am currently reading through the book (its very good by the way)

I'm pretty new to this, so go easy, but the jist seems to be that you write your grammar, transform this into a data structure (usually an AST) and then walk this one or more times actually executing the 'meat' of whatever you want your program to do.

If my input "language" was something like JSON or XML, i.e something that probably has a library that can turn it into a graph of pojos - does this negate the need to do the lexing and parsing with a compiler compiler like ANTLR? clearly if my input is very bespoke then I need to write my own lexer/parser - but could I and should I short-cut this if my input language is already broadly used.

Would be fair to say you could parse, say json, with Jackson,into POJO's and then drive your code of the resulting pojos? - or in this case, does a 'proper' compiler compiler offer some advantage?

Edited (based on the answers) to add

I probably should have pointed out that my question was slightly hypothetical - I wouldn't ever try and build a programming language in XML!

So I guess the deal is that AST != Pojo - and the tree walkers that antlr give you are more useful in the case where you need to 'walk' the data structure and execute code.

Body:
@Groostav, answering rather than commenting so I can say a bit more.

Interesting post. Since I asked my question, I made a bit more progress, so have a bit more perspective.

I think Id try to initially use something standard like YAML or JSON. Then if you feel you are stretching the boundary of what the config management system can do, only then would I make a DSL.

What does 'stretching the boundary' mean? - well I think it's things like trying to form programming idioms into things like JSON - e.g if you try and stuff a for loop into a json document, you probably went past the point where it should be a DSL rather than a standard config file solution.

You touch on the second point with your 'Null checks' observation. if you do a DSL and a grammar, you can enforce some schema constraints like

node 'shape' should always have a subnode called 'edges'

which alleviates you from some of this burden as the grammar will do this for you - although you may have to do some work to get nice 'user friendly' error messages out of it.

Having said that - JSON has schema validators, and I'd bet someone has done one for YAML as well.

TL;DR is that I think its more art than science... for your use case, with the information you provided... I'd stick to YAML.


问:
How can a object have many types?
I am currently reading Design Patterns - Elements of Reusable Object-Oriented Software. I am in chapter 1 at page 16 in section Class versus Interface Inheritance. There in the last line of the page it says " An object can have many types, and objects of different classes can have the same type. "

I think I understand the second part of the sentence, how objects of different classes can have same types. It is possible by inheritance, if Base class and derived class have same interface.

My question is how can object have many types. Is it trying to say a derived object can have two type base and derived?

答:
The big hint is in your question: "interface inheritance".

Basically, an interface is nothing but a set of method signatures. In a traditional OOP language, the only thing a class needs to do to satisfy an interface is to have implementations of those method signatures, and declare that it implements the interface. Since it's not inheriting implementations, there's no ambiguity or contradiction in having a single class implement several interfaces at once, or having several classes implement the same interface with different underlying data or algorithms.

For instance, here's some trivial Java code that declares a class which implements several other interfaces, and thus has all of their types at the same time:

public interface A { void a(); }
public interface B { void b(); }
public interface C { void c(); }
public interface D { void d(); }

public class IAmManyTypes implements A, B, C, D {
  public void a() {}
  public void b() {}
  public void c() {}
  public void d() {}
}
```

Title: How can a object have many types?


问:
Is using this complex data structure bad practice?
Right now in my current company I must "parse" a csv and extract some data out of it (in the sense of data mining).

I surprised myself by defining the following data structure (Java 8):

```<code>static List<Map<String, Map<String, LocalDate[]>>> intervalStructure
</code>```

Is this considered bad practice? Should I use a self-define class instead to store some data?

答:
I'm going to respectfully disagree with Michael here, and some rather smart programmers, like Rich Hickey, tend to think along the same lines as me.  The key here is that you take care not to pass this data structure all over the place, but you use it as a base layer from which you build the sort of abstractions that Michael talks about in his answer.

These sorts of data structures get a bad rap.  They are extremely easy to manipulate, with highly reusable tools.  Without knowing anything about your application other than that one line of code defining a data structure, I could write an interface to convert it to JSON, HOCON, or XML.  I could store it in a database.  I don't have to write any custom serialization/deserialization code, which lets me reuse generic libraries.  I can easily write queries and filters to give me nice strongly-typed class-based layers above this one.  When my CSV file format changes, I have this much more flexible and dynamic layer of isolation between it and my more rigid and static classes above it.

In summary, don't make it your sole data structure, but using it as an intermediate data structure can solve a lot of maintainability problems.


问:
Concept to differentiate between html tags and angle brackets
I have an issue with a client's requirement that wants to import a string of html text within a csv document.

For example, a sanitized version of one import line:

```<code>"IDNumber,TextIdentifierNumber,<p><strong>Hello, this text is **>** this text. 32 < 64</strong></p>"
</code>```

The issue here is not importing this text, but angle brackets. These are apart of their every day business practice and are needed to indicate a less or greater denomination.

Background:
At this time our client is using a .NET web application and a batch load application (console), both written in Visual Basic .NET 4.0. Our web application uses a WYSIWYG editor for entering such text and we handle such angle brackets by their named entities and encoding.

Our issue is discerning an angle bracket among an HTML rich input string.

What we have done to date:

We employ the use of HTMLAgilityPack to strictly parse through HTML and weed out HTML tags we don't allow. Unfortunately, HTMLAgilityPack strips out this angle bracket and any text that could follow a potential closing tag. This buggers up HTML string badly and causes issues in our reports.

We have kicked around a few options, such as text replacement (sending in [LESSTHAN]) by our customer and then our code converts it to proper angle bracket direction. Unfortunately, this most definitely will not work due to their source data coming from another system.

答:
Well, your client does not want to import html text. He may think that he wants to import html, but it's not what he actually wants. html text cannot contain the letters " ' & < >, for good reason. So the text that you showed is just not html.

Since html tools will not be able to handle this, I'd have a manual pass first where you look at < and > symbols, decide which ones are part of tags, and replace all others with < or >.


问:
Help with complex MVVM (multiple views)
I need help creating view models for the following scenario:

Deep, hierarchical data

Multiple views for the same set of data

Each view is a single, dynamically-changing view, based on the active selection

Depending on the value of a property, display different types of tabs in a tab control

My questions:

Should I create a view-model representation for each view (VM1, VM2, etc)?

```<code>1. Yes:
    a. Should I model the entire hierarchical relationship? (ie, SubVM1, HouseVM1, RoomVM1)
    b. How do I keep all hierarchies in sync? (e.g, adding/removing nodes)

2. No:
    a. Do I use a huge, single view model that caters for all views?
</code>```

Here's an example of a single view

Figure 1: Multiple views updated based on active room. Notice Tab control

Figure 2: Different active room. Multiple views updated. Tab control items changed based on object's property.

Figure 3: Different selection type. Entire view changes

答:
To answer the question, Yes, each view should have its own View Model.
But there is no need to model the entire hierarchy. Only what the view needs.

The problem I had with most online resources regarding MVVM:

In most examples, the View is almost 1-to-1 mapping of the Model.
But in my scenario, where there are different views for different facets of the same Model, I find myself stuck between two choices:

One monolithic view model that is used by all other view models

Or one view model for each view

But both are not ideal.

The Model-oriented View Model (MVM), while low in code duplication, is a nightmare to maintain

The View-oriented View Model (VVM) produces highly-specialised classes for each view, but contains duplicates.

In the end, I decided that having one VM per View is easier to maintain and code for, so I went with the VVM approach.

Once the code is working, I began refactoring all common properties and operations into its current, final form:

In this final form, the common view model class is composed into each VVM.

Of course, I still have to decide what is considered common/specialised. And when a view is added/merged/deleted, this balance changes.

But the nice thing about this is, I am now able to push up/down members from common to VVM and vice versa easily.

And a quick note regarding keeping the objects in-sync:

Having a Common View Model takes care of most of this. Each VVM can simply have a reference to the same Common View Model.

I also tend to start with simple callback methods, and evolving to event/observer if the need for multiple listeners arise.

And for really complex events (ie, unexpected cascading updates), I would switch over to using a Mediator.

I do not shy away from code where a child has a back reference to its parent. Anything to get the code working.

And if the opportunity to refactor arise, I would take it.

The lessons I learnt:

Ugly/Working code > Beautiful/Non-working code

It is easier to merge multiple small classes, than it is to break up a huge class

Title: Help with complex MVVM (multiple views)


问:
Do and Undo action in the same / different page - Is there a difference?
If I'm bulding an application like a social network and I implement a like / favorite button with AJAX, is it preferable to use one URL to like / dislike or 2 differents URL?

If I use one, for example like.php, in that url I'd check if the post ID was already liked or not, and then do the opposite action.

If I use two, for example like.php and dislike.php, in those urls I'd check if the post ID was already liked or not liked, and then return an error if the action was already done.

I'd say the first option is easier, because it requires less backend/frontend code, but many big websites use the second method. Is there a reason behind that?

答:
With your first scheme, your endpoint is not idempotent (i.e. if you execute it twice it doesn't do the same thing as executing it once).  With the latter scheme, you can easily implement it to be idempotent (and potentially use a PUT method).  In this case, if the "user" likes something they've liked before, it should just succeed and do nothing.  This allows requests to be replayed in the face of intermittent network connections.

There's also a mild maintenance benefit by splitting them up, arguably.  Each endpoint does one thing and one thing only with no conditional logic.  (The fault-tolerance and benefits with respect to concurrency are far more significant though.)


问:
Keeping git repositories on different hosts in sync
I am thinking about starting a small project and I want to make its versioning with git.

Bitbucket seems a good option for me with their free plan. I want to use it as the main tool for working with git since they have nice tools  like a web-interface, Mac OS client, and so on. But, in order to have higher protection from any accidental damages that can be caused by using a third-party service, I want also to install git on my NAS as a second back-up copy of the repository.

Now my question is, whether it is possible to create a repository on two different hosts and then keep them in sync? For example, suppose once per week I update the repository on my NAS to match the one on Bitbucket.  Then, in case something happens with Bitbucket, I will still have the full repository with full history of development on my local NAS storage.

And is there a way to import an existing repository with full history to another git-service?

I think that mirroring is what I need.
This article seems to describe exactly what I need.
And this one as well.

I believe that it will make full copy with full history and even automatically commit new versions to the repositories on both hosts automatically.

Am I right?

答:
I use a private GitLab to store all my repositories, so I only have one origin I push and pull from while I'm doing day to day development.

But, for open source projects, GitHub is a much more vibrant community, so, if I want to accept community contributions to my projects, I use web GitLab's web hook system to ping a server I run which then updates my public repos on GitHub.

This allows me to treat GitHub as another remote I can pull from when someone contributes--then I merge --no-ff locally, and there's a flow to how all my primary and public repositories distribute the changes.

ContentLicense: CC BY-SA 4.0


答:
Returning an object of built-in type from a function usually carries
  little to no overhead, since the object typically fits in a CPU
  register.

The point of this comment from wikipedia isn't that returning the value has no cost. Overhead is additional cost, and the here the cost is in addition to that of the return value mechanism. The article is contrasting additional work required for objects to have be copied when they are returned.

Thus MY QUESTION for this very particular pattern (i.e return this
  with method chaining) -- can it be optimized with no overhead? How?

In general, no. In particular cases (such as where the function can be inlined) it can be.


问:
Does unused code affects the assembly after startup (Memory for example)?
Disclaimer: I come from a PHP background.

In PHP, I could have thousands files, which are never loaded, if not needed, due to the autoloader feature (If some code is needed, it would be loaded)

How do .NET's assemblies work? Do they load all the program code into the memory on application startup?

For example, I can have some areas with multiple Controllers:

Area 1

Controller 1

Area 2

Controller 1

...

Controller 42

If Area 2 is optional by configuration, would it be a better Idea to extract this Area into a seperate Assembly and load it if needed?

答:
Do they load all the program code into the memory on application startup?

NO

You can have as many Assemblies in your project as you need. Assemblies are referenced via the using keyword. Unused assemblies are filtered out at the build time itself. For example, you can have two referenced asssemblies as:

```<code>using System.Windows.Forms;
using System.Web.UI.WebControls;
</code>```

If you haven't used assembly System.Windows.Forms, it will not affect the performance of your code but it may affect compile time and Intellisense performance.

See this StackOverflow question for unused usings.

Referenced assemblies are not immediately loaded - they are loaded on the fly as needed. So regardless of whether you have an assembly reference in a top level project, or a dependent assembly of assemblies, assemblies are typically load on an as needed basis, unless explicitly loaded by user code. The same is true of dependent assemblies.
See When does a .NET Assembly Dependency get loaded for more info.

[EDIT]

The classes in any assembly are loaded only when they are used. Not all the classes will be loaded at once in the memory. Even static classes are loaded in the main memory when they are first referenced. So having bulk of unused classes in your assembly will not degrade the performance but will increase the hard disk space required(not memory requirements).

So the simple answer is NO.

Body:
Do they load all the program code into the memory on application startup?

NO

You can have as many Assemblies in your project as you need. Assemblies are referenced via the using keyword. Unused assemblies are filtered out at the build time itself. For example, you can have two referenced asssemblies as:

using System.Windows.Forms;
using System.Web.UI.WebControls;

If you haven't used assembly System.Windows.Forms, it will not affect the performance of your code but it may affect compile time and Intellisense performance.

See this StackOverflow question for unused usings.

Referenced assemblies are not immediately loaded - they are loaded on the fly as needed. So regardless of whether you have an assembly reference in a top level project, or a dependent assembly of assemblies, assemblies are typically load on an as needed basis, unless explicitly loaded by user code. The same is true of dependent assemblies.
See When does a .NET Assembly Dependency get loaded for more info.

[EDIT]

The classes in any assembly are loaded only when they are used. Not all the classes will be loaded at once in the memory. Even static classes are loaded in the main memory when they are first referenced. So having bulk of unused classes in your assembly will not degrade the performance but will increase the hard disk space required(not memory requirements).

So the simple answer is NO.


答:
In theory, yes.  C++ has a term for it: copy elision.  The C++ standard allows for copy elision.  The concept you are asking about, in fact, has its own tla: RVO (return-value optimization).

Essentially, the compiler can (but, unfortunately, is not required to) decide on the space where the return value will reside before the function is called.  This avoids pushing the return value on the stack and then copying it to this space.  The compiler can generate the function code in such a way that instead of changing the value to be pushed on the stack it gets written directly to the space where that stack value will get copied after the function returns.

The reason why this cannot be done always (ie, by default) is that the space where the value is to be copied may contain information which is used during the execution of the function.  But there are well-known methods to get around that, too.  For example, copy-on-write is what operating systems do to blocks of memory shared by multiple processes.  Compilers can, in the same way, do copy-on-write of space which is to be populated at the return of a function.


答:
can it be optimized with no overhead? How?

As Telastyn wrote, one approach is to have a compiler providing two function versions. If I were in the role of a compiler designer, I would handle it this way:

I would build a compiler with inlining support. Such a tool can obviously optimize the return this statement out when it is not used.

and if this hypothetical compiler decides not to inline a specific function, optimizing out the machine code equivalent of return this is definitely not worth it (if it would be, the compiler would inline).

So this does not lead to "zero overhead" in a pure mathematical sense, but to "zero overhead" for any practical purpose.


问:
Building a real-time web-app with Ajax .post()
Usually, real-time web-apps are built with websockets, right?

Well, let me be radical here - what if I used Ajax?

Okay, okay, I know it has its limitations. You can't build Agar.io, sending data packets up to fifty times a second, with latency in the milliseconds.

But what about an app that had real-time updates that were a bit less frequent. Maybe receiving notifications with in a few seconds, or a turn-based game?

Is it acceptable to use Ajax.post() every, say, few seconds to receive updates from a, say, PHP script, getting information from an SQL database? As opposed to either RTS games, or the Stackexchange model, where information is loaded when the page is loaded, instead of while the page is open.

So would there be any issues with using this model? Would it lag the client's computer or have some problem related?

答:
In general, the overhead involved with AJAX requests is higher.  If an Ajax request has, say, 1K of transport overhead, then sending 50 bytes over a single request means that your transfer of actual data is only about 5% efficient.

Ajax requests are typically made to RESTful resources.  Socket communication is a persistent connection, and seems more suited for real-time, dashboard-style updates.

Stack Exchange uses a custom socket library to send updates to its pages in real-time, including edit notifications, comment additions and changes to voting tallys.


问:
How far do I, or can I take TDD tests with Service Objects?
In writing PHPSPEC tests for a Zend Framework 2 application, I'm left wondering how far to 'dig'.  Consider this very simple case:

A DomainService (Domain in the URL sense of the word) should be able to list all Foo objects, works.

Making heads/tails of the test is not simple.  This DomainService is fed via DI with a DomainMapper.  This DomainMapper is a Doctrine Mapper that transforms MySQL rows into Doctrine Entities.  In theory, would I not want to cover that my code can:

instantiate the DomainService (but this is done through ZF2 Factories -- I'm completely bypassing the Factory process in using phpspec's let).  Does this tailspin into a separate test for the Factory, that needs a functional service locator object?

test that it can find all Foo objects, but this means invoking Doctrine and running an SQL query.  The test shouldn't be database dependent I assume, we wouldn't want external data to modify the test.  But what then should I test, that it successfully returns an empty array?  Semantic query errors could create empty array conditions that are failures.  Do we simply accept that tests don't cover this?

Where do you draw the line?  Testing DI'ed services that interact with databases can't automatically be off-limits?

答:
One of the primary strengths of DI is that you can inject completely different versions of the dependent services based on your environment.

More specifically, in your unit test environment, you can inject a DomainMapper implementation that just returns canned data and does not access the database in any way. You can even vary the DomainMapper instance for every test case, so that in one test the mapper returns an error, in a second test it returns an empty list and in a third it returns a very large list.

What you want to cover in the unit tests of DomainService is

that the DomainService fulfils its requirements, if the DomainMapper returns lists of Foo objects with various lengths.

that the DomainService does not break completely, if the DomainMapper reports an error, or fulfils the requirements for handling such errors.

Being able to instantiate a DomainService object is usually not a separate test goal, but it is implicitly tested with the other tests.

Being able to obtain an instance through a ZF2 Factory would be a test for that factory or possibly an integration test.


问:
What's the point of running unit tests on a CI server?
Why would you run unit tests on a CI server?

Surely, by the time something gets committed to master, a developer has already run all the unit tests before and fixed any errors that might've occurred with their new code. Isn't that the point of unit tests? Otherwise they've just committed broken code.

答:
It is possible to imagine cases when the change A does not break the test, and change B does not break the test, but A and B together do. If A and B are made by different developers, only CI server will detect the new bug. A and B may even be two parts of the same longer sentence.

Imagine a train driven by the two locomotives A and B. Maybe one is more than enough and this is the fix to apply. However if the two "fixes" are applied removing both, the train will not move.

Also, not all developers run all Unit tests, while most good developers do.