问:
Best practices when dealing with lots of empty table columns?
I have a schema that allows for multiple post types in my Django project (kinda like Tumblr). Users can make Posts of different types. One of those types is a photo, which I'll want the EXIF data for.

If I have a super generalized table, does it make sense to create additional columns for the exif data? This would result in a ton of empty columns for every post type that isn't Photo.

Alternatively, would it make sense to create a separate model for photos completely and create a foreign key to the Posts model instead?

答:
What you are basically referring to is modelling inheritance in a database. You might find this answer on Stack Overflow useful. There are a few other similar questions answered in similar ways there too.

In terms of choosing which of the 3 options to follow, there's a couple of factors which I think you would find important. I'd say the first consideration is just how many properties your post types have in common. If they are many types, all 90% the same, you probably don't want a table per concrete (TPC).

Next, I'd consider which of the models are supported nicely by the django ORM. You don't want to pick the most pure solution from a relational database perspective, that becomes awful to use because of the limitations of your data layer.

My tendency would be to go for table per type, but most of my time is spent working without a "modern" fancy ORM, and optimization of my schema is important. It will likely have the result of making queries more complex. This approach implies your suggestion of creating a foreign key to an additional table.


问:
Is there an advantage for a C programmer to have read K&R?
This question has been haunting me because I'm now reading Kernighan & Ritchie's: The C Programming Language (K&R) but I meet a lot, and I mean A LOT, of C programmers that have never read it.

So, my question is: Is there an advantage to reading K&R? Should be a necessity?

答:
Yes.

It isn't much good if you want to know how to write programs using the current versions of C, but--

It explains very clearly why the language looks like it does and the intention behind some of the basic design decisions.

If you are ever asked to document anything "The C Programming Language" is the absolute example of how to do it. Well organised, clear, concise and readable. Its written on plain English with a minimum of Jargon and zero buzzwords.

ContentLicense: CC BY-SA 3.0


问:
Liskov substitution principle when implementing two unrelated interfaces
Suppose I have two unrelated interfaces with the same method:

```<code>interface Table {
    /**
     * @param width (0 < width <= 100)
     */
    void setWidth(int width);
}

interface Square {
    /**
     * @param width (50 <= width <= 10000)
     */
    void setWidth(int width);
}
</code>```

Then I create a class which implements both of these interfaces:

```<code>class SquareTable implements Square, Table {
    void setWidth(int width) {
        precondition = ...
        if (!precondition)
            throw new PreconditionFailedException("Precondition failed: ...");
    }
}
</code>```

How precondition expressions should be combined to satisfy Liskov substitution principle? Should they and'ed or or'ed? I.e. what should be written instead of ...:

```<code>width > 0 && width <= 10000 // using OR
width >= 50 && width <= 100 // using AND
</code>```

And which rule should be used for postconditions?

```<code>interface Table {
    /**
     * @return width (0 < width <= 100)
     */
    int getWidth();
}

interface Square {
    /**
     * @return width (50 <= width <= 10000)
     */
    int getWidth();
}

class SquareTable implements Square, Table {
    int getWidth() {
        postcondition = ...
        if (!postcondition)
            throw new PostconditionFailedException("Postcondition failed: ...");
    }
}

width > 0 && width <= 10000 // using OR
width >= 50 && width <= 100 // using AND
</code>```

答:
In this context setWidth and getWidth are different methods for both interfaces, even though they have same name. The reason for this is that pre/post conditions, combined with LSP become part of the method signature. So if the pre/post conditions are different, so are the whole methods.

That is why you should implement them as two different methods. In C#, you can use explicit interface implementation, that allows you to implement different methods for each interface, even though they have same name. Java doesn't have anything like this, so you either need to emulate it somehow or try to live without it.

And just my 2 cents, you should not create pre/post conditions for properties, there should be just condition that applies all the time.

And thinking about it, in this case, the constrainst should be ANDed. Consider this piece of code:

```<code>SquareTable st = new SquareTable();
Table t = st;
Square s = st;
t.setWidth(20); // OK, because invariant for Table is 0 < w
int w = s.getWidth(); // returns 20, which breaks the postcondition of Square
</code>```

In this case, it would be much better if it already failed at t.setWidth(20), according to "fail early" mentality. Thats because it takes more effort debuging from s.getWidth() than from t.setWidth(x).

Body:
In this context setWidth and getWidth are different methods for both interfaces, even though they have same name. The reason for this is that pre/post conditions, combined with LSP become part of the method signature. So if the pre/post conditions are different, so are the whole methods.

That is why you should implement them as two different methods. In C#, you can use explicit interface implementation, that allows you to implement different methods for each interface, even though they have same name. Java doesn't have anything like this, so you either need to emulate it somehow or try to live without it.

And just my 2 cents, you should not create pre/post conditions for properties, there should be just condition that applies all the time.

And thinking about it, in this case, the constrainst should be ANDed. Consider this piece of code:

SquareTable st = new SquareTable();
Table t = st;
Square s = st;
t.setWidth(20); // OK, because invariant for Table is 0 < w
int w = s.getWidth(); // returns 20, which breaks the postcondition of Square

In this case, it would be much better if it already failed at t.setWidth(20), according to "fail early" mentality. Thats because it takes more effort debuging from s.getWidth() than from t.setWidth(x).


答:
Yes, K&R is indispensable.

You have to read it, in the same way that you have to read Hamlet and Lord Of The Rings, in the same way that you've got to see Casablanca and Gone With The Wind and Star Wars.

It's a terrific little book. It changed programming, and it transformed technical writing, and for a generation it represented the pinnacle of style.

What do you gain by not reading it? Six hours? Twelve? Twenty? If you're serious about programming, you're going to be spending thousands and thousands of hours casting code. if you can't bother to read, what else can't you be bothered to do?

It's entirely possible that K&R shouldn't be your first C book. And nowadays, C shouldn't be your first language.  It's not vital to read K&R first, but you've got to read it.

And why wouldn't you want to? It's fun.

Title: Is there an advantage for a C programmer to have read K&R?

Body:
This question has been haunting me because I'm now reading Kernighan & Ritchie's: The C Programming Language (K&R) but I meet a lot, and I mean A LOT, of C programmers that have never read it.

So, my question is: Is there an advantage to reading K&R? Should be a necessity?


问:
Do changes in performance violate the Liskov Substitution Principle?
Say I have:

```<code>interface Thing
{
    GetThing();
}

class FastThing : Thing
{
    public int GetThing()
    {
        return 1;
    }
}

class SlowThing : Thing
{
    public int GetThing()
    {
        return GetThingFromDatabase();
    }
}
</code>```

Is this a violation of the Liskov Substitution Principle?

答:
Uncle Bob answered a very similar question where he states that an LSP violation requires 3 parties:

The Type T, the Subtype S, and the program P that uses T but is given an instance of S.

I would venture a guess that this question has a similar structure as the one he replied to, in that it doesn't mention the P that's using the T and what behavior the P expects.

You can find his answer here. (You'll need to scroll down some and look for answer from user named Robert Martin)


问:
Determine dependency between .NET projects
We have a big and complex application composed by at least 700 DLL. The number is growing month after month. The code is not well structured because every DLL is a stand alone solutions. As you can imagine, when have some problem when we have to test a new feature on a DLL because we do not know exactly where it is used.

I am thinking to write a program that scan the file system, open the solution XML file and create a graph that contain all the references.

Is it a good idea?

Do you have some other solutions?

答:
I'd first try to consolidate those dlls. Do you have a class per dll or something?!
Combine related functionality currently contained within lots of dlls into a single dll, then you can start to get a grasp on your dependency chain. 700 is just too many to manage well.</p>


问:
How would you evaluate object oriented design skills?
what kind of insights or questions would lead you to determine a person's OOAD skills.</p>

答:
If possible, ask for sample code.

Otherwise, find some procedural code to use as an example (or some poorly designed OO code), and then ask them how they would redesign, generalize and improve it. Be sure the program has extra context, so that the redesign can be meaningful.

Ultimately what you are testing-- design-- is subjective. Thus, your evaluation should be open-ended to allow for several possible good solutions, and not just a single one. Then, think about possible changes to requirements that would force an interface change: How do they handle it?

ContentLicense: CC BY-SA 2.5


问:
Good unit-testing story for a unit test training
I have to advise a training on unit testing in my company.

I would like to show a striking, real-life example of an unexpected regression not caught by compilation (of course) but detectable with unit testing.

Something more like a seemingly valid change that in fact cause a regression in another part of the program.

Would you share your unit testing epic-win stories ?

(Target language is C++, networked distributed application, but any good example will do)

答:
Personally, I actually value the unit tests more at the point of creation, in their ability to force the developer to think about the code they have written, and to validate how they think their code behaves.

When a historic unit test breaks, in my experience it is usually has been because of an intended functionality or design change, and that the unit test has to be rewritten to reflect the new code.  Whilst the rare (perhaps 1 in 20) occasions where they have caught a bug quickly is valuable, the act of forcing a developer to prove that their new code behaves the way they think it does adds much more value to the code base.


问:
Program design with multiple data sets, algorithms and results
I have a question regarding the design of my software.

There are four different data sets and three consecutive algorithms operating on the data sets and on the results from the previous algorithm runs.

Let D1 - D4 be the set of data sets, A1 - A3 the set of algorithms and R1 - R3 the set of results from the respective algorithms.

A1 uses data sets D1, D2 and D3 and has to run on n different parameters.
A2 uses data sets D1 and D3 as well as R1_1 - R1_n.
A3 uses data sets D1, D2 and D4 as well as R2.

```<code>  D1    D1    D1
  D2    D3    D2
  D3          D4

  |     |     |
  v     v     v

n*A1    A2    A3
     _     _
  |  /| |  /| |
  v /   v /   v

R1_1    R2    R3
...
R1_n
</code>```

Each of the results R1_1 - R1_n, R2 and R3 should have some output functionality.

So my question is how to organize the program and its classes. I guess I would want to create separate classes for each of D1 - D4, A1 - A3 and R1 - R3 and make the data and result objects attributes of the algorithm objects? Are there any reasons for or against creating n objects R1_1 - R1_n instead of one object R1 containing an array of n results?

Should the data classes include their own respective 'readFromFile' functions or would it be better to have a global utility class that reads all data from file and generates the data objects? The same goes for output functions, should they be placed in each of the result classes or should they be globally organized?

Kind regards!

答:
This question may be better suited to be posted at programmers.stackexchange.com or codereview.stackexchange.com

However, here are some tips about when to break things into new classes:
https://stackoverflow.com/questions/15917696/is-it-better-to-have-more-java-classes-or-have-fewer-classes-doing-more-work

If I were you, I would only keep three of the classes at most: A1, A2 and A3. Alternatively, you could make the three algorithms methods of the same class. To keep your code DRY, you want one method responsible for reading in files (and one for output), unless the input files are fundamentally different.

Every object you create has some overhead, so your performance would be better if you can create just one object to hold your results.

OwnerDisplayName: lucas


问:
Contract review for international contracting
I am intending to work as an independent contractor, writing software for a client based in another country. My work will be provided electronically so I won't need to relocate. However, there is a legal dilemma, as I see it:

If the draft contract stipulates that governing law is the law of the country where the client is based, I will find it very difficult to find a lawyer willing to review the contract. (This has been my experience.)

If the draft contract stipulates that governing law is the law of my country, the client will face the same problem: they will find it very difficult to find a lawyer willing to review the contract. Right?

There is no realistic third option. The contract has to stipulate a choice of law - anything else would be ridiculous.

Let me go into more detail on why option 1 is difficult:

Lawyers in my country, who know only my country's law, will simply throw up their hands and say "Can't help you - unless you get the stipulated law changed".

Expatriate lawyers from the client's country, working in this country, even if they are from the right state or province, will probably be too busy working for corporate clients to be interested in my (from their perspective) petty little contract review.

So, it looks like my only option remaining is... hire a lawyer based in the client's country? And interact with them by phone/VOIP, email and fax? Is this possible? Will it even be legal for them to take on me as a client? How can I get a recommendation?

Is there anything I'm missing?

答:
Not strictly the legal answer BUT the position for most independent contractor is--
They can afford lawyer(s) and you cannot.

So unless you are prepared to represent yourself and/or risk personal bankruptcy you are going to lose any legal battle.

Conversely if you set up a limited company and make sure any contract is between your client and your company they have nothing to gain by suing you.

The fact that there are two jurisdictions involved does not really change the situation.

In any case it would be professional suicide to take your client or employer to court unless the circumstances were really really extreme.

So don't worry about it. Perform your work as best you can, and, down tools the minute the bills are not paid.


答:
(yes I'm answering my own question - just happened to remember a good example)

I remember finding and busting some tricky C++ smart-pointers reference loop with the combination of unit-testing + valgrind.

Seeing some leaks in unit (= limited) tests make it easier to diagnose who is holding the unexpected reference than in the full running code. (In this case, it was a parent/children relationship with both needing a shared pointer on the other. Broken using weak_ptr)

Title: Good unit-testing story for a unit test training

Body:
I have to advise a training on unit testing in my company.

I would like to show a striking, real-life example of an unexpected regression not caught by compilation (of course) but detectable with unit testing.

Something more like a seemingly valid change that in fact cause a regression in another part of the program.

Would you share your unit testing epic-win stories ?

(Target language is C++, networked distributed application, but any good example will do)


答:
IMHO the value of unit tests can be understood most clearly whenever you have to create reusable libraries, especially when those libs are generic, with only few or no dependencies to other parts of the system.

Think of a mathematical library (for example, for vector or matrix operations, for graphs, or for graphical calculations). Those kind of things are often good unit-testable, and it should be clear that, once such a lib is used in a dozen programs or so, changing something internally in that lib will mean you will have to test a lot more of those programs again, opposed to the situation if you have a unit test suite available with a high coverage.

There are also some good videos of Brett L. Schuchert, showing live TDD coding, for example, this one for C++ or this one for Java, maybe you find them helpful.


问:
Finding the possible combinations of x switches out of y being true
I am working on an algorithm to find possible fills for gaps in text. My function will receive as input:
(example)

```<code>[false,"o",false,"b",false,"r"]
</code>```

representing the string "foobar" with some values cut out. My function should find opportunies for the possible ways to fill the gaps given a set maximum characters (and a minimum of one blank filled). so, given a maximum of 2 it should return:

```<code>[
[true,"o",false,"b",false,"r"],
[false,"o",true,"b",false,"r"],
[false,"o",false,"b",true,"r"],
[true,"o",true,"b",false,"r"],
[true,"o",false,"b",true,"r"],
[false,"o",true,"b",true,"r"]
]
</code>```

Can anyone give me a shove in the right direction?

Oh, and I planned to run the results through another function to sort these out, but if I can NOT get results where there is a false between the blanks (ie, from the above, [true,"o",false,"b",true,"r"]) it would be a huge bonus.

This is in a javascript/jQuery environment

答:
There's a simpler way, given your no-gap constraint.

There are two relevant positions, first_true and last_true. These cannot be further apart than max_chars-1. Your 6 solutions can thus be summarized as {0,0}, {1,1}, {2,2}, {0,1}, {0,2} and {1,2}.

You generate those as

```<code>FOR ( BEGIN = 0 TO LENGTH)
  FOR (END = 0 TO MINIMUM(MAXCHARS, LENGTH-BEGIN) )
    PRINT BEGIN, END
</code>```

Body:
There's a simpler way, given your no-gap constraint.

There are two relevant positions, first_true and last_true. These cannot be further apart than max_chars-1. Your 6 solutions can thus be summarized as {0,0}, {1,1}, {2,2}, {0,1}, {0,2} and {1,2}.

You generate those as

FOR ( BEGIN = 0 TO LENGTH)
  FOR (END = 0 TO MINIMUM(MAXCHARS, LENGTH-BEGIN) )
    PRINT BEGIN, END


问:
Kafka, is it possible to get the message offset after producing?
While using Apache Kafka, is it possible to get the offset of the message that has been produced?

From the Kafka documentation page it says:

each message in the partition are assigned a unique sequential id/number called Offset

Now suppose when I am producing any message I want to retrieve the offset that has been assigned to it.

答:
You shouldn't do that from a class that acts as a producer, like in most queue systems, as its responsibility is to just fire and forget the messages. The broker will do the appropriate meta data handling with id's, offsets, whatever it needs to handle the messages in a correct manner.

You can get the offsets as a consumer of messages from a Kafka broker. If you look in the SimpleConsumer class, you'll notice it fetches MultiFetchResponse objects that contains offsets as a list. Furthermore when you iterate the Kafka messages you'll end up with a MessageAndOffset objects that contains both the message sent and it's offset.


答:
Do you have some other solutions?

In short: Combine your code under one solution and define project dependencies their.

Having so many dlls is troublesome for maintenance and further development. If you have the source code, I would suggest de-compile this dlls to their own small projects and combine them under one solution. It would be much clear and easier to manage dependencies from their on.

However, all that re-organizational work would cost you time of a developer who understands the system very well.

Title: Determine dependency between .NET projects

Body:
We have a big and complex application composed by at least 700 DLL. The number is growing month after month. The code is not well structured because every DLL is a stand alone solutions. As you can imagine, when have some problem when we have to test a new feature on a DLL because we do not know exactly where it is used.

I am thinking to write a program that scan the file system, open the solution XML file and create a graph that contain all the references.

Is it a good idea?

Do you have some other solutions?


问:
Can everything in computing be classified as either data or a process?
Working in a field called "revenue assurance" I basically build systems to validate other systems.

After a while in this market it seems to me that all these "validations" are verifying either a process from my customer's environment or the data used by these processes.

With this in mind I am considering using such definition to orientate sales people and even architects working on the products. However, researching this topic I couldn't find a definitive answer although haven't dismissed the possibility either.

Is everything one of the two then?

答:
Yes.
Turing machine consists of data, in form of alphabet and infinite tape that saves this alphabet. And process how to transform this data in form of table of rules. And considering TM can compute anything that can be computed, it can be said data and processes is only thing you need in computing.

But TM is highly abstract concept and used primarily in computer science. In practical world, it is rarely used. And you cannot use it as example when talking about high-level systems and development.


问:
Is rotating developers on a project a good or bad idea?
I'm working on a small team that will begin working on a large new project with another small team. The other team is currently working on a legacy system that they have been working on for years.

The manager has decided that the developers from my team will be rotating every few months to replace developers working on the legacy system. That way the other team will have a chance to work on the new project and have a better understanding of the new system.

I want to know the benefits and drawbacks (if any) of rotating the developers from the project every 2-3 months.

I know that this is a similar question to "Is rotating the lead developer a good or bad idea?", but that question focuses on a lead developer. This question is about rotating the entire team on and off the project (tech. lead for the new project may or may not be rotated -- I don't know yet).

答:
I don't see much of a downside here myself. The rotation gets you:

Cross pollination of institutional knowlege -- everyone will know the legacy project and the new one, at least in theory.

Cross training -- different projects require different things often. You grow much more as a developer working in ugly, legacy projects than in nice, clean greenfield projects.

Fundamentally better projects -- nothing like having a new team coming in to make you finish documentation and clean up ugly processes you are willing to live with but not publicly admit to.

Better code -- more heads are better in most cases.

Likely morale improvements -- variety is the spice of life. And who wants to be stuck in legacy project bug fixing / duct taping mode permanently. Also keep in mind your "new" project will become legacy at some point, do you want to be stuck there forever?

Probably the only downside is the productivity drop you get from switching places but that should only hurt bad the first go round. Afterwards both sides will have some seat time in both places and the ugly parts of the handoff will probably be better understood and perhaps solved.


答:
Rotation is a good thing for the company, and can be a good thing for the developers too.

There are lots of good reasons and Wyatt has mentioned many of them in his answer.

That being said, in your situation, you may find when introducing this, the developers who are moving off the newer project onto the legacy project may well not be happy, so there needs to be very clear communication why this is happening and how long it is for, and the plan going forward.

It might be good to think about not swapping the teams wholesale to start and rotating 1 or 2 devs to start with, though this might seem like singling out people for a demotion (which some people may see it).

Title: Is rotating developers on a project a good or bad idea?

Body:
I'm working on a small team that will begin working on a large new project with another small team. The other team is currently working on a legacy system that they have been working on for years.

The manager has decided that the developers from my team will be rotating every few months to replace developers working on the legacy system. That way the other team will have a chance to work on the new project and have a better understanding of the new system.

I want to know the benefits and drawbacks (if any) of rotating the developers from the project every 2-3 months.

I know that this is a similar question to "Is rotating the lead developer a good or bad idea?", but that question focuses on a lead developer. This question is about rotating the entire team on and off the project (tech. lead for the new project may or may not be rotated -- I don't know yet).


答:
Interestingly, in my experience we have often started our projects with this very intent. Down the line we have often failed to act on this intent due to constraints on the newer project and a belief that the cross training is too expensive.

I do always wish we had managed it though, as long term I believe it is beneficial to all parties - team, company, client & software. 2/3 months sounds like a long enough stint that there is limited risk of any serious negative impact, there is no context switching going on for the developers involved except at the changeover point at which time they can dedicate themselves to the alternative project.

A couple of possible benefits not mentioned:

Better project management. If the project managers for both projects are on board then it is their best interests to work hard so that transition periods are not painful for either project. This is turn (depending on your setup) could yield tighter collaboration between the PMs and development teams.

Better (proactive) documentation. If you know you're getting switched in and out of a project it is not only in the project's best interest, the companies best interest, best practice in general, but now in each developers own best interest to make life easy whilst they are bouncing around.

The morale thing is a big deal, if your developers haven't had enough of being stuck on a legacy project, then they might not be the developers you want! If they have, switching them around and getting other developers to work on it will make them feel love for your company - they just might tidy up the bits of code they thought nobody would ever see as well. Legacy systems are often seen as second class projects which is often to their detriment, maybe this way you help change that perception to.


问:
Performance related doubt in Java with Hibernate
Suppose in some ORM based project (say Hibernate) I am trying to fetch only few columns rather then the whole Object with may be more than 20 attributes. I am writing HQL like "select attr1, attr2 from Entity ". I know I am not taking advantage of using Hibernate because I will get the result in Object form only and then I have to do explicit casting for it. But whether it will be a right approach to achieve optimization from database prospective or because I am performing some explicit casting the cost will still be same?

答:
I know i am not taking advantage of using Hibernate [...]

Hibernate is a little bit more than just an automatic ORM that is supposed to map full Java objects to full database tables. It provides mapping on all operations, not only queries; inserts and deletes work straightforward, even if you do not want to insert the a full object into the database. Moreover, Hibernate comes with level 2 caching (Ehcache) which significantly improves performance.

Regarding selecting only the objects that you need; Hibernate also comes with improvements. For example, me an OO developer am more familiar with the object model rather than a database developer who is familiar with SQL and relations; Hibernate comes in my help by letting me use a more object-friendly query language (HQL, JPQL). Moreover, even if it does not know to map certain tables to another class, it still converts it to an array (or list of arrays, if multiple entries are returned in one query); you still don't have to get the ResultSet and iterate over it.

Another alternative is using lazy fetching, and the call to the database will be made only when you actually call the method. If you do not need certain fields, set them as lazy, and if they are not needed, are not fetched.

As last words I must say that automatic ORM tools like Hibernate are good and greatly improve productivity, but they are not a silver bullet. They are not suitable in all scenarios; if you want special database features or are not dealing with a complex enough domain, you are probably better with good old JDBC or the better Spring alternative, JdbcTemplate.


答:
Hibernate and other ORM tools are fantastic and can get you 80% of the way to a complete application. In your example if attr1 and attr2 are primitive values read from a column I wouldn't worry about what Hibernate is doing, you'll likely incur some overhead working without Hibernate when iterating over the ResultSet yourself. If attr1 and attr2 are the result of a join then you can make the resultant collection lazy loaded which means that the variables are populated with proxy objects until the data is requested at which point (given the transaction is still open) they go back to the database to retrieve the values.

However. Hibernate builds some pretty ugly (suboptimal) queries and quite often uses a lot of queries. If you turn logging up to DEBUG for Hibernate then you may see what you expected to be a single query being executed as multiple selects. It is at this point that your performance might well bottleneck (depending on whether you saw it coming or not) and you would be better off using JdbcTemplate with all the joins modeled as is most optimal for your datasource.

Ultimately mixing the two techniques is both fine and common.

As ever, if it ain't slow, don't fix it!

Title: Performance related doubt in Java with Hibernate

Body: Suppose in some ORM based project (say Hibernate) I am trying to fetch only few columns rather then the whole Object with may be more than 20 attributes. I am writing HQL like "select attr1, attr2 from Entity ". I know I am not taking advantage of using Hibernate because I will get the result in Object form only and then I have to do explicit casting for it. But whether it will be a right approach to achieve optimization from database prospective or because I am performing some explicit casting the cost will still be same?


答:
If you want to select only some columns you may do something likeSelect new x.y.z.Object(c.column1, c.column2) FROM Object c

Of course you should declare a constructor with only those two fields.
If you analyse the logs you will see that only the columns that you require are fetched from de DB. As far as i can say this is a perfectly valid use case along with the usage of explicit fetching (optimization such as this one are sometimes required).

Hope that helps


答:
If you're not seeing performance problems when retrieving all entity attributes, don't spend time on micro-optimization.

Unless the attributes are very large, you probably won't see any performance difference in selecting only the columns you really need for a given operation as opposed to all columns.

If you're really concerned about it, believe that it will cause performance problems, and want to get ahead of those problems, run some tests (with many iterations to gain an average times) to compare the cost of retrieving all attributes versus just the ones you need. It will take less time to write the tests than you think, and it will be worth it to get the data to back up your decision.

If you get the data to prove the performance problems you're assuming, and the performance difference is big enough that it will make a difference in your specific application, then it makes sense to start researching how to improve performance.


问:
OOP - Modeling a Chat
When modeling a chat, should a chat object receive messages or a message be sent to a chat object? I'm not sure whether there is a definitive answer but maybe someone can point out benefits of one over the other.

message.send(chat);

VS.

chat.sendMessage(message);

答: For the model, it doesn't really matter.  However, the implementation is almost always easier one way compared to the other.  If you can't tell, try both ways and pick the one that's cleaner.  I suspect in this case the cleaner implementation would be chat.sendMessage, because you're mostly using the chat resources to perform the action, of which the message is just one more dependency, but there's really no way to know without seeing the rest of the code.

Title: OOP - Modeling a Chat


问:
How do I get rid of cyclic references in this design?
I have 3 classes: Meeting, Project and Agenda.

A Project contains all sort of information + a list of meetings.

The Agenda contains a list of upcoming Meetings.

A Meeting contains some data + a list of Projects that were discussed there.

The Agenda checks for upcoming meetings. When it finds one, it calls its Meeting::alarm() method, which in turn displays data it gets from the list of projects this meeting refers to.

Meetings can be referenced in a project without being scheduled in the Agenda, but it doesn't really make sense to have a reference to a meeting in the agenda if it is not contained in a project.

Because the Agenda can be parsed in a thread while the main thread deletes a project, I made both Agenda and Project use shared pointers on Meetings, so that the parsing thread doesn't find a dangling pointer.

In the destructor of Project, I ask Agenda to check the meetings related to this project to clean up those who don't have any other related project.

Here is my problem:

What kind of data structure should the Meeting::parentProjects member be?

If a Meeting gets called by the Agenda while its Project is being deleted, and parentProjects is a simple raw pointers container, I might have a dangling here. But I can't use a shared_ptr to Project either, since that would make a cyclic dependency... I feel like it is unnecessarily complicated.

How could I refactor this? Note: I have to keep the 2 threads though.

答:
The way you are asking this question seems to imply that you expect the answer has to be in data structure.  I'm not sure that it is.

The key problem is that you are wanting to modify and access the data at the same time, and have realised that attempting to access partially modified data is not good.

There are several strategies that you can do with this.

In an environment where all actions on data are quick, and there is a
low volume of changes you could use a Mutex (or if
you want, light weight semaphores) and force the second action to block

until the first action had completed.

If these actions can take a noticeable time to occur. (e.g. 1/2 a second or
more) then I would be tempted to create an action queue, and to have a your
current threads place tasks on the queue, and have a third thread that
performed these actions in sequence, calling a callback on the task to
notify the original thread it was completed.

In simple terms, the major problem you have is the concurrent data access, rather than the data structure, so you need to solve it by managing the access, rather than by a pure data structure approach.


问:
How to simulate inner join on very large files in java (without running out of memory)
I am trying to simulate SQL joins using java and very large text files (INNER, RIGHT OUTER and LEFT OUTER). The files have already been sorted using an external sort routine.

The issue I have is I am trying to find the most efficient way to deal with the INNER join part of the algorithm. Right now I am using two Lists to store the lines that have the same key and iterate through the set of lines in the right file once for every line in the left file (provided the keys still match). In other words, the join key is not unique in each file so would need to account for the Cartesian product situations ...

```<code>left_01, 1
left_02, 1
right_01, 1
right_02, 1
right_03, 1

left_01 joins to right_01 using key 1
left_01 joins to right_02 using key 1
left_01 joins to right_03 using key 1
left_02 joins to right_01 using key 1
left_02 joins to right_02 using key 1
left_02 joins to right_03 using key 1
</code>```

My concern is one of memory. I will run out of memory if i use the approach below but still want the inner join part to work fairly quickly. What is the best approach to deal with the INNER join part keeping in mind that these files may potentially be huge

```<code>public class Joiner {

  private void join(BufferedReader left, BufferedReader right, BufferedWriter output) throws Throwable {

    BufferedReader _left = left;
    BufferedReader _right = right;
    BufferedWriter _output = output;
    Record _leftRecord;
    Record _rightRecord;

    _leftRecord = read(_left);
    _rightRecord = read(_right);

    while( _leftRecord != null && _rightRecord != null ) {

      if( _leftRecord.getKey() < _rightRecord.getKey() ) {
        write(_output, _leftRecord, null);
        _leftRecord = read(_left);
      }
      else if( _leftRecord.getKey() > _rightRecord.getKey() ) {
        write(_output, null, _rightRecord);
        _rightRecord = read(_right);
      }
      else {
        List<Record> leftList = new ArrayList<Record>();
        List<Record> rightList = new ArrayList<Record>();

        _leftRecord = readRecords(leftList, _leftRecord, _left);
        _rightRecord = readRecords(rightList, _rightRecord, _right);

        for( Record equalKeyLeftRecord : leftList ){
          for( Record equalKeyRightRecord : rightList ){
            write(_output, equalKeyLeftRecord, equalKeyRightRecord);
          }
        }
      }
    }

    if( _leftRecord != null ) {
      write(_output, _leftRecord, null);
      _leftRecord = read(_left);
      while(_leftRecord != null) {
        write(_output, _leftRecord, null);
        _leftRecord = read(_left);
      }
    }
    else {
      if( _rightRecord != null ) {
        write(_output, null, _rightRecord);
        _rightRecord = read(_right);
        while(_rightRecord != null) {
          write(_output, null, _rightRecord);
          _rightRecord = read(_right);
        }
      }
    }
    _left.close();
    _right.close();
    _output.flush();
    _output.close();
  }

  private Record read(BufferedReader reader) throws Throwable {
    Record record = null;

    String data = reader.readLine();
    if( data != null ) {
      record = new Record(data.split("\t"));
    }
    return record;
  }

  private Record readRecords(List<Record> list, Record record, BufferedReader reader) throws Throwable {
    int key = record.getKey();
    list.add(record);
    record = read(reader);
    while( record != null && record.getKey() == key) {
      list.add(record);
      record = read(reader);
    }
    return record;
  }

  private void write(BufferedWriter writer, Record left, Record right) throws Throwable {
    String leftKey = (left == null ? "null" : Integer.toString(left.getKey()));
    String leftData = (left == null ? "null" : left.getData());
    String rightKey = (right == null ? "null" : Integer.toString(right.getKey()));
    String rightData = (right == null ? "null" : right.getData());

    writer.write("[" + leftKey + "][" + leftData + "][" + rightKey + "][" + rightData + "]\n");
  }

  public static void main(String[] args) {
        try {

          BufferedReader leftReader = new BufferedReader(new FileReader("LEFT.DAT"));
          BufferedReader rightReader = new BufferedReader(new FileReader("RIGHT.DAT"));
          BufferedWriter output = new BufferedWriter(new FileWriter("OUTPUT.DAT"));

      Joiner joiner = new Joiner();
      joiner.join(leftReader, rightReader, output);
    }
        catch (Throwable e) {
      e.printStackTrace();
    }
  }
}
</code>```

After applying the ideas from the proposed answer, I changed the loop to this

```<code>private void join(RandomAccessFile left, RandomAccessFile right, BufferedWriter output) throws Throwable {

    long _pointer = 0;

    RandomAccessFile _left = left;
    RandomAccessFile _right = right;

    BufferedWriter _output = output;

    Record _leftRecord;
    Record _rightRecord;

    _leftRecord = read(_left);
    _rightRecord = read(_right);

    while( _leftRecord != null && _rightRecord != null ) {

        if( _leftRecord.getKey() < _rightRecord.getKey() ) {
            write(_output, _leftRecord, null);
            _leftRecord = read(_left);
        }
        else if( _leftRecord.getKey() > _rightRecord.getKey() ) {
            write(_output, null, _rightRecord);
            _pointer = _right.getFilePointer();
            _rightRecord = read(_right);
        }
        else {
            long _tempPointer = 0;
            int key = _leftRecord.getKey();
            while( _leftRecord != null && _leftRecord.getKey() == key ) {
                _right.seek(_pointer);
                _rightRecord = read(_right);
                while( _rightRecord != null && _rightRecord.getKey() == key ) {
                    write(_output, _leftRecord, _rightRecord );
                    _tempPointer = _right.getFilePointer();
                    _rightRecord = read(_right);
                }
                _leftRecord = read(_left);
            }
            _pointer = _tempPointer;
        }
    }

    if( _leftRecord != null ) {
        write(_output, _leftRecord, null);
        _leftRecord = read(_left);
        while(_leftRecord != null) {
            write(_output, _leftRecord, null);
            _leftRecord = read(_left);
        }
    }
    else {
        if( _rightRecord != null ) {
            write(_output, null, _rightRecord);
            _rightRecord = read(_right);
            while(_rightRecord != null) {
                write(_output, null, _rightRecord);
                _rightRecord = read(_right);
            }
        }
    }
    _left.close();
    _right.close();
    _output.flush();
    _output.close();
}
</code>```

UPDATE
While this approach worked, it was terribly slow and so I have modified this to create files as buffers and this works very well. Here is the update ...

```<code>private long getMaxBufferedLines(File file) throws Throwable {
    long freeBytes = Runtime.getRuntime().freeMemory() / 2;
    return (freeBytes / (file.length() / getLineCount(file)));
}

private void join(File left, File right, File output, JoinType joinType) throws Throwable {

    BufferedReader leftFile = new BufferedReader(new FileReader(left));
    BufferedReader rightFile = new BufferedReader(new FileReader(right));
    BufferedWriter outputFile = new BufferedWriter(new FileWriter(output));
    long maxBufferedLines = getMaxBufferedLines(right);

    Record leftRecord;
    Record rightRecord;

    leftRecord = read(leftFile);
    rightRecord = read(rightFile);

    while( leftRecord != null && rightRecord != null ) {

        if( leftRecord.getKey().compareTo(rightRecord.getKey()) < 0) {
            if( joinType == JoinType.LeftOuterJoin
                    || joinType == JoinType.LeftExclusiveJoin
                    || joinType == JoinType.FullExclusiveJoin
                    || joinType == JoinType.FullOuterJoin ) {
                write(outputFile, leftRecord, null);
            }
            leftRecord = read(leftFile);
        }
        else if( leftRecord.getKey().compareTo(rightRecord.getKey()) > 0 ) {
            if( joinType == JoinType.RightOuterJoin
                    || joinType == JoinType.RightExclusiveJoin
                    || joinType == JoinType.FullExclusiveJoin
                    || joinType == JoinType.FullOuterJoin ) {
                write(outputFile, null, rightRecord);
            }
            rightRecord = read(rightFile);
        }
        else if( leftRecord.getKey().compareTo(rightRecord.getKey()) == 0 ) {
            String key = leftRecord.getKey();
            List<File> rightRecordFileList = new ArrayList<File>();
            List<Record> rightRecordList = new ArrayList<Record>();
            rightRecordList.add(rightRecord);
            rightRecord = consume(key, rightFile, rightRecordList, rightRecordFileList, maxBufferedLines);

            while( leftRecord != null && leftRecord.getKey().compareTo(key) == 0 ) {
                processRightRecords(outputFile, leftRecord, rightRecordFileList, rightRecordList, joinType);
                leftRecord = read(leftFile);
            }

            // need a dispose for deleting files in list
        }
        else {
            throw new Exception("DATA IS NOT SORTED");
        }
    }

    if( leftRecord != null ) {
        if( joinType == JoinType.LeftOuterJoin
                || joinType == JoinType.LeftExclusiveJoin
                || joinType == JoinType.FullExclusiveJoin
                || joinType == JoinType.FullOuterJoin ) {
            write(outputFile, leftRecord, null);
        }
        leftRecord = read(leftFile);
        while(leftRecord != null) {
            if( joinType == JoinType.LeftOuterJoin
                    || joinType == JoinType.LeftExclusiveJoin
                    || joinType == JoinType.FullExclusiveJoin
                    || joinType == JoinType.FullOuterJoin ) {
                write(outputFile, leftRecord, null);
            }
            leftRecord = read(leftFile);
        }
    }
    else {
        if( rightRecord != null ) {
            if( joinType == JoinType.RightOuterJoin
                    || joinType == JoinType.RightExclusiveJoin
                    || joinType == JoinType.FullExclusiveJoin
                    || joinType == JoinType.FullOuterJoin ) {
                write(outputFile, null, rightRecord);
            }
            rightRecord = read(rightFile);
            while(rightRecord != null) {
                if( joinType == JoinType.RightOuterJoin
                        || joinType == JoinType.RightExclusiveJoin
                        || joinType == JoinType.FullExclusiveJoin
                        || joinType == JoinType.FullOuterJoin ) {
                    write(outputFile, null, rightRecord);
                }
                rightRecord = read(rightFile);
            }
        }
    }
    leftFile.close();
    rightFile.close();
    outputFile.flush();
    outputFile.close();
}

public void processRightRecords(BufferedWriter outputFile, Record leftRecord, List<File> rightFiles, List<Record> rightRecords, JoinType joinType) throws Throwable {

    for(File rightFile : rightFiles) {
        BufferedReader rightReader = new BufferedReader(new FileReader(rightFile));
        Record rightRecord = read(rightReader);
        while(rightRecord != null){

            if( joinType == JoinType.LeftOuterJoin
                    || joinType == JoinType.RightOuterJoin
                    || joinType == JoinType.FullOuterJoin
                    || joinType == JoinType.InnerJoin ) {

                write(outputFile, leftRecord, rightRecord);
            }
            rightRecord = read(rightReader);
        }
        rightReader.close();
    }

    for(Record rightRecord : rightRecords) {
        if( joinType == JoinType.LeftOuterJoin
                || joinType == JoinType.RightOuterJoin
                || joinType == JoinType.FullOuterJoin
                || joinType == JoinType.InnerJoin ) {

            write(outputFile, leftRecord, rightRecord);
        }
    }
}

/**
 * consume all records having key (either to a single list or multiple files) each file will
 * store a buffer full of data. The right record returned represents the outside flow (key is
 * already positioned to next one or null) so we can't use this record in below while loop or
 * within this block in general when comparing current key. The trick is to keep consuming
 * from a List. When it becomes empty, re-fill it from the next file until all files have
 * been consumed (and the last node in the list is read). The next outside iteration will be
 * ready to be processed (either it will be null or it points to the next biggest key
 * @throws Throwable
 *
 */
private Record consume(String key, BufferedReader reader, List<Record> records, List<File> files, long bufferMaxRecordLines ) throws Throwable {
    boolean processComplete = false;
    Record record = records.get(records.size() - 1);

    while(!processComplete){
        long recordCount = records.size();
        if( record.getKey().compareTo(key) == 0 ){
            record = read(reader);
            while( record != null && record.getKey().compareTo(key) == 0 && recordCount < bufferMaxRecordLines ) {
                records.add(record);
                recordCount++;
                record = read(reader);
            }
        }
        processComplete = true;
        // if record is null, we are done
        if( record != null ) {

            // if the key has changed, we are done
            if( record.getKey().compareTo(key) == 0 ) {

                // Same key means we have exhausted the buffer.
                // Dump entire buffer into a file. The list of file
                // pointers will keep track of the files ...
                processComplete = false;
                dumpBufferToFile(records, files);
                records.clear();
                records.add(record);
            }
        }
    }
    return record;
}

/**
 * Dump all records in List of Record objects to a file. Then, add that
 * file to List of File objects
 *
 * NEED TO PLACE A LIMIT ON NUMBER OF FILE POINTERS (check size of file list)
 *
 * @param records
 * @param files
 * @throws Throwable
 */
private void dumpBufferToFile(List<Record> records, List<File> files) throws Throwable {
    String prefix = "joiner_" + files.size() + 1;
    String suffix = ".dat";
    File file = File.createTempFile(prefix, suffix, new File("cache"));
    BufferedWriter writer = new BufferedWriter(new FileWriter(file));

    for( Record record : records ) {
        writer.write( record.dump() );
    }

    files.add(file);
    writer.flush();
    writer.close();
}
</code>```

答:
you can use a random RandomAccessFile

```<code>private void join(RandomAccessFile left, RandomAccessFile right, BufferedWriter output) throws Throwable {

    long rightIndex = right.getFilePointer();

    Record leftRecord = read(left);
    Record rightRecord;

    while((leftRecord )!=null){
        right.seek(rightIndex);

        while((rightRecord = read(right))!=null && leftRecord.getKey() > rightRecord.getKey()){
            //skip right until it can match left
            // store pointer because we don't need to return to earlier
            rightIndex = right.getFilePointer();
        }

        while(rightRecord !=null && leftRecord.getKey()==rightRecord.getKey()){
            write(_output, leftRecord, rightRecord );
            rightRecord = read(right))
        }
        leftRecord = read(left);
        //you can test the need to skip this left record if you keep the previous key and the current rightRecord.getKey()
    }
}
</code>```

this will be a O(n+m) time and O(1) space algorithm

Body:
you can use a random RandomAccessFile

private void join(RandomAccessFile left, RandomAccessFile right, BufferedWriter output) throws Throwable {

    long rightIndex = right.getFilePointer();

    Record leftRecord = read(left);
    Record rightRecord;

    while((leftRecord )!=null){
        right.seek(rightIndex);

        while((rightRecord = read(right))!=null && leftRecord.getKey() > rightRecord.getKey()){
            //skip right until it can match left
            // store pointer because we don't need to return to earlier
            rightIndex = right.getFilePointer();
        }

        while(rightRecord !=null && leftRecord.getKey()==rightRecord.getKey()){
            write(_output, leftRecord, rightRecord );
            rightRecord = read(right))
        }
        leftRecord = read(left);
        //you can test the need to skip this left record if you keep the previous key and the current rightRecord.getKey()
    }
}

this will be a O(n+m) time and O(1) space algorithm


答:
Although I share Ptolemy's concerns about the design, there is also a straightforward answer.

Meeting::parentProjects should be a weak_ptr. This does require that the Project lifetime is controlled by shared_ptr in the first place.

If a Meeting gets called by the Agenda while its Project is being deleted ...

let's break this down. Either:

Meeting is called, while parent Project is still alive (shared_ptr has nonzero refcount)

calling weak_ptr::lock yields a shared_ptr which keeps the parent Project alive for the duration of this call

when the current call ends the shared_ptr implementing the temporary lock goes out of scope

or

Meeting is called after parent Project has been destroyed (shared_ptr has zero refcount)

calling weak_ptr::lock yields an empty shared_ptr: you can test for this and decide how to handle it

So, the Meeting will never keep its Project alive except while it's using it, and the Project cannot be deleted while the Meeting is using it.

Title: How do I get rid of cyclic references in this design?

Body:
I have 3 classes: Meeting, Project and Agenda.

A Project contains all sort of information + a list of meetings.

The Agenda contains a list of upcoming Meetings.

A Meeting contains some data + a list of Projects that were discussed there.

The Agenda checks for upcoming meetings. When it finds one, it calls its Meeting::alarm() method, which in turn displays data it gets from the list of projects this meeting refers to.

Meetings can be referenced in a project without being scheduled in the Agenda, but it doesn't really make sense to have a reference to a meeting in the agenda if it is not contained in a project.

Because the Agenda can be parsed in a thread while the main thread deletes a project, I made both Agenda and Project use shared pointers on Meetings, so that the parsing thread doesn't find a dangling pointer.

In the destructor of Project, I ask Agenda to check the meetings related to this project to clean up those who don't have any other related project.

Here is my problem:

What kind of data structure should the Meeting::parentProjects member be?

If a Meeting gets called by the Agenda while its Project is being deleted, and parentProjects is a simple raw pointers container, I might have a dangling here. But I can't use a shared_ptr to Project either, since that would make a cyclic dependency... I feel like it is unnecessarily complicated.

How could I refactor this? Note: I have to keep the 2 threads though.


问:
Scrape Intranet site without a web server
I'm trying to rebuild a simple c# time tool that displays certain statistics about time worked for the web, however, I don't have access to a server so I can't use server code like PHP which I would do if I could and this task would be a doddle.

The employee's work information is stored on an intranet site that the C# tool could access by scraping that site and grabbing what it needed. How can I do this (scrape the intranet site) without using server code and only client-side things like HTML, JavaScrit/jQuery?

Edit: Forgot to mention the Windows machines don't have .net installed

答:
The lack of a server isn't really an issue for C#, lack of the .net framework is.  You don't need a webserver to interact with one.

Absence of the framework is insurmountable absent a truly heroic effort (write your own compiler and linker and probably framework as well).

Your choice basically boils down to: native app (probably done in c++), install the .net framework, install the java framework.   Or more realistically in an intranet, get a server of some sort (terminal server or webserver).

That's the best you can do with your current architecture -- but I question it.  If this is on an intranet, why not directly access the resources that the sites use in order to present the data in another format, or add another page that presents the data in the way you want.


问:
Moving from C# to C++, and tips?
I've been using C# for a while now, and for the sake of furthering my career and extending my knowledge of programming, I want to get into C++. C# is very useful, and fast to work with, but since my team and I will be making large scale projects I need to consider working at a lower level language for several reasons. Most commercial companies use C/C++ due high performance and portability. Of course, C# isn't necessarily bad compared to C or C++, but I just prefer to have a different tool for each job.

So I read C++ is harder because it is a low level language, machine code, and doesn't have memory management. But the fact that it is machine code also reduces the amount of memory consumed. The language is hard to work with, but in a way difficulty makes it a powerful language. It was made to be fast and efficient, machine code, but this makes it harder to understand and learn "since it is closer the the machine".

I've made up my mind, and I want to learn C++, so what are some tips to keep in mind while learning? It's best to avoid getting into bad habits rather than to try and break them later, safe than sorry.

I plan to use the resources stated here, but I would prefer any personal recommendations, books or online guides, possibly those that can be easily understood by someone who has fair knowledge of C#.

答:
I actually went the opposite way, from C++ to C#.  I really cut my teeth on good OO design in a C++ context, so I feel I can talk about this okay.

Tips:

Unlike C#, C++ has been around for a long time.  Since the 70s.  As such, what constitutes 'good C++' depends on who you ask and when they got involved writing C++ and what books they've read.  Bjarne Stroustrup's The C++ Programming Language has been revised four times, and went from a 300 page book in the first edition, to a 1500 page book in the fourth.  Simply put, a lot has changed over the life of the language, and so there is a lot of history and opinions on how to solve problems.  C++ 11 still does more of the same.

Learn about how to use pointers, and what they are useful for.  If you can, try using pointers to work with hardware directly.

Memory management in C++ is often managed using a good practice called RAII.  jalf of StackOverflow fame has an excellent article on this: The Meaning of RAII.  Also, learn about using shared_ptr, auto_ptr, and the other pointers from the "smart pointer" family.  Using these techniques will prevent you from running into memory management issues.

Even with the above techniques, you still might run into some memory management issues, in which case valgrind is super-useful to know how to use (especially massif - massif and I got to be good buddies when we were using weak_ptrs in a funky way in some code).

C++ has a number of confusing syntax rules (which the C# designers tried to avoid in their language design), many of which if you do not follow carefully will cause you to have confusing results.  For example, you may commonly see const className& as the input type of function parameters - there are very good, extremely detailed reasons for this.  Marshall Cline's C++ FAQ is invaluable for this.

C++ has a lot of features and flexibility and power, which is a good thing, but it doesn't often make the garden-path choices the best for new users.  This means, if you aren't careful, your code will be horrible.  It took me a good 18 months to figure this out and realize how crappy my code was and why I was getting bad code reviews.  Learning to write an interface in C++ (hint: lookup what an abstract-base-class is) is crucial to making great code.  Don't be afraid to replicate good concepts and programming constructs you learned in C# land back into C++ land, when you are able.

Do learn about template-based programming.  Learn what its strengths and weaknesses are, and how it differs from C# generics.

Title: Moving from C# to C++, and tips?


答:
This is likely to get closed due to open-ended-ness, but hopefully this tip is important enough and un-controversial enough to help:

Be aware of ownership.

In C# (and other languages with automatic memory management), what object owns a variable can be a bit fuzzy. Does the event own the handler, or does the "catcher" of the event? In C#, it doesn't really matter. In C++, your program will die a horrible, horrible (and often subtle) death if you don't know who owns that handler.

This is the key difference in how you need to design programs, and will manifest itself in subtle ways if you're not very careful with it. Learning to design around who owns what is the most important transition you'll need to make, so focus on it early.

Title: Moving from C# to C++, and tips?

Body:
I've been using C# for a while now, and for the sake of furthering my career and extending my knowledge of programming, I want to get into C++. C# is very useful, and fast to work with, but since my team and I will be making large scale projects I need to consider working at a lower level language for several reasons. Most commercial companies use C/C++ due high performance and portability. Of course, C# isn't necessarily bad compared to C or C++, but I just prefer to have a different tool for each job.

So I read C++ is harder because it is a low level language, machine code, and doesn't have memory management. But the fact that it is machine code also reduces the amount of memory consumed. The language is hard to work with, but in a way difficulty makes it a powerful language. It was made to be fast and efficient, machine code, but this makes it harder to understand and learn "since it is closer the the machine".

I've made up my mind, and I want to learn C++, so what are some tips to keep in mind while learning? It's best to avoid getting into bad habits rather than to try and break them later, safe than sorry.

I plan to use the resources stated here, but I would prefer any personal recommendations, books or online guides, possibly those that can be easily understood by someone who has fair knowledge of C#.


答:
I think that you need to be a little careful with the language that you are using to describe C++ (low level language), and also with some of the technical description (machine code) as it reads as inaccurate.

Then you need to work out why you really want to learn a new language. Many companies are using C/C++ and many are using Java and many are using Perl and Python and Scala and ... (some are even using Fortran). Maybe you have a specific company, sector or project in mind? If it is purely for employment reasons I'd caution against it unless you have a way of getting provable experience (I never managed to use my spare time projects as experience in an interview). Pick something that you are interested in, maybe it won't be OO at all; you'll be better at it in the long term through being genuinely interested. Then code in public and see how it goes, asking questions as you go, if it is C++ it's going to take a little while especially if you want to get into memory management!

Title: Moving from C# to C++, and tips?


答:
Should the data classes include their own respective 'readFromFile' functions or would it be better to have a global utility class that reads all data from file and generates the data objects?

Follow the Single Responsibility Principle (SRP).

Don't put data fetch in your data class(es).

Give your data class all the functionality it needs; for example implementing Comparable, Iterator, Equality as needed. Don't make the data-client have to brute force do these kinds of things to the data object.

Neither the algorithm nor data classes should not know how to read the data - it should ask some other class. Likewise the algorithm should ask the data class to sort itself (for example), not do it for the data class.

Minimize Coupling

Don't "new-up" your data objects inside the algorithm class, for example.

Loose coupling suggests you may have essentially a framework of sorts to drive the whole thing; perhaps a class to read data, one to build specific algorithm/data object combinations (Factory pattern), one to "get the data and algorithm together", one to coordinate algorithm execution, et cetera.

Think OO all the way down into details

Do not play a "more vs fewer" classes game. This is a simply wrong-headed.  Design a good structure (class hierarchy) for your data that strongly adheres to SRP. That is, data of any complexity is likely to be a composite of other types each handling it's own behavior. Done well you will be amazed at how simple, clean, and small code becomes both in the containing data class and data clients.

Title: Program design with multiple data sets, algorithms and results

Body:
I have a question regarding the design of my software.

There are four different data sets and three consecutive algorithms operating on the data sets and on the results from the previous algorithm runs.

Let D1 - D4 be the set of data sets, A1 - A3 the set of algorithms and R1 - R3 the set of results from the respective algorithms.

A1 uses data sets D1, D2 and D3 and has to run on n different parameters.
A2 uses data sets D1 and D3 as well as R1_1 - R1_n.
A3 uses data sets D1, D2 and D4 as well as R2.

```<code>  D1    D1    D1
  D2    D3    D2
  D3          D4

  |     |     |
  v     v     v

n*A1    A2    A3
     _     _
  |  /| |  /| |
  v /   v /   v

R1_1    R2    R3
...
R1_n
</code>```

Each of the results R1_1 - R1_n, R2 and R3 should have some output functionality.

So my question is how to organize the program and its classes. I guess I would want to create separate classes for each of D1 - D4, A1 - A3 and R1 - R3 and make the data and result objects attributes of the algorithm objects? Are there any reasons for or against creating n objects R1_1 - R1_n instead of one object R1 containing an array of n results?

Should the data classes include their own respective 'readFromFile' functions or would it be better to have a global utility class that reads all data from file and generates the data objects? The same goes for output functions, should they be placed in each of the result classes or should they be globally organized?

Kind regards!


问:
Who fixes broken tests?
Our small team has made the curious observation that diagnosing and fixing broken automated tests is a useful activity; in particular, if the CI build indicates that developer A's last check-in broke some tests, developer B can learn about (and possibly improve on) what developer A was doing by understanding why the test failed, and fixing it (either the code or the test, as appropriate.) This activity confers some of the benefits normally attributed to pair programming or code review, as far as getting more pairs of eyes on tricky pieces of code.

I'm wondering if other teams have made this same observation, and whether a practice like this makes sense to other people? Should the person who broke it, fix it, or should that job fall  to co-workers?

答: Best thing would be when the team decides in consensus who should fix the broken tests, depending on the indivdual case. This may be sometimes A, sometimes another person B or both together. If B does it alone, it would be nice at least to inform A on how he fixed it. And if there is some kind of trap some other people of the team should be aware of, the one fixes the bug should inform them, too.</p>

Title: Who fixes broken tests?


问:
Who does test-driven development?
I've been working in the enterprise space for the past 4½ years and have noticed that generally speaking, enterprises are not conducive environments for the test-first style of development. Projects are usually fixed-cost, fixed-timeline and waterfall style. Any unit testing, if done at all, usually comes after development in the QA phase and done by another team.

Prior to working for an enterprise, I consulted for many small to medium sized companies, and none of them were willing to pay for a test-first style of development project. They usually wanted development started immediately, or after a short design stint: i.e., something more akin to Agile, though some clients wanted everything mapped out similar to waterfall.

With what types of shops, companies, and clients does test-driven development work
best? What types of projects tend to be conducive to TDD?

答:
If you test after, you create rework as the code you will have written will be difficult to test. When you test first, or even test-a-little-bit-in-the-middle-but-before-you-commit the software you create will be easier to test. An enterprise that creates unit tests after production code is written to satisfy a check list is wasting effort.

Integration with existing hard to test software will also create additional effort, as you will need to create test seams to be able to control the dependencies your shiny new test driven code consumes. In some cases, such as with frameworks that make heavy use of global state and god objects this can be very difficult to achieve. The perceived difficulty of test driven development is often down to a combination of inexperience with writing good tests and attempting to test tightly coupled code.

You can test drive code even in a waterfall project, it is an engineering discipline not a project management technique.

I'm not a TDD fanatic by any means, but it teaches you a lot about software design.

Title: Who does test-driven development?


答:
Sounds like you are trying to 'sell' unit testing in your company. (Good for you!)

I am going to risk being hated here, but it sounds like you youself might not
be 100% clear on all the benefits of writing unit tests. As other
answers have pointed out, there are many reasons unit tests are extremely
useful (sometimes even necessary) other than catching bugs that the compiler
did not catch.

I suggest getting familiar with all the benefits and designing my demo accordingly.

Here are some quick things I would talk about/demo (not in any special order):

Quick validation that unit of code works without having to actually run it
in its intended environment. This is extremely crucial when it takes 5 min
to build your project, 10 min to deploy it and half an hour to try to
find the scenario when the code actually runs to validate that it 'works'.

Validation of code that would be extremely hard to test in its intended
environment. A huge percentage of the code we write is handling error conditions
or conditions that only happen in certain strange circumstances. These conditions
are very hard to reproduce in real life, therefore require special attention
to test.

Validating 'library' code. If you are writing code that others consume, your only
way of validating would be to write another 'project' that consumes and drives
it. Unit tests give you a high confidence that your code works without having
to use a project that drives your code to test it or to write a 'tester' app
yourself.

TDD. Test Driven Development is a fairly new way of thinking about
unit tests. When exercising TDD developers write the tests first,
then code afterwards. TDD can improve your code by only writing code that satisfies passing your tests. There is much debate about this topic
and myself used it extremely successfully in certain situations, but not so
successfully in others (context dependent IMHO).

Tests document your code. Many times tests are the most updated documentation
on how your code is supposed to behave. How many times do you look for an already
existing piece of code that exercises a class/method just to see how you are
supposed to use it? Well unit tests give you just that.

Code breakage. Yes, unit tests do catch bugs. However I find that they most often
catch bugs during development. I write the code, then I turn around to write the
test and this is the phase when I catch most bugs.

I am sure there are more to mention here so you should do more research
before your training. One more thing. It is hard to find examples when unit tests
'saved the day in a big way' because they catch bugs during development and
very silently most of the times. You only really understand their benefits
when you have been writing them for a while to see how they save the day
(on a daily basis).

I would compare them to exercising. It is hard to find a case when daily
exercise saved someone from having cancer or a heart attack.
But you do know deep down that it is necessary to live a long and healthy life.


答:
I'm surprised that everybody thinks this is such a good thing. The authors of Peopleware (which, IMO, is still one of the precious few software project management books actually worth reading) strongly disagree. Almost the entire Part IV of the book is dedicated to this very issue.

The software team is an incredibly important functional unit. Teams need to jell to become really productive. It takes time (a lot of time) for team members to earn each others' respect, to learn each others' habits and quirks and strengths and weaknesses.

Certainly, from personal experience, I can say that after a year of working with certain people, I've learned to laugh off certain things that used to rile me up, my estimates as team lead are much better, and it's not too difficult to get the work distributed so as to make everyone happy. It wasn't like that in the beginning.

Now you might say, "Oh, but we're not breaking up the whole team, just moving a few people." But consider (a) how blindly unproductive their replacements are going to be in the beginning, and (b) how many times you'll find yourself or other teams saying, without even thinking, "I really liked X" or "This would have been easier with Y still around", subtly and unconsciously offending the new members and creating schisms within the existing team, even sowing discontent among the "old" members.

People don't do this on purpose, of course, but it happens almost every time. People do it without thinking. And if they force themselves not to, they end up focusing on the issue even more, and are frustrated by the forced silence. Teams and even sub-teams will develop synergies that get lost when you screw around with the structure. The Peopleware authors call it a form of "teamicide".

That being said, even though rotating team members is a horrible practice, rotating teams themselves is perfectly fine. Although well-run software companies should have some concept of product ownership, it's not nearly as disruptive to a team to move that entire team to a different project, as long as the team actually gets to finish the old project or at least bring it to a level they're happy with.

By having team stints instead of developer stints, you get all the same benefits you would expect to get with rotating developers (documentation, "cross-pollination", etc.) without any of the nasty side-effects on each team as a unit. To those who don't really understand management, it may seem less productive, but rest assured that the productivity lost by splitting up the team totally dwarfs the productivity lost by moving that team to a different project.

P.S. In your footnote you mention that the tech lead might be the only person not to be rotated. This is pretty much guaranteed to mess up both teams. The tech lead is a leader, not a manager, he or she has to earn the respect of the team, and is not simply granted authority by higher levels of management. Putting an entire team under the direction of a new lead whom they've never worked with and who is very likely to have different ideas about things like architecture, usability, code organization, estimation... well, it's going to be stressful as hell for the lead trying to build credibility and very unproductive for the team members who start to lose cohesion in the absence of their old lead. Sometimes companies have to do this, i.e. if the lead quits or gets promoted, but doing it by choice sounds insane.


答:
So I was being flippant in my comment, but, that should be the case and not only that there should be a defined process for what happens and how long the build may remain broken for before the code just get rolled straight back out again.

If a developer can not build the product before checking their code in, then the project is too big or not modular enough.

If developer A changed the API and this broke the tests, the developer A should have seen that coming and it should have been flagged before making the changes.

If the full suite of tests is huge and can only run over night, they should be broken down into smaller suites. Usually these would relate to the modules of your project and then further into unit and integration tests.

You have CI which is great, is it set to poll your SCM for changes and run some tests on updates?

How often is code being checked in, could it be that check ins are too large and you would benefit from more frequent check ins.

Forking/Branching can be useful to manage different development streams if your developers are checking in unrelated changes that may break each others code in ways that they could not have anticipated.

Whatever the process is it should be rare that B is fixing A's code alone.

Always be pragmatic.

I do not believe that spreading the fixes around (in this instance) is useful, you'd benefit more from pair programming around the problem areas in the first place. In essence be proactive not reactive. You can give all the low priority bugs to your new developers and get them familiar with the whole codebase :)

Regarding

and if no tests ever broke, the utility would be lost

That is silly. If what you are saying is that you lack sufficient code coverage to tell if a core function of the code has been subverted and that is why no tests are breaking then yes, they lack utility. The tests should of course break (and if you're practicing TDD they should even start broken), but the point is that they should break (and be fixed, with or without cooperation between A and B) on the developers machine.

Years ago some bloke out of Eastenders wrote some things about it, but there are probably a million newer resources to cite.. Martin Fowler says.

Title: Who fixes broken tests?

Body:
Our small team has made the curious observation that diagnosing and fixing broken automated tests is a useful activity; in particular, if the CI build indicates that developer A's last check-in broke some tests, developer B can learn about (and possibly improve on) what developer A was doing by understanding why the test failed, and fixing it (either the code or the test, as appropriate.) This activity confers some of the benefits normally attributed to pair programming or code review, as far as getting more pairs of eyes on tricky pieces of code.

I'm wondering if other teams have made this same observation, and whether a practice like this makes sense to other people? Should the person who broke it, fix it, or should that job fall  to co-workers?


答:
I like the 2nd option best.

I'd do something like this:

```<code>public interface ChatRoom {
    public void putMessage(ChatMessage m);
    public void putMessageToParticularUser(ChatMessage m, int userID);
    public void addUser(ChatUser cu);
    ...
    ...
}
</code>```

Title: OOP - Modeling a Chat

Body:
When modeling a chat, should a chat object receive messages or a message be sent to a chat object? I'm not sure whether there is a definitive answer but maybe someone can point out benefits of one over the other.

message.send(chat);

VS.

chat.sendMessage(message);

Body:
I like the 2nd option best.

I'd do something like this:

public interface ChatRoom {
    public void putMessage(ChatMessage m);
    public void putMessageToParticularUser(ChatMessage m, int userID);
    public void addUser(ChatUser cu);
    ...
    ...
}


答:
Rotation of Programmers is good thing from company point of view and developer point of view.

From a company perspective

Management will get to know , the strength and weakness of particular developer whether they can handle multitasking or not and adaptive to changes .

If some developer leaves company for some reason , company already has backup ready for future.

It will enhance performance of project , as many people will work on it , same thing get tested by more and more developers. (Testing resource wastage minimized)

All team members works in team and it will boost performance of project and in future management will get to know , what kind of team needs to be made while implementing difficult module or task.

From a developer perspective

It will make developer more positive as his confidence increases.

Developers gets better and better ideas from others team mates code and they can use those technique in future development.

From better ideas and suggestions from other team members productivity of developer increases.

Only one main thing , need to keep in mind that,

Rotation of Programmers should not happen very frequent.
after 60% - 70% development done then only shifting will be beneficial.

ContentLicense: CC BY-SA 4.0


问:
Using Git - better to do lot of incremental updates or one big daily update?
Ive just started working with Git (Github) in anticipation for an up coming project I'm project managing and designing and developing the front end of.

One thing I couldn't work out is, is it preferable to publish each individual change as you make them, ie. updated sidebar js, designed new FAQ page (each as individual commits) and the back end developers would be doing the same ie. added this class, refactored this..

Or is it better to do a daily / half daily commit of all the work you've done?

My thoughts were that if you do lots of small commits its easier to roll back, but also at the same time every commit you make the rest of the team has to get locally before they can commit their code.

You obviously don't have this problem so much if you do daily or half daily commits, but its a little more complicated to roll back if you need to?

Is there a best practice for this or is it down to team preference?

Background: I'm using Github via the mac desktop app not the CL.

答:
You're thinking of git like it's SVN. It's not.

SVN looks at versions: Version 1000 contains sidebar, version 1001 contains sidebar and FAQ.

Git looks at changesets: Changeset 100 contains all the code to put in the sidebar, codeset 101 contains the FAQ. You can then merge those two together if you want, or add another feature and leave out the FAQ if it doesn't work like you want.

For more info see this Mega Thread on stackoverflow!

I find git to be much more forgiving than SVN as well, where branching and merging has a much lower cost, so feel free to do that as much as you want.


答:
What is triggering the message to be sent? If it's a specific client then why not:

client.send(message)

or

client.send(message, otherClient) for whisper

where client would be whatever object is created when a request is received, could be a message context or could be a user object that would identify the user, etc

if you base the objects around the events it should become clearer of what things you want to be 'controller' objects and what things you want to be data objects

Title: OOP - Modeling a Chat


问:
How do you validate need for documentation?
I once was on a project where a non-tech manager had the team spending half of every hour documenting what they just did so that someone with zero understanding of the tech would be able to understand the tech. Personally, I thought this was a huge waste, but there was no way to validate this was or was not waste.

Is there a light-weight means of validating need for documentation before committing to produce the documentation?

Example 1: Say the team is using an off-the-self software without customization. The test might be posting a job description on a monthly basis to access the likelihood that an expert in the software might be found at an acceptable cost level.

Example 2: Automatically pull variables, functions, etc from the code, and two weeks after the code is written, generating questions that automatically assess the developers own knowledge of their own code without access to the code. If the developer is unable to answer the questions, then they must explain the code to another developer, and that developer decides if documentation must be produced.

Example 3: Another way would be to take the likelihood that the code is used based on runtime analysis and cross reference it both with the volatility of input/output and historical likelihood of bugs/error being reported from that section of code and/or customer based requests to update the code.

Honestly, don't believe those are great examples, but are more of an attempt to give the general gist of what I'm after, and that the goal is the most generally useful bare-bones method for doing this.

答:
Measure the time it takes for new team members to be productive. Contrast that with other resources that are available to ramp up. For instance, if you have (which I will collectively call ramp up material):

Tutorials

Documents (ie. help-style docs)

Documentation (ie. API function headers etc.)

Searchable, shared Wiki/OneNote style documents

Then you should be able to get any competent dev running at full productive capacity within 3-6 months (depending on the complexity of the software). If it's required that new devs submit some arbitrary number of improvements or useful additions to the documents and/or tutorials, then they're always up-to-date and improving.

Bonus: tutorials/documents can be made available for customers and become a part of the product.

Then, if new devs (continuously) aren't ramping up sufficiently in that time, then the quality of your ramp up material isn't in-line with the complexity of your product or the work environment, and needs to be increased or improved.


问:
Are there presently any standardized "grammar" rules for HTML & CSS?
Over the years I have assigned values to classes and html elements in all sorts of ways:

myClass

MyClass

my_class

my-class

. . .and so on.  As I am always trying to hone my craft and make my code more readable for others, I am going to discipline myself to stick to one convention moving forward.  I am leaning towards all lower case and hyphenated, but that is a purely subjective choice.

So I wanted the input of the SE community--is there a standard or recommended convention already in place?

Thanks!

答:
There is a CSS Lint, although it's more about the structure of CSS than things like hyphenation of class names. That's a personal preference and really needs to be a judgment call based on your environment.

For example, if you're working exclusively with a JavaScript framework like Knockout or AngularJS, hyphenation is the norm. On the other hand, if you're working with a control-based framework like ASP.NET Web Forms, hyphenation of certain things (IDs and names especially) can be incredibly dangerous because they're invalid on the server side.

As far as other things like whether open braces go on a new line or not, it's the same holy war that it's always been. Pick a convention that works for you and/or your team and stick with it.


问:
Liskov substitution principle when implementing two unrelated interfaces
Suppose I have two unrelated interfaces with the same method:

```<code>interface Table {
    /**
     * @param width (0 < width <= 100)
     */
    void setWidth(int width);
}

interface Square {
    /**
     * @param width (50 <= width <= 10000)
     */
    void setWidth(int width);
}
</code>```

Then I create a class which implements both of these interfaces:

```<code>class SquareTable implements Square, Table {
    void setWidth(int width) {
        precondition = ...
        if (!precondition)
            throw new PreconditionFailedException("Precondition failed: ...");
    }
}
</code>```

How precondition expressions should be combined to satisfy Liskov substitution principle? Should they and'ed or or'ed? I.e. what should be written instead of ...:

```<code>width > 0 && width <= 10000 // using OR
width >= 50 && width <= 100 // using AND
</code>```

And which rule should be used for postconditions?

```<code>interface Table {
    /**
     * @return width (0 < width <= 100)
     */
    int getWidth();
}

interface Square {
    /**
     * @return width (50 <= width <= 10000)
     */
    int getWidth();
}

class SquareTable implements Square, Table {
    int getWidth() {
        postcondition = ...
        if (!postcondition)
            throw new PostconditionFailedException("Postcondition failed: ...");
    }
}

width > 0 && width <= 10000 // using OR
width >= 50 && width <= 100 // using AND
</code>```

答:
Preconditions

Given that the implementer must be usable as either a Table or a Square, the precondition must be the union (OR) of the two interface preconditions (i.e. width > 0 && width <= 10000).

Postconditions

The implementation must satisfy both interface postconditions, therefore its postcondition could be the intersection (AND) of the two interface preconditions (i.e. width >= 50 && width <= 100).

Implementation

One possible implementation that doesn't violate LSP is to use min/max bounds to keep width >= 50 && width <= 100, e.g. setWidth(10000) effectively performs setWidth(100).

Generally speaking, this isn't a very good solution since it is opaque to setWidth's caller (which might assume that getWidth() would return the value it passed to setWidth). It is much preferable (as Euphoric mentions) to not use one implementation for methods from different interfaces.


答:
This looks like an etymology question. It does not seem suitable for Programmers.Stackexchange.

(0.1) What is data? Data is anything that can be copied (replicated)

(0.2) What is process? Process is something that takes input (data) and produces output (data), and usually takes some non-zero (and finite) amount of time to finish.

(0.2.1) Process may be computational or external - human action may be involved.

(1) resource (or capacity / constraint) - one of the necessary conditions for a computation to succeed, without time-out, or running out of memory or disk space.

(2.1) event - a piece of data that is pegged to a timestamp. Some events can be anticipated; some can't. Once an event has occurred it can be propagated to other agents to the system.

(2.2) casuality - a ordering constraint placed on events.

(3) jurisdiction - some type of data is not allowed to leak outside a certain building by law. Likewise, some type of processes are not allowed to occur outside a certain place.

Title: Can everything in computing be classified as either data or a process?

Body:
Working in a field called "revenue assurance" I basically build systems to validate other systems.

After a while in this market it seems to me that all these "validations" are verifying either a process from my customer's environment or the data used by these processes.

With this in mind I am considering using such definition to orientate sales people and even architects working on the products. However, researching this topic I couldn't find a definitive answer although haven't dismissed the possibility either.

Is everything one of the two then?


答:
I'm not going to deal with the epistemological or ontological arguments here, but there are a variety of different programming models that each have fairly strict categorizations of their "universe".

For example:

First-generation imperative languages are based on the Turing Machine which models everything with data (variables) and instructions. There's no problem that you can't represent with this model; its downside is that many problems are very difficult to represent.

OOP defines an object as a combination of state and behaviour. What you call "data" would be the state, but objects also deal with input and have to produce some output (which is not generally considered "data" unless/until it is actually stored). Strictly speaking, it's still based on the Turing machine, but relationships and inheritance between objects can massively simplify the problem. Life becomes a lot easier when you have some system of organizing all of these processes.

SOA defines the concept of services, which are orthogonal to objects, and aligned with a particular business function. Services are a way of grouping not only behaviours but (unlike OOP) also the data that affect them, since services aren't allowed to share state. What's interesting about this model is that it very closely approximates how people interact with each other as opposed to how they interact with things. Almost all businesses and communities in general are organized into departments and skill sets, with areas of fairly strict specialization; without this type of organization, most of human society would fall apart. In this model, what you refer to as a "process" is really more of an "operation", and a "process" is actually a long-running "saga" that coordinates all of the different services and operations involved.

Functional languages, based on the lambda calculus, only use functions. A function is different from a "process" because a function can't change state (and in fact there is no state to change). This is one example of how it's possible to break the problem down even more than you already have. Of course, for people who aren't accustomed to it, it can be incredibly difficult to model the problem that way.

The world can be as simple or as complex as you want to model it. If breaking everything down into simply "data" and "process" is appropriate for your purpose, then by all means do it, but keep in mind that such a mode of thinking comes more naturally to computers than humans. Programmers are good at modelling and understanding things that way, non-programmers aren't.

Non-programmers, in my experience, are most at ease with the service model: I have one guy who prepares my meals, another guy who drives me across town, another guy who keeps my money safe, and so on, and I don't really know or care how they do it, I just do what I do and tell them what I need. This last paragraph will seem to be totally irrelevant to your question, which is exactly why programmers and business people seem to have so much trouble communicating. ☺


问:
Is there a good name for "classic" .NET?
So, as Microsoft has created many forks and branches off of .NET, there have been a few different product names come up:

Silverlight

.NETCore/WinRT/.Net for Windows Store Apps

.NET for Windows Phone/CoreCLR

.NET Micro Framework

.NET Compact Edition

However, what do you call the traditional .NET we all know and love? You can't call it Desktop .NET probably, because it also runs on servers, and that might imply you're using that client-profile thing. .NET for PC seems unusual. You can't really just say "this is a product for .NET" because then people might assume that includes support for one of the other frameworks

Does Microsoft have an official "name" for the traditional .NET that runs in Windows PCs?

答:
Microsoft's own terminology labels this category as ".NET Framework (Windows desktop and server)".

It's a little long-winded but I don't see how you can be any less ambiguous. It clearly excludes Silverlight, Windows Phone, Mono, etc.

As far as the "Client Profile", the and server phrasing should take care of that; unless an application specifically labels itself as desktop-only, I would assume that it is targeted to the full framework and not the Client Profile.


问:
Should I fork for a major re-write that uses a small amount of the original code?
I'm writing a library. It's a completely rewritten version of another one, to suit my needs (PCL compatibility, mainly). However, the API will be completely rewritten, as I'll need to change a lot of stuff around for PCL compliance. Also, as it is a rewrite, I won't be able to just start from the library and just change it bit by bit, as I typically see with forks. I tried that, but it just didn't work.

So what should I do? Should I fork here or should I make a new library?

答:
So what should I do? Should I fork here or should I make a new
  library?

With both options you'll be left working on some form of new iteration of your old project. The differences lie in other things:

Forking would leave you to start working with the last version of the code of the previous iteration, so here it depends on how similar in structure / design you envision the new iteration in respect to the previous one. If it's too different, you might opt for starting a new library instead of forking.

When you create a new project you are detaching yourself from the source code repository of your previous iteration. Forking would keep your projet in the same repository, enabling you to rollback to or get from a specific historial version. Advantages of not forking, from this aspect, would probably be better order and organization and less clutter of your new repository as you start fresh.

If this is an open source community driven project, then you should consider forking or not also based on the fact that the decision will in itself convey content to the community. Forking would indicate the new iteration should be thought of in terms of being a direct continuation of the previous one. Starting a new separate project would indicate to the opposite.