问:
CI - How long is continous?
We currently are using CCNet as our continous integration server.  Most projects check for changes every 30 seconds (the default) and if needed perform a build (unit tests, stylecop, fxcop, etc).

We've gotten quite a few projects now, and the server spends most of its time near 100% cpu utilization.  This has alarmed some of the development team, even though the server is responsive and builds are still about the same length of time they've always been.

Its been suggested that we lower the check interval to about five minutes.  To me that seems too long, and we risk people committing code and then going home for the weekend and now there's a broken build possibly holding up others.  In response, the suggestion is that if someone needs to know the results they can force the build.  But that seems to defeat the purpose of CI, as I thought it was supposed to be automated.

My proposed solution is just to get another build server and split the builds amongst the servers.

Am I thinking about this the wrong way, or is there a point where if integration isn't often enough you're not really doing CI anymore?

答:
You should not be checking for changes - let the source control system 'push' checkin notifications to the build system instead (you may need to get a new SCM or build system, I seriously recommend Jenkins)

So, obviously this would stop a lot of problems on the server.

The next problem is how much checking in goes on? If people are committing every 5 minutes, it isn't going to help much. Then the last question is - how long do these builds take? If you're spending 20 minutes building a checked-in component and running tests  and analysis and creating installer packages, and it depends on others, are those built automatically too, even though they haven't changed?

Monitor the build system to see what it is doing. I've found that it is easy to set up a build server that does far too much building that is necessary. That woudl be the first step I'd take.

Title: CI - How long is continous?


答:
The CPU is supposed to be near 100% utilization.  Otherwise you're just wasting CPU.  Same with memory.

Continuous means as frequently as you can manage.  If your server is maxed out, then crank out the builds as fast as it will go.  It might sometimes get busy enough to drag your response time down, but if you lower the check interval, your response time will always be dragged down.  It makes no sense to try to "conserve" idle time on your server.  If your actual response time frequently drops to unacceptable levels, then you add additional servers.

ContentLicense: CC BY-SA 3.0

Title: CI - How long is continous?

Body:
We currently are using CCNet as our continous integration server.  Most projects check for changes every 30 seconds (the default) and if needed perform a build (unit tests, stylecop, fxcop, etc).

We've gotten quite a few projects now, and the server spends most of its time near 100% cpu utilization.  This has alarmed some of the development team, even though the server is responsive and builds are still about the same length of time they've always been.

Its been suggested that we lower the check interval to about five minutes.  To me that seems too long, and we risk people committing code and then going home for the weekend and now there's a broken build possibly holding up others.  In response, the suggestion is that if someone needs to know the results they can force the build.  But that seems to defeat the purpose of CI, as I thought it was supposed to be automated.

My proposed solution is just to get another build server and split the builds amongst the servers.

Am I thinking about this the wrong way, or is there a point where if integration isn't often enough you're not really doing CI anymore?


问:
Estimation Techniques for Linux Kernel Development
I am working in Linux Kernel area and my work includes:
code study / Understanding
Porting (say from one kernel version to another kernel version)
Implementation of new kernel module / Device driver

How to do estimation in such Linux Kernel assignments? Is there any technique? How the community is doing?

答:
There's no difference in the estimation techniques based on project types. Steve McConnell wrote a good book, Software Estimation: Demystifying the Black Art, that discusses not only estimation in general, but highlights estimation techniques and when each technique is most valuable.

If this is a project that you are working on as an individual, using your own historical data on how long it takes you to understand new code of a particular size in a given language or relating a current task to a different task that you know how long it would take using analogies or proxies would probably be the most effective. If it's a complicated task, decomposing it into smaller tasks and estimating those would be most appropriate.

Unfortunately, the best people to estimate are the people who will be doing the work. Aside from explaining different estimation techniques and their pros/cons, there's not much that anyone else can say. DeveloperDon's answer is based on a course and expected workload for a student, but I can say that different people have to put different amounts of time and effort - only you can determine what good analogies, proxies, or estimates would be based on what you know about yourself.


答:
In my team, our CI configuration enables us to trigger a job each time changes are detected in the SCM; this is what continuous means to us.

If you have the resources, consider implementing a distributed CI system to offload the workload to multiple servers and keep resource usage to a minimum on the master.

We have multiple jobs for doing specific things. Subsequently, we do not need to trigger all of the jobs, per se. Depending on where the changes were made, we may trigger one or more jobs as needed.

Because the jobs are focused on a specific task and specialized, they generally complete execution in a reasonable time.

As already noted, the best practice solution is to configure svn with a post-commit hook so it will notify hudson when changes have been committed. This reduce stress on the SCM and will still facilitate CI.

Title: CI - How long is continous?


答:
The first thing that seems odd is that you're polling for changes, rather than receiving change notifications. I've never used CruiseControl .NET, but the other continuous integration tools that I've used supported receiving a notification or trigger when the integration branch was updated. This seems more efficient, since you won't be wasting cycles checking for updates that don't exist (I would suspect this would reduce power consumption). If, after this, your build/test cycle in your CI environment is too slow or queues of work are building up, then I'd consider moving to a multiple server environment.

The next thing I would recommend is ensuring some level of confidence that what your CI tools build will always build. Depending on the size and complexity of the system, it might not make sense to build and then run every test in the development environment. However, prior to merging, the developer should at least build the system to ensure that the tests can be run. It might also be a good idea to have smoke tests that hit key areas of the system, but that can be run quickly in a development environment - if they don't pass, the developer doesn't merge changes. Having a more extensive level of unit testing over only changed components is also an option. Just leave the extensive testing to continuous integration, while maintaining sufficient confidence that you'll be left with a good build after the merge.

To me, the idea that one person not being in the office is a problem is also part of the problem. This problem would be partially reduced by what I described above - developer build and test cycles to decrease problems discovered in continuous integration. However, making sure that more than one person can fix issues discovered in parts of the system are also better. Consider code reviews, pair programming, or having people work in different subsystems to spread knowledge around.

I think that very rarely is "throw more technology at the problem" an appropriate solution. Look at how you are using the technology first, along with the goals you want to achieve. It'll probably end up being most cost-effective in the long run.

Title: CI - How long is continous?


问:
How can I get better at explaining complex software processes to developers?
I'm really struggling with my software specs.  I am not a professional programmer but enjoy doing it for fun and made some software that I want to sell later but I'm not happy with the code quality.  So I wanted to hire a real developer to rewrite my software in a more professional way so it will be maintainable by other developers in the future.

I read and found some sample specs and made my own by applying their structure to my document and wanted to get my developer friend to read it and give me advice.  After an hour and a half he understood exactly what I was trying to do and how I did it(my algorithms,stack,etc.).

How can I get better at explaining things to developers?  I add many details and explanations for everything(including working code) but I'm unsure the best way I can learn to pass detailed domain knowledge(my software applies big data, machine learning, graph theory to finance).  My end goal is to get them to understand as much as possible from the document and then ask anything they do not understand, but right now it seems they need to extract alot of information from me.  How can I get better at communicating domain knowledge to developers?

答:
I would suggest learning more about the upstream activities in software development, especially requirements engineering and system architecture. These two activities are the direct interface from the customer and user needs and environment to the person or people who are building software. These activities are not only directly derived from the inputs from the user and customer, but they also provide the inputs into system-level and acceptance testing.

When I was taught about requirements engineering and high level design, I was always taught to involve the right stakeholders from the sponsoring organization - the customer, the user, the people who will be maintaining the system, and so on. These people shouldn't just be involved in making decisions, but also understanding how the system is going to be built and what will be needed from them throughout the project. Taking the initiative and learning these areas on your own would help with interfacing with people who will be building the software.

If you want specific resources, Karl Wiegers has two books on requirements engineering - Software Requirements and More About Software Requirements. I can also recommend two books on how software architectures and designs are created - Software Systems Architecture: Working With Stakeholders Using Viewpoints and Perspectives and Software Architecture in Practice.


问:
What does using (vec col) or (vector arg1 & args) cost?
I am working through some Lisp exercises using Clojure. If I were to convert Lisp lists to Clojure vectors, solving some of the problems would be simpler, so here is my question:

Does using vec or vector cost a lot in terms of time and/or processing? Does using either function cause a meta state change, or are the values converted and moved to a vector?

答:
Both functions return a new vector for you.

vec expect a coll parameter that will be converted to a vector

vector expect args to create a new vector.

Bellow the excecution time for each one:

vec

```<code>user=> (time (vec '(1 2 4)))
;= "Elapsed time: 0.043 msecs"
;= [1 2 4]
</code>```

vector

```<code>user=> (time (vector 1 2 3)))
;= "Elapsed time: 0.025 msecs"
;= [1 2 3]
</code>```

Body:
Both functions return a new vector for you.

vec expect a coll parameter that will be converted to a vector

vector expect args to create a new vector.

Bellow the excecution time for each one:

vec

user=> (time (vec '(1 2 4)))
;= "Elapsed time: 0.043 msecs"
;= [1 2 4]

vector

user=> (time (vector 1 2 3)))
;= "Elapsed time: 0.025 msecs"
;= [1 2 3]


问:
General solution to solve different sports results in different languages
I currently have some code that checks if squash and tennis scores are valid, both in javascript and PHP.

This results in 4 blocks of code existing, 2 languages * 2 sports, which does not scale well should any extra sports come around, or extra languages...

How can one describe the valid scores of games via a settings/text file, so that each language can parse them and apply these rules.

I'm stumped with the strange tie break situations in tennis should it reach 6-6 in a set, and also infinite play off in the final set should it reach 2 sets all.

ie:

```<code>tennis = {
    "format": [
        {
            "name": "sets",
            "min": 3,
            "max": 5,
            "winby": 1
        },
        {
            "name": "games",
            "min": 6,
            "max": 7,
            "winby": 2
        }
    ]
}

squash = {
    "format": [
        {
            "name": "games",
            "min": 3,
            "max": 5,
            "winby": 1
        },
        {
            "name": "points",
            "min": 15,
            "max": 0,
            "winby": 2
        }
    ]
}
</code>```

答:
This is certainly not an easy task; what you need to is fold behavior into data structures, that is, you need a generic score check algorithm that covers all the games you need, and has configurable rules (which it takes as parameters, in a format digestible by either of the target programming languages).

The first step, obviously, is to come up with a generic data structure that can accurately represent the scores. For example, for soccer, hockey, basketball, etc., a simple pair of integers will do; but other sports, such as tennis, require more complex data structures - e.g., a list of pairs of integers. So for example a soccer result could be, in pseudocode, [(1, 3)] (a list with one pair, representing the result "1:3"); a tennis result could be [(6,1), (6,2), (7,6)] (I'm not exactly sure about tennis rules though). And obviously, if you want to model scores within sets, you have to extend your data structures accordingly. (A note on tennis scores within games: while the counting is nonlinear, there is a very small number of valid scores, and they can easily be mapped to a linear integer space - [ "love", "15", "30", "40", "game" ] can be handled internally as [ 0, 1, 2, 3, 4 ], and then mapped back to the idiomatic value for display.)

Then you need to implement generic constraints on these scores; some will work on individual pairs, others will consider the result as a whole. For example, one such constraint might be "minimum number of result pairs", and its parameter would be 1 for soccer, 3 for tennis. Another might be "scores within one pair must not be equal", and it would be applied to tennis and knock-out style soccer matches, but not pooled or league-style soccer matches (where a draw is possible). Make enough rules to cover all the constraints.

A configuration file might then look something like this:

```<code>[
    {
        "sportName" : "soccer",
        "rules" : [
            { "ruleType": "numberOfSets", "number" : 1 },
            { "ruleType": "minScoreValue", "value" : 0 }
        ]
    },
    {
        "sportName" : "soccer-knockout",
        "rules" : [
            { "ruleType": "numberOfSets", "number" : 1 },
            { "ruleType": "minScoreValue", "value" : 0 },
            { "ruleType": "noDrawsWithinSet" }
        ]
    },
    {
        "sportName" : "tennis",
        "rules" : [
            { "ruleType": "minNumberOfSets", "number" : 3 },
            { "ruleType": "maxNumberOfSets", "number" : 5 },
            { "ruleType": "minWinningSetScore", "value" : 6 },
            { "ruleType": "maxWinningSetScore", "value" : 7 },
            { "ruleType": "noDrawsWithinSet" }
        ]
    }
]
</code>```

The last part you need is glue to put it together: a rules engine that loads rules from a file, instantiates the appropriate checkers, and applies them to the specified scores. This last part is simply a matter of iterating over the applicable rules (recursively if you have nested scores such as for tennis) until you find one that doesn't match.

As you add more games to your system, you'll have to add more constraint types, but if you keep them generic and parametrizable, the chances of existing rules already covering a new game grow as you go.

In fact, you are implementing a DSL (domain-specific language) to describe game scores and rules.

Body:
This is certainly not an easy task; what you need to is fold behavior into data structures, that is, you need a generic score check algorithm that covers all the games you need, and has configurable rules (which it takes as parameters, in a format digestible by either of the target programming languages).

The first step, obviously, is to come up with a generic data structure that can accurately represent the scores. For example, for soccer, hockey, basketball, etc., a simple pair of integers will do; but other sports, such as tennis, require more complex data structures - e.g., a list of pairs of integers. So for example a soccer result could be, in pseudocode, [(1, 3)] (a list with one pair, representing the result "1:3"); a tennis result could be [(6,1), (6,2), (7,6)] (I'm not exactly sure about tennis rules though). And obviously, if you want to model scores within sets, you have to extend your data structures accordingly. (A note on tennis scores within games: while the counting is nonlinear, there is a very small number of valid scores, and they can easily be mapped to a linear integer space - [ "love", "15", "30", "40", "game" ] can be handled internally as [ 0, 1, 2, 3, 4 ], and then mapped back to the idiomatic value for display.)

Then you need to implement generic constraints on these scores; some will work on individual pairs, others will consider the result as a whole. For example, one such constraint might be "minimum number of result pairs", and its parameter would be 1 for soccer, 3 for tennis. Another might be "scores within one pair must not be equal", and it would be applied to tennis and knock-out style soccer matches, but not pooled or league-style soccer matches (where a draw is possible). Make enough rules to cover all the constraints.

A configuration file might then look something like this:

[
    {
        "sportName" : "soccer",
        "rules" : [
            { "ruleType": "numberOfSets", "number" : 1 },
            { "ruleType": "minScoreValue", "value" : 0 }
        ]
    },
    {
        "sportName" : "soccer-knockout",
        "rules" : [
            { "ruleType": "numberOfSets", "number" : 1 },
            { "ruleType": "minScoreValue", "value" : 0 },
            { "ruleType": "noDrawsWithinSet" }
        ]
    },
    {
        "sportName" : "tennis",
        "rules" : [
            { "ruleType": "minNumberOfSets", "number" : 3 },
            { "ruleType": "maxNumberOfSets", "number" : 5 },
            { "ruleType": "minWinningSetScore", "value" : 6 },
            { "ruleType": "maxWinningSetScore", "value" : 7 },
            { "ruleType": "noDrawsWithinSet" }
        ]
    }
]

The last part you need is glue to put it together: a rules engine that loads rules from a file, instantiates the appropriate checkers, and applies them to the specified scores. This last part is simply a matter of iterating over the applicable rules (recursively if you have nested scores such as for tennis) until you find one that doesn't match.

As you add more games to your system, you'll have to add more constraint types, but if you keep them generic and parametrizable, the chances of existing rules already covering a new game grow as you go.

In fact, you are implementing a DSL (domain-specific language) to describe game scores and rules.


问:
Unit testing internal components
To what extent do you unit test internal/private components of a class/module/package/etc? Do you test them at all or do you just test the interface to the outside world? An example of these internal is private methods.

As an example, imagine a recursive descent parser, which has several internal procedures (functions/methods) called from one central procedure. The only interface to the outside world is the central procedure, which takes a string and returns the parsed information. The other procedures parse different parts of the string, and they are called either from the central procedure or other procedures.

Naturally, you should test the external interface by calling it with sample strings and comparing it with hand-parsed output. But what about the other procedures? Would you test them individually to check that they parse their substrings correctly?

I can think of a few arguments:

Pros:

More testing is always better, and this can help increase code coverage

Some internal components might be hard to give specific inputs (edge cases for example) by giving input to the external interface

Clearer testing. If an internal component has a (fixed) bug, a test case for that component makes it clear that the bug was in that specific component

Cons:

Refactoring becomes too painful and time-consuming. To change anything, you need to rewrite the unit tests, even if the users of the external interface are not affected

Some languages and testing frameworks don't allow it

What are your opinions?

答:
Case: a "module" (in a broad sence, i.e. something having a public interface and possibly also some private inner parts) has some complicated / involved logic inside it. Testing just the module interface will be sort of an integration testing with relation to the module's inner structure, and thus in case a error is found such testing will not localize the exact inner part / component that is responsible for the failure.

Solution: turn the complicated inner parts into modules themselves, unit-test them (and repeat these steps for them if they are too complicated themselves) and import into your original module. Now you have just a set of modules simple enough to uniit-test (both check that behavior is correct and fix errors) easily, and that's all.

Note:

there will be no need to change anything in tests of the module's (former) "sub-modules" when changing the module's contract, unless the "sub-module"'s no more offer services sufficient to fulfil the new/changed contract.

nothing will be needlessly made public i.e. the module's contract will be kept and the encapsulation maintained.

[Update]

To test some smart internal logic in cases when it is difficult to put object's inner parts (I mean members not the privately imported modules / packages) into appropriate state with just feeding it inputs via the object's public interface:

just have some testing code with friend (in C++ terms) or package (Java) access to the innards actually setting the state from inside and testing the behavior as you'd like.

this will not break the encapsulation again while providing easy direct access to the internals for testing purposes -- just run the tests as a "black box" and compile them out in release builds.

ContentLicense: CC BY-SA 2.5

Title: Unit testing internal components


问:
Recent programming language for AI?
For a few decades the programming language of choice for AI was either Prolog or LISP, and a few more others that are not so well known. Most of them were designed before the 70's.

Changes happens a lot on many other domains specific languages, but in the AI domain it hadn't surfaced so much as in the web specific languages or scripting etc.

Are there recent programming languages that were intended to change the game in the AI and learn from the insufficiencies of former languages?

答:
While most of these answers focus on the word "language" because you used it in your question, I don't believe you should think a specific language when thinking AI.

I have been working with this technology for years and I am currently working with Proof Assistants and converting some code from OCaml to F#. It is not the language that achieves the AI but specific algorithms implemented in the language. For PROLOG this is an inference engine based on unification. Now if you start with unification and look at how it has been customized and advanced over the years I think you will find the progression of advancement you seek. Don't focus on the language, focus on the algorithms.

As an example, type inference in functional languages use Hindley–Milner which is based on unification.

Another example specific to the proof assistant is here, notice prolog.ml. The inference engine for prolog is implemented in OCaml and being translated into to F#. So while OCaml and F# are not noted normally as AI languages, they are fully capable of implementing the AI algorithms.

Title: Recent programming language for AI?


问:
What should and what shouldn't be in a header file?

What things should absolutely always/never be included in a header file?

Functions: what must go in the header file and what mustn't

Constants: Is it good practice to define lot of constants in a header file?

Any other good practices for C header files?

Example

I'm writing a parser for a documented industry standard format that has a lots of constants, is it a good practice to define them in a header file?

答:
What to put in headers:

The minimal set of #include directives that are needed to make the header compilable when the header is included in some source file.

Preprocessor symbol definitions of things that need to be shared and that can only accomplished via the preprocessor. Even in C, preprocessor symbols are best kept to a minimum.

Forward declarations of structures that are needed to make the structure definitions, function prototypes, and global variable declarations in the body of the header compilable.

Definitions of data structures and enumerations that are shared amongst multiple source files.

Declarations for functions and variables whose definitions will be visible to the linker.

Inline function definitions, but take care here.

What doesn't belong in a header:

Gratuitous #include directives. Those gratuitous includes cause recompilation of things that don't need to be recompiled, and can at times make it so a system can't compile. Don't #include a file in a header if the header itself doesn't need that other header file.

Preprocessor symbols whose intent could be accomplished by some mechanism, any mechanism, other than the preprocessor.

Lots and lots of structure definitions. Split those up into separate headers.

Inline definitions of functions that require an additional #include, that are subject to change, or that are too big. Those inline functions should have little if any fan out, and if they do have fan out, it should be localized to stuff defined in the header.

What constitutes the minimal set of #include statements?

This turns out to be a nontrivial question. A TL;DR definition: A header file must include the header files that directly define each of the types directly used in or that directly declare each of the functions used in the header file in question, but must not include anything else. A pointer or C++ reference type does not qualify as direct use; forward references are preferred.

There is a place for a gratuitous #include directive, and this is in an automated test. For every header file in a software package, I automatically generate and then compile the following:

```<code>#include "path/to/random/header_under_test"
int main () { return 0; }
</code>```

The compilation should be clean (i.e., free of any warnings or errors). Warnings or errors regarding incomplete types or unknown types mean that the header file under test has some missing #include directives and/or missing forward declarations. Note well: Just because the test passes does not mean that the set of #include directives is sufficient, let alone minimal.

Related

Naming Include Guards

ContentLicense: CC BY-SA 4.0

Body:
What to put in headers:

The minimal set of #include directives that are needed to make the header compilable when the header is included in some source file.

Preprocessor symbol definitions of things that need to be shared and that can only accomplished via the preprocessor. Even in C, preprocessor symbols are best kept to a minimum.

Forward declarations of structures that are needed to make the structure definitions, function prototypes, and global variable declarations in the body of the header compilable.

Definitions of data structures and enumerations that are shared amongst multiple source files.

Declarations for functions and variables whose definitions will be visible to the linker.

Inline function definitions, but take care here.

What doesn't belong in a header:

Gratuitous #include directives. Those gratuitous includes cause recompilation of things that don't need to be recompiled, and can at times make it so a system can't compile. Don't #include a file in a header if the header itself doesn't need that other header file.

Preprocessor symbols whose intent could be accomplished by some mechanism, any mechanism, other than the preprocessor.

Lots and lots of structure definitions. Split those up into separate headers.

Inline definitions of functions that require an additional #include, that are subject to change, or that are too big. Those inline functions should have little if any fan out, and if they do have fan out, it should be localized to stuff defined in the header.

What constitutes the minimal set of #include statements?

This turns out to be a nontrivial question. A TL;DR definition: A header file must include the header files that directly define each of the types directly used in or that directly declare each of the functions used in the header file in question, but must not include anything else. A pointer or C++ reference type does not qualify as direct use; forward references are preferred.

There is a place for a gratuitous #include directive, and this is in an automated test. For every header file in a software package, I automatically generate and then compile the following:

#include "path/to/random/header_under_test"
int main () { return 0; }

The compilation should be clean (i.e., free of any warnings or errors). Warnings or errors regarding incomplete types or unknown types mean that the header file under test has some missing #include directives and/or missing forward declarations. Note well: Just because the test passes does not mean that the set of #include directives is sufficient, let alone minimal.

Related

Naming Include Guards


问:
How to stop gold-plating and just be content to release working developments
The development team that I'm a member of has recently adapted to work according to Agile practices. This has personally highlighted the fact that I can't stop myself gold-plating code (and documentation) and I consequently exceed original estimates, when I could've delivered solutions that meet the requirements much earlier.

I think my ethic is bordering on the obsessive in that I become too attached to my code and am rarely content to release before I've refactored and perfected it to the nth degree. I am happy that I have realised this but how can I change my attitude/mentality to be content with my progress and release on-time instead?

答:
First off, I wish more developers had this problem, not because software would end up being released later than expected but because it would likely be a higher-quality release.

If you are exceeding your own original estimates, perhaps you need to include your "gold-plating" steps as part of your estimates. If they are not your own estimates, perhaps you should be involved in formulating them.

In any case, if you have a release deadline you should stick to it. Any "gold-plating" should be left as a final step that shouldn't hold up a release. If you absolutely feel it must be included as part of a release, consider adding the "gold-plating" on your own time (i.e. outside of working hours).

What you should do is bring up your "gold-plating" steps to your team and/or management and discuss why you feel they are important. If you can convince them that these steps are beneficial, they should become part of future releases.


问:
Getting some experience with asp.net
Hi I recently learned asp.net webforms and  looking to get some experience under my belt using it.I found a website that provided some exercises here:

asp.net exercises

There weren't that many and I managed to finish them all.Are there any other website or books with similar exercises or tasks that could help me get some experience in using asp.net?

答:
There are a lot of exercises to find on the internet, take a look at these websites:

Asp.net: Web Forms Getting Started

Free Web Forms Video Training from Pluralsight:

Introduction to ASP.NET

ASP.NET Web Forms Features

Working with Data

Entity Framework

Master Pages

Javascript and Ajax

Security

Using ASP.NET Dynamic Data

Web Deployment

I also recommend to follow some blogs like:

Scott Hanselman

Scott Guthrie

Phil Haack

Stephen Walther

Scott Allen

Rick Strahl

Scott Mitchell

Jon Galloway

Title: Getting some experience with asp.net


问:
"TDD is about design, not verification"; concretely, what does that mean?
I've been wondering about this. What do we exactly mean by design and verification.

Should I just apply TDD to make sure my code is SOLID and not check if it's external behaviour is correct?

Should I use BDD for verifying the behaviour is correct?

Where I get confused also is regarding TDD code Katas, to me they looked like more about verification than design; shouldn't they be called BDD Katas instead of TDD Katas?

I reckon that for example the Uncle Bob bowling Kata leads in the end to a simple and nice internal design but I felt that most of the process was centred more around verification than design. Design seemed to be a side effect of testing the external behaviour incrementally. I didn't feel so much that we were focusing most of our efforts on design but more on verification. While normally we are told the contrary, that in TDD, verification is a side effect, design is the main purpose.

So my question is what should I focus on  exactly, when I do TDD: SOLID, external API usability, or something else?

And how can I do that without being focused on verification?

What do you guys focus your energy on when you are practising TDD?

答:
Verification is about ensuring that a product meets all of the requirements as they were specified. Test Driven Development, by itself, doesn't specify the quality of the tests written, and as such, can't guarantee that a product fully conforms to its specification. When you write your tests first, you tend to focus on producing software that is easily testable - you achieve a high amount of functional code coverage, and have an opportunity to think about what your API should look like by writing your test before you write the backing functionality.

When you are writing your tests, you should also think about verification - map your tests to your requirements, think about other code paths within your functions (achieving a higher statement or decision coverage). But TDD doesn't say anything about these - it just says that you should write your tests first and then write the minimal amount of code to make the tests pass. Without ensuring at least full requirements coverage of your tests and greater path coverage, your tests might not be suitable for verification purposes.


答:
TDD code katas are about learning TDD practices and how they drive design (and learning good design in that way - yes, normally this means learning how to write SOLID code).

This means that TDD is about achieving good design - but having well designed code that is not solving a problem is useless. That's where verification comes in - this can be in many forms, BDD being one of them as one of many automated acceptance testing techniques.

Verification is about ensuring that the code written is solving the correct problem.

So, when doing TDD, focus on the design - make sure it is clean and SOLID.

But don't forget to add unit tests and acceptance tests (and any other tests that are deemed needed).

Title: "TDD is about design, not verification"; concretely, what does that mean?

Body:
I've been wondering about this. What do we exactly mean by design and verification.

Should I just apply TDD to make sure my code is SOLID and not check if it's external behaviour is correct?

Should I use BDD for verifying the behaviour is correct?

Where I get confused also is regarding TDD code Katas, to me they looked like more about verification than design; shouldn't they be called BDD Katas instead of TDD Katas?

I reckon that for example the Uncle Bob bowling Kata leads in the end to a simple and nice internal design but I felt that most of the process was centred more around verification than design. Design seemed to be a side effect of testing the external behaviour incrementally. I didn't feel so much that we were focusing most of our efforts on design but more on verification. While normally we are told the contrary, that in TDD, verification is a side effect, design is the main purpose.

So my question is what should I focus on  exactly, when I do TDD: SOLID, external API usability, or something else?

And how can I do that without being focused on verification?

What do you guys focus your energy on when you are practising TDD?


问:
Steps to maintain a good bug database
Maintaining bug database is an important for every project. I am used to store the followings at bug database

Issue date time

Who is assigned to

Whether it has been solved or not

If solved then, solved date time

Is those enough to maintain a good bug database?

答:
The process of bug tracking is just as important as the data. Try to think about the following as well:

How do Users report the bug?

Who enters the bug into the repository?

Who can confirm the bug exists?

Who can confirm the bug is resolved?

Who informs the end user that the bug is resolved?

Build a RACI Chart so everyone in your team (including end users knows their responsibilities. Combine this with proper data entry techniques and you will see a lot more value with the little extra effort.

Title: Steps to maintain a good bug database


答:
It might be useful to see a picture:

Note that acceptance tests (i.e. verification) sit outside of the usual TDD cycle.  The unit tests insure that your code works, but the acceptance tests insure that the code meets the customer's requirements.

ATDD stands for Acceptance Test-Driven Development.


问:
How can I reformat my condition to make it better?
I have a condition

```<code>if(exists && !isDirectory || !exists)
{}
</code>```

how can I modify it, so that it may be more understandable.

答:
As previously indicated, the condition can be reduced to:

```<code>if (!(exists && isDirectory))
</code>```

However, I'll bet that being a directory implies existence.  If so, we can reduce the condition to:

```<code>if (!isDirectory)
</code>```

Body:
As previously indicated, the condition can be reduced to:

if (!(exists && isDirectory))

However, I'll bet that being a directory implies existence.  If so, we can reduce the condition to:

if (!isDirectory)


问:
Acceptable memory usage as a function of input size
I know that if a computation takes linear or linearithmic time based on the size of the input, that's good, and if it takes quadratic time, then that's not so good. </p>

<p>However, what about memory usage?  Suppose a program takes a file as input and does something with that file.  Is it okay for the memory usage to be linear in the size of the file or should it be constant? </p>

答:
The problem of file input possibly exceeding available memory is an old, well known, and basically solved issue. This is what a buffered file reader is all about.  Your buffer size is the maximum amount of memory your file will take up at a time.  The idea is to read the input up to the maximum buffer size, process that chunk, then read in the next chunk.  This makes for constant memory usage (at worst).

What if your process requires more than what's available in a chunk?  There are a bunch of algorithms out there for dealing with that sort of thing too.  Worst case, you may need a larger buffer and possibly more memory, but it still should have a constant maximum.


答:
The best is the enemy of good enough.

You can always do more testing, write better documentation, ferret out those corner cases, fill in what you think are missing features, make the architecture cleaner. It's never ending. However, it has to end. There are due dates that have to be met, external constraints that depend on your part of the product being finished. Striving for perfection in one small part of a product hurts the product as a whole.

Title: How to stop gold-plating and just be content to release working developments

Body:
The development team that I'm a member of has recently adapted to work according to Agile practices. This has personally highlighted the fact that I can't stop myself gold-plating code (and documentation) and I consequently exceed original estimates, when I could've delivered solutions that meet the requirements much earlier.

I think my ethic is bordering on the obsessive in that I become too attached to my code and am rarely content to release before I've refactored and perfected it to the nth degree. I am happy that I have realised this but how can I change my attitude/mentality to be content with my progress and release on-time instead?


问:
The 10 minutes technical interview
I must do a quick assessment of dozens of fresh students very quickly. I have 30 minutes meeting with each of them (in two or three days). I want to use most of the time to discuss non technical aspects. So I plan to use 10 minutes for technical questions. The same questions for all of them.

They are all hired already (they are students), what I need to know is the average level in order to prepare a training.

Ideally, the difficulty must be progressive in order to set a level for each. Level I will average, and I'll do an average on each question too.

If you had only 10 minutes and 10 questions to ask to a candidate, what would be your top 10 ?

答:
What is a class?

What is a static method?

What is inheritance?

What is polymorphism?

What is a primary key?

What is a foreign key?

What is the difference between HTTP GET and HTTP POST?

What is a web service?

Name some data structures.

What is the purpose of an Object/Relational Mapper?

Feel free to suggest replacements, this list has much room for improvement.

Title: The 10 minutes technical interview


问:
What's the best/most efficent way to create a semi-intelligent AI for a tic tac toe game?
basically I am attempting to make a a efficient/smallish C game of Tic-Tac-Toe. I have implemented everything other then the AI for the computer so far. my squares are basically structs in an array with an assigned value based on the square. For example

```<code>s[1].value = 1;
</code>```

therefore it's a x, and then a value of 3 would be a o. My question is whats the best way to create a semi-decent game playing AI for my tic-tac-toe game? I don't really want to use minimax, since It's not what I need. So how do I avoid a a lot of if statments and make it more efficient.

Here is the rest of my code:

```<code>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

struct state{ // defined
    int state; // 0 is tie, 1 is user loss, 2 is user win, 3 is ongoing game
    int moves;
};

struct square{ // one square of the board
    int value; // 1 is x, 3 is o
    char sign; // no space used
};

struct square s[9]; //set up the struct
struct state gamestate = {0,0}; //nothing

void setUpGame(){ // setup the game
    int i = 0;
    for(i = 0; i < 9; i++){
        s[i].value = 0;
        s[i].sign = ' ';
    }
    gamestate.moves=0;
    printf("\nHi user! You're \"x\"! I'm \"o\"! Good Luck :)\n");
}

void displayBoard(){// displays the game board
    printf("\n %c | %c | %c\n", s[6].sign, s[7].sign, s[8].sign);
    printf("-----------\n");
    printf(" %c | %c | %c\n", s[3].sign, s[4].sign, s[5].sign);
    printf("-----------\n");
    printf(" %c | %c | %c\n\n", s[0].sign, s[1].sign, s[2].sign);
}

void getHumanMove(){ // get move from human
    int i;
    while(1){
        printf(">>:");
        char line[255]; // input the move to play
        fgets(line, sizeof(line), stdin);
            while(sscanf(line, "%d", &i) != 1) { //1 match of defined specifier on input line
            printf("Sorry, that's not a valid move!\n");
            fgets(line, sizeof(line), stdin);
        }
        if(s[i-1].value != 0){printf("Sorry, That moves already been taken!\n\n");continue;}
        break;
    }
    s[i-1].value = 1;
    s[i-1].sign = 'x';
    gamestate.moves++;
}

int sum(int x, int y, int z){return(x*y*z);}

void getCompMove(){ // get the move from the computer

}

void checkWinner(){ // check the winner
    int i;
    for(i = 6; i < 9; i++){ // check cols
        if((sum(s[i].value,s[i-3].value,s[i-6].value)) == 8){printf("The Winner is o!\n");gamestate.state=1;}
        if((sum(s[i].value,s[i-3].value,s[i-6].value)) == 1){printf("The Winner is x!\n");gamestate.state=2;}
    }
    for(i = 0; i < 7; i+=3){ // check rows
        if((sum(s[i].value,s[i+1].value,s[i+2].value)) == 8){printf("The Winner is o!\n");gamestate.state=1;}
        if((sum(s[i].value,s[i+1].value,s[i+2].value)) == 1){printf("The Winner is x!\n");gamestate.state=2;}
    }
    if((sum(s[0].value,s[4].value,s[8].value)) == 8){printf("The Winner is o!\n");gamestate.state=1;}
    if((sum(s[0].value,s[4].value,s[8].value)) == 1){printf("The Winner is x!\n");gamestate.state=2;}
    if((sum(s[2].value,s[4].value,s[6].value)) == 8){printf("The Winner is o!\n");gamestate.state=1;}
    if((sum(s[2].value,s[4].value,s[6].value)) == 1){printf("The Winner is x!\n");gamestate.state=2;}
}

void playGame(){ // start playing the game
    gamestate.state = 3; //set-up the gamestate
    srand(time(NULL));
    int temp = (rand()%2) + 1;
    if(temp == 2){ // if two comp goes first
        temp = (rand()%2) + 1;
        if(temp == 2){
            s[4].value = 2; s[4].sign = 'o';
            gamestate.moves++;
        }else{
            s[2].value = 2; s[2].sign = 'o';
            gamestate.moves++;
        }
    }
    displayBoard();
    while(gamestate.state == 3){
        if(gamestate.moves<10);
            getHumanMove();
        if(gamestate.moves<10);
            getCompMove();
        checkWinner();
        if(gamestate.state == 3 && gamestate.moves==9){
            printf("The game is a tie :p\n");
            break;
        }
        displayBoard();
    }
}

int main(int argc, const char *argv[]){
    printf("Welcome to Tic Tac Toe\nby The Elite Noob\nEnter 1-9 To play a move, standard numpad\n1 is bottom-left, 9 is top-right\n");
    while(1){ // while game is being played
        printf("\nPress 1 to play a new game, or any other number to exit;\n>>:");
        char line[255]; // input whether or not to play the game
        fgets(line, sizeof(line), stdin);
        int choice; // user's choice about playing or not
        while(sscanf(line, "%d", &choice) != 1) { //1 match of defined specifier on input line
            printf("Sorry, that's not a valid option!\n");
            fgets(line, sizeof(line), stdin);
        }
        if(choice == 1){
            setUpGame(); // set's up the game
            playGame(); // Play a Game
        }else {break;} // exit the application
    }
    printf("\nThank's For playing!\nHave a good Day!\n");
    return 0;
}
</code>```

答:
3x3 Tic Tac Toe is a small enough game that one could relatively easily enumerate all the possible board positions and identify the correct next move for each.  If one wanted to tackle something a little bigger like 4x4x4, which allows the first player to force a win but not always easily, a good approach would be to combine heuristics with a min-max algorithm.  A reasonably good heuristic would, for each of the possible winning lines, identify it as being empty, as being blocked, or as having 1-4 player marks by the person who just moved, or 1-3 marks by the other player.  Each of those nine possibilities would be assigned a score value (4 marks by the person who just moved move being a really huge score value, and 3 marks by the person about to move being a not-quite-as-big negative value (so if a move would create a four-in-a-row, that would leave a good board position for the person who just moved even if the other player had an unblocked three, but otherwise leaving an unblocked three by the opponent would be very bad).  A simple score-based approach would work by testing each possible move, computing how favorable the board position would be afterward, and selecting the move that yields the most favorable position.  Such an approach would work decently, but would not play optimally.

To make the computer play better, use what's called a min-max algorithm.  To find the "level 0" score for a possible move, simply score the board that would result after the move.  To find the "level n" score for a possible move, determine which possible following move by the opponent would yield the best "level n-1" score (for the opponent).  The "level n" score is that best "level n-1" score, with the sign reversed.

Min-max algorithms can work very well for many types of turn-based games.  The biggest problem with them is that they can be very slow unless some steps are taken to ensure efficiency.  Among other things, simple algorithms will often end up examining board positions many dozens of times, if not hundreds.  They will also spend a lot of time evaluating in depth the possible countermoves for moves which should be recognized as lacking any merit.  Additionally, simple algorithms will often score each board position "from scratch".  Making a playable game requires tackling all three problems: keep track of what positions have been analyzed and what scores they've received; rather than using a depth-first search to evaluate every possible move at e.g. level 5, use a cross between a breadth-first search and a priority queue, so that the best-seeming moves get evaluated first.  Finally, use an "incremental" data structure that allows rapid scoring.  For example, in addition to holding the 64 squares of the board, keep counters for each of the possible 16+16+16+24+8 possible winning lines tallying up how many of each player's markers are on the line.  Adding or removing a piece would then require incrementing or decrementing the counts for the winning lines on which the piece appears, rather than having to recompute all of them.


问:
How does the GPL static vs. dynamic linking rule apply to interpreted languages?
In my understanding, the GPL prohibits static linking from non-GPL code to GPL code, but permits dynamic linking from non-GPL code to GPL code. So which is it when the code in question is not linked at all because the code is written in an interpreted language (e.g. Perl)?

It would seem to be too easy to exploit the rule if it was considered dynamic linking, but on the other hand, it would also seem to be impossible to legally reference GPL code from non-GPL code if it was considered static! Compiled languages at least have a distinction between static and dynamic linking, but when all "linking" is just running scripts, it's impossible to tell what the intent is without an explicit license!

Or is my understanding of this issue incorrect, rendering the question moot? I've also heard of a "classpath exception" which involves dynamic linking; is that not part of the GPL but instead something that can be added on to it, so dynamic linking is only allowed when the license includes this exception?

答:
No idea how much truth there is in this, and IANAL, etc.; but in my interpretation, what is important is whether the library you link against is is in some form included in the "binary" (where "binary", in the case of dynamic programming languages, is just the source code as distributed; this is what I make of the FSF's definition of "binary" in this context).

So if you reference libraries from your code without including them in your distribution, I would consider this the equivalent of "dynamic linking", whereas if you bundle the libraries with your product, or copy-paste parts of the library into your own code, the "static linking" scenario would apply. This, at least, is in the spirit of the GPL: you can freely use (run, inspect, reference) the GPL'd software without restrictions, but as soon as you derive from it (by linking or copying parts of it into your own distributable product), it goes viral, and your software must also be GPL'd.


答:
Note: this is a legal question. Programmers.SE is not a legal forum, it's a programming forum. While the people here know quite a bit about programming, they don't know anything about the law. If you want to ask a legal question, you should ask that in a legal forum, where there are people who actually know something about the subject matter.

The GPL doesn't say anything about static or dynamic linking. It doesn't even say anything about linking at all. Every lawyer or judge I talked to says that the issue of static and dynamic linking is completely irrelevant.

Copyright is about creativity. Static vs. dynamic linking is a technical implementation detail. Whether or not something is statically or dynamically linked is not a creative act, it cannot possibly change the copyright status of a work.

In your question, you talk about "interpreted languages". But that term doesn't make sense: there is no such thing as an interpreted language. A language is an abstract set of mathematical rules and restrictions. A language isn't interpreted or compiled. A language just is. The term "interpreted language" is not just wrong, it is non-sensical. If English were a typed language, it would be a type error.

Interpretation and compilation are traits of the interpreter or compiler (duh!), not the language. Every language can be implemented with an interpreter, and every language can be implemented with a compiler. Most languages have both. Most modern language implementation even combine both in a single execution engine.

The Rubinius Ruby Implementation, for example, contains a static ahead-of-time compiler which compiles Ruby code to Rubinius byte code, an interpreter which interprets Rubinius byte code, and a dynamic just-in-time compiler which compiles Rubinius byte code to LLVM IR, which the LLVM infrastructure in turn compiles to native machine code. The MacRuby Ruby Implementation doesn't contain an interpreter at all, it compiles Ruby code straight to LLVM IR, then further to native machine code.

On the other hand, there are interpreters for C or C++.

All of this is just technical details. It is completely irrelevant to copyright.

It just doesn't make sense that whether or not someone violates someone else's copyright depends on whether or some third person chooses to run the program with an interpreter or compile it first.

The question is whether or not a work is derived from another work. It can be dynamically linked and still be derived, and it can statically linked and not derived at all.

Title: How does the GPL static vs. dynamic linking rule apply to interpreted languages?

Body:
In my understanding, the GPL prohibits static linking from non-GPL code to GPL code, but permits dynamic linking from non-GPL code to GPL code. So which is it when the code in question is not linked at all because the code is written in an interpreted language (e.g. Perl)?

It would seem to be too easy to exploit the rule if it was considered dynamic linking, but on the other hand, it would also seem to be impossible to legally reference GPL code from non-GPL code if it was considered static! Compiled languages at least have a distinction between static and dynamic linking, but when all "linking" is just running scripts, it's impossible to tell what the intent is without an explicit license!

Or is my understanding of this issue incorrect, rendering the question moot? I've also heard of a "classpath exception" which involves dynamic linking; is that not part of the GPL but instead something that can be added on to it, so dynamic linking is only allowed when the license includes this exception?


问:
Why should one use a single-use temporary variable?
Let's say we have a class called 'Automobile' and we have an instance of that class called 'myCar'. I would like to ask why do we need to put the values that our methods return in a variable? Why don't we just call the method?

For example, why should one write:

```<code>string message = myCar.SpeedMessage();
Console.WriteLine(message);
</code>```

instead of:

```<code>Console.WriteLine(myCar.SpeedMessage());
</code>```

答:
in most languages you don't need to which is handy if you want to use a getter and pass it into a method:

```<code>bar.doBaz(faa.getFoo())
</code>```

but it can improve readability by separating the calls especially when it's a non trivial function

also it reduces the horizontal footprint of the call at the cost of an extra line (provided that the new variable's name is short)

Body:
in most languages you don't need to which is handy if you want to use a getter and pass it into a method:

bar.doBaz(faa.getFoo())

but it can improve readability by separating the calls especially when it's a non trivial function

also it reduces the horizontal footprint of the call at the cost of an extra line (provided that the new variable's name is short)


问:
What corners have have you cut at work?
Have you ever let your coding standards slip to meet deadlines or save time?

I'll start with a trivial example:

We came up with a coding standard at work around which brackets/formatting to use and so on. I ignore it and use the auto-format tool in netbeans.

答: I don't usually change general coding practices but I may let the code slip from the design. Usually this happens when I find the design needs to be re-factored a bit but instead of doing that I just staple some code in place that will make it work with an inadequate design. I usually make some TODO comments about this so we can fix it later.</p>

Title: What corners have have you cut at work?


答:
Short answer: We don't. Both examples are absolutely fine.

There are three reasons why people use temporary variables anyway (like in your first example):

It gives an explicit name to the intermediate value (we now know that it's a message, not just any old string).

It helps prevent statements getting too long and too complex.

It makes step-debugging easier, because you can step over each part individually (although there are step debuggers that work at sub-line precision).

Title: Why should one use a single-use temporary variable?

Body:
Let's say we have a class called 'Automobile' and we have an instance of that class called 'myCar'. I would like to ask why do we need to put the values that our methods return in a variable? Why don't we just call the method?

For example, why should one write:

```<code>string message = myCar.SpeedMessage();
Console.WriteLine(message);
</code>```

instead of:

```<code>Console.WriteLine(myCar.SpeedMessage());
</code>```


答:
As for specific question regarding interpreted languages, GPL FAQ is very clear:

The interpreted program, to the interpreter, is just data; a free
  software license like the GPL, based on copyright law, cannot limit
  what data you use the interpreter on. You can run it on any data
  (interpreted program), any way you like, and there are no requirements
  about licensing that data to anyone.

As for generic question about dynamic vs static linking. First of all, FSF's and Stallman's view is that it doesn't matter if linking is static or dynamic, GPL infects either way. From FSF GPL FAQ:

If the program dynamically links plug-ins, and they make function calls to each other and share data structures, we believe they form a single program, which must be treated as an extension of both the main program and the plug-ins. This means that combination of the GPL-covered plug-in with the non-free main program would violate the GPL.

and

Linking [name of your program] statically or dynamically with other
  modules is making a combined work based on [name of your program].
  Thus, the terms and conditions of the GNU General Public License cover
  the whole combination

However, this is questionable from legal point of view. In the only case that actually went to court regarding dynamic linking — Galoob  v. Nintendo —  Court of Appeals ruled that derivative work "must incorporate a portion of the copyrighted work in some form". Which is not the case with dynamic linking.

Anyway regardless if dynamic linking does indeed infect or not, there is work around. It's used for example by Nvidia to provide binary drivers for Linux. You create (L)GPL wrapper, but as author you are allowed to add special exception to link with specific closed-source. Vide FSF GPL FAQ.


问:
How can I get better at explaining complex software processes to developers?
I'm really struggling with my software specs.  I am not a professional programmer but enjoy doing it for fun and made some software that I want to sell later but I'm not happy with the code quality.  So I wanted to hire a real developer to rewrite my software in a more professional way so it will be maintainable by other developers in the future.

I read and found some sample specs and made my own by applying their structure to my document and wanted to get my developer friend to read it and give me advice.  After an hour and a half he understood exactly what I was trying to do and how I did it(my algorithms,stack,etc.).

How can I get better at explaining things to developers?  I add many details and explanations for everything(including working code) but I'm unsure the best way I can learn to pass detailed domain knowledge(my software applies big data, machine learning, graph theory to finance).  My end goal is to get them to understand as much as possible from the document and then ask anything they do not understand, but right now it seems they need to extract alot of information from me.  How can I get better at communicating domain knowledge to developers?

答:
Start implementing RTVMs (requirements traceability verification matrix) for your project.  It can be a bit tedious, but it really helped me wrap my mind around all of the different aspects of developing software.

An RTVM essentially looks like a giant V and essentially revolves around Why | What | How.  Each lower layer provides the How for the Whys and Whats from the layer above.  On the left side of the V, you'll move through application requirements into module requirements into functional specifications.  On the right side of the V, you'll provide ways / means of how to verify the corresponding requirements of that level.

Some links to help get you started:

Requirements Traceability

Traceability matrix

Googling "requirements traceability verification matrix" will provide a lot of resources as well.


问:
ASP.NET Webforms developers and web designers: how to interact?
I'm an ASP.NET Webforms developer, and I face some problems when I deal with designers.

Designers always complain about the asp.net server controls. They'd rather just have an html file and create css files along with the required images to go with those. Sometimes, if the design phase is done in advance, I get html files with related css files, but then we face many problems integrating the design with the aspx files (sever controls an telerik controls ... etc).

What I want to ask about is:

How do I overcome these problems? The designers prefer php- and mvc developers because of the problems with .net server controls. I need to know how to interact with the designers in the correct way.

Are there any tools or applications to provide the designers with the rendered (html
page) of the .aspx pages? By that I mean the page in runtime rather than the aspx in Visual Studio. They do use Web Expression but they want the rendered page in html as well.

答:
You need to make them talk together, understand each others needs and preferences. It's a "problem" that cannot be solved by software and tools. Don't try to please both parties, that will never work. They need to compromise - it's like a marriage.

One way is to arrange f.ex. workshops where each parties get the chance to explain why it is so that they prefer what they prefer. Good communication is always a key in situations like this. Gathering such as these can be seen as investments.

Or simply said, the problem is organization-oriented, not technical and that is where you need to provide solution.

The other option is to raise the pay and tell them to shut up (usually a short-term solution...).


问:
Internal Mutation of Persistent Data Structures
To clarify, when I mean use the terms persistent and immutable on a data structure, I mean that:

The state of the data structure remains unchanged for its lifetime. It always holds the same data, and the same operations always produce the same results.

The data structure allows Add, Remove, and similar methods that return new objects of its kind, modified as instructed, that may or may not share some of the data of the original object.

However, while a data structure may seem to the user as persistent, it may do other things under the hood. To be sure, all data structures are, internally, at least somewhere, based on mutable storage.

If I were to base a persistent vector on an array, and copy it whenever Add is invoked, it would still be persistent, as long as I modify only locally created arrays.

However, sometimes, you can greatly increase performance by mutating a data structure under the hood. In more, say, insidious, dangerous, and destructive ways. Ways that might leave the abstraction untouched, not letting the user know anything has changed about the data structure, but being critical in the implementation level.

For example, let's say that we have a class called ArrayVector implemented using an array. Whenever you invoke Add, you get a ArrayVector build on top of a newly allocated array that has an additional item. A sequence of such updates will involve n array copies and allocations.

Here is an illustration:

However, let's say we implement a lazy mechanism that stores all sorts of updates -- such as Add, Set, and others in a queue. In this case, each update requires constant time (adding an item to a queue), and no array allocation is involved.

When a user tries to get an item in the array, all the queued modifications are applied under the hood, requiring a single array allocation and copy (since we know exactly what data the final array will hold, and how big it will be). Future get operations will be performed on an empty cache, so they will take a single operation. But in order to implement this, we need to 'switch' or mutate the internal array to the new one, and empty the cache -- a very dangerous action.

However, considering that in many circumstances (most updates are going to occur in sequence, after all), this can save a lot of time and memory, it might be worth it -- you will need to ensure exclusive access to the internal state, of course.

This isn't a question about the efficacy of such a data structure. It's a more general question. Is it ever acceptable to mutate the internal state of a supposedly persistent or immutable object in destructive and dangerous ways? Does performance justify it? Would you still be able to call it immutable?

Oh, and could you implement this sort of laziness without mutating the data structure in the specified fashion?

答:
I would be very loath to call a data structure "immutable" unless, once it was exposed to the outside world, unless all changes that are made to its internal state continue at all times to leave the object in the same observable state, and unless the state of the object would be valid with any arbitrary combination of those changes either happening or not happening.

An example of a reasonably-good "immutable" object which obeys this principle is the Java string type.  It includes a hash-code field which is initially zero, but which is used to memoize the result of querying the hash code.  The state of a string with a zero hash-code field is semantically the same as that of a string where the hash-code field is filled in.  If two threads simultaneously attempt to query the hash code, it's possible that both may end up performing the computation and storing the result, but it doesn't matter because neither store will affect the observable state of the object.  If a third thread comes along and queries the hash code, it might or might not see the stores from the first two, but the returned hash code will be the same regardless.

(BTW, my one quibble with Java's string-hashing method is that it's possible for the hash function to return zero for a non-null string.  I would have thought it better to have the hash function test for zero and substitute something else.  For example, if the hashing step is such that adding a single character to a string whose hash is zero will always yield a non-zero hash, simply return the hash of the string minus the last character.  Otherwise the worst-case time to hash a long string thousands of times may be much worse than the normal-case time.)

The big things to beware of are (1) sequences of operations which change the state of an object and then change it back, or (2) substitution of objects that appear to have the same state, but don't.  Ironically, Microsoft's fixing of what it regarded as bug in its default Struct.Equals method makes #2 harder to protect against.  If one has a number of immutable objects which hold references to what appear to be identical immutable objects, replacing all those references with references to one of those immutable objects should be safe.  Unfortunately, the Equals overrides for system types Decimal, Double, and Float will sometimes report true even when comparing slightly-different values.  It used to be that wrapping one of those types in a struct and calling Equals on that struct would test for true equivalence, but Microsoft changed things so a struct will report Equals if its members do, even if those members hold non-equivalent values of the aforementioned types.


答:
most uses for immutable copy-on-write stuff like that is for thread safety so you can use a CaS primitive for updates and not need a lock

with the underlying structure being mutable this is no longer thread safe

also for one example that would invalidate the immutability would be: (using D's template syntax) assuming this is under the hood with a pointer and length field

```<code>ImmutableArr!int a ={1,2,3,4}
ImmutableArr!int b = a.insert(2,9)
</code>```

if b gets expanded in place then a would contain {1,2,9,3} after the insert

Title: Internal Mutation of Persistent Data Structures

Body:
To clarify, when I mean use the terms persistent and immutable on a data structure, I mean that:

The state of the data structure remains unchanged for its lifetime. It always holds the same data, and the same operations always produce the same results.

The data structure allows Add, Remove, and similar methods that return new objects of its kind, modified as instructed, that may or may not share some of the data of the original object.

However, while a data structure may seem to the user as persistent, it may do other things under the hood. To be sure, all data structures are, internally, at least somewhere, based on mutable storage.

If I were to base a persistent vector on an array, and copy it whenever Add is invoked, it would still be persistent, as long as I modify only locally created arrays.

However, sometimes, you can greatly increase performance by mutating a data structure under the hood. In more, say, insidious, dangerous, and destructive ways. Ways that might leave the abstraction untouched, not letting the user know anything has changed about the data structure, but being critical in the implementation level.

For example, let's say that we have a class called ArrayVector implemented using an array. Whenever you invoke Add, you get a ArrayVector build on top of a newly allocated array that has an additional item. A sequence of such updates will involve n array copies and allocations.

Here is an illustration:

However, let's say we implement a lazy mechanism that stores all sorts of updates -- such as Add, Set, and others in a queue. In this case, each update requires constant time (adding an item to a queue), and no array allocation is involved.

When a user tries to get an item in the array, all the queued modifications are applied under the hood, requiring a single array allocation and copy (since we know exactly what data the final array will hold, and how big it will be). Future get operations will be performed on an empty cache, so they will take a single operation. But in order to implement this, we need to 'switch' or mutate the internal array to the new one, and empty the cache -- a very dangerous action.

However, considering that in many circumstances (most updates are going to occur in sequence, after all), this can save a lot of time and memory, it might be worth it -- you will need to ensure exclusive access to the internal state, of course.

This isn't a question about the efficacy of such a data structure. It's a more general question. Is it ever acceptable to mutate the internal state of a supposedly persistent or immutable object in destructive and dangerous ways? Does performance justify it? Would you still be able to call it immutable?

Oh, and could you implement this sort of laziness without mutating the data structure in the specified fashion?

Body:
most uses for immutable copy-on-write stuff like that is for thread safety so you can use a CaS primitive for updates and not need a lock

with the underlying structure being mutable this is no longer thread safe

also for one example that would invalidate the immutability would be: (using D's template syntax) assuming this is under the hood with a pointer and length field

ImmutableArr!int a ={1,2,3,4}
ImmutableArr!int b = a.insert(2,9)

if b gets expanded in place then a would contain {1,2,9,3} after the insert


答:
I would probably never say never, but statements that generate data and code as they are parsed should not be in a .h file.

Macros, inline functions and templates may look like data or code, but they do not generate code as they are parsed, but instead when they are used.  These items often need to be used in more than one .c or .cpp, so they belong in the .h.

In my view, a header file should have the minimum practical interface to a corresponding .c or .cpp.  The interface can include #defines, class, typedef, struct definitions, function prototypes, and less preferred, extern definitions for global variables.  However, if a declaration is used in only one source file, it probably should be excluded from the .h and be contained in the source file instead.

Some may disagree, but my personal criteria for .h files is that they #include all other .h files that they need to be able to compile.  In some cases, this can be a lot of files, so we have some effective methods to reduce external dependencies like forward declarations to classes that let us use pointers to objects of a class without including what could be a big tree of include files.

Title: What should and what shouldn't be in a header file?

Body:
What things should absolutely always/never be included in a header file?

Functions: what must go in the header file and what mustn't

Constants: Is it good practice to define lot of constants in a header file?

Any other good practices for C header files?

Example

I'm writing a parser for a documented industry standard format that has a lots of constants, is it a good practice to define them in a header file?


问:
In what practical ways is it good to remember the memory/pointers model?
A variable refers to a value. A variable is also stored in a memory address. People say that it's good to have this memory model in mind. Is that true? What is some sample code that shows this as beneficial in practice?

You dont have to use programming, you can use a real-world analogy if you like.

edit: they keep removing the helpful answer i summed up here -- no idea why

答:
In Java, if you store an object in a variable like

```<code>MyClass myObject = new MyClass();
</code>```

Then myObject contains only a reference to the actual object, which resides in the memory. And if you do this:

```<code>MyClass anotherObject = myObject;
</code>```

Then anotherObject contains the reference to the same object like myObject. There is only one object in the memory and both variables point to it. If you change something on myObject or on anotherObject, both will affect the same. So even in Java it is useful to keep in mind that you deal at least with references.

Body:
In Java, if you store an object in a variable like

MyClass myObject = new MyClass();

Then myObject contains only a reference to the actual object, which resides in the memory. And if you do this:

MyClass anotherObject = myObject;

Then anotherObject contains the reference to the same object like myObject. There is only one object in the memory and both variables point to it. If you change something on myObject or on anotherObject, both will affect the same. So even in Java it is useful to keep in mind that you deal at least with references.


问:
Tiling Problem Solutions for Various Size "Dominoes"
I've got an interesting tiling problem,  I have a large square image (size 128k so 131072 squares) with dimensons 256x512... I want to fill this image with certain grain types (a 1x1 tile, a 1x2 strip, a 2x1 strip, and 2x2 square) and have no overlap, no holes, and no extension past the image boundary. Given some probability for each of these grain types, a list of the number required to be placed is generated for each.

Obviously an iterative/brute force method doesn't work well here if we just randomly place the pieces, instead a certain algorithm is required. 1) all 2x2 square grains are randomly placed until exhaustion. 2) 1x2 and 2x1 grains are randomly placed alternatively until exhaustion 3) the remaining 1x1 tiles are placed to fill in all holes.

It turns out this algorithm works pretty well for some cases and has no problem filling the entire image, however as you might guess, increasing the probability (and thus number) of 1x2 and 2x1 grains eventually causes the placement to stall (since there are too many holes created by the strips and not all them can be placed).

My approach to this solution has been as follows: 1) Create a mini-image of size 8x8 or 16x16. 2) Fill this image randomly and following the algorithm specified above so that the desired probability of the entire image is realized in the mini-image. 3) Create N of these mini-images and then randomly successively place them in the large image.

Unfortunately there are some downfalls to this simplification. 1) given the small size of the mini-images, nailing an exact probability for the entire image is not possible. Example if I want p(2x1)=P(1x2)=0.4, the mini image may only give 0.41 as the closes probability. 2) The mini-images create a pseudo boundary where no overlaps occur which isn't really descriptive of the model this is being used for. 3) There is only a fixed number of mini-images so i'm not sure how random this really is.

I'm really just looking to brainstorm about possible solutions to this. My main concern is really to nail down closer probabilities, now one might suggest I just increase the mini-image size. Well I have, and it turns out that in certain cases(p(1x2)=p(2x1)=0.5) the mini-image 16x16 isn't even iteratively solvable.. So it's pretty obvious how difficult it is to randomly solve this for anything greater than 8x8 sizes.. So I'd love to hear some ideas. Thanks

答: I had a similar problem recently, trying to find polyimino patterns that would fill a board.  A simple backgracking program worked quite well. Just place random tiles and backtrack when you cannot place and have not met the constraints.</p>


问:
Whiteboard "testing" during an interview: legitimate way to back up your (whiteboard) code?
As I get it, having an error (even a typo like or missing ";") in your whiteboard code will often cost you some interview points. Avoiding that will inevitably make one proof-reading code again and again (losing time and possibly neural energy / concentration) or even using a simpler (and thus less effective) algorithm -- and both these ways are "costly" again!

So, why not just fast write code as elegant and effective as you would having a (unit) testing framework at your disposal and then just normally test it it (just on the whiteboard)?

Has anyone tried / seen this approach? Is the whole idea worthy?

[this also applies to the pen-and-paper case of course]

答: I think you've made an incorrect assumption here.  There's no way I'd expect a candidate writing up code on a whiteboard to be able to get every ';' perfectly in place.  If you're interviewing at a place which does penalise you for that then I suggest they're not an organisation you want to work for :-).</p>


问:
Could Apple and Microsoft allow the GPLv3 on their locked-down devices?
It seems that both Apple and Microsoft prohibit GPLv3-licensed software in the app stores for their locked-down devices (i.e. iOS, Windows Phone and the Metro part of Windows). I have heard various explanations for this. However: Would they even be able to allow this license in their app stores if they wanted to, or does the GPL's anti-tivoization clause already prohibit this?</p>

答:
Apple effectively ban any GPL because they only allow redistribution through the store and by registered developers. So if you distribute the GPL to your users they cannot abide by it.

Apple could simply allow any GPL app to be redistributed by any user through a free section of the site - but chose not to. Ironically OSX is based on a free BSD Unix kernel.

Microsoft have an historical objection to "the cancer of open source" and their licence explicitly bans any open source licenced app that requires redistribution of source (ie GPL). This is their right, it's a business decision -  just like banning sales in a particular country. As their position in the market becomes less dominant they might change their mind


问:
Pulling changes from master to my work branch?
There's two of us working on something. We're using this branch structure

master

dev-A

dev-B

We both work on separate branches (dev-A,B) and whenever we're done - we promote our changes to master.

But the drawback of this is we can't get changes the other developer makes. Everything exists in the master tree - but we can't get the latest updates the other developer made.

Is there a way to resolve this or should we change our branch structure (per feature?)?

答:
In your working branch if you go:

```<code>git commit -am "Committing changes before merge"
git merge master
</code>```

you can also merge from the other developers branch

```<code>git checkout dev-A
git merge dev-B
</code>```

What that will do is merge the changes in master to your development branch.

Body:
In your working branch if you go:

git commit -am "Committing changes before merge"
git merge master

you can also merge from the other developers branch

git checkout dev-A
git merge dev-B

What that will do is merge the changes in master to your development branch.


问:
How important is it for a programmer to know how to implement a QuickSort/MergeSort algorithm from memory?
I was reviewing my notes and stumbled across the implementation of different sorting algorithms.

As I attempted to make sense of the implementation of QuickSort and MergeSort, it occurred to me that although I do programming for a living and consider myself decent at what I do, I have neither the photographic memory nor the sheer brainpower to implement those algorithms without relying on my notes. All I remembered is that some of those algorithms are stable and some are not. Some take O(nlog(n)) or O(n^2) time to complete. Some use more memory than others...

I'd feel like I don't deserve this kind of job if it weren't because my position doesn't require that I use any sorting algorithm other than those found in standard APIs. I mean, how many of you have a programming position where it actually is essential that you can remember or come up with this kind of stuff on your own?

答:
Just remembering which algorithm is useful in what scenarios, would be more than enough to help during your work. In fact, most programming jobs don't require the memorization of approach, rather they are interested in your way of recognizing algorithmic pattern when faced with the problem.

As a matter of fact, there is abundance of information in most programming blogs/articles on algorithm topics. Thus, memorizing exact implementation does not carry importance. Most valuable information would be getting basic idea on what type of algorithm's are available, and what specific problem are they good in solving. Searching for exact implementation once you know what you are looking for is pretty fast.

In summary, it is always better to know what you look for and where are the references - which will guide you to the source.


问:
Avoid GPL violation by moving library out of process
Assume there is a library that is licensed under GPL. I want to use it is closed source project. I do following:

Create small wrapper application around that GPL library that listens to socket, parse messages and call GPL library. Then returns results back.

Release it's sources (to comply with GPL)

Create client for this wrapper in my main application and don't release sources.

I know that this adds huge overhead compared to static/dynamic linking, but I am interested in theoretical way.

答:
Would it be legal for Adam Brown to write a program which used a GPL library and acted as a "server", if he released all the source code to everything associated with it, but the only client code he released was pretty feeble because that's all he'd written client-side?  I see no basis whatsoever for thinking it wouldn't.

If Charles Dover found Adam Brown's "server" and decided to write a closed-source program to communicate with it, would the GPL constrain his actions in any way?  Not that I can see, since his only usage of GPL'ed software would be as the binaries he received from Adam Brown.  If he distributed Adam's binaries he'd have to include a link to the source as well, but nothing else in the GPL would affect any of Charles' code.

With regard to one person writing a GPL-licensed server, and then using the server for his own closed-source purposes, I wouldn't think there should be any legal problem if in writing the server he made a bona fide effort to make it useful to others who might wish to use the supplied GPL code in the same way.  In particular, the publicly-released documentation of the interface should be sufficient to allow a competent programmer to either write code for a server which would be accepted by the client program just as the original would be, and to write client programs that would use the server in the same fashion as the author's application.


答:
I think the only time you need to remember it all is when applying for a job when you have to come up with answers on the spot and have no outside resources.

I've had coworkers rewrite quicksort and whatnot, but I keep telling them to go back to using the built in sorting functions that are in the language.  I do know that depending on what types of projects we work on we do have to remember other algorithms since they're not usually included in standard libraries, but sorting isn't one that comes up since it's usually built into the language.

When we do need to remember those algorithms though, we usually turn to google or a book, and usually it's not looking for a specific implementation, but what would be the best implementation for our problem.

Title: How important is it for a programmer to know how to implement a QuickSort/MergeSort algorithm from memory?

Body:
I was reviewing my notes and stumbled across the implementation of different sorting algorithms.

As I attempted to make sense of the implementation of QuickSort and MergeSort, it occurred to me that although I do programming for a living and consider myself decent at what I do, I have neither the photographic memory nor the sheer brainpower to implement those algorithms without relying on my notes. All I remembered is that some of those algorithms are stable and some are not. Some take O(nlog(n)) or O(n^2) time to complete. Some use more memory than others...

I'd feel like I don't deserve this kind of job if it weren't because my position doesn't require that I use any sorting algorithm other than those found in standard APIs. I mean, how many of you have a programming position where it actually is essential that you can remember or come up with this kind of stuff on your own?


问:
Instantiating Interfaces in C#?
I am reading/learning about interfaces in C# at the moment, and thus far I managed to understand how it differs from an abstract class. In the book I am reading the author explains that interfaces are the ultimate abstract class and that it simply sets the standard of certain methods the inheriting class will have, but then provides the following example.

```<code>static void Main(string[] args)
{
...
Circle c = new Circle("Lisa");
IPointy itPt = null;
try
{
itPt = (IPointy)c;
Console.WriteLine.(itPt.Points);
}
catch (InvalidCastException e)
{
 Console.WriteLine(e.Message);
}
...
}
</code>```

The line that absolutely throws me off is the IPointy itfPt=null; did he just declare an interface? I thought interfaces are abstract and can only be inherited? What kind of sorcery is going on here?

答:
An interface is declared using the interface keyword, which that line of code does not contain.

What you're seeing is a variable declaration, a variable named itfPt, whose type is IPointy.  The variable gets the value 'null', which is not an instance.

Instantiating the interface IPointy is not possible, you can try doing it by type itfPt = new IPointy(); and examining the compile errors.  The only values that can be assigned to itfPt are instances of concrete subtypes of IPointy and null.

Title: Instantiating Interfaces in C#?


答:
I think what you look for is instantiation of Interface and use of it. Here is an example that may help you:</p>

```<code>public interface IFoo
{
    void Bar1();
    void Bar2();
}

public Class ActionableFoo : IFoo
{
    Action _bar1, _bar2;

    public ActionableFoo(Action b1, Action b2)
    {
        _bar1 = b1;
        _bar2 = b2;
    }

    public void Bar1() { if(_bar1 != null) _bar1(); }
    public void Bar2() { if(_bar2 != null) _bar2(); }
}

public void PushFoo(Action bar1, Action bar2)
{
    IFoo foo = new ActionableFoo(bar1, bar2);
    _fooStack.Push(foo);
}
</code>```

Title: Instantiating Interfaces in C#?

Body:
I am reading/learning about interfaces in C# at the moment, and thus far I managed to understand how it differs from an abstract class. In the book I am reading the author explains that interfaces are the ultimate abstract class and that it simply sets the standard of certain methods the inheriting class will have, but then provides the following example.

```<code>static void Main(string[] args)
{
...
Circle c = new Circle("Lisa");
IPointy itPt = null;
try
{
itPt = (IPointy)c;
Console.WriteLine.(itPt.Points);
}
catch (InvalidCastException e)
{
 Console.WriteLine(e.Message);
}
...
}
</code>```

The line that absolutely throws me off is the IPointy itfPt=null; did he just declare an interface? I thought interfaces are abstract and can only be inherited? What kind of sorcery is going on here?

Body:
I think what you look for is instantiation of Interface and use of it. Here is an example that may help you:

public interface IFoo
{
    void Bar1();
    void Bar2();
}

public Class ActionableFoo : IFoo
{
    Action _bar1, _bar2;

    public ActionableFoo(Action b1, Action b2)
    {
        _bar1 = b1;
        _bar2 = b2;
    }

    public void Bar1() { if(_bar1 != null) _bar1(); }
    public void Bar2() { if(_bar2 != null) _bar2(); }
}

public void PushFoo(Action bar1, Action bar2)
{
    IFoo foo = new ActionableFoo(bar1, bar2);
    _fooStack.Push(foo);
}


答:
That example demonstrates a try...catch more than anything.

Interfaces are types too.. but they only expose their contract. So this:

```<code>IPointy itPt = new IPointy();
</code>```

..won't work. Consider this:

```<code>interface IPointy {
    void MyMethod();
}

class Pencil : IPointy {
    void MyMethod() {
    }

    void MyOtherMethod() {
    }
}
</code>```

You can declare an IPointy like this:

```<code>IPointy itPt = new Pencil();
</code>```

..however, this will work:

```<code>itPt.MyMethod();
</code>```

..this won't work:

```<code>itPt.MyOtherMethod();
</code>```

This is because MyMethod is part of the IPointy contract.. MyOtherMethod isn't.. Hopefully that helps.

EDIT: Expanding this to explain my comment.

Inheriting from a class represents an "is-a" relationship. Implementing an interface represents a "can-do" relationship.

Consider:

```<code>interface ISwitchable {
    void SwitchOn();
    void SwitchOff();
}

class Light : ISwitchable {
    void SwitchOn() { }
    void SwitchOff() { }
}

class Television : ISwitchable {
    void SwitchOn() { }
    void SwitchOff() { }
}
</code>```

Both a Television and Light inherit from ISwitchable.. which is fine. The interface defines a "can-do" relationship.. they can both be switched on orr of. Both of the following blocks of code are valid:

```<code>ISwitchable mySwitchableObject1 = new Light();
ISwitchable mySwitchableObject2 = new Television();

mySwitchableObject1.SwitchOn(); // calls Light's SwitchOn method
mySwitchableObject2.SwitchOn(); // calls Television's SwitchOn method
</code>```

Title: Instantiating Interfaces in C#?

Body:
That example demonstrates a try...catch more than anything.

Interfaces are types too.. but they only expose their contract. So this:

IPointy itPt = new IPointy();

..won't work. Consider this:

interface IPointy {
    void MyMethod();
}

class Pencil : IPointy {
    void MyMethod() {
    }

    void MyOtherMethod() {
    }
}

You can declare an IPointy like this:

IPointy itPt = new Pencil();

..however, this will work:

itPt.MyMethod();

..this won't work:

itPt.MyOtherMethod();

This is because MyMethod is part of the IPointy contract.. MyOtherMethod isn't.. Hopefully that helps.

EDIT: Expanding this to explain my comment.

Inheriting from a class represents an "is-a" relationship. Implementing an interface represents a "can-do" relationship.

Consider:

interface ISwitchable {
    void SwitchOn();
    void SwitchOff();
}

class Light : ISwitchable {
    void SwitchOn() { }
    void SwitchOff() { }
}

class Television : ISwitchable {
    void SwitchOn() { }
    void SwitchOff() { }
}

Both a Television and Light inherit from ISwitchable.. which is fine. The interface defines a "can-do" relationship.. they can both be switched on orr of. Both of the following blocks of code are valid:

ISwitchable mySwitchableObject1 = new Light();
ISwitchable mySwitchableObject2 = new Television();

mySwitchableObject1.SwitchOn(); // calls Light's SwitchOn method
mySwitchableObject2.SwitchOn(); // calls Television's SwitchOn method


答:
You can declare variables typed as interfaces: that does not amount to instantiating them. Once you declare a variable of interface type, you can assign it an object of any class that implements the interface.

For example, you can declare a variable of interface type IDictionary<string,string>, but you cannot instantiate it: you must choose a class that implements IDictionary<string,string>, for example

```<code>IDictionary<string,string> d = new Dictionary<string,string>();
</code>```

or

```<code>IDictionary<string,string> d = new SortedList<string,string>();
</code>```

Title: Instantiating Interfaces in C#?

Body:
You can declare variables typed as interfaces: that does not amount to instantiating them. Once you declare a variable of interface type, you can assign it an object of any class that implements the interface.

For example, you can declare a variable of interface type IDictionary<string,string>, but you cannot instantiate it: you must choose a class that implements IDictionary<string,string>, for example

IDictionary<string,string> d = new Dictionary<string,string>();

or

IDictionary<string,string> d = new SortedList<string,string>();