答:
This is (sort of) an example of the bin packing problem, which is frequently confused with the knapsack problem. In bin packing, you have bins of a certain capacity, and you are trying to distribute objects of various sizes into the bins. The idea is to use the least possible number of bins.

You aren't exactly trying to minimize the number of bins, though, you are trying to minimize the number of empty seats. And it is possible that you are trying to minimize the number of empty seats across the fleet, that is, you have four tour groups of various sizes, and you want to accomodate all of them with the fewest number of empty seats. I can't think of an instance right off the bat, but I imagine it might be possible to construct a fleet and a set of tour groups such that you would be better off with a substandard solution for some group because it allowed you to avoid using an even worse solution for some other group.

It gets worse. What if you have 20,30, and 50 passenger busses. Each one uses different amounts of fuel, but it is more efficient to run one 50 than it is to run a 20 and a 30. But from our single measure (least number of empty seats), it makes sense to run either for a 50 passenger tour.

Also, buses with weird numbers, like 28 or 39, would skew a lot of our shortcuts.

So, depending on the complexity of the situation, you could do one of two things:

First, and exhaustive search tree: use every possible combination of buses. If you only have 3 or 4 bus sizes, this is probably a reasonable solution. Otherwise, something like Best fit decreasing would yield reasonable, but not optimal, results.

Title: Efficient Bus Loading

Body:
This is something I did for a bus travel company a long time ago, and I was never happy with the results. I was thinking about that old project recently and thought I'd revisit that problem.

Problem:

Bus travel company has several buses with different passenger capacities (e.g. 15 50-passenger buses, 25 30-passenger buses ... etc). They specialized in offering transportation to very large groups (300+ passengers per group). Since each group needs to travel together they needed to manage their fleet efficiently to reduce waste.

For instance, 88 passengers are better served by three 30-passenger buses (2 empty seats) than by two 50-passenger buses (12 empty seats). Another example, 75 passengers would be better served by one 50-passenger bus and one 30-passenger bus, a mix of types.

What's a good algorithm to do this?


问:
How do you deal with the anxiety of not knowing enough?
I just finished college a couple of months ago and I'm taking time out to improve my knowledge. I love programming but I feel like I don't know enough to be confident if I went for an interview. Last night I was browsing through questions and came across a question that asks interviewees how to work out a linked list. I learned these at college but if I was asked on the spot how to do it I wouldn't know. So that's another thing added to the list of what to learn.

This is when the anxiety hit me because I have so much to learn in so little time (at least it feels that way). Upon introspection, I think this anxiety is related to my perfectionism even though being perfect isn't rational e.g. Shakespeare and Einstein failed 80% of the time.

So the questions are, have you felt this anxiety of not knowing enough? If so, how did you deal with it? I suppose there's a point in time when you begin to feel comfortable in your abilities?

答:
This is when the anxiety hit me
  because i have so much to learn in so
  little time.

Granted, you have a lot to learn, but you have all the time in the world.  You are only 21 according to your profile.  I'm 63 and still learning.  Sure, I worked out the linked list thing a few decades ago, but there was (and is) always something else.

Always having new stuff to learn is what makes programming still fun for me even though I've been doing it for 40 years.  If I knew it all at your age, it would have gotten a little boring by now.

ContentLicense: CC BY-SA 3.0

ContentLicense: CC BY-SA 2.5


问:
Efficient Bus Loading
This is something I did for a bus travel company a long time ago, and I was never happy with the results. I was thinking about that old project recently and thought I'd revisit that problem.

Problem:

Bus travel company has several buses with different passenger capacities (e.g. 15 50-passenger buses, 25 30-passenger buses ... etc). They specialized in offering transportation to very large groups (300+ passengers per group). Since each group needs to travel together they needed to manage their fleet efficiently to reduce waste.

For instance, 88 passengers are better served by three 30-passenger buses (2 empty seats) than by two 50-passenger buses (12 empty seats). Another example, 75 passengers would be better served by one 50-passenger bus and one 30-passenger bus, a mix of types.

What's a good algorithm to do this?

答:
I'm going to answer this from the customer perspective. I would not want a hard coded algorithm for this application. There are too many variables that can change over time. Although nothing about your buses may change the weights of the factors could change or new factors could be discovered that I never thought of (e.g. over-time, laws, and other driver costs).

Because of this, I would want to be able to create my own lookup table based on a range of the number of passengers requested and I would create my own settings for the best bus combinations. Example: 31-50 = 1 X 50, 51-60 = 2 X 30. Does this really need to be calculated? Easier to change settings than a bunch of formulas factoring seats, gas and drivers. Figure out the best combination and be done with it and have plenty of room for the user to change these settings as they see fit.

New factors could be discovered. Do larger buses pay an exponentially higher rate on tolls? Can I get less expensive drivers for small buses when a new law for extra certification and licensing goes up on drivers of buses over 30 passengers?

They hire a new consultant with a different logic to their formula and your app may need to be rewritten. You mean you have to factor cost of parking?

Title: Efficient Bus Loading


问:
What design pattern do you use to support graceful fallback on old platforms?
Let's say I need to add a drop shadow behind a box. Some old platforms do not support drop shadows, so I have to fake it by putting an image behind the box. Here's the pseudo code of how I'm currently handling this fallback:

```<code>if (dropShadowsAreSupported) {
    box.addDropShadow("black");
} else {
    box.putImageBehindIt("gaussianBlur.png");
}
</code>```

Is this the right way to handle it? It seems too amateur to me. Is there a better design pattern?

In my actual project, there are a ton of places where I need to style the user interface differently for different operating system versions. It's not only one if-else.

答: This sounds like a job for the Strategy Pattern.  Pass in a rendering strategy, and instantiate the rendering strategy based on your platform.</p>


答:
if you are going to do something like that then conditional compilation or different library implementations are the key

this way you can say

```<code>addShadow(box,black);
</code>```

and depending on what library you link it with it will become either the addDropShadow or the addImageBehind

in C you could also say

```<code>#IFDEF DROP_SHADOW_SUPPORTED
    box.addDropShadow("black");
#ELSE
    box.putImageBehindIt("gaussianBlur.png");
#ENDIF
</code>```

you abstract this (or it is already abstracted) in your graphics library so the source code won't be need to change only the library

Title: What design pattern do you use to support graceful fallback on old platforms?

Body:
Let's say I need to add a drop shadow behind a box. Some old platforms do not support drop shadows, so I have to fake it by putting an image behind the box. Here's the pseudo code of how I'm currently handling this fallback:

```<code>if (dropShadowsAreSupported) {
    box.addDropShadow("black");
} else {
    box.putImageBehindIt("gaussianBlur.png");
}
</code>```

Is this the right way to handle it? It seems too amateur to me. Is there a better design pattern?

In my actual project, there are a ton of places where I need to style the user interface differently for different operating system versions. It's not only one if-else.

Body:
if you are going to do something like that then conditional compilation or different library implementations are the key

this way you can say

addShadow(box,black);

and depending on what library you link it with it will become either the addDropShadow or the addImageBehind

in C you could also say

#IFDEF DROP_SHADOW_SUPPORTED
    box.addDropShadow("black");
#ELSE
    box.putImageBehindIt("gaussianBlur.png");
#ENDIF

you abstract this (or it is already abstracted) in your graphics library so the source code won't be need to change only the library


答: As Scott Whitlock mentioned, a strategy can provide different implementations of the behavior. That said, it is probably over-engineering in the supplied case. Not everything has to fit into a pattern; some simple conditional behavior like this is fine as a simple conditional. No need to make things more complicated if they don't need to be.</p>


问:
Motivation and use of move constructors in C++
I recently have been reading about move constructors in C++ (see e.g. here) and I am trying to understand how they work and when
I should use them.

As far as I understand, a move constructor is used to alleviate the performance problems caused by copying large objects. The wikipedia page says: "A chronic performance problem with C++03 is the costly and unnecessary deep copies that can happen implicitly when objects are passed by value."

I normally address such situations

by passing the objects by reference, or

by using smart pointers (e.g. boost::shared_ptr) to pass around the object (the smart pointers get copied instead of the object).

What are the situations in which the above two techniques are not sufficient
and using a move constructor is more convenient?

答:
Move semantics aren't necessarily all that big of an improvement when you're returning a value -- and when/if you use a shared_ptr (or something similar) you're probably prematurely pessimizing. In reality, nearly all reasonably modern compilers do what's called Return Value Optimization (RVO) and Named Return Value Optimization (NRVO). This means that when you're returning a value, instead of actually copying the value at all, they simply pass a hidden pointer/reference to where the value's going to be assigned after the return, and the function uses that to create the value where it's going to end up. The C++ standard includes special provisions to allow this, so even if (for example) your copy constructor has visible side effects, it's not required to use the copy constructor to return the value. For example:

```<code>#include <vector>
#include <numeric>
#include <iostream>
#include <stdlib.h>
#include <algorithm>
#include <iterator>

class X {
    std::vector<int> a;
public:
    X() {
        std::generate_n(std::back_inserter(a), 32767, ::rand);
    }

    X(X const &x) {
        a = x.a;
        std::cout << "Copy ctor invoked\n";
    }

    int sum() { return std::accumulate(a.begin(), a.end(), 0); }
};

X func() {
    return X();
}

int main() {
    X x = func();

    std::cout << "sum = " << x.sum();
    return 0;
};
</code>```

The basic idea here is fairly simple: create a class with enough content we'd rather avoid copying it, if possible (the std::vector we fill with 32767 random ints). We have an explicit copy ctor that'll show us when/if it gets copied. We also have a little more code to do something with the random values in the object, so the optimizer won't (at least easily) eliminate everything about the class just because it does nothing.

We then have some code to return one of these objects from a function, and then use the summing to ensure the object is really created, not just ignored completely. When we run it, at least with most recent/modern compilers, we find that the copy constructor we wrote never runs at all -- and yes, I'm pretty sure that even a fast copy with a shared_ptr is still slower than doing no copying at all.

Moving allows you to do a fair number of things you simply couldn't do (directly) without them. Consider the "merge" part of an external merge sort -- you have, say, 8 files you're going to merge together. Ideally you'd like to put all 8 of those files into a vector -- but since vector (as of C++03) needs to be able to copy elements, and ifstreams can't be copied, you're stuck with some unique_ptr/shared_ptr, or something on that order to be able to put them in a vector. Note that even if (for example) we reserve space in the vector so we're sure our ifstreams will never really be copied, the compiler won't know that, so the code won't compile even though we know the copy constructor will never be used anyway.

Even though it still can't be copied, in C++11 an ifstream can be moved. In this case, the objects probably won't ever be moved, but the fact that they could be if necessary keeps the compiler happy, so we can put our ifstream objects in a vector directly, without any smart pointer hacks.

A vector that does expand is a pretty decent example of a time that move semantics really can be/are useful though. In this case, RVO/NRVO won't help, because we're not dealing with the return value from a function (or anything very similar). We have one vector holding some objects, and we want to move those objects into a new, larger chunk of memory.

In C++03, that was done by creating copies of the objects in the new memory, then destroying the old objects in the old memory. Making all those copies just to throw away the old ones, however, was quite a waste of time. In C++11, you can expect them to be moved instead. This typically lets us, in essence, do a shallow copy instead of a (generally much slower) deep copy. In other words, with a string or vector (for only a couple of examples) we just copy the pointer(s) in the objects, instead of making copies of all the data those pointers refer to.

Body:
Move semantics aren't necessarily all that big of an improvement when you're returning a value -- and when/if you use a shared_ptr (or something similar) you're probably prematurely pessimizing. In reality, nearly all reasonably modern compilers do what's called Return Value Optimization (RVO) and Named Return Value Optimization (NRVO). This means that when you're returning a value, instead of actually copying the value at all, they simply pass a hidden pointer/reference to where the value's going to be assigned after the return, and the function uses that to create the value where it's going to end up. The C++ standard includes special provisions to allow this, so even if (for example) your copy constructor has visible side effects, it's not required to use the copy constructor to return the value. For example:

#include <vector>
#include <numeric>
#include <iostream>
#include <stdlib.h>
#include <algorithm>
#include <iterator>

class X {
    std::vector<int> a;
public:
    X() {
        std::generate_n(std::back_inserter(a), 32767, ::rand);
    }

    X(X const &x) {
        a = x.a;
        std::cout << "Copy ctor invoked\n";
    }

    int sum() { return std::accumulate(a.begin(), a.end(), 0); }
};

X func() {
    return X();
}

int main() {
    X x = func();

    std::cout << "sum = " << x.sum();
    return 0;
};

The basic idea here is fairly simple: create a class with enough content we'd rather avoid copying it, if possible (the std::vector we fill with 32767 random ints). We have an explicit copy ctor that'll show us when/if it gets copied. We also have a little more code to do something with the random values in the object, so the optimizer won't (at least easily) eliminate everything about the class just because it does nothing.

We then have some code to return one of these objects from a function, and then use the summing to ensure the object is really created, not just ignored completely. When we run it, at least with most recent/modern compilers, we find that the copy constructor we wrote never runs at all -- and yes, I'm pretty sure that even a fast copy with a shared_ptr is still slower than doing no copying at all.

Moving allows you to do a fair number of things you simply couldn't do (directly) without them. Consider the "merge" part of an external merge sort -- you have, say, 8 files you're going to merge together. Ideally you'd like to put all 8 of those files into a vector -- but since vector (as of C++03) needs to be able to copy elements, and ifstreams can't be copied, you're stuck with some unique_ptr/shared_ptr, or something on that order to be able to put them in a vector. Note that even if (for example) we reserve space in the vector so we're sure our ifstreams will never really be copied, the compiler won't know that, so the code won't compile even though we know the copy constructor will never be used anyway.

Even though it still can't be copied, in C++11 an ifstream can be moved. In this case, the objects probably won't ever be moved, but the fact that they could be if necessary keeps the compiler happy, so we can put our ifstream objects in a vector directly, without any smart pointer hacks.

A vector that does expand is a pretty decent example of a time that move semantics really can be/are useful though. In this case, RVO/NRVO won't help, because we're not dealing with the return value from a function (or anything very similar). We have one vector holding some objects, and we want to move those objects into a new, larger chunk of memory.

In C++03, that was done by creating copies of the objects in the new memory, then destroying the old objects in the old memory. Making all those copies just to throw away the old ones, however, was quite a waste of time. In C++11, you can expect them to be moved instead. This typically lets us, in essence, do a shallow copy instead of a (generally much slower) deep copy. In other words, with a string or vector (for only a couple of examples) we just copy the pointer(s) in the objects, instead of making copies of all the data those pointers refer to.


问:
How abstract should you get with BDD
I was writing some tests in Gherkin (using Cucumber/Specflow). I was wondering how abstract should I get with my tests.

In order to not make this open-ended, which of the following statements is better for BDD:

```<code>Given I am logged in with email admin@mycompany.com and password 12345
When I do something
Then something happens
</code>```

as opposed to

```<code>Given I am logged in as the Administrator
When I do something
Then something happens
</code>```

The reason I am confused is because 1 is more based on the behaviour (filing in email and password) and 2 is easier to process and write the tests.

答:
They're not really tests; they're scenarios or examples of how to use your code. If you avoid the word "test" you'll have an easier time, and it will become obvious that 2 is the way forward because you'll be able to discuss your scenarios with the business.

The business have no interest in tests phrased in the way you've described in 1. Business people would generally much rather talk through an example of how to use the code, which will lead inevitably to 2.

Additionally, the fact that you're asking suggests you're not talking to the business yet. Please go have the conversations. It's the most important bit of BDD - far more important than the automation - and will save you a lot of rework and pain, as well as helping to keep the scenarios interesting and maintainable in the event that you do automate them.

That first scenario doesn't describe the behavior any differently to the second one - it just describes the mechanics of the behavior, which will make it harder to change those mechanics later, as well as introducing unnecessary detail. The only time you'd need a scenario phrased in the same way as 1 is if you're really fascinated by logging in. I would prefer to see a scenario focused on the business-valuable activity you're logging in for.

OwnerDisplayName: Newton

Title: How abstract should you get with BDD

OwnerDisplayName: Lunivore


答:
Another key thing to think about when penning your features and scenarios is this: If we change X in the system, will I need to refactor my scenarios? If the answer is yes, I would say that it is getting to specific about the details. IMO features and scenarios should only change because of changes in requirements from the business/stakeholders.

So in your examples:
Say you change the authentication system, and it enforces a username rather than an email address as the user identifier for logging in.

In your first example you're going to have to go back to your scenario and change that. In the second example - you won't.

Title: How abstract should you get with BDD

Body:
I was writing some tests in Gherkin (using Cucumber/Specflow). I was wondering how abstract should I get with my tests.

In order to not make this open-ended, which of the following statements is better for BDD:

```<code>Given I am logged in with email admin@mycompany.com and password 12345
When I do something
Then something happens
</code>```

as opposed to

```<code>Given I am logged in as the Administrator
When I do something
Then something happens
</code>```

The reason I am confused is because 1 is more based on the behaviour (filing in email and password) and 2 is easier to process and write the tests.

OwnerDisplayName: SaxonMatt


问:
sorting using a custom definition of ">" and "< " in python
suppose I have a custom function such as

```<code>def greater(a, b):
    if (a % b) % 2 == 0:
        return 1
    return 0
</code>```

It defines how to compare two numbers and determine which is greater.
In this case, if the function returns 1 a > b else, a < b. Can I use inbuilt <built-in function sorted> orto create a sorted array of numbers with respect to this definition?

答:
If you're using Python 2.x, then that's easily achievable by using cmp, although you have to modify your function to return -1 instead of 0. Something like this:

```<code>def greater(a, b):
    if (a % b) % 2 == 0:
        return 1
    return -1

x = [2,7,5,10,30,15]

print(sorted(x, cmp=greater))
</code>```

But if you're using Python 3.x, then it gets a bit more complicated since cmp was removed. My best idea is to implement a class to hold the number and override the comparison operators __lt__ (less than) and __gt__ (greater than). Something like this:

```<code>class my_int(int):
    def __lt__(a,b):
        return (a % b) % 2 != 0
    def __gt__(a,b):
        return (a % b) % 2 == 0

x = [my_int(2),my_int(7),my_int(5),my_int(10),my_int(30),my_int(15)]

print (sorted(x))
</code>```

Body:
If you're using Python 2.x, then that's easily achievable by using cmp, although you have to modify your function to return -1 instead of 0. Something like this:

def greater(a, b):
    if (a % b) % 2 == 0:
        return 1
    return -1

x = [2,7,5,10,30,15]

print(sorted(x, cmp=greater))

But if you're using Python 3.x, then it gets a bit more complicated since cmp was removed. My best idea is to implement a class to hold the number and override the comparison operators __lt__ (less than) and __gt__ (greater than). Something like this:

class my_int(int):
    def __lt__(a,b):
        return (a % b) % 2 != 0
    def __gt__(a,b):
        return (a % b) % 2 == 0

x = [my_int(2),my_int(7),my_int(5),my_int(10),my_int(30),my_int(15)]

print (sorted(x))


问:
Historical origins of Scala implicits
Scala has been called complex with its rich feature set by many of my colleagues and some even blamed all those new features of it. While most programmers are aware of the OO-features, and at least the decent ones also know about functional programming, there is one feature in particular in Scala for which I am not aware of its historical origins.

Given that a major mantra of our profession is to not reinvent the wheel, I am rather confident, that Scala does not have any actual unheard-of-before features, but I stand to be corrected on this one if necessary.

To get to the actual question, while I am aware of the origins of most of Scala's features I have never seen something like its implicit declarations before. Are there other (older!) languages out there which also provide this feature?

Does it make sense to distinguish the different cases of implicits (as they may originate from different sources), namely implict conversions and implicit parameters?

答:
I disagree with Brian's answer on that other question.

As far as I know, there's no implicit concept on any other language. The change history for Scala implies that implicits were a generalization of view bounds, and a view bound is, itself, a generalization of automatic type conversion, which is very common indeed.

Implicits then enabled type classes, but I'd be very surprised if that was the original intent.

Edit

The release notes for Scala 2.0 (2006) say:

Views in Scala 1.0 have been replaced by the more general concept of
  implicit parameters

That doesn't mean, of course, that implicit parameters were introduced with the goal of replacing views.

However, Odersky clearly likes it when once concept can replace multiple ones. In that sense, it may well be the case that Odersky wanted type classes, but did not want to introduce a mechanism to handle that exclusively, and, therefore, came up with something else that let him remove one concept (Views) and replace it with a more generic concept that handles both views and type classes.

In case anyone is interested, Poor Man's Type Classes, referred to by Brian back at Stack Overflow, is dated 2006 as well. Clearly, Odersky was aware of the link between implicits and type classes when he introduced them.

Yet, I stand by my claim. :-)

Title: Historical origins of Scala implicits


问:
Approaching Java/JVM internals
I've programmed in Java for about 8 years and I know the language quite well as a developer, but my goal is to deepen my knowledge of the internals. I've taken undergraduate courses in PL design, but they were very broad academic overviews (in Scheme, IIRC).  </p>

<p>Can someone suggest a route to start delving into the details? Specifically, are there particular topics (say, garbage collection) that might be more approachable or be a good starting point?  Is there a decent high-level book on the internals of the JVM and the design of the Java programming language?  My current approach is going to be to start with the JVM spec and research as needed. </p>

答:
I did a bit of this when I started with Java, years ago. My approach was to read the VM spec, and to look at the output of javap -c, which displays the disassembled bytecode of a class. I also tried creating java classes with particular bytecode, using a java bytecode assembler. There is an assembler called jasmin, if you want to try that.

You might also want to look at the Lambda Expression Translation document that Brian Goetz of Oracle has posted, which covers the strategy that will be used to translate the lambdas (closures, essentially) that are being added in Java 8.

You can also get the source code for the Hotspot VM from OpenJDK, and the early access version of the javac compiler with lambda support (hg repository) for JDK 8, if you really feel like diving into the deep end of the pool.

Looking into garbage collection is probably a good idea. A quick search turned up this Dr. Dobbs article on Java's garbage-first GC. I don't know if that's a good introduction. I assume you already know about mark-and-sweep and generational garbage collectors; if not, you will want to read up on those first.

Title: Approaching Java/JVM internals


问:
Are More Comments Better in High-Turnover Environments?
I was talking with a colleague today. We work on code for two different projects. In my case, I'm the only person working on my code; in her case, multiple people work on the same codebase, including co-op students who come and go fairly regularly (between every 8-12 months). She said that she is liberal with her comments, putting them all over the place. Her reasoning is that it helps her remember where things are and what things do since much of the code wasn't written by her and could be changed by someone other than her. Meanwhile, I try to minimize the comments in my code, putting them in only in places with a unobvious workaround or bug. However, I have a better understanding of my code overall, and have more direct control over it. </p>

<p>My opinion in that comments should be minimal and the code should tell most of the story, but her reasoning makes sense too. Are there any flaws in her reasoning? It may clutter the code but it ultimately could be quite helpful if there are many people working on it in the short- to medium-run. </p>

答:
The problem with comments is that they tend to grow out-of-synch with the code really quickly. This means there are often misleading or flat-out wrong comments in the code, so they hurt readability more than they help.

The goal is to make a codebase easy to understand and modify. You can do this though liberal use of comments (though you might run into the problem out of data comments), or you can write self-documenting code (as much as possible), and only use comments to explain the non-trivial "why" questions. Either approach might work, but keep in my that to modify the code you will have to understand the code itself, and not just the comments. So while comments might help you understand the code, at the end of the day you will still probably have to understand the code itself. With that said, I prefer the self-documenting code approach. It seems to be a more direct way to create a clean codebase.


答:
Prolific comments in that kind of environment are covering up for a problem that should be solved another way.

Quality, readable code should never need additional comments to explain what it does. The only time to comment is when you want to explain why something was done in a particular way. And even then, those comments could arguably be in source control commit messages.

So, the problem she's solving is that she's having to work with students who don't know how to write their code in a readable manner. In my opinion, cluttering the code with comments is a weak solution to that problem.

Stringent code reviews would be much more effective, both in keeping the code tidy and in improving those students for the future, whether that be in the same company or elsewhere.

Title: Are More Comments Better in High-Turnover Environments?

Body:
I was talking with a colleague today. We work on code for two different projects. In my case, I'm the only person working on my code; in her case, multiple people work on the same codebase, including co-op students who come and go fairly regularly (between every 8-12 months). She said that she is liberal with her comments, putting them all over the place. Her reasoning is that it helps her remember where things are and what things do since much of the code wasn't written by her and could be changed by someone other than her. Meanwhile, I try to minimize the comments in my code, putting them in only in places with a unobvious workaround or bug. However, I have a better understanding of my code overall, and have more direct control over it. </p>

<p>My opinion in that comments should be minimal and the code should tell most of the story, but her reasoning makes sense too. Are there any flaws in her reasoning? It may clutter the code but it ultimately could be quite helpful if there are many people working on it in the short- to medium-run. </p>


答:
Comments don't clutter the code.

And when they do, well, every half decent IDE can hide / fold comments. Ideally the story should be told by your code, your requirements document, your commit history and your unit tests, and not by comments. However excessive commenting can only hurt when comments are concentrated on the how and not the why, however that's a different discussion.

I think both you and your colleague are "right", the difference being, of course, that you work alone and she in a team, that oftenly includes inexperienced developers. You don't have so much a different philosophy on comments, but vastly different requirements on communicating your code. The "it helps me remember" argument could also stem from the fact that she deals with a lot more code than you, and more importantly code produced by different people, each one with their own personal preferences and quirks.

At the end of the day, code comments, albeit their obvious flaws, are the simplest and quickest way of communicating your code. Depending on team composition and organization, it might even be the only way that applies to the lowest common denominator. I usually find myself following your commenting philosophy when working alone and adjusting to your colleague's when working in a team, especially if it's an unbalanced team skill wise.


问:
when should a database table be broken into multiple tables with relations?
I have an application that needs to store client data, and part of that is some data about their employer as well. Assuming that a client can only have one employer, and that the chance of people having identical employer data is slim to none, which schema would make more sense to use?

Schema 1

```<code>Client Table:
-------------------
id int
name  varchar(255),
email varchar(255),
address varchar(255),
city varchar(255),
state char(2),
zip varchar(16),
employer_name varchar(255),
employer_phone varchar(255),
employer_address varchar(255),
employer_city varchar(255),
employer_state char(2),
employer_zip varchar(16)
</code>```

```<code>**Schema 2**

   Client Table
   ------------------
id int
name  varchar(255),
email varchar(255),
address varchar(255),
city varchar(255),
state char(2),
zip varchar(16),

Employer Table
---------------------
id int
name varchar(255),
phone varchar(255),
address varchar(255),
city varchar(255),
state char(2),
zip varchar(16)
patient_id int
</code>```

Part of me thinks that since are clearly two different 'objects' in the real world, seperating them out into two different tables makes sense. However, since a client will always have an employer, I'm also not seeing any real benefits to seperating them out, and it would make querying data about clients more complex. Is there any benefit / reason for creating two tables in a situation like this one instead of one?

答:
As usual...

It Depends

Both structures could be valid, depending on what you are going to do with the data.

If you just need a 'dump' table for a fast report of the current client+employer information, then the first arrangement is fine.

If you are modeling a simplistic subset of the real world, where every client has zero or one employer, then the second arrangement will suffice (though client should point at employer and not vice-versa).

If you are maintaining a more 'real world' model, where time matters, then client and company could be separate tables, with a third table for the is-employed-by relationship which includes start-date and end-date fields; people do change employers from time to time ;)

If you want a minimal, nonredundant (even object-oriented) model, then you'll note that you are storing almost exactly the same information about client and company, which could be generalized to a single Company table. Another table would note that some of the Companies are your clients, while another table would note the employed-by relationship.

The latter is arguably less redundant and more 'real world' than the other models, but can be more difficult to query and maintain.

Which brings us back to: what, exactly, are you going to be doing with this data?


问:
When using method chaining, do I reuse the object or create one?
When using method chaining like:

var car = new Car().OfBrand(Brand.Ford).OfModel(12345).PaintedIn(Color.Silver).Create();
```

<p>there may be two approaches:</p>

<ul>
<li><p>Reuse the same object, like this:</p>

<pre class="lang-cs prettyprint-override"><code>public Car PaintedIn(Color color)
{
    this.Color = color;
    return this;
}
</code>```

Create a new object of type Car at every step, like this:

public Car PaintedIn(Color color)
{
    var car = new Car(this); // Clone the current object.
    car.Color = color; // Assign the values to the clone, not the original object.
    return car;
}
```</li>
</ul>

<p>Is the first one <em>wrong</em> or it's rather a personal choice of the developer?</p>

<hr>

<p>I believe that he first approach may quickly cause the intuitive/misleading code. Example:</p>

<pre class="lang-cs prettyprint-override"><code>// Create a car with neither color, nor model.
var mercedes = new Car().OfBrand(Brand.MercedesBenz).PaintedIn(NeutralColor);

// Create several cars based on the neutral car.
var yellowCar = mercedes.PaintedIn(Color.Yellow).Create();
var specificModel = mercedes.OfModel(99).Create();

// Would `specificModel` car be yellow or of neutral color? How would you guess that if
// `yellowCar` were in a separate method called somewhere else in code?
</code>```

Any thoughts?

答:
This is a variation on the above methods. The differences are that there are static methods on the Car class that match the method names on the Builder, so you don't need to explicitly create a Builder:

```<code>Car car = Car.builder().ofBrand(Brand.Ford).ofColor("Green")...
</code>```

You can use the same method names that you use on the chained builder calls:

```<code>Car car = Car.ofBrand(Brand.Ford).ofColor("Green")...
</code>```

Also, there is a .copy() method on the class that returns a builder populated with all the values from the current instance, so you can create a variation on a theme:

```<code>Car red = car.copy().paintedIn("Red").build();
</code>```

Finally, the .build() method of the builder checks that all required values have been provided and throws if any are missing. It might be preferable to require some values on the constructor of the builder and allow the rest to be optional; in that case, you'd want one of the patterns in the other answers.

```<code>public enum Brand {
    Ford, Chrysler, GM, Honda, Toyota, Mercedes, BMW, Lexis, Tesla;
}

public class Car {
    private final Brand brand;
    private final int model;
    private final String color;

    public Car(Brand brand, int model, String color) {
        this.brand = brand;
        this.model = model;
        this.color = color;
    }

    public Brand getBrand() {
        return brand;
    }

    public int getModel() {
        return model;
    }

    public String getColor() {
        return color;
    }

    @Override public String toString() {
        return brand + " " + model + " " + color;
    }

    public Builder copy() {
        Builder builder = new Builder();
        builder.brand = brand;
        builder.model = model;
        builder.color = color;
        return builder;
    }

    public static Builder ofBrand(Brand brand) {
        Builder builder = new Builder();
        builder.brand = brand;
        return builder;
    }

    public static Builder ofModel(int model) {
        Builder builder = new Builder();
        builder.model = model;
        return builder;
    }

    public static Builder paintedIn(String color) {
        Builder builder = new Builder();
        builder.color = color;
        return builder;
    }

    public static class Builder {
        private Brand brand = null;
        private Integer model = null;
        private String color = null;

        public Builder ofBrand(Brand brand) {
            this.brand = brand;
            return this;
        }

        public Builder ofModel(int model) {
            this.model = model;
            return this;
        }

        public Builder paintedIn(String color) {
            this.color = color;
            return this;
        }

        public Car build() {
            if (brand == null) throw new IllegalArgumentException("no brand");
            if (model == null) throw new IllegalArgumentException("no model");
            if (color == null) throw new IllegalArgumentException("no color");
            return new Car(brand, model, color);
        }
    }
}
</code>```

Body:
This is a variation on the above methods. The differences are that there are static methods on the Car class that match the method names on the Builder, so you don't need to explicitly create a Builder:

Car car = Car.builder().ofBrand(Brand.Ford).ofColor("Green")...

You can use the same method names that you use on the chained builder calls:

Car car = Car.ofBrand(Brand.Ford).ofColor("Green")...

Also, there is a .copy() method on the class that returns a builder populated with all the values from the current instance, so you can create a variation on a theme:

Car red = car.copy().paintedIn("Red").build();

Finally, the .build() method of the builder checks that all required values have been provided and throws if any are missing. It might be preferable to require some values on the constructor of the builder and allow the rest to be optional; in that case, you'd want one of the patterns in the other answers.

public enum Brand {
    Ford, Chrysler, GM, Honda, Toyota, Mercedes, BMW, Lexis, Tesla;
}

public class Car {
    private final Brand brand;
    private final int model;
    private final String color;

    public Car(Brand brand, int model, String color) {
        this.brand = brand;
        this.model = model;
        this.color = color;
    }

    public Brand getBrand() {
        return brand;
    }

    public int getModel() {
        return model;
    }

    public String getColor() {
        return color;
    }

    @Override public String toString() {
        return brand + " " + model + " " + color;
    }

    public Builder copy() {
        Builder builder = new Builder();
        builder.brand = brand;
        builder.model = model;
        builder.color = color;
        return builder;
    }

    public static Builder ofBrand(Brand brand) {
        Builder builder = new Builder();
        builder.brand = brand;
        return builder;
    }

    public static Builder ofModel(int model) {
        Builder builder = new Builder();
        builder.model = model;
        return builder;
    }

    public static Builder paintedIn(String color) {
        Builder builder = new Builder();
        builder.color = color;
        return builder;
    }

    public static class Builder {
        private Brand brand = null;
        private Integer model = null;
        private String color = null;

        public Builder ofBrand(Brand brand) {
            this.brand = brand;
            return this;
        }

        public Builder ofModel(int model) {
            this.model = model;
            return this;
        }

        public Builder paintedIn(String color) {
            this.color = color;
            return this;
        }

        public Car build() {
            if (brand == null) throw new IllegalArgumentException("no brand");
            if (model == null) throw new IllegalArgumentException("no model");
            if (color == null) throw new IllegalArgumentException("no color");
            return new Car(brand, model, color);
        }
    }
}


答:
An oversimplified answer:  "The more likely your code is to be reread, the higher the burden of explaining what you are doing."  This could be by making the code easier to read, by commenting it, by creating formal documentation, by following style standards...   Please note that it could be you that is doing the rereading later, though it's certainly also true of others in a high turnover environment.

There is another great thread which covers whether or not comments are documentation.


答:
In my opinion, unless you have some sort of reason to abandon good relational database practices (like extreme scaling needs or the like) you should follow good relational database practices even if you think the today's requirements don't force it. Having said that, I think your individual tables should contain only the columns that pertain to the concept you are trying to model with that table.

An employer is definitely a separate concept from the client, so mixing them together in the same table is ... problematic. Can it work? Sure, for a while. But it will eventually become a problem.

You are heading in the right direction by removing the employer data from the client data, but I would go one step further and create an Address table, too. Then, your schema would look more like:

```<code>Client Table
------------------
id int
name  varchar(255),
email varchar(255),
employer_id int,
address_id int

Employer Table
---------------------
id int
name varchar(255),
phone varchar(255),
address_id int

Address Table
---------------------
id int
address varchar(255),
city varchar(255),
state char(2),
zip varchar(16)
</code>```

Now the tables are much more straight-forward.

And, when you eventually need to add more information (think 'delivery_instructions' for an address or some employer-specific attribute) you'll have an appropriate place to put it.

Title: when should a database table be broken into multiple tables with relations?

Body:
I have an application that needs to store client data, and part of that is some data about their employer as well. Assuming that a client can only have one employer, and that the chance of people having identical employer data is slim to none, which schema would make more sense to use?

Schema 1

```<code>Client Table:
-------------------
id int
name  varchar(255),
email varchar(255),
address varchar(255),
city varchar(255),
state char(2),
zip varchar(16),
employer_name varchar(255),
employer_phone varchar(255),
employer_address varchar(255),
employer_city varchar(255),
employer_state char(2),
employer_zip varchar(16)
</code>```

```<code>**Schema 2**

   Client Table
   ------------------
id int
name  varchar(255),
email varchar(255),
address varchar(255),
city varchar(255),
state char(2),
zip varchar(16),

Employer Table
---------------------
id int
name varchar(255),
phone varchar(255),
address varchar(255),
city varchar(255),
state char(2),
zip varchar(16)
patient_id int
</code>```

Part of me thinks that since are clearly two different 'objects' in the real world, seperating them out into two different tables makes sense. However, since a client will always have an employer, I'm also not seeing any real benefits to seperating them out, and it would make querying data about clients more complex. Is there any benefit / reason for creating two tables in a situation like this one instead of one?

Body:
In my opinion, unless you have some sort of reason to abandon good relational database practices (like extreme scaling needs or the like) you should follow good relational database practices even if you think the today's requirements don't force it. Having said that, I think your individual tables should contain only the columns that pertain to the concept you are trying to model with that table.

An employer is definitely a separate concept from the client, so mixing them together in the same table is ... problematic. Can it work? Sure, for a while. But it will eventually become a problem.

You are heading in the right direction by removing the employer data from the client data, but I would go one step further and create an Address table, too. Then, your schema would look more like:

Client Table
------------------
id int
name  varchar(255),
email varchar(255),
employer_id int,
address_id int

Employer Table
---------------------
id int
name varchar(255),
phone varchar(255),
address_id int

Address Table
---------------------
id int
address varchar(255),
city varchar(255),
state char(2),
zip varchar(16)

Now the tables are much more straight-forward.

And, when you eventually need to add more information (think 'delivery_instructions' for an address or some employer-specific attribute) you'll have an appropriate place to put it.


答:
"Are More Comments Better in High-Turnover Environments?"

I think they may well be worse:

Different authors will use different styles and levels of details and will be less into updating comments by other people.

The opinion of "What needs commenting" changes from person to person.

They continue the practice of writing code that is hard to read with comments to explain it as opposed to easy to read code with descriptive names.

Maintaining their format and consistency becomes a job in itself.

New users have to learn the 'format' standard before being able to make quick changes.


问:
What is the best C++ source code to read for a beginner?
I'm trying to improve my c++ coding technique by reading c++ source code. Which open source project would you recommend? Is the code of Boost C++ Libraries a good one?</p>

答:
Reading existing clean C++ code is a great way to learn the language.

The code in the OpenFST toolkit is very clean, for example. It is readable and uses slightly advanced features without going overboard.

Boost, on the other hand, can be a bit hard to read, partly because they use C++ tricks that are hard to understand and because they often sprinkle the code with different workarounds for different compiler versions.


问:
What algorithm(s) can be used to achieve reasonably good next word prediction?
What is a good way of implementing "next-word prediction"? For example, the user types "I am" and the system suggests "a" and "not" (or possibly others) as the next word. I am aware of a method that uses Markov Chains and some training text(obviously) to more or less achieve this. But I read somewhere that this method is very restrictive and applies to very simple cases.

I understand basics of neural networks and genetic algorithms(though have never used them in a serious project) and maybe they could be of some help. I wonder if there are any algorithms that, given appropriate training text(e.g., newspaper articles, and the user's own typing) can come up with reasonably appropriate suggestions for the next word. If not (links to)algorithms, general high-level methods to attack this problem are welcome.

答:
You are looking for a (statistical) language model.

A statistical language model assigns a probability to a sequence of m words P(w_1,...,w_m) by means of a probability distribution...

In speech recognition and in data compression, such a model tries to capture the properties of a language, and to predict the next word in a speech sequence...


问:
What is a widely accepted term for a string variable that would probably contain a file path and file name?
For functions that need to index files in a directory and rename them FileName0001, FileName0002, etc... I often need to write a function that splits the file name from the file path and rename the file.  When I put the file name and file path back together, I don't have a very good name for the variable that contains both of them and I usually just wind up concatenating them every time I want to use them (usually using them as parameters for functions labeled either filename or filepath) so I never really know what I'm doing until I notice a lot of files being written in the same directory as my binaries.

Anyway, what do I call a file name and a file path?  I don't want to call it File, because that usually means the binary information behind the file.  I don't want to call it URI because that usually means I've got some sort of protocol, which I don't.  I just want a good way to denote "c:\somedir\somedir\somedir\somefile.txt" so as to deconfuse this mess I've just realized I'm in.

Please don't just list your personal preference.  I think an excellent answer should "'site its sources". (as in, provide a link to a repository with a good example of the code being used as I described)

答:
For fun, here's another perspective.  I worked on the asset management system of a large online game 10 years ago.  Here is some of the concepts I concluded to allow for flexibility and scalability.

a file (for my design at the time) could contain multiple "files" therefore,

the data that makes up a file is called a record

the record data is found in a data source (eg : the diskdrive is a type of data source).  web/ftp/remote servers are examples of other data sources

A record was accompanied by a 'packing slip' (meta data including its 64 bit MD5 hash, caching rules, etc...).  The packing slip also specified the record's "Persistent Name"  which was the "fully qualified path + filename" for the local_disk data source.

As the years have passed, I've added to the complexity of this area of study with URI and URL nomenclature.  the data source is in effect the "scheme". hence "file:///blablabla

I still battle with this too sometimes. Just keep the file stuff in one place, load the data into memory and the problem kind of goes away :)


问:
Will TSQL become useless because of new ORMs?
By introducing LINQ to SQL, I found myself and my .NET developer colleagues gradually moving from TSQL to C# to create queries on the database. Entity Framework made that shift almost permanent.

Now it's nearly 2 years that I use LINQ to SQL and LINQ to Entities and haven't used TSQL that much.

Yesterday, a colleague encountered a problem (he had to create a SP) and we went to help him. But we all found that our TSQL knowledge was diminished for sure, and a simple SP that seemed trivial to us 2 or 3 years ago, was a challenge to be solved yesterday.

Thus it came to my mind that while TSQL's life is attached to SQL Server, and logically as long as SQL Server lives and doesn't change it's SQL language, TSQL would also live, practically it might die, and soon very few people might know it.

Am I right? Do existence of ORMs like Entity Framework threaten TSQL's life and usability?

答:
The way you've phrased your question is a bit misleading, since it seems you are comparing T-SQL to LINQ to SQL (as opposed to say ANSI SQL to LINQ to SQL).  While that might be a valid comparison if we are only considering object-relational mappings, LINQ to SQL definitely does not give similar capabilities to T-SQL itself.

While I agree that there are better ways to solve the ORM problem than hand-coding SPs, T-SQL is pretty much the native scripting and programming environment for SQL Server, and every major relational DB platform has its equivalent.  ANSI SQL, specifically, has been around for decades, and I don't think it's going anywhere any time soon.  As a data retrieval and manipulation language, it is extremely good (if a bit more verbose than we like, nowadays), and rather standardised.

Most likely, T-SQL will be less popular with application developers than in the past, but ever-present and used for performance-sensitive operations, as well as by anyone not coding applications (I don't see DBAs using LINQ to SQL to manipulate their DBs...).


问:
How can I get the business analysts more involved in BDD?
I am a proponent of Behavior Driven Development, mainly with Cucumber and RSpec, and at my current gig (a Microsoft shop) I am introducing SpecFlow as a tool to help with testing.

I'd like to get the business analysts on my team involved in writing the features and scenarios, but they are put off by the "technical" aspect of it, meaning creating the files in Visual Studio (or even having Visual Studio on their machines). They want to know if we can put all the scenarios for a feature in Jira.

What I'm looking for is suggestions for a workflow that will work well with BA types that are accustomed to project management/work tracking tools like Jira (we also use Greenhopper).

答:
You shouldn't force the business analysts to use Visual Studio to get your BDD process running smoothly. This is a tool for developers, not for the business.

SpecFlow has a command line tool that can generate the requires tests based on .feature files. This would allow you to create a build script that gather .feature files from somewhere, generate the .cs files, compile them, and execute the tests. If your business analysts prefer to use Jira, then you should make a tool that extracts .feature files from Jira, at least if it is practical and possible. I don't know Jira enough to say whether or not it is practical.

Remember any good software solution should be based around the processes and needs of the user; it should not dictate new processes for the user. And in this case, the user is the business analysts.


答:
Point 1: Clarity is important in high-turnover environments

Point 2: Verbosity is not Clarity

Adding comments to your code may or may not improve the clarity; it depends on the comments you add. And once optimal clarity is reached, additional comments will make the situation worse, not better.

While comments are a component of clarity, code quality is a significantly more important component. Cleverness is the opposite of clarity. If the function of the code isn't immediately apparent through a casual reading, then the code isn't particularly clear, and comments (no matter how high-quality the comments are) are a poor and ineffective substitute for clear code.

For example, stuffing a flag in the high-bit of an unrelated field may be perfectly allowable in certain circumstances, and it may make loads of sense from a performance perspective in certain circumstances, but it's pretty much always a bad idea with respect to clarity, even if you comment the hell out of it.

If you find yourself having to explain in prose what your code does, then consider any of the following: Note that some of these may affect performance, but performance may not be as important as clarity in certain cases.

Better variable names and function names

Better code layout and spacing

Remove any "tricks" that you thought were a good idea

Group code according to conceptual function (e.g. extract code for a specific purpose into an appropriately-named function, even if you only call it once)

Use a more straight-forward algorithm (conditions permitting)

Use well-known libraries for common functionality


问:
What is the purpose of "re-type your email" field?
Many web sites when you registering an account present you with a form where you put in your details such as name and other profile data. One of the fields without a change is email address. It seems that there are quite a lot of web sites that double this field up. They have email address field and then re-type your email address field.

When this comes to password, I can understand the purpose of that. For security reasons operating system and browsers treat the fields of type of password differently and in some circumstances subset of copy/paste operations can be disabled on these fields. Since it is important that there is no mistake in the password, user is asked to repeat it.

I cannot apply the same logic to the re-type email filed. Every time I register an account for a site that has this field I simply copy and paste the fields, and I suspect that most people do the same. Thus I can't see value in having this field.

I'm building a web site and creating an account registration page. I'm not intending putting the retype your email field on it, but may be I'm missing something and it serve some other role that I could not think of?

Is there any other purpose of this field apart from I described above that would justify including it on a account registration screen (be it a web site or desktop or mobile app)?

答: Your e-mail may be needed if it serves as a login, if the website will send a confirmation link to it, or for advertisement purposes. In that case, it's important that you type it right, which is why you will be asked to type it twice.</p>


答: The reasoning for the re-type email is somewhat similar to the one for the password: making sure that the user has not typed it wrongly. In many web apps a user's email is a very important piece of information, and if a user enters it incorrectly it might compromise some functions (such as resend password). Having the user type it twice minimizes the chance that he typed it wrong.</p>

Title: What is the purpose of "re-type your email" field?

Body:
Many web sites when you registering an account present you with a form where you put in your details such as name and other profile data. One of the fields without a change is email address. It seems that there are quite a lot of web sites that double this field up. They have email address field and then re-type your email address field.

When this comes to password, I can understand the purpose of that. For security reasons operating system and browsers treat the fields of type of password differently and in some circumstances subset of copy/paste operations can be disabled on these fields. Since it is important that there is no mistake in the password, user is asked to repeat it.

I cannot apply the same logic to the re-type email filed. Every time I register an account for a site that has this field I simply copy and paste the fields, and I suspect that most people do the same. Thus I can't see value in having this field.

I'm building a web site and creating an account registration page. I'm not intending putting the retype your email field on it, but may be I'm missing something and it serve some other role that I could not think of?

Is there any other purpose of this field apart from I described above that would justify including it on a account registration screen (be it a web site or desktop or mobile app)?


答:
You may use copy/paste to save typing the e-mail address twice but in doing so you are defeating the object of the repeated entry.

Many e-mail addresses are long and as such are prone to entry error as you type.  I have had addresses with the domains @freeserve.co.uk, @virginmedia.co.uk and @emsglobaltracking.com all of which are long enough for a finger slip to occur during typing.  A colleague made an error when entering his address when buying a rail ticket online; his notification e-mail went to @gmial.com, fortunately he printed the confirmation screen or he would have lost his booking.

Having a repeat on the enter e-mail address allows typing errors to be trapped, providing the user actually types their address into the box.  A small inconvenience that makes some attempt at ensuring that your data is correct.  As a small aside, in the 1970's I went to a Tate & Lyle data entry office.   Everything was entered into the computer twice, by different operators.  Any differences were automatically flagged for verification, after all "garbage in, garbage out".


答:
Think of SQL as the Assembly language of the DB, and ORMs and LINQ to SQL as the higher level languages. While we might not use Assembly as much as we used to in the computer stone age, it's still there behind the scenes and it serves a purpose. The same thing applies to SQL. All those abstraction levels (ORMs, LINQ ... etc) in the end generate SQL that they communicate to the DB.

So no. While there are relational DBs then SQL (and all it's other localized dialects like T-SQL and PL/SQL) are not going anywhere

Title: Will TSQL become useless because of new ORMs?

Body:
By introducing LINQ to SQL, I found myself and my .NET developer colleagues gradually moving from TSQL to C# to create queries on the database. Entity Framework made that shift almost permanent.

Now it's nearly 2 years that I use LINQ to SQL and LINQ to Entities and haven't used TSQL that much.

Yesterday, a colleague encountered a problem (he had to create a SP) and we went to help him. But we all found that our TSQL knowledge was diminished for sure, and a simple SP that seemed trivial to us 2 or 3 years ago, was a challenge to be solved yesterday.

Thus it came to my mind that while TSQL's life is attached to SQL Server, and logically as long as SQL Server lives and doesn't change it's SQL language, TSQL would also live, practically it might die, and soon very few people might know it.

Am I right? Do existence of ORMs like Entity Framework threaten TSQL's life and usability?


答:
Some additional ideas:

Get involved in the OpenJDK project. Nothing beats understanding the internals of some software by hacking on it!

Look at how other JVM languages (e.g. Clojure or Scala) generate code for the JVM

Do a mini-project that interests you and requires use of JVM internals. Perhaps using something like ASM to manipulate bytecode..

Title: Approaching Java/JVM internals

Body:
I've programmed in Java for about 8 years and I know the language quite well as a developer, but my goal is to deepen my knowledge of the internals. I've taken undergraduate courses in PL design, but they were very broad academic overviews (in Scheme, IIRC).  </p>

<p>Can someone suggest a route to start delving into the details? Specifically, are there particular topics (say, garbage collection) that might be more approachable or be a good starting point?  Is there a decent high-level book on the internals of the JVM and the design of the Java programming language?  My current approach is going to be to start with the JVM spec and research as needed. </p>


问:
XML: Multiple roots + text content outside the root. Does anyone do it?
I have another one of those "is it done in XML" questions (my last one about xml comments hasn't been answered if anyone has a good explanation)

I was just wondering if anyone, anywhere would:

Use multiple root elements in an XML document

Put text content outside of a root element

W3C discourages these practices, Javascript's DOMParser doesn't even allow these cases, and I can't think of one sane reason to do either of these things. However, I know how bizarre some implementations of XML have been, so I wouldn't be surprised.

Does anyone have any real world examples where this would be done? I will also accept an answer that specifies if other mainstream parsers allow doing either of these.

答:
As a "real world" example of multiple roots and intervening text code, consider the XML produced by "mysql -xml".

A compound query (or stored procedure) can return multiple result sets, each starting with the root  ...  .  If one of the subqueries has an error, then mysql produces a single non-XML line "ERROR xxxx - message" instead of XML.

Parsing mysql's XML output involves both multiple roots as well as textual messages.

I'd like to say mysql is messed up and should be fixed, but the reality is, I need to parse mysql output as it currently exists.


问:
What is really happening when we change encoding in a string?
http://php.net/manual/en/function.mb-convert-encoding.php

Say I do:

```<code>$encoded = mb_convert_encoding ($original);
</code>```

That looks like simple enough. WHat I am imagining is the following

$original has a pointer to the way the string is actually encoded. Something like char * kind of thing. And then there are things like what the character actually encoded.

It's probably somewhere along UTF-64 kind of thing where each glyph is indeed a character.

Now when we do

```<code>$encoded = mb_convert_encoding ($original);
</code>```

several thing can happen:

the original internal representation doesn't change however it is REINTERPRETED so that the code that show up differs

the original string that it represent doesn't change however the ENCODING change.

Which one is right?

答:
A string isn't a bag of bytes and a specification of the encoding : in most languages a string is a bag of bytes, and in best cases an implicit encoding defined by the language. It's your responsability as a coder to know what to do depending on the encoding (edit : as tdhammer pointed, most modern language explicitly forbids manipulating strings in other encoding than the implicitely defined one).

When you use an encoding function, you don't set a mention somewhere that the string uses a different encoding, you changes the bytes (the internal representation) so that it is correct regarding the intended encoding. But you must keep trace yourself of the used encoding.

For example, if you change the encoding of a string to UTF-16, strlen will give you an incorrect result (at least if you expect it to be the number of characters) because it will count the bytes. You must use mb-strlen and precise the encoding.


问:
Single Responsibility Principle - How Can I Avoid Code Fragmentation?
I'm working on a team where the team leader is a virulent advocate of SOLID development principles. However, he lacks a lot of experience in getting complex software out of the door.

We have a situation where he has applied SRP to what was already quite a complex code base, which has now become very highly fragmented and difficult to understand and debug.

We now have a problem not only with code fragmentation, but also encapsulation, as methods within a class that may have been private or protected have been judged to represent a 'reason to change' and have been extracted to public or internal classes and interfaces which is not in keeping with the encapsulation goals of the application.

We have some class constructors which take over 20 interface parameters, so our IoC registration and resolution is becoming a monster in its own right.

I want to know if there is any 'refactor away from SRP' approach we could use to help fix some of these issues. I have read that it doesn't violate SOLID if I create a number of empty coarser-grained classes that 'wrap' a number of closely related classes to provide a single-point of access to the sum of their functionality (i.e. mimicking a less overly SRP'd class implementation).

Apart from that, I cannot think of a solution which will allow us to pragmatically continue with our development efforts, while keeping everyone happy.

Any suggestions ?

答:
I agree with all the answers about SRP and how it can be taken too far. In your post you mention that due to "over-refactoring" to adhere to SRP you found encapsulation breaking or being modified. The one thing that has worked for me is to always stick to the basics and do exactly what is required to meet an end.

When working with Legacy systems the "enthusiasm" to fix everything to make it better is usually quite high in Team Leads, especially those that are new to that role. SOLID, just doesn't have SRP - That's just the S. Make sure that if you are following SOLID, you don't forget the OLID as well.

I am working on a Legacy system right now and we started going down a similar path in the beginning. What worked for us was a collective team decision to make the best of both worlds - SOLID and K.I.S.S (Keep It Simple Stupid). We collectively discussed major changes to code structure and applied common sense in applying various development principles. They are great as guidelines not "Laws of S/W Development". The team is not just about the Team Lead - its about all the developers on the team. The thing that has always worked for me is to get everyone in a room and come up with a shared set of guidelines your entire team agrees to follow.

Regarding how to fix your current situation, if you use a VCS and have not added too many new features to your application, you can always go back to a version of code the entire team thinks is understandable, readable and maintainable. Yes! I am asking you to throw away work and start from scratch. This is better than trying to "fix" something that was broken and move it back to something that already existed.

OwnerDisplayName: Dean Chalk


问:
How can I reduce the amount of time it takes to fully regression test an application ready for release?
An app I work on is being developed with a modified version of scrum.  If you are not familiar with scrum, it's just an alternative approach to a more traditional watefall model, where a series of features are worked on for a set amount of time known as a sprint.  The app is written in C# and makes use of WPF.  We use Visual C# 2010 Express edition as an IDE.

If we work on a sprint and add in a few new features, but do not plan to release until a further sprint is complete, then regression testing is not an issue as such.  We just test the new features and give the app a good once over.  However, if a release is planned that our customers can download - a full regression test is factored in.  In the past this wasn't a big deal, it took 3 or 4 days and the devs simply fix up any bugs found in the regression phase, but now, as the app is getting larger and larger and incorporating more and more features, the regression is spanning out for weeks.

I am interested in any methods that people know of or use that can decrease this time.  At the moment the only ideas I have are to either start writing Unit Tests, which I have never fully tried out in a commercial environment, or to research the possibilty of any UI Automation API's or tools that would allow me to write a program to perform a series of batch tests.  I know literally nothing about the possibilities of UI automation so any information would be valuable.  I don't know that much about Unit testing either, how complicated can the tests be?  Is it possible to get Unit tests to use the UI?  Are there any other methods I should consider?

Thanks for reading, and for any advice in advance.

Edit: Thanks for the information. Does anybody know of any alternatives to what has been mentioned so far (NUnit, RhinoMocks and CodedUI)?

答:
Since you are using VS 2010 - MS Test framework is an alternate testing framework you can use. - See here for a comparison of NUnit to MS Test http://www.barebonescoder.com/2010/06/mstest-vs-nunit-with-visual-studio-2010-tdd/

Here is an article that speaks specifically about how to write UI tests for WPF applications: http://msdn.microsoft.com/en-us/magazine/dd483216.aspx

In general, when dealing with large complex applications Unit tests are usually the best way to have comprehensive coverage but also the most expensive in terms of time to write when starting from scratch. You will likely need to refactor a large portion of code that is not written with test-ability in mind. In these cases its often faster and more efficient to invest in Integration and UI tests first; using the quality confidence they provide to re-factor code to make unit testing easier.

The most efficient approach, that I have used on multiple applications now is as follows:

Automate the most time consuming System/End to End Integration tests first

Start automating as you go: New defects should have an automated tests to cover regression; if you are modifying some code which doesnt have a test around it, write a few

You can't automate everything: So do a benefit cost analysis on which test cases you want to automate vs. which ones you can still run manually.

As you start automating tests, consider integrating the tests with a Continuous Integration engine like Teamcity, Bamboo or Cucumber so your tests run on every check-in thus reducing effort required to discover root cause of bugs and fixing them as they are introduced.

OwnerDisplayName: DrLazer


问:
Reasons for either 32-bit or 64-bit as development machine
I'm about to make a new Linux install, which will be primarily used for programming. I've seen benchmarks showing speed improvement of 64-bit version, however, I have hard time of telling how much these benchmarks translate to improvement in every day usage. And of course there are other aspects to consider.

Usage I have in mind:

mainly programming Python, with occasional C, C++ and Java;

IDEs, which are using Java platforms (Eclipse and IntelliJ);

on very rare occasions having to compile for 32-bit platform;

not planning to have more than 64GB of RAM anytime soon (and I don't mind using PAE kernels);

machine in question has 4GB RAM and Athlon II X2;

What are pros and cons of choosing either i386 or x86_64 distro?

答:
32bits limits you to 4gb, 64bits doesn't. Other than that, it shouldn't bother you much which one you use.

64bits also typically has more memory overhead since memory pointers use 64 bits there instead of 32 bits, so 64 bit programs tend to use up more memory.

Software wise, you typically get everything you need on both. Only for old, unsupported hardware specific legacy stuff, you might run into surprises.


答:
I can only think of two reasons against a 64 bit system:

You have legacy code or a third-party library that doesn't compile on a 64-bit platform.

Your target platform(s) consists mainly of 32-bit systems and you want to make sure your application runs smoothly there without exceeding the 4GB memory limit or compilation problems.

On the other hand, I can't think of many reasons for 64-bit, other than the usually touted "faster & more memory" that (in most cases) isn't all that relevant to everyday development work. This, however, may change over the years (and may already have and I just didn't notice it) once 32-bit platforms are dying out and developers of third-party libraries and other applications are phasing out 32-bit support.

In the end, I don't think there's any harm in using a 64- over a 32-bit OS.

Title: Reasons for either 32-bit or 64-bit as development machine

Body:
I'm about to make a new Linux install, which will be primarily used for programming. I've seen benchmarks showing speed improvement of 64-bit version, however, I have hard time of telling how much these benchmarks translate to improvement in every day usage. And of course there are other aspects to consider.

Usage I have in mind:

mainly programming Python, with occasional C, C++ and Java;

IDEs, which are using Java platforms (Eclipse and IntelliJ);

on very rare occasions having to compile for 32-bit platform;

not planning to have more than 64GB of RAM anytime soon (and I don't mind using PAE kernels);

machine in question has 4GB RAM and Athlon II X2;

What are pros and cons of choosing either i386 or x86_64 distro?


问:
What are the alternatives to "overriding a method" when using composition instead of inheritance?
If we should favor composition over inheritance, the data part of it is clear, at least for me.

What I don't have a clear solution to is how overwriting methods, or simply implementing them if they are defined in a pure virtual form, should be implemented.

An obvious way is to wrap the instance representing the base-class into the instance representing the sub-class. But the major downsides of this are that if you have say 10 methods, and you want to override a single one, you still have to delegate every other methods anyway. And if there were several layers of inheritance, you have now several layers of wrapping, which becomes less and less efficient. Also, this only solve the problem of the object "client"; when another object calls the top wrapper, things happen like in inheritance. But when a method of the deepest instance, the base class, calls it's own methods that have been wrapped and modified, the wrapping has no effect: the call is performed by it's own method, instead of by the highest wrapper.

One extreme alternative that would solve those problems would be to have one instance per method. You only wrap methods that you want to overwrite, so there is no pointless delegation. But now you end up with an incredible amount of classes and object instance, which will have a negative effect on memory usage, and this will require a lot more coding too.

So, are there alternatives (preferably alternatives that can be used in Java), that:

Do not result in many levels of pointless delegation without any changes.

Make sure that not only the client of an object, but also all the code of the object itself, is aware of which implementation of method should be called.

Does not result in an explosion of classes and instances.

Ideally puts the extra memory overhead that is required at the "class"/"particular composition" level (static if you will), rather than having every object pay the memory overhead of composition.

My feeling tells me that the instance representing the base class should be at the "top" of the stack/layers so it receives calls directly, and can process them directly too if they are not overwritten. But I don't know how to do it that way.

[EDIT] It seems that many people reading this question think that I am debating if I should use Composition or Inheritance, and that "guiding" me to the one or the other will solve my problem. This is not the case. I always use inheritance when I can, for the simple fact that composition requires more coding, and also more memory. No need to convince me that inheritance is not evil.

I have a very good reason to want to use composition. I want to create a system that model domain objects that can "change nature" over time. That is they can both gain and loose functionality/properties over time, as a result of some actions. This is a lot more natural when modeled as composition.

If the components that can be dynamically added and removed where composed only of properties, it would be easy. In fact I have already found 14 different possible designs that support that case, with varying compromise on code complexity, memory usage, and speed.

The real problem comes when all those components need to be aware of each other, and talk to each other. This is not required when they are just "beans" (in the Java sense). I want to know if there are any, and hopefully several, ways of allowing the components to talk to each other, and more specifically how to have several components of the same type, where one serves as base-class and the others progressively override some of it's methods.

I can see two ways to simulate the overriding present in inheritance.

The first is to have a base component, and all overriding components are built as wrapper on top of another component of the same type. Like that, you can choose at runtime which hierarchy of components you want. This is like pipes and filters. But the problem is that with inheritance, not only can the derived class call methods of the base class, but it works the other way around too. A base class can declare a pure virtual method, which is implemented by the sub-class, and the base class can call this method. I don't see how to accomplish that using whole component wrapping. Also, if we have N inheritance/wrapping layers, then calls to method of the base component then gets N level of delegation, even if the method was not overwritten by any of the wrapping components.

The other alternative, like I said in "One extreme alternative ...", is to do it like above, but forcing each component to contain a single method. In that case we solve the problem of the base-class not seeing/calling the methods of the derived classes, for all methods, except it's own method. So it works now correctly for all cases except for recursion. But the price we pay in memory consumption is high, at least in Java. And Java isn't "functional", so there is a lot of syntax overhead to turn every object method into an individual object.

If there any better alternatives then the two mentioned above, I would like to know about it.

答:
A way to reduce the memory overhead of your second solution is to add one level of indirection and push the behavior in an object which would be shared by all the objects which share the same behavior (more or less like prototype based language behaves). As you seem to want a very dynamic behavior, finding it could be difficult if the objects have to make evolve their behavior independently.</p>

```<code>class Composed {
public:
    void foo() { proto->foo(this); } // with a proto member, less overhead per call, maintaining it could be hard
    void bar() { protos[state]->bar(this); } // with a static map allowing to decode a state member
    void qux() { findProto(this)->qux(this); } // find it however you want
    // you need to handle the data part
};
</code>```

Body:
A way to reduce the memory overhead of your second solution is to add one level of indirection and push the behavior in an object which would be shared by all the objects which share the same behavior (more or less like prototype based language behaves). As you seem to want a very dynamic behavior, finding it could be difficult if the objects have to make evolve their behavior independently.

class Composed {
public:
    void foo() { proto->foo(this); } // with a proto member, less overhead per call, maintaining it could be hard
    void bar() { protos[state]->bar(this); } // with a static map allowing to decode a state member
    void qux() { findProto(this)->qux(this); } // find it however you want
    // you need to handle the data part
};


答:
In the mainstream Linux-based distro's, the amd64 version is completely on par with the x86 one, so as far as software availability goes, you have nothing to fear either way (a few obscure platform-specific hacks aside). Also, it is possible, albeit with some severe hacking, to run 32-bit code on a 64-bit kernel, so if you absolutely have to, there are probably ways to make that happen. And if all else fails, you can always install a 32-bit virtual machine to compile for that particular architecture.

CPU-performance-wise, there isn't much difference either way: some applications benefit from 64-bit operations (typically, these are applications that have to deal with large integers and such); others don't get any benefit and might even run a tiny bit faster on a 32-bit kernel, especially if they need to handle a lot of natively-sized integers or pointer (which take up twice as much space on a 64-bit platform).

However, if you want to use more than 4 GB of RAM, 32-bit kernels do carry a real performance penalty, because you have to use PAE to make it happen.

As a general rule of thumb, these days I'd say go with 64-bits, unless you have strong reasons not to, most notably:

you are using 32-bit libraries that you cannot recompile to a 64-bit platform (e.g. because you don't have the sources)

you need to use a package from your distro that isn't included in the 64-bit distribution and cannot be installed from other trusted sources

you are short on physical RAM (many programs use significantly less RAM on 32-bit systems, and 'short on RAM' invariably means 'less than 4 GB')

you are coding for 32-bit production systems (you want to eliminate as many differences as possible; for example, PHP's ip2long function has a nasty gotcha that only shows on 32-bit systems)


答: Consider using a dynamic language (e.g. Python) instead of Java, if possible. That way you get the dynamic language and its features from the beginning, instead of having to implement it yourself.</p>

Title: What are the alternatives to "overriding a method" when using composition instead of inheritance?

Body:
If we should favor composition over inheritance, the data part of it is clear, at least for me.

What I don't have a clear solution to is how overwriting methods, or simply implementing them if they are defined in a pure virtual form, should be implemented.

An obvious way is to wrap the instance representing the base-class into the instance representing the sub-class. But the major downsides of this are that if you have say 10 methods, and you want to override a single one, you still have to delegate every other methods anyway. And if there were several layers of inheritance, you have now several layers of wrapping, which becomes less and less efficient. Also, this only solve the problem of the object "client"; when another object calls the top wrapper, things happen like in inheritance. But when a method of the deepest instance, the base class, calls it's own methods that have been wrapped and modified, the wrapping has no effect: the call is performed by it's own method, instead of by the highest wrapper.

One extreme alternative that would solve those problems would be to have one instance per method. You only wrap methods that you want to overwrite, so there is no pointless delegation. But now you end up with an incredible amount of classes and object instance, which will have a negative effect on memory usage, and this will require a lot more coding too.

So, are there alternatives (preferably alternatives that can be used in Java), that:

Do not result in many levels of pointless delegation without any changes.

Make sure that not only the client of an object, but also all the code of the object itself, is aware of which implementation of method should be called.

Does not result in an explosion of classes and instances.

Ideally puts the extra memory overhead that is required at the "class"/"particular composition" level (static if you will), rather than having every object pay the memory overhead of composition.

My feeling tells me that the instance representing the base class should be at the "top" of the stack/layers so it receives calls directly, and can process them directly too if they are not overwritten. But I don't know how to do it that way.

[EDIT] It seems that many people reading this question think that I am debating if I should use Composition or Inheritance, and that "guiding" me to the one or the other will solve my problem. This is not the case. I always use inheritance when I can, for the simple fact that composition requires more coding, and also more memory. No need to convince me that inheritance is not evil.

I have a very good reason to want to use composition. I want to create a system that model domain objects that can "change nature" over time. That is they can both gain and loose functionality/properties over time, as a result of some actions. This is a lot more natural when modeled as composition.

If the components that can be dynamically added and removed where composed only of properties, it would be easy. In fact I have already found 14 different possible designs that support that case, with varying compromise on code complexity, memory usage, and speed.

The real problem comes when all those components need to be aware of each other, and talk to each other. This is not required when they are just "beans" (in the Java sense). I want to know if there are any, and hopefully several, ways of allowing the components to talk to each other, and more specifically how to have several components of the same type, where one serves as base-class and the others progressively override some of it's methods.

I can see two ways to simulate the overriding present in inheritance.

The first is to have a base component, and all overriding components are built as wrapper on top of another component of the same type. Like that, you can choose at runtime which hierarchy of components you want. This is like pipes and filters. But the problem is that with inheritance, not only can the derived class call methods of the base class, but it works the other way around too. A base class can declare a pure virtual method, which is implemented by the sub-class, and the base class can call this method. I don't see how to accomplish that using whole component wrapping. Also, if we have N inheritance/wrapping layers, then calls to method of the base component then gets N level of delegation, even if the method was not overwritten by any of the wrapping components.

The other alternative, like I said in "One extreme alternative ...", is to do it like above, but forcing each component to contain a single method. In that case we solve the problem of the base-class not seeing/calling the methods of the derived classes, for all methods, except it's own method. So it works now correctly for all cases except for recursion. But the price we pay in memory consumption is high, at least in Java. And Java isn't "functional", so there is a lot of syntax overhead to turn every object method into an individual object.

If there any better alternatives then the two mentioned above, I would like to know about it.


答: In addition to what everyone else have said, check out the Java Performance Tuning page. It contains a lot of articles on garbage collection and performance tuning in general. It also contains a list of performance tuning books that might be interesting for you as well.</p>

Title: Approaching Java/JVM internals


答:
The problem is that PHP treats strings as bags-of-bytes, not making any distinction between bytestrings and 'proper' strings, and it doesn't track the encoding of these bytestrings.

An encoding is, basically, a mapping of byte sequences to proper string codepoints. So what mb_convert_encoding does is split the given string into appropriate byte sequences according to the input encoding, translate them into code points, and then back into byte sequences based on the target encoding.

Since many encodings do not define all the code points, and some encodings may treat certain byte sequences as invalid (e.g. ASCII does not allow anything above 127), you can specify what PHP should do when it encounters such a situation.

Note that mb_convert_encoding has two parameters that specify the input and output encodings (to and from); if you don't specify the from_encoding, the currently set internal encoding is used. You should always set the internal encoding to UTF-8, unless you have convincing reasons not to.

Title: What is really happening when we change encoding in a string?

Body:
http://php.net/manual/en/function.mb-convert-encoding.php

Say I do:

```<code>$encoded = mb_convert_encoding ($original);
</code>```

That looks like simple enough. WHat I am imagining is the following

$original has a pointer to the way the string is actually encoded. Something like char * kind of thing. And then there are things like what the character actually encoded.

It's probably somewhere along UTF-64 kind of thing where each glyph is indeed a character.

Now when we do

```<code>$encoded = mb_convert_encoding ($original);
</code>```

several thing can happen:

the original internal representation doesn't change however it is REINTERPRETED so that the code that show up differs

the original string that it represent doesn't change however the ENCODING change.

Which one is right?


问:
Is hiring a "chief intern" a good idea?
I'm starting an internship program for our software department and I was wondering about creating a position ("chief intern", intern supervisor, or whatever one should call it) with the following responsibilities:

Train interns

Coach interns

Manage projects and tasks for interns

Supervise intern's work in terms of rhythm and quality

Act as a liaison between the main team's needs and interns performance/aspirations

Evaluate and facilitate intern's progress when they want to grab a higher-level domain-specific task (at this point, a main dev team member can do mentoring)

Get freely involved in the main team's software development tasks so that he himself can grow, and have full mentorship from the main dev team.

I'm thinking that an apprentice-level engineer (below Jr., or Jr.; but being a graduate and working full-time) can handle this for a while (he will be trained by the main dev team first), until one of two things happen:

He/she decides to move on to the main dev team by recommending an appropriate replacement (or me finding another one as a new hire)

Keep leading the interns while still being able to grow to Jr. Eng., Eng., Sr. Eng

I know the notion of a "chief intern" is common within the medical world, but I don't really know about that in the software world (I was a freelancer for most of my university years).

A side-intention to this is also that, if this ends up being a higher rotation position (organically) because the intern supervisor wants to join the main dev team, this could help interns that aspire this position emerge as leaders.

My main intention for this, though, is removing distractions from the main team but without making the interns suffer the lack of attention, which could lead to boredom and little intern retention.

Is this "chief intern" idea common (or good at least)?, are there any obvious risks to it that I might not be seeing?

Edit: I have a draft plan for the kind of work the interns would be doing: https://softwareengineering.stackexchange.com/questions/149866/are-rd-mini-projects-a-good-activity-for-interns

Edit #2:  My intention is not keeping them isolated, but having someone focus on giving attention to them when we cannot.

Edit #3: I'm now convince it is a good idea, but I will take the organic approach to hiring someone in such position: do it myself until I cannot. This way I'll know better what to expect from a person I hire for this role in the future, as well as what works and what doesn't with interns.

答: Looking across industry, this is common elsewhere.  At investment banks, there is frequently an HR person assigned to watch all the interns, and frequently a somewhat senior (6-10 years?) line manager as well.  Even when the interns get spread out, there is a line manager who watches over them since the interns are viewed as a corporate asset.</p>

Title: Is hiring a "chief intern" a good idea?


问:
Approaching Java/JVM internals
I've programmed in Java for about 8 years and I know the language quite well as a developer, but my goal is to deepen my knowledge of the internals. I've taken undergraduate courses in PL design, but they were very broad academic overviews (in Scheme, IIRC).  </p>

<p>Can someone suggest a route to start delving into the details? Specifically, are there particular topics (say, garbage collection) that might be more approachable or be a good starting point?  Is there a decent high-level book on the internals of the JVM and the design of the Java programming language?  My current approach is going to be to start with the JVM spec and research as needed. </p>

答:
If you are not familiar yet with the Java bytecode format, then consider writing a tiny compiler which creates valid Java byte code (or Jasmin assembler) and make it run correctly.

Seeing "Hello World" or "4" (given 2+2) generated by your code is very satisfying.

Title: Approaching Java/JVM internals