问:
What is the difference between CSDA and CSDP?
This question is in reference to the IEEE's CSDA and CSDP certifications.

I've already taken the CSDA course, which covered all of the knowledge areas in the Software Engineering Body of Knowledge (SWEBOK).

I'm thinking about doing the CSDP certification as well, but I can't find anywhere that tells me how it differs from the CSDA. I know that it's aimed more at professionals rather than recent graduates, and I'd imagine that it covers the same areas as the CSDA, but in greater detail. Unfortunately I can't find much evidence to back that up.

This is making it difficult to justify to my boss that he should spend several hundred pounds of the group's training budget on it.

So the question is: What does the CSDP offer that the CSDA doesn't?

答:
You're correct in your statement that the CSDP is aimed more at professionals. The requirements to sit for the CSDP are one of a Bachelor's degree, completion of the CSDA exam, post-baccalaureate teaching experience, or IEEE membership and one of an advanced degree in software engineering with 2 years of experience or four years of experience.

You can also through the recommended references for the CSDP and compare them to the recommended references for the CSDA), along with some sample test questions from the CSDP and compare them to some sample test questions from the CSDA.

There are also two bulletins from 2011 that provide a breakdown of topics on each exam: the CSDA and CSDP - it includes the amount of the exam devoted to each high level topic and the competency level (introductory "I" or competency "C") for the various subtopics. I don't suspect that much has changed between then and now, other than some refinements. I suspect the next major refresh may come after SWEBOK v3 is published.

All of the weights and competencies are (CSDA / CSDP).

Software Requirements (7% / 11%)

Software Requirements Fundamentals (I / C)

Requirements Process (I / C)

Requirements Elicitation (I / C)

Requirements Analysis (C / C)

Requirements Specification (I / C)

Requirements Validation (C / C)

Practical Considerations (I / C)

Software Design (8% / 11%)

Software Design Fundamentals (C / C)

Key Issues in Software Design (C / C)

Software Structure and Architecture (C / C)

Human Computer Interface Design (C / C)

Software Design Quality Analysis and Evaluation (C / C)

Software Design Notations (C / C)

Software Design Strategies and Methods (C / C)

Software Construction (10% / 9%)

Software Construction Fundamentals (C / C)

Managing Construction (C / C)

Practical Considerations (C / C)

Construction Tools (C / C)

Construction Technologies (C / C(

Product Documentation (C / C)

Formal Construction Methods (C / I)

Software Testing (7% / 11%)

Software Testing Fundamentals (I / C)

Test Levels (C / C)

Test Techniques (C / C)

Human Computer User Interface Testing and Evaluation (C / C)

Test-Related Measures (C / C)

Test Process (C / C)

Software Maintenance (7%  / 5%)

Software Maintenance Fundamentals (I / C)

Key Issues in Software Maintenance (I / C)

Maintenance Process (C / C)

Techniques for Maintenance (C / C)

Software Configuration Management (3% / 5%)

Management of the SCM Process (I / C)

Software Configuration Identification (I / C)

Software Configuration Control (I / C)

Software Configuration Status Accounting (I / I)

Software Configuration Auditing (I / I)

Software Release Management and Delivery (I / C)

Software Configuration Management Tools (I / I)

Software Engineering Management (3% / 8%)

Initiation and Scope Definition (I / I)

Software Project Planning (C / C)

Software Project Enactment (C / C)

Review and Evaluation (I / I)

Closure (I / I)

Software Engineering Measurement (I / I)

Software Management Tools (I / I)

Software Engineering Process (4% / 7%)

Process Implementation and Change (I / I)

Process Definition (C / C)

Process Assessment (I / I)

Measurement (I / I)

Software Process Tools (I / I)

Software Engineering Methods (5% / 4%)

Modeling (C / C)

Types of Models (C / C)

Analysis (C / C)

Development Methods  (C / C)

Software Quality (6% / 7%)

Software Quality Fundamentals (I / C)

Software Quality Management Processes (C / C)

Software Quality Practical Considerations (C / C)

Software Engineering Professional Practice (7% / 5%)

Professionalism (C / C)

Codes of Ethics (C / C)

Group Dynamics / Psychology (C / C)

Communications Skills (C / C)

Intellectual Property, Confidentiality, Security (C / C)

Software Engineering Economics (3% / 5%)

Software Engineering Economy Fundamentals (C / C)

For-Profit Decision-Making (C / C)

Not-for-Profit Decision-Making (C / C)

Present Economy (C / C)

Estimation, Risk, and Uncertainty (C / C)

Multiple Attribute Decisions (C / C)

Computing Foundations (10% / 5%)

Programming Fundamentals (C / C)

Algorithms, Data Structures/Representation and Complexity (C / C)

Problem Solving Techniques (C / C)

Abstraction Use (C / C)

Computer Organization (C / C)

Basic Concept of a System (C / C)

Basic User Human Factors (C / C)

Basic Developer Human Factors (C / C)

Operating System Basics (C / C)

Database Basics and Data Management (C / C)

Network Communication Basics (C / C)

Distributed and Parallel Computing (C / C)

Concepts of Programming Languages (C / C)

Debugging Tools and Techniques (C / C)

Secure Coding (C / C)

Mathematical Foundations (10% / 3%)

Functions, Relations, and Sets (C / C)

Basic Logic (prepositional and predicate) (C / C)

Proof Techniques (C / C)

Basic Counting (C / C)

Graphs and Trees (C / C)

Discrete Probability (C / C)

Finite State Machines (C / C)

Grammars (C / C)

Numerical Precision, Accuracy, and Errors (C / C)

Number Theory (C / C)

Algebraic Structures (C / C)

Engineering Foundations (10% / 4%)

Empirical Methods and Experimental Techniques (C / C)

Statistical Analysis (C / C)

Measurement (I / C)

Systems Development (I / C)

Engineering Design (C / C)

Theory of Measurement (C / C)

Simulation, Modeling and Conceptual Prototyping (C / C)

Goal-Question-Metric Paradigm (I / C)

Standards (identify, evaluate, select and adapt) (I / C)

Tool and Platform Selection (I / C)

Root Cause Analysis (C / C)


问:
Working with data and meta data that are separated on different servers
While developing a product, I've come across a situation where my group wants to store meta data for data entry forms (questions, layout, etc) in a different database then the database where the collected data is stored.  This is mostly for security because we want to be able to have our meta data public facing, while keeping collected data as secure as possible.

I was thinking about writing a web service that provides the meta information that the data collection program could access.  The only issue I see with this approach is the front end is going to have to match the meta data with the collected data, which would be more efficient as a join on the back end.

Currently, this system is slated to run on .NET and MSSQL.

I haven't played around with .NET libraries running in SQL, but I'm considering trying to create logic that would pull from the web service, convert the meta data into a table that SQL can join on, and return the combined data and meta data that way.

Is this solution the wrong way to approach the problem?  Is there a pattern or "industry standard" way of bringing together two datasets that don't live in the same database?

答:
Well, the bigger problem is that effectively prevents you from maintaining consistency between the data sets. If you store the data like this, it will break.

I would probably store the metadata in the internal database alongside the data and set up replication of the metadata only to another server in DMZ where the public facing interface can access it.

ContentLicense: CC BY-SA 3.0


问:
When to decide to introduce interfaces (pure abstract base classes) in C++?
Assume that you are developing a functionality and are 90% sure that the implementation class will stay alone. If I was in this position in Java I would probably not use the interface right now to keep the things simple. In Java it is easy to refactor the code and extract the interface later.

In C++ the refactoring is not always so easy. It may require replacing values with smart pointers (because of the introduction of polymorphism) and other non-trivial tasks.

On the other hand I don't much like the idea of introducing virtual calls when I am 90% sure they won't be needed. After all speed is one of the reasons to prefer C++ over simpler languages.

答:
I would like to point out a thing 1st then share some of my experience. Please be careful with saying Abstract Base Classes and Interfaces so freely alongside. ABCs are language concept and Interface is a design concept. Of course ABCs are very handy in implementing interfaces in c++, however I do not think it is said anywhere (high credible source) that they are meant specifically for it. There are other ways to do it! Please take a read http://accu.org/index.php/journals/471.

That being said, to answer your question. In my experience as the rule of thumb you should always write code that you feel is designed well. If you think virtuals will cripple your performance, seriously do not bother unless you can prove it is more than 10% if you plan on managing your code. If it is one-shot, squeeze it all, code design does not matter.

Sadly one needs to learn how to analyze and profile applications, at a level that I would consider quite high, to properly re-design code. You should be able to tell if you need to reorganize branches, eliminate virtuals or memory management or find bottlenecks. I believe nowadays they are much more often hardware related. If you look through some SO c++ performance questions you will see that bottle necks lied in very strange places and only people who profiled code for cache misses or branch predictions were able to find causes.

I must say that, I had fallen victim to pre-mature optimizations, as well as under- and over- design. I tried to implement (heck, i did implement) clever things where they were not needed, and only complicated code and interface system to a point where it was not fun to extend my own programs. For the sake of like 5% speed-up I effectively encumbered process of testing to the point I had to spend a day to implement tests or test it manually after adding some new feature. I also went down to such thing as get_x(){ return x;}; was virtual because it shared interface with something that had different memory management.

To sum up, for now my advice would be:

Write code that is well designed for current needs (and maybe immediate future). Do not try to over complicate it beforehand. It's just as bad as premature opitmizations. Personal experience.

When it is appropriate, then refactor and introduce templates.

Don't care about performance, unless you are sure you need. Learn to high-quality analyze your code. Then work on bottle necks.

Of course its probably twice as much work as getting everything right in the 1st place. In my case the problem is I miss the right way 2 out of 3 times if not more :). I believe over time a good programmer is able to choose good approach beforehand more often.

On the templates vs ABCs for interfaces.

I think ABCs are more-programmer friendly and readable, however I would got for template polymorphism if I ran into something like:

```<code>...
virtual get_x() {return coords[0];};
virtual get_y() {return coords[1];};
virtual get_z() {return coords[2];};
...

void some_fancy_algorithm_that_work_on_coords(){
  // for example calculate distances between every pair of instances
  // that can provide `ICoords` interface
}
</code>```

I template base polymorphism a half-decent compiler can eliminate implicit object casts and use referenced methods and properties directly. It is good to avoid virtuals and intermediate access, even though everything is wrapped in the code design.

Body:
I would like to point out a thing 1st then share some of my experience. Please be careful with saying Abstract Base Classes and Interfaces so freely alongside. ABCs are language concept and Interface is a design concept. Of course ABCs are very handy in implementing interfaces in c++, however I do not think it is said anywhere (high credible source) that they are meant specifically for it. There are other ways to do it! Please take a read http://accu.org/index.php/journals/471.

That being said, to answer your question. In my experience as the rule of thumb you should always write code that you feel is designed well. If you think virtuals will cripple your performance, seriously do not bother unless you can prove it is more than 10% if you plan on managing your code. If it is one-shot, squeeze it all, code design does not matter.

Sadly one needs to learn how to analyze and profile applications, at a level that I would consider quite high, to properly re-design code. You should be able to tell if you need to reorganize branches, eliminate virtuals or memory management or find bottlenecks. I believe nowadays they are much more often hardware related. If you look through some SO c++ performance questions you will see that bottle necks lied in very strange places and only people who profiled code for cache misses or branch predictions were able to find causes.

I must say that, I had fallen victim to pre-mature optimizations, as well as under- and over- design. I tried to implement (heck, i did implement) clever things where they were not needed, and only complicated code and interface system to a point where it was not fun to extend my own programs. For the sake of like 5% speed-up I effectively encumbered process of testing to the point I had to spend a day to implement tests or test it manually after adding some new feature. I also went down to such thing as get_x(){ return x;}; was virtual because it shared interface with something that had different memory management.

To sum up, for now my advice would be:

Write code that is well designed for current needs (and maybe immediate future). Do not try to over complicate it beforehand. It's just as bad as premature opitmizations. Personal experience.

When it is appropriate, then refactor and introduce templates.

Don't care about performance, unless you are sure you need. Learn to high-quality analyze your code. Then work on bottle necks.

Of course its probably twice as much work as getting everything right in the 1st place. In my case the problem is I miss the right way 2 out of 3 times if not more :). I believe over time a good programmer is able to choose good approach beforehand more often.

On the templates vs ABCs for interfaces.

I think ABCs are more-programmer friendly and readable, however I would got for template polymorphism if I ran into something like:

...
virtual get_x() {return coords[0];};
virtual get_y() {return coords[1];};
virtual get_z() {return coords[2];};
...

void some_fancy_algorithm_that_work_on_coords(){
  // for example calculate distances between every pair of instances
  // that can provide `ICoords` interface
}

I template base polymorphism a half-decent compiler can eliminate implicit object casts and use referenced methods and properties directly. It is good to avoid virtuals and intermediate access, even though everything is wrapped in the code design.


问:
Why is TDD not working here?
I want to write a class A that has a method calculate(<params>). That method should calculate a value using database data. So I wrote a class Test_A for unit testing (TDD). The database access is done using another class which I have mocked with a class, let's call it Accessor_Mockup.

Now, the TDD cycle requires me to add a test that fails and make the simplest changes to A so that the test passes. So I add data to Accessor_Mockup and call A.calculate with appropriate parameters.

But why should A use the accessor class at all? It would be simpler (!) if the class just "knows" the values it could retrieve from the database. For every test I write I could introduce such a new value (or an if-branch or whatever).

But wait ... TDD is more. There is the refactoring part. I could refactor class A using the DB accessor. But I could refactor it in any other way as well (e.g. introducing new classes that encapsulate the data). So, again: How do I write tests that force A to use the database (and nothing else)?

答:
You shouldn't write tests that Force class A to use the database. What you can write are tests which expect that the class calls the Accessor class. How the Accessor class gets its data is up to it, class A is just expecting something back.

It seems to me as though you've come up against the same problem I did when I first started using TDD, thinking all the way along a chain. You write unit tests for each link in the chain. I hope this analogy makes sense.

Title: Why is TDD not working here?


问:
Fair 2-combinations
I need to fairly assign 2 experts from x experts (x is rather small - less than 50) for every n applications, so that:

each expert has the same number of applications (+-1);

each pair of experts (2-combination of x) has the same number of applications (+-1);

It is simple to generate all 2-combinations:

```<code>for (i=0; i<n; i++) {
  for (j=i+1; j<n; j++) {
    combinations.append(tuple(i,j));
  }
}
</code>```

But to assign experts fairly I need to assign a combination to an application i correct order, for example:

```<code>experts: 0 1 2 3 4

fair combinations:
     counts
     01234

01   11000
23   11110
04   21111
12   22211
34   22222
02   32322
13   33332
14   34333
03   44343
24   44444
</code>```

I'm unable to come up with a good algorithm for this (the best I came up with is rather complicated and with O(x4) complexity). Could you help me?

答:
Here's some musings and ideas, although no code:

Given x experts, n applications and each expert has the same number of applications (+-1), you can trivially derive that each expert will average (n/x) applications.  If this is a fraction, some of the experts will round up and the others will round down.

So define a = floor(n/x); b = a+1;  These are your only allowed values for each expert's number of applications.  Additionally, you know that all the a and b combined have to sum to n.

When choosing tuples, you simply pair each a expert with a b expert until you run out of one or the other, then pair up the rest.

Title: Fair 2-combinations


问:
If you had to go back and re-learn your skill set, how would you do it?
My younger brother is looking to start programming. He's 14, and technically-inclined, but no real experience programming. He's looking to me for guidance, and I don't feel as if my experience is enough, so I figured I'd ask here.

He's more interested in web programming, but also has an interest in desktop/mobile/server applications.

What would be a good learning path for him to take? I'm going to buy him a bunch of books for Christmas to get him started; the question is, what should he learn, and in which order?

The way I see it, he needs to learn theory and code. I'd like to start him off with Python or Ruby or PHP. If he wants to get in to web, he's also going to need to learn HTML, CSS, Javascript, etc.

Out of those three domains (Languages, Theory, Markup/Etc.), what is the best order do you think to learn in? Also, am I missing anything?

Thanks!

答:
I would start him off with a C based language. I have found that there are more helpful resources for them. You can also look into getting a book on how to design and format your code so he starts off using good coding principles. I had a class devoted to it and we used a book called, "Clean Code" and another one titled, "Software Development: Design Principles" if I remember correctly. I also wish that I would have been introduced to this site sooner haha.

What helped me the most though was getting an internship early in my college career. I went out to the career fairs as a freshman and received an internship my sophomore year. I also try to have a project that I am working on at all times and I like to do something that I have never done before so I can keep learning. Right now I am working on using a Raspberry Pie and implementing Apple's Siri for a home automation system.

Basically though, do whatever it takes to keep it fun. Don't get frustrated. Take breaks. Don't get too caught up in books. Sometimes the best way to learn is to just go for it and use trial and error.

Oh... and learn how to Google :)

ContentLicense: CC BY-SA 2.5


答:
Depending on how secure the data needs to be, if the web service is restricted to using a Database User account that only has security set up to access the specific data that is needed, then that may be enough to satisfy concerns.  MSSQL has pretty robust security.

I don't think this is a superior solution to replication, but it is an alternative.  So while the replication solution may be cleaner, using MSSQL's security to limit a database account in what it has access to will keep all the data in one place.

Title: Working with data and meta data that are separated on different servers

Body:
While developing a product, I've come across a situation where my group wants to store meta data for data entry forms (questions, layout, etc) in a different database then the database where the collected data is stored.  This is mostly for security because we want to be able to have our meta data public facing, while keeping collected data as secure as possible.

I was thinking about writing a web service that provides the meta information that the data collection program could access.  The only issue I see with this approach is the front end is going to have to match the meta data with the collected data, which would be more efficient as a join on the back end.

Currently, this system is slated to run on .NET and MSSQL.

I haven't played around with .NET libraries running in SQL, but I'm considering trying to create logic that would pull from the web service, convert the meta data into a table that SQL can join on, and return the combined data and meta data that way.

Is this solution the wrong way to approach the problem?  Is there a pattern or "industry standard" way of bringing together two datasets that don't live in the same database?


答:
You just need to cycle the possible pairings in an order that guarantees that the usage counts for each person differ by no more than one.  This is the same problem as generating pairings for a round robin tournament.  If you have an even number of people, one simple technique for generating pairings is to arrange them in two rows.  Hold the top-left person fixed, and rotate the rest.

```<code>1) a b c
   f e d

2) a c d
   b f e

3) a d e
   c b f

4) a e f
   d c b

5) a f b
   e d c
</code>```

In each cycle, "a" is fixed and the other people rotate.  Read pairings vertically.  So you would cycle through pairings as follows:

```<code>af be cd ab cf de ac bd ef ...
</code>```

With an odd number of people, leave the stationary box empty and ignore that column.

Title: Fair 2-combinations

Body:
I need to fairly assign 2 experts from x experts (x is rather small - less than 50) for every n applications, so that:

each expert has the same number of applications (+-1);

each pair of experts (2-combination of x) has the same number of applications (+-1);

It is simple to generate all 2-combinations:

```<code>for (i=0; i<n; i++) {
  for (j=i+1; j<n; j++) {
    combinations.append(tuple(i,j));
  }
}
</code>```

But to assign experts fairly I need to assign a combination to an application i correct order, for example:

```<code>experts: 0 1 2 3 4

fair combinations:
     counts
     01234

01   11000
23   11110
04   21111
12   22211
34   22222
02   32322
13   33332
14   34333
03   44343
24   44444
</code>```

I'm unable to come up with a good algorithm for this (the best I came up with is rather complicated and with O(x4) complexity). Could you help me?

Body:
You just need to cycle the possible pairings in an order that guarantees that the usage counts for each person differ by no more than one.  This is the same problem as generating pairings for a round robin tournament.  If you have an even number of people, one simple technique for generating pairings is to arrange them in two rows.  Hold the top-left person fixed, and rotate the rest.

1) a b c
   f e d

2) a c d
   b f e

3) a d e
   c b f

4) a e f
   d c b

5) a f b
   e d c

In each cycle, "a" is fixed and the other people rotate.  Read pairings vertically.  So you would cycle through pairings as follows:

af be cd ab cf de ac bd ef ...

With an odd number of people, leave the stationary box empty and ignore that column.


答:
If you just wrote calculate() without requiring it to use the database, it would need to get its data from somewhere else.  I know, that sounds trivially simple and boring, but please bear with me.  So write that.  Let's say that "somewhere else" is most naturally a new parameter or two.  Now you can test to your heart's delight without using a real database or mocking one.  And now you have a clean, independent, nicely decoupled unit.  That's good design.  And it's test-driven design.  You can call your new method from a class that does have database access, and feed it from the database.  But testing that interaction will be less arduous, because you already trust - even know - that the calculate() unit is working correctly.  So all the testing you need to do with your database-associated calculation is that it's feeding the right values to your well-tested calculate() method.

That is separation of concerns and that is good design.  You started with an assumption about your design: that calculate() would entail both the concern of database access and the concern of calculation.  That's a somewhat muddy assumption, a somewhat weak design.  And the difficulty you have in testing under that assumption reveals better design.  That is TDD.

Title: Why is TDD not working here?

Body:
I want to write a class A that has a method calculate(<params>). That method should calculate a value using database data. So I wrote a class Test_A for unit testing (TDD). The database access is done using another class which I have mocked with a class, let's call it Accessor_Mockup.

Now, the TDD cycle requires me to add a test that fails and make the simplest changes to A so that the test passes. So I add data to Accessor_Mockup and call A.calculate with appropriate parameters.

But why should A use the accessor class at all? It would be simpler (!) if the class just "knows" the values it could retrieve from the database. For every test I write I could introduce such a new value (or an if-branch or whatever).

But wait ... TDD is more. There is the refactoring part. I could refactor class A using the DB accessor. But I could refactor it in any other way as well (e.g. introducing new classes that encapsulate the data). So, again: How do I write tests that force A to use the database (and nothing else)?


问:
Understanding how memory contents map into a struct
I am not able to understand how bytes in memory are being mapped into a struct.
My machine is a little-endian x86_64. The code was compiled with gcc 4.7.0 from the Win64 mingw32-64 distribution for Win64.

These are contents of the relevant memory fragment:

...450002cf9fe5000040115a9fc0a8fe...

And this is the struct definition:

```<code>typedef struct ip4 {
    unsigned int ihl :4;
    unsigned int version :4;
    uint8_t tos;
    uint16_t tot_len;
    uint16_t id;
    uint16_t frag_off; // flags=3 bits, offset=13 bits
    uint8_t ttl;
    uint8_t protocol;
    uint16_t check;
    uint32_t saddr;
    uint32_t daddr;
    /*The options start here. */
} ip4_t;
</code>```

When a pointer to such an structure (let it be *ip4) is initialized to the starting address of the above pasted memory region, this is what the debugger shows for the struct's fields:

```<code>ip4:          address=0x8da36ce
ip4->ihl:     address=0x8da36ce, value=0x5
ip4->version: address=0x8da36ce, value=0x4
ip4->tos:     address=0x8da36d2, value=0x9f
ip4->tot_len: address=0x8da36d4, value=0x0
...
</code>```

I see how ihl and version are mapped: 4 bytes for a long integer, little-endian. But I don't understand how tos and tot_len are mapped; which bytes in memory correspond to each one of them.

Thank you in advance.

答: tosis mapped to 0x8da36d2, just 4 bytes after ihl, and it uses the byte at that address for storing the value 9f. The compiler seems to use 16-bit alignment here, so the start of tot_len is two bytes later from 0x8da36d4 to 0x8da36d5, and the value at 0x8da36d3 (which seems to be e5in your example) is just unused garbage.


答:
TDD is not about enforcing a specific implementation, a specific algorithm or a specific internal design on your functions.

It just enforces a given signature and a specific input/output behaviour of your functions to some test cases. It will guide you also to decouple your functions from external resources / dependencies. No less, no more. How you build your things internally is still up to you. And if you are going to implement a function specficially in a way that it fulfills all unit tests, but will immediately break in production because it cannot work together with a database, then TDD does not prevent that.

For implementing a real-world, production-ready program, you will have to care using different instruments like

problem solving

algorithm design

making architectural decisions

make decisions about a specfic implementation

integration tests

acceptance testing

These are things TDD cannot really help you with.

Title: Why is TDD not working here?


问:
Notifying a separate application of an event
I have an application that runs through various tasks as an automated process.

My client would like me to create a file in a given folder for each task as a way to flag when each task completes.  They prefer this to a database flag because they can be notified by the file system rather than continually polling a database table.

I can do this but creating and deleting files as flags feels clunky.  Is there a more elegant approach to notifying a third-party of an event?

答:
Message queues are designed for this type of task. ZeroMQ has bindings available in a lot of different languages and a plethora of information about messaging in general. Apache has their ActiveMQ project and there's also RabbitMQ which is using the Advanced Message Queue Protocol (AMQP).

When using a filesystem for these kind of tasks you'll run into some various issues. If working on windows / c# the FileSystemWatcher class is known to have its fair share of issues where it simply misses the change events.

Beyond missing events I would also raise the question to the customer about reliability. If the system that is monitoring the filesystem for changes goes down how will it "catch up" when it does come back online? With a message queue these changes would be sitting in a queue (well, they don't have to be sitting in a queue somewhere but the can be) waiting for the service to come back up and process through them. With a standard filesystem you would be left looking at the current state of the files and not knowing any of the previous changes to the flags.


问:
Is context inheritance, as shown by Head First Design Patterns' Duck example, irrelevant to strategy pattern?
In Head First Design Patterns it teaches the strategy pattern by using a Duck example where different subclasses of Duck can be assigned a particular behavior at runtime.  From my understanding the purpose of the strategy pattern is to change a single object's behavior at runtime, yet they are using inheritance of Duck to change the behavior of various types of Duck.

Relevance?

Is context inheritance of Duck irrelevant to the strategy pattern or is varying Duck types and also varying their behaviors a good reason to employ the strategy pattern? Do situations where you need to vary both constitute a good reason to use strategy pattern?  Why would they include this as the strategy pattern example?

A Simpler Example

Could I further simplify this example by just having a Duck class (no derived classes)?  Then when implementing one duck object it can be assigned different behaviors based on certain circumstances that aren't dependent on its own object type. For example: FlyBehavior changes based on the weather or QuackBehavior changes based on the time of day or how hungry a duck is. I realize this would be solving a different problem than from the one in the book, but what I am looking for is a relevant strategy pattern example to fall back on.

Would my example above constitute the strategy pattern as well?

Edit:

I was successful in finding 2 simpler strategy pattern examples that adhere more strictly to being just strategy patterns without context inheritance: Hunter.java and solver.py.

答:
Could I further simplify this example by just having a Duck class (no derived classes)? Then when implementing one duck object it can be assigned different behaviors based on certain circumstances that aren't dependent on its own object type.

Certainly. For inspiration take a look in Head First Object-Oriented Analysis and Design. There's a "Rick's Guitars" showing an explosion of (musical) Instrument sub-classes. To remedy this all that varying behavior is wrapped in a "specification" class, observing the principle of encapsulate that which varies.

Abstract Factory - Context Based Construction

Here is the pattern. BTW, note that it uses strategy itself.

Focusing on concept, not implementation ...  You might have a "WeatherFactory" that builds specification objects based on sunny or rainy, etc. conditions.

You could have "factories of factories" to get at constructing those "NoFlyInFogQuackableMallard" thingies. And indeed, this is what the Abstract Factory pattern is about. So perhaps a DuckFactory to make general duck-types, then a WeatherFactory to give it duck-type-specific foggy weather behavior.


问:
How can I quickly weed out "copy & paste" coders?
I need a way to filter out resumes of folks who just copy-and-paste code then hope it works, and check it in if it does.  All this happens without having an understanding (or care) to understand the rest of the code in the system.

Sure I know that copying and pasting code is part of learning a new object, control, etc... but how can one tell if that accounts for 70% (or more) of their development career?

I've come across some senior level guys perhaps whose skills are so outdated or irrelevant for the project, that all they do is google, copy-then-paste some code without thinking about the solution as a whole.  As a result we have a mismash of JSON, AJAX, callbacks, ASMX, WCF and postbacks in the same project.  It is clear there is no consistency or logic behind where each technology is being used.

In the worst case, this type of developer creates security issues and vectors for attack.

Question

How would you recommend I filter out people who have a poor programming background?  Can I do it at the resume level?  If not, how do I do this during the interview.

答:
You cannot do this at the resume level as they essentially have infinite time to write that up, but you can do it on a phone interview if you ask a few questions which require technical insight in what they do.  This gives you both the answer (good or bad) and how long time it took them to get there.

When at an interview, make them write code.  It is the only way you can tell if they can program for real.  Make the problem simple, give them a computer with an internet connection, and the IDE you use installed, let them ask any question (except gimme-hte-codez) and watch how they work.

EDIT:  For post-mortem analysis it appears that PMD has a copy/paste detector to find it: http://pmd.sourceforge.net/cpd.html


问:
Name for this antipattern? Fields as local variables
In some code I'm reviewing, I'm seeing stuff that's the moral equivalent of the following:

```<code>public class Foo
{
    private Bar bar;

    public MethodA()
    {
        bar = new Bar();
        bar.A();
        bar = null;
    }

    public MethodB()
    {
        bar = new Bar();
        bar.B();
        bar = null;
    }
}
</code>```

The field bar here is logically a local variable, as its value is never intended to persist across method calls. However, since many of the methods in Foo need an object of type Bar, the original code author has just made a field of type Bar.

This is obviously bad, right?

Is there a name for this antipattern?

答: This looks to me like a horrible misapplication of the Flyweight pattern. I've unfortunately known a few developers who have to use the same "thing" multiple times in different methods and simply pull it out into a private field in a misguided attempt at saving memory or improving performance or some other weird pseudo-optimization. In their mind they are trying to solve a similar problem as Flyweight is meant to address only they're doing it in a situation where it isn't actually a problem that needs solving.</p>


问:
Why not have a High Level Language based OS? Are Low Level Languages more efficient?
Without being presumptuous, I would like you to consider the possibility of this.
Most OS today are based on pretty low level languages (mainly C/C++)
Even the new ones such as Android uses JNI & underlying implementation is in C

In fact, (this is a personal observation) many programs written in C run a lot faster than their high level counterparts (eg: Transmission (a bittorrent client on Ubuntu) is a whole lot faster than Vuze(Java) or Deluge(Python)). Even python compilers are written in C, although PyPy is an exception.

So is there a particular reason for this? Why is it that all our so called "High Level Languages" with the great "OOP" concepts can't be used in making a solid OS?

So I have 2 questions basically.

Why are applications written in low level languages more efficient than their HLL counterparts? Do low level languages perform better for the simple reason that they are low level and are translated to machine code easier?

Why do we not have a full fledged OS based entirely on a High Level Language?

答:
To better phase what I wrote previously.

The Burroughs 5xxx - 6xxx machines did not have an assembly language. The lowest language available was an extension to Algol. The Algol was implemented in hardware. The OS and all languages were written in  Algol. It outperformed all the competitor machines of the time. It also required significantly less code which made it much easier to maintain. It had stack hardware which supported a recursive language such a Algol.

The Burroughs operating system evolved into a version called MCP. MCP currently runs on Unisys systems.


问:
Banking Applications - Saving Account Balance
From what I know, most banking applications periodically store the account balance at a certain point in time as it would not be plausible to calculate it over the entire history of transactions every time it is needed. In order to find the account balance, the application would first load the latest balance saved and add transactions that occurred after that point.

What is this process of saving account balances called? What are some common techniques used in this process?(e.g., run it on every weekend night)

答:
While not specific to the banking industry I would call the technical process snapshotting. </p>

<p>When and how you should take your snapshots is going to vary based on your domain and specific requirements. The main reason to take a snapshot is performance (as you mentioned it saves you from having to go through the entire line of events that brought you to the current point). There is also a performance cost in generating and saving that snapshot. Ideally you should take your snapshots right at the point where the performance cost of taking a snapshot is less than the performance cost of going through the entire chain of events. </p>

Body:
While not specific to the banking industry I would call the technical process snapshotting.

When and how you should take your snapshots is going to vary based on your domain and specific requirements. The main reason to take a snapshot is performance (as you mentioned it saves you from having to go through the entire line of events that brought you to the current point). There is also a performance cost in generating and saving that snapshot. Ideally you should take your snapshots right at the point where the performance cost of taking a snapshot is less than the performance cost of going through the entire chain of events.


答:
MQTT might work for you.  This is a very simple and lightweight publish and subscribe system.  It was invented for embedded devices, but works fine in all sorts of applications.

A zillion Facebook user's can't be wrong, can they?

Title: Notifying a separate application of an event

Body:
I have an application that runs through various tasks as an automated process.

My client would like me to create a file in a given folder for each task as a way to flag when each task completes.  They prefer this to a database flag because they can be notified by the file system rather than continually polling a database table.

I can do this but creating and deleting files as flags feels clunky.  Is there a more elegant approach to notifying a third-party of an event?


答:
There are a number of good reasons for this.

Today's low-level language was yesterday's high-level language

Yes, believe it or not, once upon a time even C was viewed as a high-level language.  Even ~20 years ago it was common enough to see it described as a "mid-level" language.  This was a time before OO was as popular as it is today, Java didn't exist, C# didn't exist, even C++ wasn't properly standardized yet.

Historical Inertia

Operating systems that you use today have deep deep roots in history.  Windows goes back to the early/mid 80s, Unix goes back to the early/mid 70s.  There is a LOT of old, working code in operating systems, and you generally don't want to rewrite old, working code.

At some point you have to go down to the hardware

This happens in the kernel, it happens in drivers, it happens in memory management subsystems, it happens in the filesystem.  Sure you can layer a high-level language on top of it, but you still need the ability to more directly access the hardware that a lower-level language offers.

Portability

I don't mean portability to different hardware or a different OS as it's more commonly understood today; this is more subtle.  There is one major advantage of providing a C-based interface for something, and that is the fact that virtually every other language that exists can link to C.  Even the Windows API is still a C-based API these days for that reason.

Personal Preference

Some people just prefer to program this way, and that can be a major factor.  For example, Linus Torvalds has a famous rant against C++ which makes it pretty clear that as far as he's concerned, C will always be his tool of choice for this kind of work (the content of the rant and whether or not you agree with it is irrelevant to this discussion; the fact that the rant exists is enough).

Taken together, these should clearly establish why an operating system was originally written in something like C back in the old days, and why very significant chunks of it - even today - remain so.

Title: Why not have a High Level Language based OS? Are Low Level Languages more efficient?

Body:
Without being presumptuous, I would like you to consider the possibility of this.
Most OS today are based on pretty low level languages (mainly C/C++)
Even the new ones such as Android uses JNI & underlying implementation is in C

In fact, (this is a personal observation) many programs written in C run a lot faster than their high level counterparts (eg: Transmission (a bittorrent client on Ubuntu) is a whole lot faster than Vuze(Java) or Deluge(Python)). Even python compilers are written in C, although PyPy is an exception.

So is there a particular reason for this? Why is it that all our so called "High Level Languages" with the great "OOP" concepts can't be used in making a solid OS?

So I have 2 questions basically.

Why are applications written in low level languages more efficient than their HLL counterparts? Do low level languages perform better for the simple reason that they are low level and are translated to machine code easier?

Why do we not have a full fledged OS based entirely on a High Level Language?


问:
How is a "Software Developer" different from a "Software Consultant"? What makes a consultant?
I have seen a lot of people claiming themselves to be a "software consultant". These consultants do what a normal software developer does, write code, estimate tasks, fix bugs and attend meetings etc. The only difference being the financials, consultants end up earning more. Then how is a software developer different from a "consultant"?

In addition to the main question, I would like to know how can a software developer become a consultant? Are there any specific guidelines for a consultant? Do they need to amass certifications and write up research papers? Please do not confuse the software consultant with a management consultant. Software consultants I have seen are not managers.

答:
How to become a software consultant:

Go to a copy shop and print some 100 business cards with your name,
your phone number, your mail adress and the title "Software
Consultant".

Mission accomplished: You are now a software consultant.


问:
How many threads should access the file system at the same time?
We have a module in an application which stores data in multiple files and multilevel directories and access them from multiple threads (both reads and writes). The directory structure is based on a splitted hash value, like:

```<code>b1/94/6a/92/a.txt
b1/94/6a/ee/a.txt
a1/0e/db/bb/b.txt
...
</code>```

If a caller removes a file the module deletes empty directories immediately.

How much should be the concurrency level of the module? Is it worth to create and delete folders from multiple threads at the same time? Can filesystems handle these effectively?

Is it worth to use a multi-threaded module? (It would be much easier to write a single-threaded one.)

(The application is written in Java and mainly runs on Windows, NTFS, non-SSDs but I'm also interested in other operating and filesystems if there are  differences.)

答:
Of course any OS will handle multiple requests, but even so when you ask a file system based on physical media with seek times to do more than one thing at once your performance will get progressively worse.  In my experience it's better on the performance side to have just one thread that queues up your requests and then hands them off to the OS sequentially.

One option would be for this thread to separate the unlink operations and hold those until it detects a slack time when few data operations are happening, then delete those directories to keep your data requests as fast as possible and your housekeeping out of the way.

It's obviously a simple solution, but I think that simple is good until some other requirement forces an optimization or reorganization.


问:
What would be the fastest way of storing or calculating legal move sets for chess pieces?
For example if a move is attempted I could just loop through a list of legal moves and compare the x,y but I have to write logic to calculate those at least every time the piece is moved.

Or, I can store in an array [,] and then check if x and y are not 0 then it is a legal move and then I save the data like this
[0][1][0][0] etc etc for each row where 1 is a legal move, but I still have to populate it.

I wonder what the fastest way to store and read a legal move on a piece object for calculation.

I could use matrix math as well I suppose but I don't know.

Basically I want to persist the rules for a given piece so I can assign a piece object a little template of all it's possible moves considering it is starting from it's current location, which should be just one table of data. But is it faster to loop or write LINQ queries or store arrays and matrices?

```<code>public class Move
{
    public int x;
    public int y;
}

public class ChessPiece : Move
{
    private List<Move> possibleMoves { get; set; }

    public bool LegalMove(int x, int y){
      foreach(var p in possibleMoves)
      {
         if(p.x == x && p.y == y)
         {  return true;  }
      }
    }
}
</code>```

Anyone know?

答:
Figuring out the legal moves available for a particular piece on a chess board in a particular chess position is very situational, especially when considering pawns...1 space except when it is on its starting position, then two, and then throw in captures and en passant captures...so building an array of moves that are "mechanically" possible is a bit hairy to start.  In the case of en passant, you even need to know whether the opponents last move enabled en passant, as the move is only valid for one move after the opponent made a move to enable it.

Then it gets further complicated by other situational considerations.  Does the move expose the player's king to check?  For castling, will the king have to move through check (whether final position results in check or not)?  If the king is already in check, does the move counter the check?

I think you would be best off to set up rules for each piece including special considerations, direction and distance, rather than an array to step through, since you literally have to determine where the piece is designed to go, then examine whether the position after it goes there will be legal.


问:
Blank lines in C
I'm working through K&R and I notice that their code is extremely tightly spaced.

I haven't developed C since at University, but professionally most source from other languages I've worked in has used blank lines to aid readability.

Is C generally more tightly packed or is it a historical matter related to display size in the 70s?

Exercise 1-16 seems to hinder readability by, for example, an if immediately after for loop that doesn't have braces.

```<code>/* mygetline: read a line into s, return length */
int mygetline(char s[], int lim)
{
  int c,i;

  for (i=0; i<lim-1 && (c=getchar()) != EOF && c!='\n'; ++i)
    s[i] = c;
  if (c == '\n') {
    s[i] = c;
    ++i;
  }
  s[i] = '\0';
  return i;
}
</code>```

答:
There is a historical dimension to your question. Computers were not always having a screen attached to them. Just think of old command line/ DOS boxes having limited number of lines per screen. Then you can imagine that a programmer wanted to see as much code as possible at once.

Furthermore with teletypewriters, etc. you could not even be sure to have a screen. Blank lines were a waste.

Title: Blank lines in C


问:
How do you educate your customers?
Customers need some education because they think different. Customers think:

changes are not a problem in any time of the project

details are not important (exceptions even less)

time does not cost money (they have a fix price agreed)

one sentence in the specification can be extended/read freely to fit the actual needs - and this does not affect the contract. (here we see often the "common sense" discussion - example: "Of course we need a invoice management screen when we talk about accounting managment - this is common sense!")

the list goes on...

The main problem is that customer (no matter if external or internal/department) do not want or can not understand. It took me many years to understand software creation process and I am still learning, so how can they in just a few months.

What is your experience, what is the best approach to educate customers?

答:
This last summer, I have had a very similar conversation with a customer.

The customer wanted me to provide a competitive price for the defined work, and then when their needs change, or their understanding of their needs change, they wanted to change the spec without allowing me to change the cost to reflect the change in work.

I asked my customer if they had any suggestions for how I could cost for unknown changes as part of the quote.  The solution we worked out was for me to quote including an itemised contingency allowance of 15%, which we would then work with the customer to prioritise their changes to utilise that allowance. In the end the contingency was not completely used I only invoiced for the work done.

The end result was that I was happy I'd been paid for the work done, the customer delivered internally under budget, and because I'd raised the issue in a professional way with them up front they chose me over a competitor to actually do the work.

I just wish all the potential customers out there are this professional and actually value quality workmanship.

Title: How do you educate your customers?


答:
You should profile your app to be sure. Depends on how you use your files it could be bad or very good. If you only read & write to a handful of files, those files will be cached and their blocks will be buffered. It might not touch the disk for some time.

If you create a lot of files & directories and remove them as quick as you create them, then surely you will trash the cache and the buffers. No matter how many threads are doing it.

If you have more processes (not threads), you will get a bigger share of file system time.

Having a thread to gather files read/write requests from other threads is only duplicating the job of the OS and usually OS can schedule and reorder those requests better than what you want to invest time with.

Title: How many threads should access the file system at the same time?

Body:
We have a module in an application which stores data in multiple files and multilevel directories and access them from multiple threads (both reads and writes). The directory structure is based on a splitted hash value, like:

```<code>b1/94/6a/92/a.txt
b1/94/6a/ee/a.txt
a1/0e/db/bb/b.txt
...
</code>```

If a caller removes a file the module deletes empty directories immediately.

How much should be the concurrency level of the module? Is it worth to create and delete folders from multiple threads at the same time? Can filesystems handle these effectively?

Is it worth to use a multi-threaded module? (It would be much easier to write a single-threaded one.)

(The application is written in Java and mainly runs on Windows, NTFS, non-SSDs but I'm also interested in other operating and filesystems if there are  differences.)


答: Umm, I'm not sure what you are attempting to do here, but are you sure your needs wouldn't be better served by using a database rather than accessing the filesystem directly. A database would handle multiple concurrent requests for you and help guard against race conditions. </p>


问:
get weighted random item
I have, for example, this table

```
+-----------------+
| fruit  | weight |
+-----------------+
| apple  |   4    |
| orange |   2    |
| lemon  |   1    |
+-----------------+
```

I need to return a random fruit. But apple should be picked 4 times as frequent as Lemon and 2 times as frequent as orange.

In more general case it should be f(weight) times frequently.

What is a good general algorithm to implement this behavior?

Or maybe there are some ready gems on Ruby? :)

PS

I've implemented current algorithm in Ruby https://github.com/fl00r/pickup

答:
This gist is doing exactly what you are asking for.

```<code>public static Random random = new Random(DateTime.Now.Millisecond);
public int chooseWithChance(params int[] args)
    {
        /*
         * This method takes number of chances and randomly chooses
         * one of them considering their chance to be choosen.
         * e.g.
         *   chooseWithChance(0,99) will most probably (%99) return 1
         *   chooseWithChance(99,1) will most probably (%99) return 0
         *   chooseWithChance(0,100) will always return 1.
         *   chooseWithChance(100,0) will always return 0.
         *   chooseWithChance(67,0) will always return 0.
         */
        int argCount = args.Length;
        int sumOfChances = 0;

        for (int i = 0; i < argCount; i++) {
            sumOfChances += args[i];
        }

        double randomDouble = random.NextDouble() * sumOfChances;

        while (sumOfChances > randomDouble)
        {
            sumOfChances -= args[argCount -1];
            argCount--;
        }

        return argCount-1;
    }
</code>```

you can use it like that:

```<code>string[] fruits = new string[] { "apple", "orange", "lemon" };
int choosenOne = chooseWithChance(98,1,1);
Console.WriteLine(fruits[choosenOne]);
</code>```

The above code will most probably (%98) return 0 which is index for 'apple' for the given array.

Also, this code tests the method provided above:

```<code>Console.WriteLine("Start...");
int flipCount = 100;
int headCount = 0;
int tailsCount = 0;

for (int i=0; i< flipCount; i++) {
    if (chooseWithChance(50,50) == 0)
        headCount++;
    else
        tailsCount++;
}

Console.WriteLine("Head count:"+ headCount);
Console.WriteLine("Tails count:"+ tailsCount);
</code>```

It gives an output something like that:

```<code>Start...
Head count:52
Tails count:48
</code>```

ContentLicense: CC BY-SA 4.0

Title: get weighted random item

Body:
This gist is doing exactly what you are asking for.

public static Random random = new Random(DateTime.Now.Millisecond);
public int chooseWithChance(params int[] args)
    {
        /*
         * This method takes number of chances and randomly chooses
         * one of them considering their chance to be choosen.
         * e.g.
         *   chooseWithChance(0,99) will most probably (%99) return 1
         *   chooseWithChance(99,1) will most probably (%99) return 0
         *   chooseWithChance(0,100) will always return 1.
         *   chooseWithChance(100,0) will always return 0.
         *   chooseWithChance(67,0) will always return 0.
         */
        int argCount = args.Length;
        int sumOfChances = 0;

        for (int i = 0; i < argCount; i++) {
            sumOfChances += args[i];
        }

        double randomDouble = random.NextDouble() * sumOfChances;

        while (sumOfChances > randomDouble)
        {
            sumOfChances -= args[argCount -1];
            argCount--;
        }

        return argCount-1;
    }

you can use it like that:

string[] fruits = new string[] { "apple", "orange", "lemon" };
int choosenOne = chooseWithChance(98,1,1);
Console.WriteLine(fruits[choosenOne]);

The above code will most probably (%98) return 0 which is index for 'apple' for the given array.

Also, this code tests the method provided above:

Console.WriteLine("Start...");
int flipCount = 100;
int headCount = 0;
int tailsCount = 0;

for (int i=0; i< flipCount; i++) {
    if (chooseWithChance(50,50) == 0)
        headCount++;
    else
        tailsCount++;
}

Console.WriteLine("Head count:"+ headCount);
Console.WriteLine("Tails count:"+ tailsCount);

It gives an output something like that:

Start...
Head count:52
Tails count:48


答: K&R was written in the heart of the "Glass TTY" era, when the standard resolution screen was 80 characters by 24 lines.   Whitespace was a luxury that usually lost out to the desire to keep the relevant lines of code visible.</p>

Title: Blank lines in C

Body:
I'm working through K&R and I notice that their code is extremely tightly spaced.

I haven't developed C since at University, but professionally most source from other languages I've worked in has used blank lines to aid readability.

Is C generally more tightly packed or is it a historical matter related to display size in the 70s?

Exercise 1-16 seems to hinder readability by, for example, an if immediately after for loop that doesn't have braces.

```<code>/* mygetline: read a line into s, return length */
int mygetline(char s[], int lim)
{
  int c,i;

  for (i=0; i<lim-1 && (c=getchar()) != EOF && c!='\n'; ++i)
    s[i] = c;
  if (c == '\n') {
    s[i] = c;
    ++i;
  }
  s[i] = '\0';
  return i;
}
</code>```


问:
What are good reasons to drop Windows XP support?
Recently the software team in my company decide to use VS2012 (upgrade from VS2008) but we found out that VS2012 does not provide a nice support for Windows XP (e.g. really hard to deploy .Net 3.5 managed C++ project).

So we want to convince our manager to drop Windows XP compatible development and and target Windows 7 only. This allows us to use some new technologies such as .Net 4.5 (we are using 3.5 ATM). But we have many existing customers are using Windows XP and they will not able to upgrade to new version of our software (we may still provide bug fixes for XP though).

So what are some good reasons to use VS2012 and drop XP compatibility?

What in my list currently:

Able to use .Net 4.5

Use VS2012 (without compile some project using VS2008 tool chain)

No need to test on XP machine

答:
Windows XP has been out of mainstream support since April 2009, and is due to go out of extended support in April 2014.  What that means for your customers is that from April of next year they will be getting no security updates, no MS Knowledge Base support, no paid support, no nothing.

See the Microsoft Support Lifecycle Policy FAQ for further information on this.

In other words, while XP may very well still work, if anything does go wrong they're on their own.  In particular, it seems reasonable to expect that there will be quite an onslaught of exploits in the months following April, designed by malware authors to catch any XP holdouts.

Given the timescales involved, now is close to the last possible minute for most corporations to seriously start evaluating an upgrade.  Many of your customers may have already advanced beyond the planning stage, and you may find it useful to talk to them about what their own plans are for transitioning from XP.

Despite this, I personally don't think that you should be dropping XP support just yet.  If I were in your shoes, I'd be aiming to drop XP support at the same time as Microsoft do.  That seems reasonable, and would allow you a good time window to start building and testing on 7+, which you're definitely going to need as there are some significant changes between the versions which you're going to need to deal with.


答:
Every line of code you keep on the screen is saved time when programming.

In the days of the K&R being written, the screens were 80 characters wide by 24 lines tall.  This is all that you could see at the time on one page.  Visual editors were not yet written - you had tools that were more along the lines of ed (written in 1971, C is from 1972).

When working in such an environment, vertical space is important.  Unnecessary braces to denote a block represent a 'wasted' line on the screen.  Putting an open curly brace on its own line is another wasted line.  Elses with ears } else {  represents two lines saved on the screen.

When tracing program flow it can become difficult to keep things in your head, your code size becomes limited to about one screen size (even today that is true), maybe two.  While printing lines in line editors isn't cumbersome it isn't just scrolling down the mouse on the side of the screen (or hitting page down in vi), it is commands such as .,.+10p to print the next ten lines, or .-10,.+10 to "scroll up 10 lines and display the next ten lines too" - it isn't exactly easy either to navigate the code, or move from "page" to "page".

If one looks at How many lines of code is too many? on StackOverflow, one will see several references to "screen size".

We unconsciously can keep in our head what we can see - swapping out to screen.  If you were to be asked a question about something that is on the page of a book you are reading, it is in short term memory and you can quickly see it and look at it to get the rest of the memory quickly.  When asked about something two pages ago, you may have to go back and refresh your memory.  This is even more critical when working with programs because the small things matter (x++ vs ++x).  So now you've got to go back and "scroll" with ed, which takes some thought too (which becomes one of the spots of seven plus or minus two and pushed out something else).

On the other "not space saving" things in the block of code and their reasons...

If anything, I am surprised at the code at not saving more space:

```<code>int mygetline(char s[], int lim)
{
  int c,i;

  for (i=0; i<lim-1 && (c=getchar()) != EOF && c!='\n'; ++i)
    s[i] = c;
  if (c == '\n')
    s[i++] = c;
  s[i] = '\0';
  return i;
}
</code>```

By moving the increment into the assignment of the array two lines can be removed (and yes, there are even more lines that can be removed for more dense code, the K&R appears to maintain the code style of the open brace for a function on a line by itself and a blank line between declarations and code).

The open brace on a line by itself is likely from the original style of C functions declaration.  From Section 1.7 in K&R (second edition):

```<code>/* power:  raise base to n-th power; n >= 0 */
/*         (old-style version) */
power(base, n)
int base, n;
{
    int i, p;

    p = 1;
    for (i = 1; i <= n; ++i)
        p = p * base;
    return p;
}
</code>```

You can see the awkwardness of moving the open curly for power onto a previous line - and if anything, it helps keep the function declaration identifiable.

Likewise, keeping a declaration block at the top and then a blank line.  This was important in some early compliers where declarations could only happen at the top of a block.  Separating the two helped ensure you didn't make a mistake by interweaving declarations and code (this was prohibited as recently as C89 - C89, Mixing Variable Declarations and Code).  Making the declaration block separate could save you a pass through the complier (not necessarily a quick thing).

Title: Blank lines in C

Body:
Every line of code you keep on the screen is saved time when programming.

In the days of the K&R being written, the screens were 80 characters wide by 24 lines tall.  This is all that you could see at the time on one page.  Visual editors were not yet written - you had tools that were more along the lines of ed (written in 1971, C is from 1972).

When working in such an environment, vertical space is important.  Unnecessary braces to denote a block represent a 'wasted' line on the screen.  Putting an open curly brace on its own line is another wasted line.  Elses with ears } else {  represents two lines saved on the screen.

When tracing program flow it can become difficult to keep things in your head, your code size becomes limited to about one screen size (even today that is true), maybe two.  While printing lines in line editors isn't cumbersome it isn't just scrolling down the mouse on the side of the screen (or hitting page down in vi), it is commands such as .,.+10p to print the next ten lines, or .-10,.+10 to "scroll up 10 lines and display the next ten lines too" - it isn't exactly easy either to navigate the code, or move from "page" to "page".

If one looks at How many lines of code is too many? on StackOverflow, one will see several references to "screen size".

We unconsciously can keep in our head what we can see - swapping out to screen.  If you were to be asked a question about something that is on the page of a book you are reading, it is in short term memory and you can quickly see it and look at it to get the rest of the memory quickly.  When asked about something two pages ago, you may have to go back and refresh your memory.  This is even more critical when working with programs because the small things matter (x++ vs ++x).  So now you've got to go back and "scroll" with ed, which takes some thought too (which becomes one of the spots of seven plus or minus two and pushed out something else).

On the other "not space saving" things in the block of code and their reasons...

If anything, I am surprised at the code at not saving more space:

int mygetline(char s[], int lim)
{
  int c,i;

  for (i=0; i<lim-1 && (c=getchar()) != EOF && c!='\n'; ++i)
    s[i] = c;
  if (c == '\n')
    s[i++] = c;
  s[i] = '\0';
  return i;
}

By moving the increment into the assignment of the array two lines can be removed (and yes, there are even more lines that can be removed for more dense code, the K&R appears to maintain the code style of the open brace for a function on a line by itself and a blank line between declarations and code).

The open brace on a line by itself is likely from the original style of C functions declaration.  From Section 1.7 in K&R (second edition):

/* power:  raise base to n-th power; n >= 0 */
/*         (old-style version) */
power(base, n)
int base, n;
{
    int i, p;

    p = 1;
    for (i = 1; i <= n; ++i)
        p = p * base;
    return p;
}

You can see the awkwardness of moving the open curly for power onto a previous line - and if anything, it helps keep the function declaration identifiable.

Likewise, keeping a declaration block at the top and then a blank line.  This was important in some early compliers where declarations could only happen at the top of a block.  Separating the two helped ensure you didn't make a mistake by interweaving declarations and code (this was prohibited as recently as C89 - C89, Mixing Variable Declarations and Code).  Making the declaration block separate could save you a pass through the complier (not necessarily a quick thing).


问:
Best practices for merging a new version of third party source into an old version you've made changes to
A project I work on uses source code that's been purchased from a third party.  The source code is delivered to us in a zip file.  We store this source code in version control (TFS 2010) and routinely make modifications to it.

When the third party releases a new version of the product we've purchased, I need to merge their new code into ours.  Because the code I get is not under any kind over version control, it's very difficult to do this merge correctly.

The last time I did this, we had not made many changes. As a result, I was able to check all the files out, copy the new files into their place, and fix up everything by hand without the help of any merging tools.  Now that we've got a much larger set of changes, fixing things up by hand is too fragile to be a viable option.

Are there any better ideas, or is this doomed to be painful and fragile each time?

答:
The best tool for that is a good diff/merge tool. Most of those support three way merging. With that you take the old original code, your modifications and their modifications and get them in three panes side by side and can see who changed what.

I'm mostly using meld, but there are tons of other such tools working more or less equally well.


问:
Should I Use Native Generic PHP or a Framework
I'm working with a team i just met.

I've been using the normal native generic php for coding up until now,
and built several webapps with it.
But a team member suggests we switch to using a framework for development.
I personally prefer going the normal way, using native generic PHP codes,
but he Suggests we use a framework.

I learnt Code Igniter has problem with loading images,
and this is one problem with some frameworks, they have some difficulties you just have to go with, unlike writing native PHP Codes.

I have a large archive of PHP Codes, that does the work of what some Framework does,
i can use this and implement it in the WebApp.

Is it better to go with a Framework or Go Native & Generic PHP.

Another thing is that, this is a web app for mobile devices, which me and the team are developing for a company, and there will be need for maintenance in the nearest future, if we are not available for the maintenance.

Our codes has to be very simple, not too ambiguous and self explanatory, and with comments too, for the future developer. Which is why i'm thinking we write out our own codes, and make it very Simple in the best possible way.

答:
This article gives an overview of some reasons that you might want to use a framework. To me it sounds like you've built up your own custom framework.

Points like less code for faster development and neat and tidy code/files are good points to consider when starting from scratch.

The Job oppertunities point is one to consider for yourself and your personal development.  It's also work considering the inverse of this which is your going to appear a more desirable place to work when/if you attempt to hire on more staff.  The staff you hire will also be productive faster if they can quickly recognise the patterns in the code.

Performance and security are always good things to think about as well.

It's also worth considering if your coworker is politely trying to say that they are finding the current code base difficult to work with and would like some more predictable structure.

In conclusion my opinion would be yes use a framework, it'll make things easier in the long run.


问:
How ensure secure two cloud services can only talk to each other?
Question

Given two cloud services, Sender A & Receiver B, communicating over HTTPS, what options do I have to ensure that Receiver B only response to Sender A?  For the purposes of

Background

The receiver is generating activation keys for some hardware from a serial number.  Our support team is using Salesforce and we're making callouts from Salesforce to an Azure service to generate the key.  Since neither are behind a firewall we want to make sure that only request from our Salesforce instance can generate an activation key.

My thought was just to create a nice long key stored on both sides that could be used to validate the request, but I'm not a security expert and don't know if there is anything else I should be considering.

答: You're probably looking for client certificates.  It depends on the cloud environment's ability to allow you manage the ssl certificates, but here is another stackexchange article about it:  https://security.stackexchange.com/questions/14589/advantages-of-client-certificates-for-client-authentication</p>


问:
Backend devs put down by user stories
I planned to slice in backend development into to the user stories vertically.
But a backend guy on our team started to complain that this makes their work invisible.

My answer was that

at the sprint planning and review meetings we discuss backend tasks
in front of stakeholders so it makes it visible, and

maintaining a high quality during the project will result a slower
startin pace than other teams, but we will have a stable velocity
during the project. And velocity is highly visible to stakeholders.

He still insist having stories like:
"As a developer
I need to have a domain layer
so I can encapsulate business logic."

How can I solve the issue before it pollutes the team?

The root of the issue is that our management systematically consider backend work as invisible and call backed devs miners, or other pejorative terms.

答:
Your problems are:

You have layers of management up in your business where they serve no purpose. Scrum, agile, I don't care. Management and development should be isolated with business concerns handled by a product manager who has a !@#$ing clue about technology. Maybe it worked for Steve Jobs but I have never been in a situation where non-tech-adept managers being close to dev was a healthy thing or ultimately served to produce the best quality product a team could have made.

You have devs who are more worried about appearances than they are solving problems. That is either a very serious culture problem (seems likely given this whole "miner" phenomenon) and/or you have a dev quality issue, which also wouldn't shock me given the lack of confidence.

Get the people who don't need to be there out of planning and standup. Anybody who has notions about back-end being any less important than front-end is somebody who doesn't need to be there and is in fact hampering the process by being there.

Ditch stories. Yes, I'm serious. If they're causing these kinds of issues, toss 'em out the airlock. At my current job we just stick to the "done" criteria for a given task, which typically stays more focused on the app than the user of it which may offend those who think agile (which has been changing constantly for 20ish years) won't work if you don't follow it to the letter, but really if we're pros, we don't need anything that's causing problems for us. Crumple 'em up, toss 'em over your shoulder.

And you might want to remind that dev that the people they really need to worry about are their immediate peers, not the folks who are too clueless to be at sprint planning.

Title: Backend devs put down by user stories


答:
Something to add on to @Klee points, on a team member's point of view it is much better that everyone is working on the same page with a known documented framework, which might not be the case with your own archive PHP codes.

Also you might want to start converting some of your archive codes to use-able modular libraries so you/your team can readily extend the framework if similar functions are not provided.

Title: Should I Use Native Generic PHP or a Framework

Body:
I'm working with a team i just met.

I've been using the normal native generic php for coding up until now,
and built several webapps with it.
But a team member suggests we switch to using a framework for development.
I personally prefer going the normal way, using native generic PHP codes,
but he Suggests we use a framework.

I learnt Code Igniter has problem with loading images,
and this is one problem with some frameworks, they have some difficulties you just have to go with, unlike writing native PHP Codes.

I have a large archive of PHP Codes, that does the work of what some Framework does,
i can use this and implement it in the WebApp.

Is it better to go with a Framework or Go Native & Generic PHP.

Another thing is that, this is a web app for mobile devices, which me and the team are developing for a company, and there will be need for maintenance in the nearest future, if we are not available for the maintenance.

Our codes has to be very simple, not too ambiguous and self explanatory, and with comments too, for the future developer. Which is why i'm thinking we write out our own codes, and make it very Simple in the best possible way.


答:
I can say nothing about TFS, but in other SCMs with good branching/merging it's known as "Vendor branching" workflow.

In short: your repository will get (at least) two branches - f.e Vendor and Custom

In Vendor branch you'll store vanilla versions of code as is, Custom branch will get your local modification on top of original.

Process of update is rather straightforward:

Update sources in Vendor with new version, commit

Merge Vendor into Custom

Not-conflicted changes (no intersection of upstream changes with own) will be merged automatically, conflicts must be resolved by hand

Title: Best practices for merging a new version of third party source into an old version you've made changes to

Body:
A project I work on uses source code that's been purchased from a third party.  The source code is delivered to us in a zip file.  We store this source code in version control (TFS 2010) and routinely make modifications to it.

When the third party releases a new version of the product we've purchased, I need to merge their new code into ours.  Because the code I get is not under any kind over version control, it's very difficult to do this merge correctly.

The last time I did this, we had not made many changes. As a result, I was able to check all the files out, copy the new files into their place, and fix up everything by hand without the help of any merging tools.  Now that we've got a much larger set of changes, fixing things up by hand is too fragile to be a viable option.

Are there any better ideas, or is this doomed to be painful and fragile each time?


问:
TDD Mock call verification - is it an anti-pattern?
I've been doing TDD for a while now, I feel pretty good about it, I love my test suites and all. However I've noticed that lately I've been doing a lot of mock call verification. For example I'd have a Service that will have a Repository injected - in my unit test I'd pass a mock of the Repository and verify that it was called within the method that I'm testing. I'd then check if the results returned are correct (in another test). This definitely "feels" wrong, since my unit tests are now tightly coupled to the implementation details. I've heard that you should test "behavior", however in a lot of the situations that's ... emm - not possible? If you have a void method for example, you usually test side-effects. I mean it's easy to go ahead and show some simple code-kata's where this can be demonstrated, but IMHO it doesn't reflect very well to the real world programs that we write. Is what I'm doing wrong? Is this type of testing sort of an anti-pattern? I'd appreciate your opinion on this.

答:
Well, you should be trying to test inputs and outputs. You should be verifying externally visible behavior. The "promises" or "contract" that your class makes.

At the same time sometimes there's no better way to test a method than to do what you said.

I do think that it makes your test more brittle, so you should avoid tests that rely on implementation details if you can, but it's not an all-or-nothing deal. It's OK sometimes, the worst thing that happens is you change the implementation and have to update the test.


问:
What is the most inspiring speech from a developer you ever watched?
Please put a direct link to it.

Required:

Still available online (please put a direct link to it)

Must be a speech from a current or former developer

Speaker's popularity doesn't matter

Target audience should be other developers

It is not required that the topic is programming (the task). I'm more looking for subject generally developing here within P.SE rather than SO.

Explain why it was inspiring

(please, native english speaker, edit my question)

答:
The Principles of Agile Design:
http://www.infoq.com/presentations/principles-agile-oo-design

Pretty much hits the nail on the head as to why your code becomes unmanegable as time goes by, and what can be done about it.


问:
When deploying updates, do you deploy all or selected/changed assemblies?
I'm a developer and I have had several experiences in web application deployment which are the following:

Deploy all files then apply configuration values as appropriate to the environment. We've used this style of deployment for larger softwares with long development cycles and quick releases aren't needed or allowed unless for emergencies.

Deploy only what has changed; manually update configuration files with what new or updated configuration as appropriate to environment. We've used this style for web applications that tend to be more agile, i.e. fix and feature releases are almost done daily. I've had issues with this before where not all assemblies dependent on an assembly that has changed were identified (A constant value was change in assembly A and the same constant was used in assembly B and only assembly A identified as changed).

Which of the 2 is a better (or best) practice? I'm starting a new medium sized project where deployments would be on a monthly basis and would like to establish this process early on.

答:
I like deploying everything. To me it ensures that both the deployment and configuration are completely repeatable, and if you use this process for populating your DEV and QA environments, you're testing it on a very regular basis.

As you've seen, if you only deploy what has changed, or what your deployment process thinks has changed, there is a risk of code updates and configuration adjustments falling out of sync. That could make it hard to reproduce the exact process environment if you needed to. (think failed backups, crashed servers, or just debugging difficult problems)

Your mileage may vary, but I've been using some form of method #1 for a long time with good success.


问:
Should user input of a contact form be validated?
On software company websites I visit the first time, I often open the "Contact us" page and try to submit the contact form with all fields empty. I am just curios if they validate the user input.

If it is just submitted or only validated poorly (e.g. only Javascript validation), I often hear myself thinking

Oh, look how sloppy they are! Can't even validate user input. That calls itself a software company? No, I don't think I want to buy any software services of them.

A friend of mine has such a "sloppy" contact form. You can submit a completely empty form. I asked him why he does not validate user input, and he said:

Look, I want that customers can contact me. They should enter any information they want. If they only want to enter a message and leave the other fields empty, why should I care? They enter the relevant information anyway. I do not want to add any barriers when contacting me.

I did not ask him how many empty messages he gets, though.

However, what is the better option now? Both arguments (check how company handles user input vs. not adding any barriers in contacting) seem to make sense for me.

I want that the user can easily contact me, but still has the impression that I am precise when programming webpages.

答: Depends on the requirements. In general, you should strike a balance between no and too much validation. I would validate on fields that are required to be meaningful all the time, like phone numbers, email addresses and the like. Free text fields are of course free of validation. I would say not validating on empty forms is a waste of round-trip and storage (if it does get saved!). One thing you should consider for contact forms as with all input is validating/sanitizing against cross-site scripting.</p>


问:
Building a sequential list in languages with cons/linked lists
In languages where cons lists are a major datatype, it is very easy to create a list from last to first by prepending items. When doing processing from some input file, however, one is most likely to encounter items in first to last order.

Do languages like these typically recurse?

```<code>(define (parse file)
  ...
  (cons datum (parse file)))
</code>```

Use append operations at each step? Build the list in reverse order and then reverse it?

Is there some canonical design pattern that can solve the problem that input is typically going to be in the reverse order of the way the list is constructed?

答:
Yes, languages that favor recursive data types almost always also favor recursive functions, and for this kind of stream processing it is the obvious solution. (Particularly if the language runtime supports tail recursion elimination, which it usually does.) With recursive processing, the list in fact comes out in the right order, so everything is well.

Appending is often comparably expensive and would make a linear problem effectively into a quadratic one, therefore it is usually an anti-pattern in functional programming languages.


答:
From UX point of view

and try to submit the contact form with all fields empty

  [...]

  If they only want to enter a message and leave the other fields empty, why should I care?

You and your friend are not talking about the same scenarios.

Letting the user submit all fields empty on a contact form is a mistake, because there are no valid cases where the customer would be contacting you while saying nothing. If he has nothing to say, why is he submitting a form?

The only possible scenario where the customer actually submits an empty contact form is that he pressed Enter by mistake when the focus was on a single-line text field (or he pressed by mistake the submit button).

Validation, at this level, at least client-side one, is a must-have and has a specific purpose. If a customer is submitting an empty contact form, he should be notified that something is wrong and the submission should be prevented.

Making all field mandatory on a contact form is not a solution neither. When I want to tell someone that there is a typo on the home page of their website, I don't want to think about the subject of the message, I don't want to give my email address, I don't want to give my phone number,  and I don't want to specify the name of my girlfriend, because, damn it, all I want is to tell is that there is a typo.

From technical point of view

Processing submitted contact forms is a complicated task which requires lots of time. Filtering technically the submissions you don't need improves productivity of the person in charge of reading those messages.

There is no need to display the empty messages in the administration panel. I would even say that messages with a length inferior to, say, ten characters, are useless, and shouldn't be displayed neither.

On the other hand, doing validation response properly is a difficult task: you have to implement validation itself both server-side and optionally client-side, and respond properly with a (often) localized error message or a cleaner, more UX-oriented way.

For the sake of simplicity and given the specificity of the case, I wouldn't do any server-side validation response, only client-side. If the user with no JavaScript wants to submit an empty contact form, that's fine: administrators will never see those submissions, but the customer will be convinced that the form was submitted successfully. This case is too specific (i.e. the user doesn't have JavaScript, makes a mistake when submitting a form and this mistake doesn't affect the system) to handle specifically.

Title: Should user input of a contact form be validated?

Body:
On software company websites I visit the first time, I often open the "Contact us" page and try to submit the contact form with all fields empty. I am just curios if they validate the user input.

If it is just submitted or only validated poorly (e.g. only Javascript validation), I often hear myself thinking

Oh, look how sloppy they are! Can't even validate user input. That calls itself a software company? No, I don't think I want to buy any software services of them.

A friend of mine has such a "sloppy" contact form. You can submit a completely empty form. I asked him why he does not validate user input, and he said:

Look, I want that customers can contact me. They should enter any information they want. If they only want to enter a message and leave the other fields empty, why should I care? They enter the relevant information anyway. I do not want to add any barriers when contacting me.

I did not ask him how many empty messages he gets, though.

However, what is the better option now? Both arguments (check how company handles user input vs. not adding any barriers in contacting) seem to make sense for me.

I want that the user can easily contact me, but still has the impression that I am precise when programming webpages.


答: Alan Kay's OOPSLA 1997 speech: The Computer Revolution hasn't happened yet.

Title: What is the most inspiring speech from a developer you ever watched?

Body:
Please put a direct link to it.

Required:

Still available online (please put a direct link to it)

Must be a speech from a current or former developer

Speaker's popularity doesn't matter

Target audience should be other developers

It is not required that the topic is programming (the task). I'm more looking for subject generally developing here within P.SE rather than SO.

Explain why it was inspiring

(please, native english speaker, edit my question)


问:
What is better: multiple sql entries or one sql entry with a list field?
Suppose that I have the following logical information:
(tag_name, id). For example: (food, 1),(food, 2),(food, 3),(drink, 1),(drink, 2)

I'm trying to decide what is the best way to store it in a database. I can simply use a (STRING, INTEGER) table like in the example, or a more compact (STRING, INTEGER_LIST), like so: (food, [1,2,3]),(drink, [1,2]). This method is definitely more compact, but the other method seems more trivially flexible (for example, I can do a join by tag_name or id with another table, and I don't need to parse the results of my SQL queries).

Which method is better, and why? Is the redundancy of the first method overwhelmingly wasteful, or are SQL databases smart enough to figure out efficient storage for that? Is the post-query processing that the second method needs (like checking if an id is already associated with a tag before adding it) more expensive than putting this burden on the database in the first method?

答: Never, ever try to stuff set-typed values into one attribute because it looks easier than creating another relation. Data bases live for handling relational data efficiently. Unless you think you could write a better storage method than e.g. the Postgres or Oracle maintainers, it is a bad idea to try to manage relations by serializing and processing them yourself.


答:
A best solution for your question is to decide with your team members about this matter and which is best using a framework or Native generic programming .I suggest you to develop your own framework which contains all features your team want.

There are plenty of tutorials available i internet , see a tutsplus tutorial on php framework development :-

Php5 framework development


答: You should validate your form before user submission .Because if you did'nt validate the fields properly user can submit empty forms without any data .</p>


答:
How much will your client pay to have a XP-compatible application? (Think maintenance cost over several years)

How much will your client pay to replace its old XP workstations by new Seven ones? (Which is probably already planned)

Title: What are good reasons to drop Windows XP support?

Body:
Recently the software team in my company decide to use VS2012 (upgrade from VS2008) but we found out that VS2012 does not provide a nice support for Windows XP (e.g. really hard to deploy .Net 3.5 managed C++ project).

So we want to convince our manager to drop Windows XP compatible development and and target Windows 7 only. This allows us to use some new technologies such as .Net 4.5 (we are using 3.5 ATM). But we have many existing customers are using Windows XP and they will not able to upgrade to new version of our software (we may still provide bug fixes for XP though).

So what are some good reasons to use VS2012 and drop XP compatibility?

What in my list currently:

Able to use .Net 4.5

Use VS2012 (without compile some project using VS2008 tool chain)

No need to test on XP machine


答: Rich Hickey's Clojure presentation at the JVM Languages Summit 2008 led me to try it out: http://www.infoq.com/presentations/hickey-clojure</p>


答:
In one comment you say most of your customers are using XP.

You make the false assumption that it's good for your company to drop XP support.

You come with technical reasons but the only good reason you can give to your manager to drop XP support is:
"It's going to make us more money."
That's the only reason there is. And honestly I don't think you have a case for that.


问:
Modeling user in MongoDB
Our team is learning to work with MongoDB. We have to model the user among other things for an OAuth-based application. We know how to model in the relational world, but are unsure about how to do it in NoSQL.

In our application we identify the user uniquely by her email address. Email addresses are naturally unique and also verifiable. The email address seems to be a good candidate for a key.

We don't model the person. We don't have the possibility to identify a person, only her email address. That means, if a person has more than an email address, she would have several documents in the database. Also if she changes her email address she would use a different document. And also, because people login with OAuth, there's no concept of them managing their data. There's no password, and the user name is given by OAuth.

Why not using the email adress for a collection's primary key _id? Like this:

```<code>{
  _id: "john.doe@example.com",
  name: "John Doe",
  provider: "example.com",
  comments: [
    // all comments
  ]
}
</code>```

What are the pros and cons of such an approach?

Edited to clarify the difference between person and user

答:
This answer is not related to MongoDB in anyway, but more to the applicability of using email as a key for your user objects.

If your application is some sort of internet based application where users sign up with their email address, then it is perfectly possible that a user will get a new email address over time, and the users would want to update the registered email address.

This will lead to some challenges, if you use the email as a key.

You say you treat a person with several email addresses as several users. But there is a difference between one user having several email addresses, and one user changing his primary email to a new one. Locking down on such a design decision limits your possibilities of modifying the system in new ways in the future. At least it makes it more difficult.

If the system was some sort of internal line of business system for a company, the email might not change as it would probably be the corporate email address.

But as a general rule of thumb, I would always choose my key to be some computer generated value, and not a value that has a meaning in the real world (see surrogate key).

Title: Modeling user in MongoDB


答:
One common way to do this efficiently, at least in Haskell, is using a difference list which permit O(1) snoc, which is the inverse of cons (yes, it's a silly name).

An alternative is not using linked lists in favor of a more appropriate data structure, such as finger trees (Data.Seq in Haskell, amortized constant time cons/snoc) or queues (there are persistent queues with constant time operations, both amortized and worst-case).

Title: Building a sequential list in languages with cons/linked lists

Body:
In languages where cons lists are a major datatype, it is very easy to create a list from last to first by prepending items. When doing processing from some input file, however, one is most likely to encounter items in first to last order.

Do languages like these typically recurse?

```<code>(define (parse file)
  ...
  (cons datum (parse file)))
</code>```

Use append operations at each step? Build the list in reverse order and then reverse it?

Is there some canonical design pattern that can solve the problem that input is typically going to be in the reverse order of the way the list is constructed?