答:
it is easy to hire developers

This is the problem. The developers you hire simply are not motivated or don't have experience to keep the codebase in high quality. You should focus on hiring developers who take it upon themselves to keep the code quality high. And finding developers like that is extremely hard. Both because there are not many of them and that figuring out from interview that developer cares about code is tricky.

Title: Getting coders to do code review

Body:
I am running a project where I pay developers to contribute to my semi open source project. My problem is that it is easy to hire developers, but it is very difficult to get anyone to do code reviewing. I have repeatedly attempted to get the senior developers to review the code of the junior developers. I have attempted to pay them more, give them higher status etc. But they just seem to want to code instead of reviewing code.

Now I am considering forcing all developers that want to code, to also review code, but I have a feeling that it is a bad idea.

My question is, therefore, how can I motivate capable people to review the code of others? How is this done in successful open source projects like Linux, PostgreSQL, LibreOffice etc.


问:
What's the most used programming language in high performance computing? And why?
I believe a lot of Fortran is used in HPC, but not sure if that's only for legacy reasons.

Features of modern programming languages like garbage collection or run-time polymorphism are not suitable for HPC since speed matters so not sure where C# or Java or C++ come in.

Any thoughts?

答:
Just some anecdotal note. I haven't done any high performance computing myself.

For calculations (number crunching), Fortran and C. Yes it is for legacy reasons:

Ample availability of public domain source code and recipes.

Both support MPI.

Both languages are compiled.

Compilers for both languages are provided by all HPC OSes and vendors.

Vectorizing compilers are available.

Both requires crazy level of tweaking to get high performance when ported to a different cluster (different memory size, number of CPUs etc)

This actually explains why the open source code is important: tweaking is necessary, therefore the original recipe must be written in a language that is good for manual tweaking.

The current trend for number crunching is to write program generators that automate the source code tweaking in order to optimize performance given the cluster characteristics. These generators often output in C.

A second trend is to write in some specialized dialect of C for specific GPUs or Cell BE.

For non-numerical work, such as programs that process data from a database (but not the database itself), it is much cheaper to run on clusters of "commodity" machines without the expensive customized networking equipments. This is usually called "High Throughput Computing". And Python is the #1 language here (using the famous Map Reduce). Prior to Python, batch processing projects can be written in any language, and are usually dispatched by Condor.

ContentLicense: CC BY-SA 2.5


问:
Getting coders to do code review
I am running a project where I pay developers to contribute to my semi open source project. My problem is that it is easy to hire developers, but it is very difficult to get anyone to do code reviewing. I have repeatedly attempted to get the senior developers to review the code of the junior developers. I have attempted to pay them more, give them higher status etc. But they just seem to want to code instead of reviewing code.

Now I am considering forcing all developers that want to code, to also review code, but I have a feeling that it is a bad idea.

My question is, therefore, how can I motivate capable people to review the code of others? How is this done in successful open source projects like Linux, PostgreSQL, LibreOffice etc.

答:
Code review is a solution to a problem. Do you have a problem and will "Code Review" solve it? Are the other people checking in bad code? My guess is they are to some degree, but maybe your other coders don't think it is so bad that it is worth the time/effort to do a review. Ask your senior devs to come up with a solution to limit the amount of bad code checked into the system. They may come up with more effective solutions.

Solve the problem of having bad code (Code review is one of the pieces to the puzzle). One way to motivate developers is to stop the adding of new functionality until bugs/bad code are fixed. Most devs like building new stuff. Make the seniors fix bugs and refactor bad code. Maybe they'll learn it is easier to catch this in the code review.

Again, identify a problem and give your senior people a chance to come up with a solution.

You can't keep paying people who don't do what you tell them, so make sure those things are very important. It helps if everyone agrees there is a problem and contributes to the solution. Eventually, you have to make them accountable. They don't do code review, they take a lesser position or get fired.

In the future, hire people willing to do code review or at least let them know this is part of the job so they can make an informed choice.

Edit If you are having problems with your jr. dev's code, your seniors may feel the quality is so low, it would be faster to rewrite it than go through a review and correction process. It would be important to stress the long-term benefits of taking the time now to review, in order to give feedback to junior developers to make them better in the future.

ContentLicense: CC BY-SA 3.0

Title: Getting coders to do code review


问:
Is it considered 'reasonable' to implement a major part of a program largely by subclassing a library class?
I'm planning to implement a word processor using Java, and Swing for the GUI.

I was thinking how I can implement the text area where the user types the text.

My idea was to subclass JTextArea. It already has a lot of functionality for setting text, changing font size, etc. I will than add all the additional functionality, such as the ability to be affected by button presses on the UI, etc.

This seems reasonable to me, however I have a question regarding this:

Is it considered reasonable in a 'serious' program, to implement a major part of the program by subclassing an existing class of a common library? Is it a 'serious' and 'professional' thing to do?

Of course professional developers use and subclass existing code all the time, no point in reinventing the wheel.

But here I'm talking about implementing a major part of the application, probably the largest part, largely by subclassing an existing library class.

I am not a professional, and I know I don't have to work 'as professionals do'. But I am interested in how professionals view this.

1- Is something like this considered reasonable in a 'professional' application?

2- Have you ever seen this in practice in a 'professional' application?

答:
I'm going to ignore the specific class entirely and try to just answer your questions. As mentioned elsewhere, specifics are better handled on Stack overflow.

Is it considered reasonable in a 'serious' program, to implement a major part of the program by subclassing an existing class of a common library? Is it a 'serious' and 'professional' thing to do?

1- Is something like this considered reasonable in a 'professional' application?

2- Have you ever seen this in practice in a 'professional' application?

My answer is no, don't do it, you will live to regret it. No, this is not a 'professional' approach. No, I have not seen it done well and those who have tried have wished they hadn't.

As summarised here, there are good reasons for inheritance (subtyping and polymorphism) and then there is implementation inheritance, which is inherently evil in all but the most compelling cases.

Yes, if you are going to implement a new kind of button it makes a lot of sense to inherit from the Button class and add you own behaviour. You will be unable to preserve the encapsulation of your code because it will be all mixed up with Button code but it will probably be worth it.

However, if your new code merely has as number of features in common with a button then use aggregation. Include a button somewhere in your implementation to the extent that it makes sense to use button features, but keep it at a distance. Preserve your encapsulation. Keep layers between you and code supplied by others.

One way of looking at this is the "is a/has a" test. If your code really "is a" button then inherit away. If you code merely "has a" need for button features than include a button, but don't inherit from it.

Another reason: the services of the class from which you think to inherit should be (from your point of view) substitutable. That is, you should be free at some future time to discard that specific class in favour of a different one. Instead of using the Button class, you should be able to switch over to using the SpecialButton class or the SuperButton class.

You ability to do this will be sharply controlled by the level of encapsulation you make around your code. If you inherit, that ability to switch is probably lost.

Finally: I think you can probably have it both ways. Write a (small) subclass that captures the essential features that you need, and use it to expose an API customised to your specific needs. Then write the rest of your code to consume that API as a service. If you need to substitute the inherited class you will only need to rewrite the small subclass to inherit a different parent class or consume a different service, and your internal API remains intact. That preserves your encapsulation.

On reflection, this is the path I would probably take. I can make it clearer what it means if needed.


问:
How to avoid churn when you are defining a schema while others are trying to program against it
I'm in charge of defining an XML schema for some data; the plan is to have various systems (all under our control) upload XML files that match this schema to a central server for processing. I don't have much knowledge of the design of these other systems, so I'm working collaboratively with those system experts to make this XML schema reasonable to both consume (on our side) and produce (on their side).

The schema is not entirely clear-cut, and I'm defining the data we want to collect at the same time as defining the schema. There are a million ways to do it so there's a definite "do something, think about it, talk to so-and-so, refactor, repeat" process in place.

All of that said, we have an unfortunate situation where myself and a few others are defining things and a few other developers are implementing it. I'd like to write some code but haven't found the time. This leads to the frustrating cycle whereby the design changes in the ivory tower and then the guys writing the code have to go and change it again and again. Avoiding details for various reasons, the developers writing the implementation aren't in a position to effectively define the requirements of the schema and the data we must collect.

Should I be the one writing and playing with this stuff as I figure out how it should be done? This would be ideal to me, but we're under pressure to get things done and it's quicker to have a few people working on it rather than just me.

Do we have too many cooks in the kitchen with the XML file providers influencing the schema? Ease of XML file creation should be a consideration of the schema, right?

Is there a better way to solve this problem, or is churn a necessary evil when you're trying to fly the plane as you build it?

What is the correct development process to apply here which will minimize wasted time?

答: Add a version element or attribute up near the root of your xml.  Each time you publish a new schema increment this version.  Producers set the version and use the corresponding schema.  Consumers read the version and apply the appropriate shredding.  This works best if the position of the version tag doesn't change between versions.</p>


问:
Why are more programmers not freelance these days?
Leaving the whole pie to only a few of them, amplifying the huge differences between the two status. Pay is a (huge) one, not having to do overtime is another.

I leave the question open to hopefully get many great answers on all the different subjects that affects that feeling and decision not to go.

While this question is really global, I'll be interested in any studies, facts, articles, opinions regarding local markets such as US, India and even Australia in which I'm in love with.

答:
Good programmers who stayed in the freelance realm are good with customer service, business oriented and proactive. I think being freelance is much more challenging rather than being a programmer for a corporate world. The challenge do come along with rewards.

Other than that I think all developers should at least pick up side freelance project if they have corporate jobs as their main source of income. In doing this it gives them the opportunity to market, network and also test the water of freelance world.


答:
Being self-employed is great. You can name your own price, and only have to work half a day.

You even get to choose whether it's the first twelve hours or the second twelve hours.

Title: Why are more programmers not freelance these days?

Body:
Leaving the whole pie to only a few of them, amplifying the huge differences between the two status. Pay is a (huge) one, not having to do overtime is another.

I leave the question open to hopefully get many great answers on all the different subjects that affects that feeling and decision not to go.

While this question is really global, I'll be interested in any studies, facts, articles, opinions regarding local markets such as US, India and even Australia in which I'm in love with.


问:
Versioning Strategy for Service Interfaces JAR
I'm building a service oriented architecture composed (mostly) of Java-based services, each of which is a Maven project (in an individual repository) with two submodules: common, and server. The common module contains the service's interfaces that clients can include in their project to make service calls. The server submodule contains the code that actually powers the service.

I'm now trying to figure out an appropriate versioning strategy for the interfaces, such that each interface change results in a new common jar, but changes to the server (so long as they don't impact the contract of the interfaces) receive the same common jar.

I know this is pretty simple to do manually (simply increment the server version and don't touch the common one), but this project will be built and deployed by a CI server, and I'd like to come up with a strategy for automatically versioning these. The only thing I have been able to come up with so far is to have the CI server md5 the service interfaces.

答:
I would consider using the specification-version and implementation-version fields in the Manifest.  Specification-version would increment on changes to the interface specification, while the implementation-version would increment on each build.

Typically specification-version would be something like 1.0 and the implementation-version would append something related to the build something like 1.0.3432.

Look at the way JST is versioned for an example.

In declaring your dependencies you likely want to avoid using exact match.


问:
Algorithm for indexing strings in "list"
Imagine I have file called strings.dat. Inside this file there are a lot of strings, for example: one million. Strings are sorted. Now I want to find a specified string, so I can write method like this:

```<code>public long FindByName (string text)
{
  // ...
}
</code>```

This method can return to me a position within a file where this string occurs. But iterating through lots of data is not efficient.
I can do some indexing system, like an Dictionary<char, long> which tells about at what position within file is placed first string with its value starting from given char.

Example: if I got 5 strings:
hello

hello2

world

world2

Zzz

So my dictionary will be like:

h 0

w 2

z 4

But it's not efficient if I will have 1000 string with "d" char as first letter, and 10 million with "r" letter.

Do you know any good algorithms to achieve what I'm asking for?

答:
Because your data is sorted, I would use a Binary Search algorithm on it.

Since this is a text file (i.e., string lengths / record sizes are not all equal) you'll have a little adjusting to do.

As an example, say your file is 1GB in size - (average string length including end of line is around 1,024 bytes.

Open the file and start reading bytes at position 512 MB.  Chances are you've hit the middle of a string.  No problem, just keep reading bytes until you get to the end of the line, then read the next line and use that as your pivot.

It will be a little bit messier than if all the strings were the same length, but not terribly so.

If your search target comes before the pivot string, your next random access read would begin around 256 MB.

ContentLicense: CC BY-SA 4.0


问:
In event sourcing, is it ok to introduce a dependency in my message class?
Following Martin Fowler's explanation on event sourcing, I have a message class that looks something like this:

```<code>ShippingEvent
{
    Process(Ship ship) {}
}
</code>```

However, in my case, I need to talk to another component in the Process method. More specific, I need to access a repository to get some basic data. Is it ok to add this repository to the method, i.e.:

```<code>ShippingEvent
{
    Process(Ship ship, IBasicDataRepository repo) {}
}
</code>```

I could put it in the constructor of my message too, of course. However, I can't pass in the basic data, because the repo will be called multiple times with different parameters, depending on what's in the ´ship´ object.

So is it ok to introduce external dependencies in the event/message class or is there a better way?

答:
I think that whatever is listening to your event should have a dependency on a repository, as opposed to having that dependency inside of your message.

Your message might be used in different contexts and an additional repository might not be needed every single time.

I would suggest keeping events as simple as possible. My events normally transfer a data structure. A listener then picks up an event and does something with that data structure.

You can implement IShippingEventProcessor - this would have a dependency on the IBasicDataRepository.

Finally, events normally promote loose coupling. A single event might be published and then picked up by a range of domains. It might be the case that one of the domains should know nothing about the IBasicDataRepository dependency.


问:
Relevance of HTML5: Is now the time?
It seems like most of the jobs I'm receiving, and most of the Internet, is still using standard HTML (HTML 4, let's say) + CSS + JS. Does anyone have any vision on where HTML5 is as a standard, particularly regarding acceptance and diffusion? It's easy to find information about inconsistencies between implementations of HTML5 and so forth. What I want to know about is relevance of HTML5.

答:
Depending on what elements of HTML5 you're referring to, some are only available in FF beta 4 and IE beta 9 right now. I just ran an HTML5 test on FF beta 4 and got a result of 207 out of 300. If you want to try the tester - http://html5test.com/

There are some options for forcing it to work, such as the HTML5 Boilerplate, though I haven't been able to use it yet myself - http://html5boilerplate.com/ And Modernizr can help - http://www.modernizr.com/

That said, my position is to focus more on CSS and JavaScript with a solid base in XHTML 1.1 for now. I like to keep the foundation strong and use progressive enhancement on top of the HTML. Jumping to HTML5 means building ahead and then spending a lot of time making it backwards compatible, instead of making a solid foundation and looking forward. XHTML 1.1 encourages clean coding and is the way I like to code for now.

Title: Relevance of HTML5: Is now the time?


答:
You mention in the comments to your question that you used to use a DBMS but are moving away in order to save money and make your project more portable.

There are free and portable DBMS alternatives.  I highly recommend looking into those instead of writing your own.

Existing products will have been designed by better devs than you or me, and will already have hundreds of testing hours on them.  In other words:  They will be faster and more stable.

Try looking into sqlite.

Title: Algorithm for indexing strings in "list"

Body:
Imagine I have file called strings.dat. Inside this file there are a lot of strings, for example: one million. Strings are sorted. Now I want to find a specified string, so I can write method like this:

```<code>public long FindByName (string text)
{
  // ...
}
</code>```

This method can return to me a position within a file where this string occurs. But iterating through lots of data is not efficient.
I can do some indexing system, like an Dictionary<char, long> which tells about at what position within file is placed first string with its value starting from given char.

Example: if I got 5 strings:
hello

hello2

world

world2

Zzz

So my dictionary will be like:

h 0

w 2

z 4

But it's not efficient if I will have 1000 string with "d" char as first letter, and 10 million with "r" letter.

Do you know any good algorithms to achieve what I'm asking for?


答:
Use a hash table. The hash table would include a reasonably unique key generated from the string and pointers to the strings that match that hash key.

A simple, fast hash with a small hash table (256 entries), but lots of key collisions, would be the xor of all bytes in the string. A slower, more complicated hash with a much larger hash table (as many entries as strings), but where key collisions are unlikely, would be AES encryption.

I realize you're using C#, but here's a little perl script to help you investigate what hash table size you'd like to use. This version of the keyify() function just sums the string into a 16 bit integer.

```
# keyspace.pl
sub keyify {
    use constant HASH_KEY_SIZE_IN_BITS =&gt 16;
    return unpack( '%' . HASH_KEY_SIZE_IN_BITS . 'A*', $_ );
}

$/ = "\r\n"; # Windows EOL
$offset = 0;
while(&lt&gt) {
    $newoffset = $offset + length($_);
    $key = keyify($_);
    if (defined $myhash{$key}) {
        # key collision, add to the list of offsets
        push @{ $myhash {$key} }, $offset;
    } else {
        # new key, create the list of offsets
        $myhash { $key } = [$offset];
    }
    $offset = $newoffset;
}
printf "%d keys generated\n", scalar (keys %myhash);
$max = 0;
foreach (keys%myhash) {
    $collisions = scalar @{ $myhash{$_} };
    $max = $collisions      if ( $collisions &gt $max );
}
print "maximum # of string offsets in a hash = $max\n";
exit;

# dump hash table
foreach (keys%myhash) {
    print "key = $_:";
    foreach my $offset ( @{ $myhash{$_} } ) {
        print " $offset";
    }
    print "\n";
}
```

Use it like so:

```<code>perl keyspace.pl <strings.dat
</code>```

The same thing in PowerShell, with a much simpler hashing function. You'll have to put in some effort if you want this to be useful.

```
# keyspace.ps1
# Don't use "gc -Encoding Byte -Raw" because it reads the ENTIRE file into memory.
function keyify {
    return $args[0].Substring(0,1);
}

$myHash = @{};
$offset = 0;
$file = New-Object System.IO.StreamReader($args[0]);
while ($line = $file.ReadLine()) {
    $newoffset = $offset + $line.Length + 2;    # adjust by 2 for Windows EOL (CRLF)
    $key = keyify($line);
    if ($myHash.ContainsKey($key)) {
        # key collision, add to the list of offsets
        $myHash.Set_Item($key, $myHash.Get_Item($key)+$offset);
    } else {
        # new key, create the list of offsets
        $myHash.Add($key, @($offset));
    }
    $offset = $newoffset;
}
$file.close()
echo "$($myHash.Count) keys generated";
$max = 0;
foreach ($i in $myHash.KEYS.GetEnumerator()) {
    $collisionList = $myHash.Get_Item($i);
    if ($collisionList.Count -gt $max) { $max = $collisionList.Count; }
}
echo "maximum # of string offsets in a hash = $max";

# echo $myHash;
```

Use it like so:

```<code>.\keyspace.ps1 strings.dat
</code>```

Body:
Use a hash table. The hash table would include a reasonably unique key generated from the string and pointers to the strings that match that hash key.

A simple, fast hash with a small hash table (256 entries), but lots of key collisions, would be the xor of all bytes in the string. A slower, more complicated hash with a much larger hash table (as many entries as strings), but where key collisions are unlikely, would be AES encryption.

I realize you're using C#, but here's a little perl script to help you investigate what hash table size you'd like to use. This version of the keyify() function just sums the string into a 16 bit integer.

# keyspace.pl
sub keyify {
    use constant HASH_KEY_SIZE_IN_BITS =&gt 16;
    return unpack( '%' . HASH_KEY_SIZE_IN_BITS . 'A*', $_ );
}

$/ = "\r\n"; # Windows EOL
$offset = 0;
while(&lt&gt) {
    $newoffset = $offset + length($_);
    $key = keyify($_);
    if (defined $myhash{$key}) {
        # key collision, add to the list of offsets
        push @{ $myhash {$key} }, $offset;
    } else {
        # new key, create the list of offsets
        $myhash { $key } = [$offset];
    }
    $offset = $newoffset;
}
printf "%d keys generated\n", scalar (keys %myhash);
$max = 0;
foreach (keys%myhash) {
    $collisions = scalar @{ $myhash{$_} };
    $max = $collisions      if ( $collisions &gt $max );
}
print "maximum # of string offsets in a hash = $max\n";
exit;

# dump hash table
foreach (keys%myhash) {
    print "key = $_:";
    foreach my $offset ( @{ $myhash{$_} } ) {
        print " $offset";
    }
    print "\n";
}

Use it like so:

perl keyspace.pl <strings.dat

The same thing in PowerShell, with a much simpler hashing function. You'll have to put in some effort if you want this to be useful.

# keyspace.ps1
# Don't use "gc -Encoding Byte -Raw" because it reads the ENTIRE file into memory.
function keyify {
    return $args[0].Substring(0,1);
}

$myHash = @{};
$offset = 0;
$file = New-Object System.IO.StreamReader($args[0]);
while ($line = $file.ReadLine()) {
    $newoffset = $offset + $line.Length + 2;    # adjust by 2 for Windows EOL (CRLF)
    $key = keyify($line);
    if ($myHash.ContainsKey($key)) {
        # key collision, add to the list of offsets
        $myHash.Set_Item($key, $myHash.Get_Item($key)+$offset);
    } else {
        # new key, create the list of offsets
        $myHash.Add($key, @($offset));
    }
    $offset = $newoffset;
}
$file.close()
echo "$($myHash.Count) keys generated";
$max = 0;
foreach ($i in $myHash.KEYS.GetEnumerator()) {
    $collisionList = $myHash.Get_Item($i);
    if ($collisionList.Count -gt $max) { $max = $collisionList.Count; }
}
echo "maximum # of string offsets in a hash = $max";

# echo $myHash;

Use it like so:

.\keyspace.ps1 strings.dat


答:
First answer the question why you want the developers to do code reviews. Are there too much bugs, are coding conventions not followed, is knowledge not shared, is code checked in with insufficient tests, etc.

Then discuss this with the developers. Tell them what you expect and ask them how they would improve on this. They should all agree to implement these changes or it will be difficult to enforce them.

If everyone agrees code review are useful, which they normally are, then a new rule might be that from now on only reviewed code can make into the product.

To be able to do a review it should be clear what is expected. So define what rules apply to code, like:

coding conventions (naming, code style)

default solutions

constructs to avoid

Use good tools, so make it easy to find code to review, see the changes and talk about those changes.

Code review should become part of the normal workflow to implement a change. That could be organized in this way:

a developer is expected to find someone else to do a review of the changes to include.

or, for every committed change you must do review.

Title: Getting coders to do code review


问:
Why do C arrays not keep track of their length?
What was the reasoning behind not explicitly storing an array's length with an array in C?

The way I see it, there are overwhelming reasons to do so but not very many in support of the standard (C89). For instance:

Having length available in a buffer can prevent buffer overrun.

A Java-style arr.length is both clear and avoids the programmer from having to maintain many ints on the stack if dealing with several arrays

Function parameters become more cogent.

But perhaps the most motivating reason, in my opinion, is that usually, no space is saved without keeping the length. I would venture to say that most uses of arrays involve dynamic allocation. True, there may be some cases where people use an array allocated on the stack, but that's just one function call* - the stack can handle 4 or 8 bytes extra.

Since the heap manager has to track the free block size used up by the dynamically allocated array anyway, why not make that information usable (and add the additional rule, checked at compile time, that one can't manipulate the length explicitly unless one would like to shoot oneself in the foot).

The only thing I can think of on the other side is that no length tracking may have made compilers simpler, but not that much simpler.

*Technically, one could write some kind of recursive function with an array with automatic storage, and in this (very elaborate) case storing the length may indeed result in effectively more space usage.

答:
The question assumes that there are arrays in C. There aren't. Things that are called arrays are just a syntactic sugar for operations on continuous sequences of data and pointer arithmetics.

The following code copies some data from src to dst in int-sized chunks not knowing that it is actually character string.

```<code>char src[] = "Hello, world";
char dst[1024];
int *my_array = src; /* What? Compiler warning, but the code is valid. */
int *other_array = dst;
int i;
for (i = 0; i <= sizeof(src)/sizeof(int); i++)
    other_array[i] = my_array[i]; /* Oh well, we've copied some extra bytes */
printf("%s\n", dst);
</code>```

Why C is so simplified it doesn't have proper arrays? I don't know correct answer to this new question. But some people often say that C is just (somewhat) more readable and portable assembler.

Body:
The question assumes that there are arrays in C. There aren't. Things that are called arrays are just a syntactic sugar for operations on continuous sequences of data and pointer arithmetics.

The following code copies some data from src to dst in int-sized chunks not knowing that it is actually character string.

char src[] = "Hello, world";
char dst[1024];
int *my_array = src; /* What? Compiler warning, but the code is valid. */
int *other_array = dst;
int i;
for (i = 0; i <= sizeof(src)/sizeof(int); i++)
    other_array[i] = my_array[i]; /* Oh well, we've copied some extra bytes */
printf("%s\n", dst);

Why C is so simplified it doesn't have proper arrays? I don't know correct answer to this new question. But some people often say that C is just (somewhat) more readable and portable assembler.


答:
Back in the day when C was created, and extra 4 bytes of space for every string no matter how short would have been quite a waste!

There's another issue - remember that C is not object-oriented, so if you do length-prefix all strings, it would have to be defined as a compiler intrinsic type, not a char*. If it was a special type, then you would not be able to compare a string to a constant string, i.e.:

```<code>String x = "hello";
if (strcmp(x, "hello") == 0)
  exit;
</code>```

would have to have special compiler details to either convert that static string to a String, or have different string functions to take account of the length prefix.

I think ultimately though, they just didn't choose the length-prefix way unlike say Pascal.

Title: Why do C arrays not keep track of their length?

Body:
What was the reasoning behind not explicitly storing an array's length with an array in C?

The way I see it, there are overwhelming reasons to do so but not very many in support of the standard (C89). For instance:

Having length available in a buffer can prevent buffer overrun.

A Java-style arr.length is both clear and avoids the programmer from having to maintain many ints on the stack if dealing with several arrays

Function parameters become more cogent.

But perhaps the most motivating reason, in my opinion, is that usually, no space is saved without keeping the length. I would venture to say that most uses of arrays involve dynamic allocation. True, there may be some cases where people use an array allocated on the stack, but that's just one function call* - the stack can handle 4 or 8 bytes extra.

Since the heap manager has to track the free block size used up by the dynamically allocated array anyway, why not make that information usable (and add the additional rule, checked at compile time, that one can't manipulate the length explicitly unless one would like to shoot oneself in the foot).

The only thing I can think of on the other side is that no length tracking may have made compilers simpler, but not that much simpler.

*Technically, one could write some kind of recursive function with an array with automatic storage, and in this (very elaborate) case storing the length may indeed result in effectively more space usage.

Body:
Back in the day when C was created, and extra 4 bytes of space for every string no matter how short would have been quite a waste!

There's another issue - remember that C is not object-oriented, so if you do length-prefix all strings, it would have to be defined as a compiler intrinsic type, not a char*. If it was a special type, then you would not be able to compare a string to a constant string, i.e.:

String x = "hello";
if (strcmp(x, "hello") == 0)
  exit;

would have to have special compiler details to either convert that static string to a String, or have different string functions to take account of the length prefix.

I think ultimately though, they just didn't choose the length-prefix way unlike say Pascal.


问:
How important is graceful degradation of JavaScript?
Should web developers continue to spend effort progressively enhancing our web applications with JavaScript, ensuring that features gracefully degrade, thereby ensuring accessibility?  Or should we spend that time focused on new features or other areas of development?

The subtext of that question would be:  How many of our customers/clients/users utilize our websites or applications with JavaScript disabled?  Do you have any projects with requirements that specifically demand JavaScript functionality (almost all of mine do), and do those requirements also demand graceful degradation?

For the sake of asking this question, I pulled up programmers.stackexchange.com without JavaScript enabled, and I was greeted with this message: "Programmers - Stack Exchange works best with JavaScript enabled".  It was difficult to log in, albeit the site seemed to generally work okay.  (I wasn't able to vote up any questions.)

I think this is a satisfactory approach to development.  Imagine the effort involved in making all of the site's features work with plain old HTML and server-side logic. On the other hand, I wonder how many users have been alienated by this approach.

We've all been trained (at least the good developers among us) to use progressive enhancement and to ensure our web applications' dynamic features degrade gracefully.  Is this progressive enhancement just pissing into the wind, or do some of our customers actually utilize certain web services without JavaScript enabled?

答:
Or do some of us actually utilize
  certain web services without
  JavaScript enabled

Yes.

My browsing falls into three categories.

Normal Browsing  - On Safari or Chrome (Mac OS X)

 - iGoogle, Stack Overflow, some blogs

Special websites: - Firefox, with NoScript, AdBlock Plus and FlashBlock

Sites with unnecessarily heavy JavaScript. (Some Indian sites for Bollywood movies/music, if that is important. Unnecessarily heavy script - the page itself reloads every 5 mins or so)

Mobile Browsing:

I used to have a Nokia 5310. Lost it. Now I have an even older Sony Ericsson W700i. I browse using it when I am traveling (Opera Mini is pretty good). This is the place (the absence of) JavaScript is a pain. I don't want to interact with the site (mostly), just read. Still most of the sites are impossible to view.


答:
C arrays do keep track of their length, as the array length is a static property:

```<code>int xs[42];  /* a 42-element array */
</code>```

You can't usually query this length, but you don't need to because it's static anyway – just declare a macro XS_LENGTH for the length, and you're done.

The more important issue is that C arrays implicitly degrade into pointers, e.g. when passed to a function. This does make some sense, and allows for some nice low-level tricks, but it loses the information about the length of the array. So a better question would be why C was designed with this implicit degradation to pointers.

Another matter is that pointers need no storage except the memory address itself. C allows us to cast integers to pointers, pointers to other pointers, and to treat pointers as if they were arrays. While doing this, C is not insane enough to fabricate some array length into existence, but seems to trust in the Spiderman motto: with great power the programmer will hopefully fulfill the great responsibility of keeping track of lengths and overflows.

Body:
C arrays do keep track of their length, as the array length is a static property:

int xs[42];  /* a 42-element array */

You can't usually query this length, but you don't need to because it's static anyway – just declare a macro XS_LENGTH for the length, and you're done.

The more important issue is that C arrays implicitly degrade into pointers, e.g. when passed to a function. This does make some sense, and allows for some nice low-level tricks, but it loses the information about the length of the array. So a better question would be why C was designed with this implicit degradation to pointers.

Another matter is that pointers need no storage except the memory address itself. C allows us to cast integers to pointers, pointers to other pointers, and to treat pointers as if they were arrays. While doing this, C is not insane enough to fabricate some array length into existence, but seems to trust in the Spiderman motto: with great power the programmer will hopefully fulfill the great responsibility of keeping track of lengths and overflows.


问:
Using LGPL Library with Java static or Dynamic linking
I've searched and read many posts about LGPL and C, and when I was able to find one that related to Java, my mind still didn't rest with ease, so I'll try to be more specific and hopefully get a viable guide lines, and I would eventually consult a lawyer obviously!

Setup:

There is a LGPL library, lets call it Lib-B

I have My Library which is based on Lib-B lets call it My-Lib

In my opinion Lib-B architecture is not well formulated, and I want to apply in My-Lib my own architecture and use some of the functions of Lib-B.

Problem is, that Lib-B, wraps the functions I want to access in a manner that does not suit the architecture of My-Lib so I've changed Lib-B and encapsulated (duplicated) the code lines I wanted/needed within a couple of objects still inside Lib-B and call these functions from My-Lib.

That is my current static setup...

=====================

The second thing I can do is to make my setup dynamic, so:

I could create a Library that would define an interface with the functions My-Lib needs lets call it Lib-A.

Later, I will compile and link My-Lib with Lib-A, and let Lib-B implement the interface from Lib-A, and load Lib-B dynamically in My-Lib.

I understand that in both cases I must release my changes of Lib-B as LGPL as well and allow my end users access to the code etc... what about My-Lib?

Thanks,
Adam.

答:
The LGPL allows you to release My-lib without opening its source code.  That's the whole purpose of the LGPL; it provides a linking exception to allow users to link the LGPL library without opening their own source.

The LGPL still provides users with access to the source code of your changes to Lib-B, without preventing you from keeping the rest of your application closed-source.


问:
Is it better to pass the whole object or use a setter?
Here is my initial code that I would like to modify by using strategy design pattern.

```<code>class Bar
{
  int a;
  int b;
  ...
}

Class Foo
{
  Bar *bar;

  bool action1(){
    // this function does a lot of work that only uses "bar.a"
  }
  bool action2(){
    // this function does also a lot of work that only uses "bar.a"
  }
  void command(){
    ...
    Bar bar2 = new Bar();
    bar = bar2; // this function modifies the attribute bar.
    ...
  }

  ...
}
</code>```

I am trying to separate the code of both action1 and action2 from the class Foo by creating a strategy object that will implement those actions. I don't know which of those implementations is better.

First Solution:

```<code>class ActionStrategy {
  Bar *bar;

  bool action1();
  bool action2();
}

Class Foo
{
  Bar *bar;
  ActionStrategy strategy

  bool action1(){
    strategy.action1();
  }
  bool action2(){
    strategy.action2();
  }
  void command(){
    ...
    Bar bar2 = new Bar();
    bar = bar2; // this function modifies the attribute bar.
    ...
  }

  ...
}
</code>```

Second Solution:

```<code>class ActionStrategy {
  int a;

  bool action1();
  bool action2();
}

Class Foo
{
  Bar *bar;
  ActionStrategy strategy

  bool action1(){
    strategy.action1();
  }
  bool action2(){
    strategy.action2();
  }
  void command(){
    ...
    Bar bar2 = new Bar();
    setBar(bar2); // this function modifies the attribute bar.
    ...
  }

  void setBar(Bar* target) {
    bar = target;
    strategy.a = target->a;
  }

  ...
}
</code>```

答:
The answer may very be "neither."  Neither of your solutions appear to cleanly separate out responsibility for the variable a and the two methods.

The answer you're looking for depends upon what a actually represents and what the methods are doing to it.  Once you understand that, then you can follow the single responsibility principle and decide where to place the variable and methods.

At the moment, your solutions appear to be pushing too much knowledge regarding a and the methods that act upon a to classes that don't have responsibility for a.  Perhaps the methods should be moved to Bar; have Foo instantiate Bar by passing a value of a; and have Foo call the methods off of Bar.


答:
I would use a bucket sort to help optimize this.

Since strings are different lengths in your example, and there is a lot of data considering this is a flat file, I would simply split the file into multiple pieces based on the string prefix.

So instead of having strings.dat I would have the following:

a.dat

b.dat

...

z.dat

If any particular file is still too large, for example, a common letter such as r or t is disproportionately larger, split that into smaller buckets:

r.dat

ra.dat

re.dat

...

This can continue with rab.dat and so on.

To find a string, simply start with the full string and look for a file matching its name. If not found, look for a file matching the string minus the last character. Do this until a match is found or the string is zero length (e.g. maybe there is no x.dat so no word starting with x will ever be found).

Example: here are some files, and a string that could be located in each one.

r.dat - rhombus (no rh.dat)

ra.dat - rat (no rat.dat)

rab.dat - rabid (no rabi.dat)

Each file should be small enough for efficient searching either using a full scan or a binary search, whatever you believe is appropriate given the amount of data.

Benefits

Smaller text files are easier to manage in a text editor if you need to modify them.

Seeking through text files can be inefficient depending on your language, library, and file mode. By reducing the amount of data in each file, this may alleviate that.

From an algorithmic complexity perspective this does not buy you much if anything. However, from a practical perspective it does. File I/O is expensive, easily one of the most expensive operations a computer can perform (unless you have an SSD). By minimizing file seeks/reads, you mitigate the real-world performance impact of searching 500 MB of data each time. How much? Profile it to say for sure, but I would feel comfortable sticking my neck out and saying it would be a measurable amount.


问:
What is the (craziest, stupidest, silliest) thing a client/boss asked you to do?
See title, but I am asking from a technical perspective, not

Take my 40 year old virgin niece on a date or you're fired.

答:
Just last week someone asked me to make a simple change to an existing DLL (left pad a numerical value with leading zeros).

It was a COM DLL, originally coded in VB 6 - source code long since lost - which interfaced on one side with some external hardware (interface unknown) and whose functions were called from an Active X control on a web page (interface, again, unknown).

It only took me a week and I only slept overnight on the office floor twice.

But I got it done and it is live in the field as of yesterday - working.

Punchline - it was a government project, of course.


问:
UML class diagram: how to annotate observer-subject relationship?
How can I annotate in a UML class diagram that an instance of ClassA is registered as an observer of an instance of ClassB? (Both implement the appropriate interfaces).

This doesn't really belong in a class diagram, because they are static, but if this is something that is important to the design - how can you annotate it in this type of diagram?

Edit:

To clarify: I know how to annotate the Observer pattern in UML. My question is more specific.

ClassA being registered as an observer to ClassB is important for the design, however I'm not sure if an association relationship between the two classes is appropriate, since ClassA and ClassB don't know about each other. They're totally decoupled, and only connected through the Observer pattern.

答:
Documenting this type of relationship is suitable for a class diagram. You can add role names to the association links between classes, similar to how it's demonstrated on Scott Ambler's introduction to UML class diagrams or the Wikipedia example of Associations. I would also indicate the fact that they implement the interfaces or inherit from the base class, even if you are using a language like Java that provides the necessary classes (although I would consider omitting the details for these language-provided classes).

You can also apply notes in the UML diagram. Most tools that I've used allow for attaching notes to classes. These could annotate the usage of a pattern or even provide for a pseudocode implementation of a few functions, if it doesn't lead to clutter on the diagram.


答:
In any plan there is liable to be some difference between what you would like to be high priority and what actually is high priority. Since you're paying, you pretty much get to decide what is high priority, and you pretty much get to tell the people you're paying to work on high priority stuff first.

So, if they're avoiding code review then either:

You are not making code review higher priority than writing more new code. You might think you are, when actually you're saying "can we get this done by the end of tomorrow?" and letting them respond "sure, if we drop everything else". "Everything else" means they skip code review on this and anything they've done recently that needs review.

They aren't doing what you asked them and paid them to do. Since you're prepared to pay extra for code review and they'd still prefer to write new code without review for less money, you have to find out from them why code review is so unpleasant.

Either way, to get the developers involved you could look into the Scrum concept of a "Definition of Done". You could have this even if you're not doing Scrum, and include code review in your team's definition. That is, they can't say that X is finished until X has been reviewed, which means they have to find someone to review their code (and the code of the juniors they're responsible for). Hopefully this will lead to them trading off reviews with each other.

Another way to present it is that by reviewing code they are familiarising themselves with parts of the system they may need to work on in future. If you encourage shared responsibility for the whole code base, as opposed to ownership of components, then you force more eyes onto each piece of code. Granted that's not the same as a formal review phase, but it's a move in the right direction since it achieves the same goal of avoiding using code that only one person thinks is correct.

Of course if they really hate reviewing then they could choose to do a completely cursory review, passing everything more-or-less without reading it. In that case you'll have to drill deeper into the problem and convince them to do a good job. To demonstrate that review is beneficial you can point to problems that occur due to someone having goofed off a review they were supposed to do. Professionals hopefully respond fairly strongly once their mistakes are seen to cause real problems, but often less strongly if they're failing to tick off what they perceive as a pointless task. If you cannot find problems that can be at least partially ascribed to lack of review, then consider again how you decided that review really is beneficial for this project.

Another possibility, that I can't rule out from what you say in the question, is that the coders you have simply aren't very good, or at least aren't very good at producing a working project without additional technical support. You don't say anything about testing, bug-fixing, or QA in general. If all they want to do is write code, and don't want to make it actually work reliably, then naturally not doing code review would be one part of this. The flip side, I suppose, is that maybe your coders are so universally awesome that their code always works first time and doesn't need testing, bug-fixing, or review. That seems unlikely!

Title: Getting coders to do code review


问:
Persisting type in Java - should I be using flags?
Is there some specific piece of advice around persist values that indicate type? Specifically I want to know if I should persist a flag/state indicating the type in persistence or not. I get the feeling I'm forgetting/not understanding some core concept of OO or data modelling.

Something that's been on my mind for the last while is to consider when to use flags and when not to, and intermixing this idea of recreating objects of some certain type out of persistence.

The reason for my concern over flags is that in the software I often create (in-house created corporate software developed with Java), these flags become pieces of information which are hard to maintain and which subsequent developers need to be aware of in order to maintain them (perhaps creating code bloat).

So, when I persist my foo, should I persist with it some flag that indicates whether it is a foobar or a foobo? Is there specific advice about this, some gap in my OO-foo or data modelling that I'm forgetting?

答:
It depends on where you persist and what you persist. It would make sense to use some enums when wanting to persist a class hierarchy and you want to persist all the elements of the class hierarchy in a single place.

Take for example mapping inheritance to a single table in and ORM (e.g. @Inheritance(strategy = InheritanceType.SINGLE_TABLE in JPA). Say you have a superclass User and two subclasses CustomerUser and AdminUsers and you want them mapped to a single column users. Here you need a discriminator column to differentiate between possible user types; this column is better a string or an enum rather than a flag. This column should have the value customer for entries that represent CustomerUser and admin for entries that represent AdminUser.

But if you do not have some common elements from distinct classes that have a common superclass, then it doesn't make sense to specify the type when you persist it. You should know from the context/metadata what the type is (be it a column name in a relational database, a name of the file, a tag name in a XML etc.) and you shouldn't strongly couple it with your application model because you may want other applications reading the persisted data. Given the above example you might as well have two distinct columns admin_users and customer_users and then there is no need for persisting the type.


问:
Why the question "give five things you hate about C#" is so difficult to answer during an interview?
In podcast 73, Joel Spolsky and Jeff Atwood discuss, among other subjects, "five things everyone should hate about their favorite programming language":

If you’re happy with your current tool chain, then there’s no reason you need to switch. However, if you can’t list five things you hate about your favorite programming language, then I argue you don’t know it well enough yet to judge. It’s good to be aware of the alternatives, and have a healthy critical eye for whatever it is you’re using.

Being curious, I asked this question to any candidate I interviewed. None of them were able to quote at least one thing they hate about C#¹.

Why? What's so difficult in this question? It is because of the stressful context of the interview that this question is impossible to answer by the interviewees?

Is there something about this question which makes it bad for an interview?

Obviously, it doesn't mean that C# is perfect. I have myself a list of five things I hate about C#:

The lack of variable number of types in generics (similar to params for arguments).

Action<T>,

Action<T1, T2>,

Action<T1, T2, T3>,

       ⁞

Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>

Seriously?!

The lack of support for units of measure, like in F#.

The lack of read only properties. Writing a backing private readonly field every time I want a read only property is boring.

The lack of properties with default values. And yes, I know that I can initialize them in the parameterless constructor and call it from all other constructors. But I don't want to.

Multiple inheritance. Yes, it causes confusion and you don't need it in most cases. It's still useful in some (very rare) cases, and the confusion applies as well (and was solved in C#) to the class which inherits several interfaces which contain methods with the same name.

I'm pretty sure that this list is far from being complete, and there are much more points to highlight, and especially much better ones than mine.

¹ A few people criticized some assemblies in .NET Framework or the lack of some libraries in the framework or criticized the CLR. This doesn't count, since the question was about the language itself, and while I could potentially accept an answer about something negative in the core of .NET Framework (for example something like the fact that there is no common interface for TryParse, so if you want to parse a string to several types, you have to repeat yourself for every type), an answer about JSON or WCF is completely off-topic.

答:
Because languages shape the way we think. By using C# everyday, you have taken the habit of thinking and designing your code in a way that naturally works around the problems of the language.

You now do it without thinking, without even knowing that you do it. This is why it is so difficult to point out what the bad things are. No doubt that the day when you started learning C#, you found a lot of issues, but now you don't see them anymore. Habits are powerful things. Thought habits, even more.

The positive side of this is, if you find it difficult to list the flaws in C#, it must be because you are a good C# programmer, you like the language, and use it more than other languages.

But if you want to become more able to see the flaws in C#, you have to change your way of thinking. Learn more programming languages, and become used to them. Aim for the most different possible languages. You are used to static typing? Try Python or Ruby. You are used to object-oriented and imperative? Haskell is another world entirely.

And when you come back to C#, you will be like, "Why do I need one hundred lines of C# to do this simple thing that's just one line in Haskell?". You will hate a lot of things about C#.

C# does not have non-nullable reference types.

No algebraic data types.

No string interpolation.

Syntax is overly verbose everywhere.

No macro system.

Type inference is limited.

No regexp literals.

No structural typing.

Poor support for immutability.

C# structs are error-prone.

Standard collections library is very limited.

Can't define constraints on parameters of constructors.

Can't program generically with constraints on math operators.

No 'newtype'.

No array slicing, no range literal.

Functions do not list the side-effects they can do as part of their type. :)

(Of course no language can have everything. Language design is extremely difficult, and adding every feature into the same language cannot work. Different tools for different purposes.)

Yes, the question is difficult to answer well, especially during an interview. But people that can answer it prove that they have thought about it, that they have some perspective.


问:
Would form keys reduce the amount of spam we receive?
I work for a company that has an online store, and we constantly have to deal with a lot of spam product reviews, and bogus customer accounts.  These are all created by automated systems and are more of a nuisance than anything.

What I am thinking of (in lieu of captcha, which can be broken) is adding a sort of form key solution to all relevant forms.  I know for certain some of the spammers are using XRumer, and I know they seldom request a page before sending us the form data (Is this the definition of CSRF?) so I would think that tying a key to each requested form would at least stem the tide.  I also know the spammers are lazy and don't check their work, or they would see that we have never posted a spam review, and they have never gained any revenue from our site.

Would this succeed in significantly reducing the volume of spam product reviews and customer account creations we are seeing?

EDIT:  To clarify what I mean by "Form Keys":  I am referring to creating a unique identifier (or "key") that will be used as an invisible, static form field.  This key will also be stored either in the database (relative to the user session) or in a cookie variable.  When the form's target gets a request, the key must be validated for the form's data to be processed.  Those pesky bots won't have the key because they don't load the javascript that generates the form (they just send a blind request to the target) and even if they did load the javascript once, they'd only have one valid key, and I'm not sure they even use cookies.

答:
What you're suggesting sounds like the honeypot method. I've used this on forms that were getting a lot of spam and found it works quite nicely. It wasn't perfect but it did cut our spam down quite a bit with no impact on legitimate users -- they didn't have to decode a cumbersome CAPTCHA or stop to think what 2 + 1 is equal to.

Now when we compared the honeypot against forms with reCAPTCHA, reCAPTCHA was waaaaay more effective, pretty much blocking everything.

It's not clear from your question but requiring an account to post a review and requiring email verification of said account (i.e., person signs up, you send an email with activation link, they click activation link before they can do anything on the site) can also go a long way to cutting down spam.

To specifically address you question: yes, this tactic will reduce spam, but you're likely to still get a decent volume of spam if you rely on it alone.

I'd start with a honeypot on your forms and see how it goes. It's easy to implement and is low impact on users. If the results are acceptable then be happy and move on to something else. If not, look into something like reCAPTCHA. You mentioned that management isn't too psyched at the idea of a CAPTCHA, likely because they fear a reduced number of legit reviews. In this case doing an A/B test of non-CAPTCHA vs CAPTCHA form submissions will give you some insight into whether this is actually a concern.


答:
The biggest problem with having arrays tagged with their length is not so much the space required to store that length, nor the question of how it should be stored (using one extra byte for short arrays generally wouldn't be objectionable, nor would using four extra bytes for long arrays, but using four bytes even for short arrays might be).  A much bigger problem is that given code like:

```<code>void ClearTwoElements(int *ptr)
{
  ptr[-2] = 0;
  ptr[2] = 0;
}
void blah(void)
{
  static int foo[10] = {1,2,3,4,5,6,7,8,9,10};
  ClearTwoElements(foo+2);
  ClearTwoElements(foo+7);
  ClearTwoElements(foo+1);
  ClearTwoElements(foo+8);
}
</code>```

the only way that code would be able to accept the first call to ClearTwoElements but reject the second would be for the ClearTwoElements method to receive information sufficient to know that in each case it was receiving a reference to part of the array foo in addition to knowing which part.  That would typically double the cost of passing pointer parameters.  Further, if each array was preceded by a pointer to an address just past the end (the most efficient format for validation), optimized code for ClearTwoElements would likely become something like:

```<code>void ClearTwoElements(int *ptr)
{
  int* array_end = ARRAY_END(ptr);
  if ((array_end - ARRAY_BASE(ptr)) < 10 ||
      (ARRAY_BASE(ptr)+4) <= ADDRESS(ptr) ||
      (array_end - 4) < ADDRESS(ptr)))
    trap();
  *(ADDRESS(ptr) - 4) = 0;
  *(ADDRESS(ptr) + 4) = 0;
}
</code>```

Note that a method caller could, in general, perfectly legitimately pass a pointer to the start of the array or the last element to a method; only if the method tries to access elements which go outside passed-in array would such pointers cause any trouble.  Consequently, a called method would have to first ensure the array was large enough that the pointer arithmetic to validate its arguments won't itself go out of bounds, and then do some pointer calculations to validate the arguments.  The time spent in such validation would likely exceed the cost spent doing any real work.  Further, the method could likely be more efficient if it was written and called:

```<code>void ClearTwoElements(int arr[], int index)
{
  arr[index-2] = 0;
  arr[index+2] = 0;
}
void blah(void)
{
  static int foo[10] = {1,2,3,4,5,6,7,8,9,10};
  ClearTwoElements(foo,2);
  ClearTwoElements(foo,7);
  ClearTwoElements(foo,1);
  ClearTwoElements(foo,8);
}
</code>```

The concept of a type which combines something to identify an object with something to identify a piece thereof is a good one.  A C-style pointer is faster, however, if it's not necessary to perform validation.

Body:
The biggest problem with having arrays tagged with their length is not so much the space required to store that length, nor the question of how it should be stored (using one extra byte for short arrays generally wouldn't be objectionable, nor would using four extra bytes for long arrays, but using four bytes even for short arrays might be).  A much bigger problem is that given code like:

void ClearTwoElements(int *ptr)
{
  ptr[-2] = 0;
  ptr[2] = 0;
}
void blah(void)
{
  static int foo[10] = {1,2,3,4,5,6,7,8,9,10};
  ClearTwoElements(foo+2);
  ClearTwoElements(foo+7);
  ClearTwoElements(foo+1);
  ClearTwoElements(foo+8);
}

the only way that code would be able to accept the first call to ClearTwoElements but reject the second would be for the ClearTwoElements method to receive information sufficient to know that in each case it was receiving a reference to part of the array foo in addition to knowing which part.  That would typically double the cost of passing pointer parameters.  Further, if each array was preceded by a pointer to an address just past the end (the most efficient format for validation), optimized code for ClearTwoElements would likely become something like:

void ClearTwoElements(int *ptr)
{
  int* array_end = ARRAY_END(ptr);
  if ((array_end - ARRAY_BASE(ptr)) < 10 ||
      (ARRAY_BASE(ptr)+4) <= ADDRESS(ptr) ||
      (array_end - 4) < ADDRESS(ptr)))
    trap();
  *(ADDRESS(ptr) - 4) = 0;
  *(ADDRESS(ptr) + 4) = 0;
}

Note that a method caller could, in general, perfectly legitimately pass a pointer to the start of the array or the last element to a method; only if the method tries to access elements which go outside passed-in array would such pointers cause any trouble.  Consequently, a called method would have to first ensure the array was large enough that the pointer arithmetic to validate its arguments won't itself go out of bounds, and then do some pointer calculations to validate the arguments.  The time spent in such validation would likely exceed the cost spent doing any real work.  Further, the method could likely be more efficient if it was written and called:

void ClearTwoElements(int arr[], int index)
{
  arr[index-2] = 0;
  arr[index+2] = 0;
}
void blah(void)
{
  static int foo[10] = {1,2,3,4,5,6,7,8,9,10};
  ClearTwoElements(foo,2);
  ClearTwoElements(foo,7);
  ClearTwoElements(foo,1);
  ClearTwoElements(foo,8);
}

The concept of a type which combines something to identify an object with something to identify a piece thereof is a good one.  A C-style pointer is faster, however, if it's not necessary to perform validation.


问:
Where do utility libraries fit in a layered architecture?
Consider this mock-up of a software stack designed with layered architecture in mind :

Every application layer is decoupled through API calls, but a memory handling library is used throughout. All layers need to copy, allocate or somehow affect memory.

Is this bad use of the layered architecture pattern, or is it one of its pitfall ? On one hand, trying to force the pattern upon the library calls, perhaps by adding memory handling wrappers to every application layers, would create a lot of boilerplate code. On the other hand, letting layers, through library calls, create arbitrary entry points into different layers seems to contradict the very rationale behind layered architecture.

答: Layered Architecture speaks to the flow of business-related data between layers.  It has nothing to say about utility libraries; every layer can potentially access a given utility library, just like you have done.


问:
What does "mockable" mean?
I came across this term when looking into PHP's "traits" (which are apparently bad, since, among things, they're not mockable), but I can't really find a definition for this "mockability". It might be related to polymorphism? There isn't even a Wikipedia entry I could find!</p>

答:
In order for something to be called mockable, you must be able to replace its implementation with another implementation within the context of a unit test, without affecting the code used during normal runtime.  This is used to make the testing easier, by not pulling in a ton of dependencies or performing resource-intensive operations.

There are a number of fallacies in that article.  First of all, when you use a trait, you should think of it as copying and pasting the trait's code into your class.  The trait's code becomes part of the class, and therefore part of the unit you are testing.  The complaint that traits aren't mockable is a little ridiculous.  It's like complaining that base classes aren't mockable.

If a trait doesn't make sense as part of the unit, it shouldn't be a trait.  You should use another means to share the functionality, like  inheritance or composition.  Like any other language feature, there are good and bad situations in which to use traits.

Second, traits are mockable, although not as easily.  You should generally avoid it, just like you would generally avoid mocking any other method of the class you're testing.  For example:

trait MyTrait {
    public function traitFunction() {
        expensiveDatabaseCall();
    }
}

class MyClass {
    use MyTrait;
}
```

<p>To mock the trait, use something like the following in your unit test:</p>

<pre class="lang-php prettyprint-override"><code>trait MockTrait {
    public function traitFunction() {
        echo "don't have to make a database call";
    }
}

class TestMyClass extends MyClass {
    use MockTrait;
}
</code>```

This is a variant of the "subclass and override" technique Michael Feathers details in his book Working Effectively with Legacy Code.

Again, the technique is not the first choice for unit testing, but it will do in a pinch.  The preference would be to mock expensiveDatabaseCall().

Mock objects are usually passed in as an argument to a constructor or a method.  You can't pass a trait as an argument, which I suspect is why the author of that article called them not mockable, but it's far from the case that traits prevent you from effectively unit testing a class, even if you don't mock them.

In fact, using traits properly can simplify your code, making it easier to unit test.  They reduce boilerplate and reduce the "plumbing" code that only exists to connect up other classes that do the real work.

Title: What does "mockable" mean?

Body:
In order for something to be called mockable, you must be able to replace its implementation with another implementation within the context of a unit test, without affecting the code used during normal runtime.  This is used to make the testing easier, by not pulling in a ton of dependencies or performing resource-intensive operations.

There are a number of fallacies in that article.  First of all, when you use a trait, you should think of it as copying and pasting the trait's code into your class.  The trait's code becomes part of the class, and therefore part of the unit you are testing.  The complaint that traits aren't mockable is a little ridiculous.  It's like complaining that base classes aren't mockable.

If a trait doesn't make sense as part of the unit, it shouldn't be a trait.  You should use another means to share the functionality, like  inheritance or composition.  Like any other language feature, there are good and bad situations in which to use traits.

Second, traits are mockable, although not as easily.  You should generally avoid it, just like you would generally avoid mocking any other method of the class you're testing.  For example:

trait MyTrait {
    public function traitFunction() {
        expensiveDatabaseCall();
    }
}

class MyClass {
    use MyTrait;
}

To mock the trait, use something like the following in your unit test:

trait MockTrait {
    public function traitFunction() {
        echo "don't have to make a database call";
    }
}

class TestMyClass extends MyClass {
    use MockTrait;
}

This is a variant of the "subclass and override" technique Michael Feathers details in his book Working Effectively with Legacy Code.

Again, the technique is not the first choice for unit testing, but it will do in a pinch.  The preference would be to mock expensiveDatabaseCall().

Mock objects are usually passed in as an argument to a constructor or a method.  You can't pass a trait as an argument, which I suspect is why the author of that article called them not mockable, but it's far from the case that traits prevent you from effectively unit testing a class, even if you don't mock them.

In fact, using traits properly can simplify your code, making it easier to unit test.  They reduce boilerplate and reduce the "plumbing" code that only exists to connect up other classes that do the real work.


答:
You can find people writing books more or less alone on this subject (alongside concepts like "stub", "spy", "fake" or "dummy"). Puritans (pardon the possible insult to some people here) will argue on the suttle differences between e.g. mocks and stubs (see e.g. Martin Fowlers exellent article http://martinfowler.com/articles/mocksArentStubs.html).

My 5 cents would argue that a mock is an object mimicking the behaviour of a dependent object of the object being tested. You can make the mock return expected values or you can check that certain attributes / properties or methods are being called as part of the test. Being mockable then, somehow infers having substitutuable behaviour, either through an interface or otherwise. This enables the mock object to record and replace the behaviour.

I've come to find that for my (.NET) testing purposes a library like NSubstitute (http://nsubstitute.github.io/) is just right. One of the driving ideas is (quote): "Mock, stub, fake, spy, test double? Strict or loose? Nah, just substitute for the type you need!"

Title: What does "mockable" mean?

Body: I came across this term when looking into PHP's "traits" (which are apparently bad, since, among things, they're not mockable), but I can't really find a definition for this "mockability". It might be related to polymorphism? There isn't even a Wikipedia entry I could find!</p>


问:
How can robots beat CAPTCHAs?
I have a website e-mail form. I use a custom CAPTCHA to prevent spam from robots. Despite this, I still get spam.

Why? How do robots beat the CAPTCHA? Do they use some kind of advanced OCR or just get the solution from where it is stored?

How can I prevent this? Should I change to another type of CAPTCHA?

I am sure the e-mails are coming from the form, because it is sent from my email-sender that serves the form messages. Also the letter style is the same.

 For the record, I am using PHP + MySQL, but I'm not searching for a solution to this problem. I was interested in the general situation how the robots beat these technologies. I just told this situation as an example, so you can understand better what I'm asking about.

答: Have you ever tried using cat-dog captcha? I have a forum that had standard captcha and changed it and I have no guest spams since.

Title: How can robots beat CAPTCHAs?


答:
A lot of this had to do with the computers available at the time.  Not only did the compiled program have to run on a limited resource computer, but, perhaps more importantly, the compiler itself had to run on these machines.  At the time Thompson developed C, he was using a PDP-7, with 8k of RAM.  Complex language features that didn't have an immediate analog on the actual machine code were simply not included in the language.

A careful read through the history of C yields more understanding into the above, but it wasn't entirely a result of the machine limitations they had:

Moreover, the language (C) shows considerable power to describe important concepts, for example, vectors whose length varies at run time, with only a few basic rules and conventions. ... It is interesting to compare C's approach with that of two nearly contemporaneous languages, Algol 68 and Pascal [Jensen 74]. Arrays in Algol 68 either have fixed bounds, or are `flexible:' considerable mechanism is required both in the language definition, and in compilers, to accommodate flexible arrays (and not all compilers fully implement them.) Original Pascal had only fixed-sized arrays and strings, and this proved confining [Kernighan 81].

C arrays are inherently more powerful.  Adding bounds to them restricts what the programmer can use them for.  Such restrictions may be useful for programmers, but necessarily are also limiting.


问:
how do you manage api keys?
I have a few projects that use various webservices e.g. DropBox, AWS. For managing private information I use bash_profile which works great with heroku that uses env variables to manages secret informations. The problem is my bash_profile is growing significantly (HEROKU_ADD_ON_1 HEROKU_ADD_ON_2 etc.) and it bit me today.

What's the better way?

答:
If you are using ruby or a ruby based framework, you could look at using a project such as dotenv which allows you to manage these environment variables inside of a single .env file (which you need to git ignore) within your code repository instead of using your system wide files.

If you like the way it handles it for local development, there is a sister project that handles it for production or staging environments also.

Title: how do you manage api keys?


答: In C, any contiguous subset of an array is also an array and can be operated on as such. This applies both to read and write operations. This property would not hold if the size was stored explicitly.</p>


答:
The problem of the extra storage is an issue, but in my opinion a minor one.  After all, most of the time you are going to need to track the length anyway, although amon made a good point that it can often be tracked statically.

A bigger problem is where to store the length and how long to make it.  There isn't one place that works in all situations.  You might say just store the length in the memory just before the data.  What if the array isn't pointing to memory, but something like a UART buffer?

Leaving the length out allows the programmer to create his own abstractions for the appropriate situation, and there are plenty of ready made libraries available for the general purpose case.  The real question is why aren't those abstractions being used in security-sensitive applications?


问:
Getting coders to do code review
I am running a project where I pay developers to contribute to my semi open source project. My problem is that it is easy to hire developers, but it is very difficult to get anyone to do code reviewing. I have repeatedly attempted to get the senior developers to review the code of the junior developers. I have attempted to pay them more, give them higher status etc. But they just seem to want to code instead of reviewing code.

Now I am considering forcing all developers that want to code, to also review code, but I have a feeling that it is a bad idea.

My question is, therefore, how can I motivate capable people to review the code of others? How is this done in successful open source projects like Linux, PostgreSQL, LibreOffice etc.

答:
Getting coders to do code review

This is a cultural problem, and you're currently in a state of equilibrium because they're used to not having to give or receive criticism of their work. To change the culture from the top-down, you need to lead, direct, and enforce, as necessary, to maintain it as a cultural habit.

I suggest you start off by scheduling the review, asking your best coders to walk you through their code, with the other offering feedback. If you think there's too much speculation or unproductive interaction, get it back on track. If small issues are identified that can be fixed on the spot, have it done on the spot. Take notes and ask questions that demonstrate you're doing your best to follow along. Keep track of issues that are emphatically known to need addressing, i.e. technical debt, and have them devote time to specifically addressing the technical debt issues.

You might begin with an entire architectural overview, and then on a weekly or even daily basis begin to dig in to each module they've written. I recommend starting with your best coders and then working your way through to your more junior developers so that they don't feel as threatened having seen others accept criticism, even though they might get quite a bit more criticism.

The only way you'll get change at this point is to take ownership of the problem and lead the change.

Title: Getting coders to do code review


答:
I've typically managed all kinds of project secrets via configuration files (often environment-specific) and then never commit these to source control. The format of these files can be whatever you want / whatever works well: xml, yaml, json, etc. Then the code is responsible for reading the values out of the config file.

Sometimes it is annoying that these values aren't in source control (makes deployment a little more difficult, for example), but it sounds like you are managing the values separately anyway, so that shouldn't add much overhead.

Edit:
I'm not very familiar with Heroku, so I just answered the question generally. But after looking into it more, I can see where this could be a pain to manage.

It sounds like you already manage the config vars via the bash_profile -- that's good because you'll want to have a "source of record" document where you can look at and change these values.

Beyond that, it sounds like naming is going to be the next most important thing. HEROKU_ADD_ON_1 isn't very descriptive. But DROPBOX_API_KEY or AWS_S3_BUCKET_KEY give a better idea of what the variable is. And you can distinguish between keys from the same provider through good naming too: FEATURE_A_AWS_KEY vs FEATURE_B_AWS_KEY.

Title: how do you manage api keys?

Body:
I have a few projects that use various webservices e.g. DropBox, AWS. For managing private information I use bash_profile which works great with heroku that uses env variables to manages secret informations. The problem is my bash_profile is growing significantly (HEROKU_ADD_ON_1 HEROKU_ADD_ON_2 etc.) and it bit me today.

What's the better way?


答:
I am guessing you have already decided that doing code reviews is a necessary task if you are willing to pay senior developers more for it.

Most developers (in my jr developer experience) would rather develop something new, rather than look back over code that they, or somebody else, have already done. That being said, there are extra points that need to happen or it will make the task especially undesirable.

Coding Standards. There should be some kind of standards on how code is generally displayed so everyone isn't doing it differently, everywhere. Better coding standards, if followed, will mean quicker and less painful reviews. It also gives the code reviewers a reason to tell a developer why it needs to be redone without saying, "I don't like how you did that," which nobody likes to hear or say.

Code Reviews should have an impact. After a code review, the results should be acted on rather soon. There is no point to doing the review if nothing changes anyway. Likewise, the developer who created the code needs to know why their code had to change, or they may just keep doing the same thing in the future and the code reviewer will get tired of repeatedly fixing the same thing.

Keep it fair. Like any undesirable task, the same person will not want to do code review all the time. If somebody gets stuck doing it most of the time, everyone else will try to push it onto that person, either actively or just by not volunteering. You will need to set up "turns", or if you only have a a few people you trust to do the review, have everyone go through the code at the same time together. That will establish what your coding standards are and get the newer developers comfortable in doing the code reviews.

In conclusion, code review often seems like a pain to everyone involved. It should not be an assigned task to a single person / couple people. Only by sharing the pain, acting on the outcome, and getting the newer developers to learn from their mistakes can everybody come out ahead.

Title: Getting coders to do code review


问:
How to annotate method signature changes?
I'm developing a mini framework and I want to perform changes to existing methods. I know in order to deprecate a method I can use the @deprecated annotation. However, what annotation should I use to let the users know that I'm going to change the amount of parameters a method will receive or maybe the returned result?

I'd like to know what annotations to use in PHP.

答:
Assuming you're using versioning, you should make a note of breaking changes in the changelog when it occurs, and announce the breaking change a version ahead of time (or a couple versions ahead of time depending on how widely your project is used). If all you're doing is expanding an existing function signature and can get away with having the new parameters being optional then you don't need to announce this, but might still want to consider putting it in the changelog.

To put it plainly, function signatures can't be deprecated in PHP. You can deprecate an entire function, but not a signature, since PHP functions only have one signature.

Perhaps keep the old method and have the new signature in a function with a transitional name, like "foo()" and "_future_foo()" and wait for the next-next version to replace the old one with the new one. This might complicate things, so it would be best to do what the PHP devs do and just announce the breaking change a version (or two) ahead of time.

If you find yourself changing a function signature and its return type completely, consider instead making a new function and leaving the old one alone, but mark the old one as deprecated. For that, yes, you would use @deprecated


问:
Finding all subsets of a set running time
Given a set {1,2,3} output { {}, {1}, {2}, {3}, {1,2}, {1,3}, {2,3}, {1,2,3} }
I have only been able to find as fast as O(2^n), is there any techniques for achieving faster results (besides parallelizing)</p>

答:
No.

Since there are 2^n subsets for a set with n items in it, and you have to print them all, your algorithm MUST perform the print step 2^n times (even if you tried to combine all the prints into one you would still have to "generate" the opening and closing braces 2^n times).

In fact we can look at something even lower level than printing an entire subset and determine that each particular item in the set will be printed exactly (2^n)/2 times. There are 2^n subsets and each item is in exactly half of them. This operation is even lower level than printing an entire set and we can see that it is O(2^n)


问:
Aren't decorators easily breaking the ISP?
"The Interface-Segregation Principle (ISP) states that no client should be forced to depend on methods it does not use."

The decorator pattern is a design pattern to decorate a method of a class. For this, the decorator implements the same interface as the decorated object, so it can take its place.

But doesn't this mean that it has to implement all of the methods in the interface, when it uses only one of them, the one it decorates? So I guess it violates the ISP. The only case it doesn't it is when the decorated interface only contains the method that needs to be decorated, but I see it as a rather rare case.

An example would be that there are pages in a book. Some pages have footnotes, other pages have titles at the top. So we implement these extras as decorators of a method, let's say draw(). But a page has other methods as well, let's say: fold() and tear() and other methods can come in later. But if we want to use decorated versions of pages inserted in a book, and working the same way, we end up implementing in every decorator every method of a page, where the only thing happening is that the decorator passes the call to the page it's containing.

```<code>interface IPage {
    public ITearResult tear();
    public void draw();
}

class FooterDecorator implements IPage {
    private IPage page;

    public FooterDecorator(IPage page) {
        this.page = page; //the object it decorates
    }

    //violates the ISP, because it has to implement it, but it's not using it,
    //just passes the operation
    public ITearResult tear() {
        return page.tear();
    }

    //decorated method
    public void draw() {
        page.draw();
        ... draw footer - the decoration
    }
}
</code>```

Am I not understanding the decorator pattern or the ISP correctly? Is it an acceptable violation or do these two really contradict each other?

答:
You may be missing a layer of abstraction in your decorator implementation.  Consider the following alternative:

```<code>interface IPage {
public ITearResult tear();
public void draw();
}

abstract class PageBaseDecorator implements IPage {
    protected IPage page;

    public PageBaseDecorator(IPage page) {
        this.page = page; //the object it decorates
    }

    public ITearResult tear() {
        return page.tear(); // delegate implementation to object
    }

    public void draw() {
        page.draw(); // delegate implementation to object
    }
}

class FooterDecorator extends PageBaseDecorator {

    public FooterDecorator(IPage page) {
        super(page);
    }

    // tear does not need to be implemented as it exists in PageBaseDecorator
    // and is not used by FooterDecorator

    //decorated method
    public void draw() {
        super.draw();
        ... draw footer - the decoration
    }
}
</code>```

I'm not up on my Java programming so I'm not certain if the syntax above is correct, but it should give you an idea of what you might be missing in the decorator pattern. The Base Decorator is not violating ISP because it depends on the entire interface it is delegating to. The children of the Base Decorator should only need to implement the pieces they actively decorate though.

Body:
You may be missing a layer of abstraction in your decorator implementation.  Consider the following alternative:

interface IPage {
public ITearResult tear();
public void draw();
}

abstract class PageBaseDecorator implements IPage {
    protected IPage page;

    public PageBaseDecorator(IPage page) {
        this.page = page; //the object it decorates
    }

    public ITearResult tear() {
        return page.tear(); // delegate implementation to object
    }

    public void draw() {
        page.draw(); // delegate implementation to object
    }
}

class FooterDecorator extends PageBaseDecorator {

    public FooterDecorator(IPage page) {
        super(page);
    }

    // tear does not need to be implemented as it exists in PageBaseDecorator
    // and is not used by FooterDecorator

    //decorated method
    public void draw() {
        super.draw();
        ... draw footer - the decoration
    }
}

I'm not up on my Java programming so I'm not certain if the syntax above is correct, but it should give you an idea of what you might be missing in the decorator pattern. The Base Decorator is not violating ISP because it depends on the entire interface it is delegating to. The children of the Base Decorator should only need to implement the pieces they actively decorate though.


问:
Implementing Syncing between localStorage and SQL database?
I have made a simple web app, which runs completely offline - all data is saved in HTML5's localStorage. Now, I want the data to get synced with the server, so that the user is able to use the app on multiple devices at a time.

What I have done so far is:

For each operation the user performs, a log entry is added.

When the user is online, all logs are transferred from localStorage to PHP through AJAX.

Corresponding changes are made in the SQL Database.

All logs are deleted from the localStorage.

So, all the localStorage data is getting "backed up" on the server properly.

Anyhow, changes made from one device is not being reflected to the other device and vice-versa, to do this, we would have to get some data from SQL to the localStorage.

Now, my question is as to what will be the appropriate and best way to do this?

After the four steps above, do I

Clear all localStorage data and save the SQL data into localStorage.

Keep a log of changes made in the database, and do them on the localStorage.

Any other approach.

Also, what about timestamps? What if there are conflicts?

答:
It will depend on who is considered the "master" in your application, the client device or the server? If it's the client, you'll want to do a combination of #1 and #2: Push up any writes to the server, then pull down any changes made on the server side. If the server is master, do the opposite.

As for conflicts, you might want to look at how CouchDB handles that. It keeps both copies and marks them as conflicted for the application level to sort out. How you handle them is pretty highly dependent on what you're storing and what your business rules are.


答:
I used to work at a publishing, rather than software company, but the principle is the same.

In the publishing company, the road to management (and higher paying jobs) was editing/reviewing the work of other, more junior, professionals. A few people were content to remain senior writers, with no editing/reviewing responsibilities, but "most" (more than half) of the competent people wanted these review/editing jobs. NOT having one of those jobs was something of a stigma, because it was "career limiting," so most "juniors" tried to advance to editing as soon as possible.

Title: Getting coders to do code review


问:
Should classes that define settings and application configuration follow SOLID?
I'm just wondering if you have an application where you define a class that defines some user configurable settings (from an xml file, or a GUI), should you design it so that it follows SOLID as much as possible like the rest of the application?

More specifically, how do you change the available settings without violating the Open Closed Principle?

Because I'm having trouble picturing this.  I can see the addition of settings you can extend the class, but with the removal of settings, or change of a setting there would be no way to modify the configuration class so that it follows SOLID. Or is it possible somehow?

I can also imagine trickle down effect from those settings changes, that require classes that depend on them to be modified as well.

答:
I think the problem that you are experiencing is not with the Open / Closed principle, but more so with the Interface Segregation Principle.

If you treat configuration as a dependency of the classes that use it, you would want that configuration interface to have method / properties that have high cohesion.  Therefore a new configuration variable would have a relatively small impact on the system.

Having such an interface allows you to do do unit-testing for different configurations, and allow you to change how those configuration values are derived without significant changes to your application (store in database instead of xml).

```<code>public interface IBlogConfiguration
{
    public int GetNumberOfPostsPerPage();
}

public interface ICommentsConfiguration
{
    public bool AreCommentsAllowed();
    public bool CanCommentsBeNested();
}

public class WebConfigConfiguration : IBlogConfiguration, ICommentsConfiguration
{
    // implementation of both those interfaces
}
</code>```

Body:
I think the problem that you are experiencing is not with the Open / Closed principle, but more so with the Interface Segregation Principle.

If you treat configuration as a dependency of the classes that use it, you would want that configuration interface to have method / properties that have high cohesion.  Therefore a new configuration variable would have a relatively small impact on the system.

Having such an interface allows you to do do unit-testing for different configurations, and allow you to change how those configuration values are derived without significant changes to your application (store in database instead of xml).

public interface IBlogConfiguration
{
    public int GetNumberOfPostsPerPage();
}

public interface ICommentsConfiguration
{
    public bool AreCommentsAllowed();
    public bool CanCommentsBeNested();
}

public class WebConfigConfiguration : IBlogConfiguration, ICommentsConfiguration
{
    // implementation of both those interfaces
}


问:
Organizing uncommented, dirty code?
I would like to ask you some questions about dirty code. There are some beginners who coded on a medium project. The code is a very huge ball of mud. They are not advanced programmers. They just know how to use keyboard an a little about java. They just wrote code with 12 000 lines in their main class, though, 6 000 lines belongs to NetBeans itself.

My job is to analyze the code and suggest a good way to maintain the code. My idea is to scrap the project and start a new one with OOP methodology. Recently I collected some notes and ideas about the problem, from this site and some others.

Now, I have the followings questions:

Should we repair the code, and change it to a OOP? We are now debugging it.

The code has no comments, no documentation, no particular style of programming, and so forth. Changing it is really expensive and time consuming. What do we can do about this?

How can I teach them to follow all the rules (commenting, OOP, good code quality, etc.)?

The code is erroneous and error prone. What can we do? Testing? We almost write two or three A4 papers for correction, but it seems endless.

I should have to say that I am new with them. I think I have broken the rules about adding people too late to the project, as well. Do you think I have to leave them?

答: If it works, refactor it. There are tools to help you do that. If it doesn't work, use the magical code improvement command, i.e. deltree on Windows resp. rm -rf on Linux.

Title: Organizing uncommented, dirty code?


问:
How Byte loading/storing is implemented By the CPU?
I know that in 32bit machine, cpu read from memory 32bits at a time. since the registers in this case is 32bit in size too, I can understand how this works.

What I don't understand is how the cpu implement load instructions of 1 byte. does it load the whole word where the single byte is located to the register, then perform some kind of "byte shifting", or does the cpu can load a single byte, in this case when does the byte masking happen, is it until the byte got loaded in the register, or it happen when byte is send through the data bus ?

P.S. The cpu Im using is MIPS, the instructions Im talking about are: lb or lbu

答:
CPU can read single byte, but not only that one byte. In broader term, the byte might not be in memory yet, so a page needed to be loaded, update memory map and a store a chunk in cache (cache is in CPU too), then it can be loaded.

If you need less than a word, sign extension might be performed as mentioned in MIPS instruction set. The cpu loads the machine word (32bit) and depending on the instruction it'll either perform sign extension or nullify the uninteresting bytes. So, it's not simply "byte shifting". Operations are done on register, so after it's loaded.