问:
Is this modified BSD license compatible with GPL?
I am working on open source project, that uses the source code from FlatAssembler project, which uses following license, based on BSD 2-clause with one additional clause added at the end of the text.

So, the questions are:

What this additional clause changes?

Is it legal to use this code and to license my project under GNU GPL? (The original BSD 2-clause license is compatible with GPL, but this one seems to be not.)

flat assembler  version 1.71 Copyright (c) 1999-2012, Tomasz Grysztar.
  All rights reserved.

This program is free for commercial and non-commercial use as long as
  the following conditions are adhered to.

Copyright remains Tomasz Grysztar, and as such any Copyright notices
  in the code are not to be removed.

Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are
  met:

Redistributions of source code must retain the above copyright notice,    this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright    notice, this list of conditions and the following disclaimer in the

  documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The licence and distribution terms for any publically available
  version or derivative of this code cannot be changed. i.e. this code
  cannot simply be copied and put under another distribution licence
  (including the GNU Public Licence).

答:
I received an official answer, provided by CITnet JIRA for FUNCTIONAL SUPPORT Joinup:

The clause that makes this specific “BSD-like” licence becoming
  “copyleft-like” is:

“The licence and distribution terms for any publically available version or
  derivative of this code cannot be changed. i.e. this code cannot simply be
  copied and put under another distribution licence (including the GNU Public
  Licence).”

However, the copyleft character is explicitly limited to the source code
  (as it is the case in a weak or moderated copyleft licence like the LGPL or
  the MPL). There is no pretention for “virality” regarding the merged object
  code.

Therefore, as long the source files of your own code and the source file of
  “FlatAssembler” are independent and separated in different directories, you
  can distribute the whole project compiled together in one executable file
  (that is product of the both sets of source files), and you are authorised
  to license it as follows:

“This project < XXX > (source and binaries) is copyrighted < Your name, Year >
  under the EUPL, at the exception of specific source code files where other
  specific copyright licensing mentions exist.”

So, in this case, this should be the proper answer, given by an lawyer.


问:
When to import names into the global namespace? (using x::y, from x import y etc.)
I've been programming in various languages for about 10 years now. And I still haven't figured out when it is a good idea to import something into the global namespace (using x::y in C++, from x import y in Python etc.), so I hardly ever do it.

It almost always seems like a bad idea to me, if only because it limits the set of variable names I can use. For example: Where I to use using namespace std; or using std::string;in C++, I couldn't use stringas a variable name anymore, which I occasionally do (e.g. for string utility functions).

But I'm wondering: Are there some situations where importing a name into the global namespace really makes sense? Any rules of thumb?

答:
Working in Python, I use from x import y (as z) constantly, to have clear, concise names to reference imports.

From imports are invaluable in a codebase with a deep namespace hierarchy.  This is especially so when the style standard for the codebase is PEP 8, which limits line length to under 80 characters.

For example, consider:

```<code>import foo

foo.bar.baz.baf.perform_task(foo.bar.baz.quux.SOME_CONSTANT, foo.bar.alice.bob.preferred_hash_function, '42', foo.bar.magic_numbers.MY_SALT)
</code>```

Which could instead be written:

```<code>from foo.bar import baf
from foo.bar.alice import bob
from foo.bar.baz.quux import SOME_CONSTANT
from foo.bar.magic_numbers import MY_SALT

baf.perform_task(SOME_CONSTANT, bob.preferred_hash_function, '42', MY_SALT)
</code>```

Since Python identifiers are case-sensitive and unlimited in length, we won't run out of names regardless of how many we import.

If we want to use the same name in our module as one of the modules we wish to import, we can use an alias for the import:

```<code>from foo.bar.alice import bob as carol

def bob(x, y):
    print "running bob function"
    return carol(x, y, 42)
</code>```

ContentLicense: CC BY-SA 3.0

Body:
Working in Python, I use from x import y (as z) constantly, to have clear, concise names to reference imports.

From imports are invaluable in a codebase with a deep namespace hierarchy.  This is especially so when the style standard for the codebase is PEP 8, which limits line length to under 80 characters.

For example, consider:

import foo

foo.bar.baz.baf.perform_task(foo.bar.baz.quux.SOME_CONSTANT, foo.bar.alice.bob.preferred_hash_function, '42', foo.bar.magic_numbers.MY_SALT)

Which could instead be written:

from foo.bar import baf
from foo.bar.alice import bob
from foo.bar.baz.quux import SOME_CONSTANT
from foo.bar.magic_numbers import MY_SALT

baf.perform_task(SOME_CONSTANT, bob.preferred_hash_function, '42', MY_SALT)

Since Python identifiers are case-sensitive and unlimited in length, we won't run out of names regardless of how many we import.

If we want to use the same name in our module as one of the modules we wish to import, we can use an alias for the import:

from foo.bar.alice import bob as carol

def bob(x, y):
    print "running bob function"
    return carol(x, y, 42)


问:
How do I learn algorithms and data structures?
This is in continuation to my previous question where I asked is it necessary to learn algorithms and data structures. I feel yes it is.

Now I work in an environment where I won't ever get the chance to learn it by experimenting or practically or in any assignment. What is the right approach like the right books, right kind of problems, right kind of resources that I can go through to give six months or a year or two to learn algorithms and data structures?  And also mold my mind in a way that it can relate problems to data structures and algorithms.

答:
Read.

No, really, read.

Read everything about algorithm and design you can possible find.  There are phenomenal books out there.  The Sedgewick algorithm books are good.  The Algorithm Design Manual by Skiena is good as well.  Together these books follow me on every bookshelf at every job I go to, along with The Mythical Man-Month.

Then ask.

Talk to people you respect.  Ask them what decision points they had and why they made the decisions they did.  The good ones will always be able to tell you "I chose to do X because it's better than A, B in these ways.  I could have gone with C, but I felt this was a better choice because of this".

Next, do.

Build stuff.  Build stuff that you'll never use.  Build stuff that you'll never need.  Go write a program that solves a Sudoku puzzle.  Now go do it again.  And again.  Build it 5 completely different ways.  Build a program that generates Sudoku puzzles and feed it into the solvers.  Find which solver is fastest.  And then...

Find out why.

The "what" is almost never important.  I mean, yeah, it is critical to finishing the project at hand, but at the end if you know the "what" without knowing the "why", then you might as well never done it in the first place.  You got a bullet point on your resume.  Go get a cookie and congratulate yourself.  The "why" is so much more important than the "what".

And for the record Sudoku was an example.  I spent a lot of free time going through that exercise with a ton of the logic puzzles on Kongregate and learned a lot on the way.

http://www.amazon.com/Bundle-Algorithms-Parts-1-5-Fundamentals/dp/020172684X/
http://www.amazon.com/Algorithm-Design-Manual-Steven-Skiena/dp/1848000693/
http://www.amazon.com/Mythical-Man-Month-Software-Engineering-Anniversary/dp/0201835959/


问:
Why do code generators always use fully-qualified identifiers?
When you look at the code for the Winforms Designer, you see things like this:

```<code>this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", ... etc.
</code>```

instead of

```<code>using System.Drawing;
label1.Font = new Font("Microsoft Sans Serif", ... etc.
</code>```

The same is true of tools like Linq to XSD, XSD2Code and, I suspect, of Linq to SQL.  These tools generate hoards of code with extremely long fully-qualified names.

Wouldn't it be easier to generate the appropriate using statements, and ditch the long names?  Or is there some technical reason for this that I'm missing?

Note: For those folks that are baffled by the notion that I might want these classes to actually be readable by a human, note that this is exactly my goal.  I have an XSD with about 300 classes in it, I don't want to write them all by hand, and yes, I'd like them to look like ordinary code written by humans.

答: If you created or imported another library that also defined Font, then without full qualification the generated code would have an error. </p>


问:
Java Generics - how to strike a balance between expressiveness and simplicity
I'm developing some code that utilizes generics, and one of my guiding principles was to make it usable for future scenarios, and not just today's. However, several coworkers have expressed that I may have traded off readability for the sake of extensibility. I wanted to gather some feedback about possible ways to resolve this.

To be specific, here is an interface that defines a transform - you start with a source collection of items, and you apply the transform to each element, storing the results in a destination collection. Additionally, I want to be able to return the destination collection to the caller, and rather than forcing them to use a Collection reference, I want them to be able to use whatever collection type they actually provided for the destination collection.

Finally, I make it possible for the type of items in the destination collection to be different from the type of items in the source collection, because maybe that's what the transform does. In my code, for instance, several source items make up one destination item after the transform.

This yields the following interface:

```<code>interface Transform<Src, Dst> {
    <DstColl extends Collection<? super Dst>> DstColl transform(
                Collection<? extends Src> sourceCollection,
                DstColl                   destinationCollection);
}
</code>```

I tried to be all nice and apply Josh Bloch's PECS principle (producer extends, consumer super) to make sure the interface is usable with super- and sub-types where appropriate. The end result is somewhat of a monstrosity.

Now, it would have been nice if I could extend this interface and specialize it somehow. For example, if I don't really care about playing nice with subtypes of the source items and supertypes of the destination items, I could have:

```<code>interface SimpleTransform<Src, Dst> {
    <DstColl extends Collection<Dst>> DstColl transform(
                  Collection<Src> sourceCollection,
                  DstColl         destinationCollection);
}
</code>```

But there is no way to do that in Java. I want to make implementations of this interface something that others would actually consider doing, as opposed to running in fear. I've considered several options:

Don't return the destination collection. Seems weird given that you do a transform but get nothing back.

Have an abstract class that implements this interface, but then translates the parameters to something easier to use and calls another method "translateImpl()" which has the simpler signature and thus presents less of a cognitive burden for implementers. But then it's weird to have to write an abstract class just to make an interface user-friendly.

Forgo extensibility and just have the simpler interface. Possibly couple that with not returning the destination collection. But then that limits my options in the future.

What do you think? Am I missing an approach I could use?

答: Guava Collections already provides this functionality and if you can hold off a little longer, Java 8 will provide this also :-). FWIW I think your use of ? extends T is the correct idiom, not much you can do given that Java uses Type Erasure


答:
Code generators are usually designed to create machine readable code more than human readable code.  Humans are expected to mostly work with the original format used as input to the generator.  using statements enhance human readability, but computers don't care.

Try going through the exercise of writing a simple code generator as you describe, and you'll see why they use the fully-qualified names.  Usually you make some sort of abstract syntax tree based on the original input format, then you walk the tree to generate the code.  Using using statements would require keeping an extra "registry" of using statements you want to use, checking it for duplicates, then going back to insert them at the top of the file.  That's worth it if it's required, like say an include statement, but it's a lot more trouble than it's worth for something with an easy enough workaround.

Title: Why do code generators always use fully-qualified identifiers?

Body:
When you look at the code for the Winforms Designer, you see things like this:

```<code>this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", ... etc.
</code>```

instead of

```<code>using System.Drawing;
label1.Font = new Font("Microsoft Sans Serif", ... etc.
</code>```

The same is true of tools like Linq to XSD, XSD2Code and, I suspect, of Linq to SQL.  These tools generate hoards of code with extremely long fully-qualified names.

Wouldn't it be easier to generate the appropriate using statements, and ditch the long names?  Or is there some technical reason for this that I'm missing?

Note: For those folks that are baffled by the notion that I might want these classes to actually be readable by a human, note that this is exactly my goal.  I have an XSD with about 300 classes in it, I don't want to write them all by hand, and yes, I'd like them to look like ordinary code written by humans.


答:
Short names and usings are useful for humanly written code, because:

developers prefer writing var defaultFont = new Font(...) versus var defaultFont = new System.Drawing.Font(...),

other developers prefer readable code, not something with long variable names and fully qualified types.

That's why usings were invented in a first place. We could specify fully qualified types, but it would severely reduce code qualify.

Wouldn't it be easier to ditch the long names in generated code? Not really; in fact, it doesn't matter. When the code is generating other code, it makes no difference between type.Name and type.FullName. By using the full names, the code generator doesn't need to prepend the usings, making the generator easier to develop.

I noticed that you commented the answer by Karl Bielefeldt, writing:

That's great if you can treat the generated code as a black box, and never have to modify it. That's not always the case.

Code generators are never designed to generate clean code which would be read and modified by humans. In general, you shouldn't modify generated code, because either you lose the ability to use the generator again, or all your modifications will be lost the next time you call the generator. Case when you do need to modify generated code by hand are rare, and it's understandable that people writing code generators don't take those scenarios into account.

If code generators were written for humans, they would have generated code:

With a few more comments,

Properly indented,

Conform to style guidelines (see yourself how many StyleCop warnings are caused by generated code for a simple Windows Forms class),

With clean names which don't start with @ character,

Unit tested for regression testing.

This would make the code much more readable, but would also introduce potential bugs and more code to write in support when developing a code generator.


问:
Is it plausible to use a filesystem-based configuration format rather than an INI file?
After having had endless issues with INI-style configuration files and parsing them correctly (let along getting binary data right), a crazy idea crossed my mind recently:

What if an INI file like

```<code># settings.ini
[Windows]
DirectorySeparator='\\'
PathSeparator=';'

[Linux]
DirectorySeparator='/'
PathSeparator=':'
</code>```

Would rather be stored in the file system; each group is a directory, each key/value pair is a file, so

```<code>settings/Windows/DirectorySeparator (contains just `\`)
settings/Windows/PathSeparator      (contains just ';')
... you get the idea ...
</code>```

Disadvantages:

Possibly slow due to IO work, but maybe file system caches help?

Running low of inodes on some file systems?

Group/Key names may only consists of characters which are also valid for directory/filenames, may be rather restrictive depending on the FS.

Advantages:

Arbitrarily deeply nested groups

No worries about escaping, binary data is easy. Just have each file contain the raw data.

Automatic locking, access control and whatever the filesystem provides

Easy to access with most programming languages, even by hand

I'm very tempted to try this in my next project, I wonder whether anybody else has experience with this approach already?

答:
That would be super obnoxious. You:

Wouldn't be able to see them all at once

Wouldn't be able to place comments explaining why things are set the way they are

Wouldn't be able to have documentation on what commands do, or what possible options are right in the configuration

It would make backing up/version controlling your configs more obnoxious.

Using a library to store and read stuff in XML (ugh) or JSON or INI files is so easy there is no excuse to come up with other stuff.

Filesystems are meant to store and organize files. Don't abuse it and come up with a half-baked configuration alternative when there are plenty of configuration libraries available.


答:
You could always try something like this: http://codekata.pragprog.com/

I always learned better by thinking it out as opposed to reading.  However, you should have documentation/reading material available to look for answers.

Title: How do I learn algorithms and data structures?

Body:
This is in continuation to my previous question where I asked is it necessary to learn algorithms and data structures. I feel yes it is.

Now I work in an environment where I won't ever get the chance to learn it by experimenting or practically or in any assignment. What is the right approach like the right books, right kind of problems, right kind of resources that I can go through to give six months or a year or two to learn algorithms and data structures?  And also mold my mind in a way that it can relate problems to data structures and algorithms.

ContentLicense: CC BY-SA 2.5


问:
Is this an implementation of the promise pattern?
I am writing a library in C++ (making use of many C++11 features) that (as far as I can tell) implements the promise pattern.

The library consists of a class that makes asynchronous network requests. When a user of this class invokes a method that issues a network request, an instance of another class (we'll call it the "promise class") is returned that provides methods for canceling the request.

Since this application uses the Qt framework, the promise class also emits signals when certain events happen, one of which is the successful completion of the request. Because the result of the network request is often included when the signal is emitted, I feel that this class implements the promise pattern.

According to the Wikipedia article:

"In computer science, future, promise, and delay refer to constructs used for synchronizing in some concurrent programming languages. They describe an object that acts as a proxy for a result that is initially unknown, usually because the computation of its value is yet incomplete."

* emphasis mine

Have I missed anything? Does my class indeed implement the promise pattern?

答:
I think you have implemented it. Design patterns necessarily have somewhat generous definitions, as they need to work in a variety of application contexts.

Note: If your particular context is a homework problem and you are gathering evidence to challenge an unfavorable grade, well, that's between your and your professor. :) Out in industry, clean, functional code carries a lot more weight than compliance with narrow pattern definitions.


答:
Code generators explicitly declare the classes they are using to prevent unexpected behaviour from naming conflicts.

If a project includes a class with the same name as a class in another namespace, it introduces ambiguity.  Where there's ambiguity, the compiler defaults to the local namespace.  Consider this:

```<code>using System.Drawing;

namespace MyProject {
    class MyClass {
        void InitialiseComponent() {
            this.label1.Font = new Font("Microsoft Sans Serif", ...);
        }
    }
}
</code>```

This works fine as it is.  But what if we add a new Font class to the project?

```<code>namespace MyProject {
    class Font : System.Drawing.Font {
        public Font(string fontName, ...) { ... }
    }
}
</code>```

Now we have System.Drawing.Font and MyProject.Font.  The code in MyProject.MyClass.InitialiseComponent() still compiles and runs.  But which version of Font does it use?

The compiler defaults to the local namespace of MyProject.MyClass and uses MyProject.Font, even though using System.Drawing is defined.

Is this what the programmer wanted?  It's not the IDE's job to guess that.  The programmer should explicitly state whether they want to use their implementation of Font or System.Drawing.Font.

Within a single project, the IDE could detect this change and alter all code generated files to clarify which Font to use.  But what if the project isn't currently loaded?  How can the IDE know which files require future maintenance?  Start by being specific and there's never ambiguity.

Body:
Code generators explicitly declare the classes they are using to prevent unexpected behaviour from naming conflicts.

If a project includes a class with the same name as a class in another namespace, it introduces ambiguity.  Where there's ambiguity, the compiler defaults to the local namespace.  Consider this:

using System.Drawing;

namespace MyProject {
    class MyClass {
        void InitialiseComponent() {
            this.label1.Font = new Font("Microsoft Sans Serif", ...);
        }
    }
}

This works fine as it is.  But what if we add a new Font class to the project?

namespace MyProject {
    class Font : System.Drawing.Font {
        public Font(string fontName, ...) { ... }
    }
}

Now we have System.Drawing.Font and MyProject.Font.  The code in MyProject.MyClass.InitialiseComponent() still compiles and runs.  But which version of Font does it use?

The compiler defaults to the local namespace of MyProject.MyClass and uses MyProject.Font, even though using System.Drawing is defined.

Is this what the programmer wanted?  It's not the IDE's job to guess that.  The programmer should explicitly state whether they want to use their implementation of Font or System.Drawing.Font.

Within a single project, the IDE could detect this change and alter all code generated files to clarify which Font to use.  But what if the project isn't currently loaded?  How can the IDE know which files require future maintenance?  Start by being specific and there's never ambiguity.


问:
Is it considered poor practice to include a bug number in a method name for a temporary workaround?
My coworker who is a senior guy is blocking me on a code review because he wants me to name a method 'PerformSqlClient216147Workaround' because it's a workaround for some defect ###. Now, my method name proposal is something like PerformRightExpressionCast which tends to describe what the method actually does. His arguments go along the line of: "Well this method is used only as a workaround for this case, and nowhere else."

Would including the bug number inside of the method name for a temporary workaround be considered bad practice?

答:
There's value in your coworker's suggestion; it provides traceability by associating changes to the code with the reason, documented in the bug database under that ticket number, why the change was made.

However it also suggests that the only reason that function exists is to work around the bug. That, if the problem were not an issue, you would not want the software to do that thing. Presumably you do want the software to do its thing, so the name of the function should explain what it does and why the problem domain requires that be done; not why the bug database needs it. The solution should look like part of the application, not like a band-aid.


答:
So it's a temporary solution? Then use the name suggested by the reviewer, but mark the method as obsolete, so that using it would generate a warning every time somebody is compiling the code.

If it's not, you may always tell that 216147 makes no sense in code, since the code is not linked to the bug tracking system (it's rather the bug tracking system which is linked to the source control). The source code is not a good place for references to bug tickets and versions, and if you really need to put those references there, do it in the comments.

Note that even in comments, the bug number alone is not very valuable. Imagine the following comment:

public IEnumerable<Report> FindReportsByDateOnly(DateTime date)
{
    // The following method replaces FindReportByDate, because of the bug 8247 in the
    // reporting system.
    var dateOnly = new DateTime(date.Year, date.Month, date.Day);
    return this.FindReportByDate(dateOnly);
}

private IEnumerable<Report> FindReportsByDate(DateTime date)
{
    Contract.Requires(date.Hour == 0);
    Contract.Requires(date.Minute == 0);
    Contract.Requires(date.Second == 0);

    // TODO: Do the actual work.
}
```

<p>Imagine that the code was written ten years ago, that you've just joined the project, and that when you asked where could you find any information about the bug 8247, your colleagues told that there was a list of bugs on the website of the reporting system software, but the website was redone five years ago, and the new list of bugs has different numbers.</p>

<p>Conclusion: you have no idea what this bug is about.</p>

<p>The same code could have been written in a slightly different way:</p>

<pre class="lang-cs prettyprint-override"><code>public IEnumerable<Report> FindReportsByDateOnly(DateTime date)
{
    // The reporting system we actually use is buggy when it comes to searching for a report
    // when the DateTime contains not only a date, but also a time.
    // For example, if looking for reports from `new DateTime(2011, 6, 9)` (June 9th, 2011)
    // gives three reports, searching for reports from `new DateTime(2011, 6, 9, 8, 32, 0)`
    // (June 9th, 2011, 8:32 AM) would always return an empty set (instead of isolating the
    // date part, or at least be kind and throw an exception).
    // See also: http://example.com/support/reporting-software/bug/8247
    var dateOnly = new DateTime(date.Year, date.Month, date.Day);
    return this.FindReportsByDate(dateOnly);
}

private IEnumerable<Report> FindReportsByDate(DateTime date)
{
    Contract.Requires(date.Hour == 0);
    Contract.Requires(date.Minute == 0);
    Contract.Requires(date.Second == 0);

    // TODO: Do the actual work.
}
</code>```

Now you get a clear view of the issue. Even if it appears that the hypertext link at the end of the comment is dead five years ago, it doesn't matter, since you can still understand why FindReportsByDate was replaced by FindReportsByDateOnly.

Title: Is it considered poor practice to include a bug number in a method name for a temporary workaround?

Body:
My coworker who is a senior guy is blocking me on a code review because he wants me to name a method 'PerformSqlClient216147Workaround' because it's a workaround for some defect ###. Now, my method name proposal is something like PerformRightExpressionCast which tends to describe what the method actually does. His arguments go along the line of: "Well this method is used only as a workaround for this case, and nowhere else."

Would including the bug number inside of the method name for a temporary workaround be considered bad practice?

Body:
So it's a temporary solution? Then use the name suggested by the reviewer, but mark the method as obsolete, so that using it would generate a warning every time somebody is compiling the code.

If it's not, you may always tell that 216147 makes no sense in code, since the code is not linked to the bug tracking system (it's rather the bug tracking system which is linked to the source control). The source code is not a good place for references to bug tickets and versions, and if you really need to put those references there, do it in the comments.

Note that even in comments, the bug number alone is not very valuable. Imagine the following comment:

public IEnumerable<Report> FindReportsByDateOnly(DateTime date)
{
    // The following method replaces FindReportByDate, because of the bug 8247 in the
    // reporting system.
    var dateOnly = new DateTime(date.Year, date.Month, date.Day);
    return this.FindReportByDate(dateOnly);
}

private IEnumerable<Report> FindReportsByDate(DateTime date)
{
    Contract.Requires(date.Hour == 0);
    Contract.Requires(date.Minute == 0);
    Contract.Requires(date.Second == 0);

    // TODO: Do the actual work.
}

Imagine that the code was written ten years ago, that you've just joined the project, and that when you asked where could you find any information about the bug 8247, your colleagues told that there was a list of bugs on the website of the reporting system software, but the website was redone five years ago, and the new list of bugs has different numbers.

Conclusion: you have no idea what this bug is about.

The same code could have been written in a slightly different way:

public IEnumerable<Report> FindReportsByDateOnly(DateTime date)
{
    // The reporting system we actually use is buggy when it comes to searching for a report
    // when the DateTime contains not only a date, but also a time.
    // For example, if looking for reports from `new DateTime(2011, 6, 9)` (June 9th, 2011)
    // gives three reports, searching for reports from `new DateTime(2011, 6, 9, 8, 32, 0)`
    // (June 9th, 2011, 8:32 AM) would always return an empty set (instead of isolating the
    // date part, or at least be kind and throw an exception).
    // See also: http://example.com/support/reporting-software/bug/8247
    var dateOnly = new DateTime(date.Year, date.Month, date.Day);
    return this.FindReportsByDate(dateOnly);
}

private IEnumerable<Report> FindReportsByDate(DateTime date)
{
    Contract.Requires(date.Hour == 0);
    Contract.Requires(date.Minute == 0);
    Contract.Requires(date.Second == 0);

    // TODO: Do the actual work.
}

Now you get a clear view of the issue. Even if it appears that the hypertext link at the end of the comment is dead five years ago, it doesn't matter, since you can still understand why FindReportsByDate was replaced by FindReportsByDateOnly.


答:
The major goals of a programmer should be working code, and, clarity of expression.

Naming a workaround method (....Workaround). Would seem to achieve this goal. Hopefully at some stage the underlying problem will be fixed and the workaround method removed.


答:
I would not name the method as your co-worker suggested. The method name should indicate what the method does. A name like PerformSqlClient216147Workaround does not indicate what it does. If anything, use comments that describe the method to mention that it is a workaround. This could look like the following:

```<code>/**
 * Cast given right-hand SQL expression.
 *
 * Note: This is a workaround for an SQL client defect (#216147).
 */
public void CastRightExpression(SqlExpression rightExpression)
{
    ...
}
</code>```

I agree with MainMa that bug/defect numbers should not appear in the source code itself but rather in the source control comments as this is meta-data, but it's not terrible if they appear in the source code comments. Bug/defect numbers should never be used in the names of methods.

Body:
I would not name the method as your co-worker suggested. The method name should indicate what the method does. A name like PerformSqlClient216147Workaround does not indicate what it does. If anything, use comments that describe the method to mention that it is a workaround. This could look like the following:

/**
 * Cast given right-hand SQL expression.
 *
 * Note: This is a workaround for an SQL client defect (#216147).
 */
public void CastRightExpression(SqlExpression rightExpression)
{
    ...
}

I agree with MainMa that bug/defect numbers should not appear in the source code itself but rather in the source control comments as this is meta-data, but it's not terrible if they appear in the source code comments. Bug/defect numbers should never be used in the names of methods.


问:
Management wants an API in purchased software
My company wants to purchase new software for our General Ledger.  We want to be able to interface it with various other sytems, all purchased.  Nothing is custom built.  The software our Accountants like does not have any APIs.  However it does allow for imports and exports through various file formats.

The imports (which are most import to us) can be triggered by an import file being placed in a folder.  A "steering committee" that is involved in this purchasing decision is made up of people who are not either IT people or programmers.  They're lawyers, a chief executives, a compliance officer and a few others in similar roles.  They are fixated on this software having an API, or APIs, I don't which is more proper.

It seems to me that with the import and export functionality we can do what we need to do.  Since we don't write our own software we couldn't code to an API.  But, I don't have enough experience to really know what an API might offer that the software in question couldn't deliver.  I chair the steering committee and would like us not to get side tracked by something that I suspect is irrelevant.  Can anyone help me to understand what I might be missing, or rather how an API would be advantageous?

答:
Trained Software Engineer in a debate/discussion/argument with Lawyers, Accountants and CEO's - you will lose, no doubt about it! The only way out for you is to have appropriate levels of CYA documentation....

Seriously - you cannot use facts and numbers against this emotional attachment to an idea/ideal. If they have read an magazine saying "It must have an API", then they will say "We need an API", and will not be happy without one. They will have absolutely no idea what one is - this is your biggest asset, use it.

What I would do (before / apart from giving up and writing a stack of CYA emails), is discuss the file import/export as an API, and always use the word "API" when discussing it. This will move the focus onto functional requirements and how it can achieve what needs to be done, and away from the "I must have an API" dance.


答:
In addition to an excellent answer provided by @whatsisname:

It won't be possible to make two elements of the same name;

It won't be possible to share the config;

It won't be possible to make custom order of elements;

Different file systems have different limitations as per file names. They also have reserved names, like CON or NUL for Windows;

Also, file systems may be case-sensitive or not.

I completely concur with the idea of using a ready-made library for working with configuration files.

Regarding your concern of storing large chunks of binary data, most database-driven config libraries provide with that feature. If chosen a library that doesn't, using a file/directory reference plus individual binary files seems to be the best idea.

Title: Is it plausible to use a filesystem-based configuration format rather than an INI file?

Body:
After having had endless issues with INI-style configuration files and parsing them correctly (let along getting binary data right), a crazy idea crossed my mind recently:

What if an INI file like

```<code># settings.ini
[Windows]
DirectorySeparator='\\'
PathSeparator=';'

[Linux]
DirectorySeparator='/'
PathSeparator=':'
</code>```

Would rather be stored in the file system; each group is a directory, each key/value pair is a file, so

```<code>settings/Windows/DirectorySeparator (contains just `\`)
settings/Windows/PathSeparator      (contains just ';')
... you get the idea ...
</code>```

Disadvantages:

Possibly slow due to IO work, but maybe file system caches help?

Running low of inodes on some file systems?

Group/Key names may only consists of characters which are also valid for directory/filenames, may be rather restrictive depending on the FS.

Advantages:

Arbitrarily deeply nested groups

No worries about escaping, binary data is easy. Just have each file contain the raw data.

Automatic locking, access control and whatever the filesystem provides

Easy to access with most programming languages, even by hand

I'm very tempted to try this in my next project, I wonder whether anybody else has experience with this approach already?


答:
Nothing is more permanent than a temporary fix that works.

Does his suggestion look good in 10 years time? It used to be common practice to comment each change with the defect it fixed. More recently (like the last 3 decades), this style commenting is widely accepted as reducing code maintainability - and that is with mere comments, not method names.

What he is proposing is compelling evidence your QC and QA systems are significantly deficient. Tracking of defects and defect fixes belongs in the defect tracking system, not the source code. Tracing of the source code changes belongs in the source control system. Cross referencing between these systems allows tracing of defects to source code.....

The source code is there for today, not yesterday, and not tomorrow (as in, you don't type into source what to are planing to do next year)...


答:
I find PerformSqlClient216147Workaround more informative then PerformRightExpressionCast. There is no doubt at all in the name of the function as to what it does, why it does it or how to get more information about it. It's an explicit function that will be super easy to search in the source code.

With a bug tracking systems that number uniquely identifies the issue, and when you pull up that bug in the system it provides all the details you need. This is a very smart thing to do in the source code, and will save future developers time when trying to understand why a change was made.

If you see a lot of these function names if your source code, then the problem isn't your naming convention. The problem is you have buggy software.


答:
I think that both you and he have gotten this whole thing out of proportion.

I agree with your technical argument, but at the end of the day it won't make that much difference, especially if this is a temporary fix that can be removed from the codebase in a few days / weeks / months.

I think you should put your ego back into its box, and just let him have his own way.  (If he was listening too, I'd say that you guys need to compromise.  Both egos back in their boxes.)

Either way, you and he have better things to do.


答:
This is a perfectly fine way of representing tree-shaped data. A file system is a tree database, why re-implement one on top of it?

The most well-known implementation of this idea is the Windows Registry. Its main flaw is that it implements a filesystem alongside the filesystem and doesn't support the filesystem API, which means you can't use filesystem tools such as find or grep on it.

Elektra is a project which implements a global configuration key-value database similar to the Windows Registry in a portable manner. It uses a storage format very similar to the one you describe.

The Linux sysfs virtual filesystem which is used to both expose data about the kernel object graph and change settings also uses a "one-value-per-file" format and uses symlinks extensively to represent graph-shaped data.

The Gatling web server even uses filesystem metadata for configuration. Here's how you configure two virtual hosts:

```<code>mkdir www.example.com:80
mkdir internal.example.com:8080
</code>```

Here's how you configure a redirect:

```<code>ln -s http://www.google.com/mail gmail
</code>```

Here's how you tell Gatling that a file is a server side script, i.e. that it should be executed and not served:

```<code>chmod +x script
</code>```

Here's how you tell Gatling to serve or not serve a file:

```<code>chmod o+r serve_this
chmod o-r dont_serve_that
</code>```

Gatling appears to have been inspired by qmail.

Body:
This is a perfectly fine way of representing tree-shaped data. A file system is a tree database, why re-implement one on top of it?

The most well-known implementation of this idea is the Windows Registry. Its main flaw is that it implements a filesystem alongside the filesystem and doesn't support the filesystem API, which means you can't use filesystem tools such as find or grep on it.

Elektra is a project which implements a global configuration key-value database similar to the Windows Registry in a portable manner. It uses a storage format very similar to the one you describe.

The Linux sysfs virtual filesystem which is used to both expose data about the kernel object graph and change settings also uses a "one-value-per-file" format and uses symlinks extensively to represent graph-shaped data.

The Gatling web server even uses filesystem metadata for configuration. Here's how you configure two virtual hosts:

mkdir www.example.com:80
mkdir internal.example.com:8080

Here's how you configure a redirect:

ln -s http://www.google.com/mail gmail

Here's how you tell Gatling that a file is a server side script, i.e. that it should be executed and not served:

chmod +x script

Here's how you tell Gatling to serve or not serve a file:

chmod o+r serve_this
chmod o-r dont_serve_that

Gatling appears to have been inspired by qmail.


问:
Why Was Python Written with the GIL?
The global interpreter lock (GIL) seems to be often cited as a major reason why threading and the like is a touch tricky in Python - which raises the question "Why was that done in the first place?"

Being Not A Programmer, I've got no clue why that might be - what was the logic behind putting in the GIL?

答:
First off: Python doesn't have a GIL. Python is a programming language. A programming language is a set of abstract mathematical rules and restrictions. There is nothing in the Python Language Specification which says that there must be a GIL.

There are many different implementations of Python. Some have a GIL, some don't.

One simple explanation for having a GIL is that writing concurrent code is hard. By placing a giant lock around your code, you force it to always run serially. Problem solved!

In CPython, in particular, one important goal is to make it easy to extend the interpreter with plugins written in C. Again, writing concurrent code is hard, so by guaranteeing that there will be no concurrency, it makes it easier to write extensions for the interpreter. Plus, many of those extensions are just thin wrappers around existing libraries which may not have been written with concurrency in mind.

Title: Why Was Python Written with the GIL?


答:
This has in fact been done. For example, qmail control files are individual files that contain a single line with the configuration setting.

The fact that this is not a very popular method of configuration is supported by reasons given in other answers to this question.


答:
There are several implementations of Python, for example, CPython, IronPython, RPython, etc.

Some of them have a GIL, some don't. For example, CPython has the GIL:

From http://en.wikipedia.org/wiki/Global_Interpreter_Lock

Applications written in programming languages with a GIL can be designed to use separate processes to achieve full parallelism, as each process has its own interpreter and in turn has its own GIL.

Benefits of the GIL

Increased speed of single-threaded programs.

Easy integration of C libraries that usually are not thread-safe.

Why Python (CPython and others) uses the GIL

From http://wiki.python.org/moin/GlobalInterpreterLock

In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython's memory management is not thread-safe.

The GIL is controversial because it prevents multithreaded CPython programs from taking full advantage of multiprocessor systems in certain situations. Note that potentially blocking or long-running operations, such as I/O, image processing, and NumPy number crunching, happen outside the GIL. Therefore it is only in multithreaded programs that spend a lot of time inside the GIL, interpreting CPython bytecode, that the GIL becomes a bottleneck.

From http://www.grouplens.org/node/244

Python has a GIL as opposed to fine-grained locking for several reasons:

It is faster in the single-threaded case.

It is faster in the multi-threaded case for i/o bound programs.

It is faster in the multi-threaded case for cpu-bound programs that do their compute-intensive work in C libraries.

It makes C extensions easier to write: there will be no switch of Python threads except where you allow it to happen (i.e. between the Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS macros).

It makes wrapping C libraries easier. You don't have to worry about thread-safety. If the library is not thread-safe, you simply keep the GIL locked while you call it.

The GIL can be released by C extensions. Python's standard library releases the GIL around each blocking i/o call. Thus the GIL has no consequence for performance of i/o bound servers. You can thus create networking servers in Python using processes (fork), threads or asynchronous i/o, and the GIL will not get in your way.

Numerical libraries in C or Fortran can similarly be called with the GIL released. While your C extension is waiting for an FFT to complete, the interpreter will be executing other Python threads. A GIL is thus easier and faster than fine-grained locking in this case as well. This constitutes the bulk of numerical work. The NumPy extension releases the GIL whenever possible.

Threads are usually a bad way to write most server programs. If the load is low, forking is easier. If the load is high, asynchronous i/o and event-driven programming (e.g. using Python's Twisted framework) is better. The only excuse for using threads is the lack of os.fork on Windows.

The GIL is a problem if, and only if, you are doing CPU-intensive work in pure Python. Here you can get cleaner design using processes and message-passing (e.g. mpi4py). There is also a 'processing' module in Python cheese shop, that gives processes the same interface as threads (i.e. replace threading.Thread with processing.Process).

Threads can be used to maintain responsiveness of a GUI regardless of the GIL. If the GIL impairs your performance (cf. the discussion above), you can let your thread spawn a process and wait for it to finish.

Title: Why Was Python Written with the GIL?

Body:
The global interpreter lock (GIL) seems to be often cited as a major reason why threading and the like is a touch tricky in Python - which raises the question "Why was that done in the first place?"

Being Not A Programmer, I've got no clue why that might be - what was the logic behind putting in the GIL?


问:
What are some things you have read that inspired and guided you as a programmer?
For example, being a beginner, I find a lot of inspiration and direction from reading this post by Bryan Woods.</p>

答: I know it's a hard read, but Knuth's The Art of Computer Programming is a Really Big Deal in our field.  And Douglas Hofstadter's Gödel, Escher, Bach: An Eternal Golden Braid is inspirational for those of us with a mathematical or algorithmic bent.


问:
Is it called an instance in Javascript?
Say I have a function.

```<code>function foo(){
    //do stuff
}
</code>```

And then I create an object of that function.

```<code>var fooObj = new foo();
</code>```

What is fooObj called? An instance, An object instance, or something else entirely? Pardon the newbie question, but I am rather new to prototype based programming(and all programming really).

答:
fooObj is an object and it is also an instance of the foo prototype.

Though javascript doesn't technically have classes, many would also call fooObj an object of the foo class because it works somewhat similarly to classes in other languages.

Title: Is it called an instance in Javascript?


问:
Keeping tech support on the latest software version
I'm the only software developer maintaining a subset of products at a small company. The main product I'm concerned with here is a web app which is installed on various clients' machines, with a database and background processes.

I make changes on a need-to basis for this program. It's not the company's flagship product, it's not my main project, but it needs maintenance. I have 2 and a half support technicians who take in questions from customers. When they don't know how to fix things, I'm their support.

Because I do some maintenance here and there, I release updates irregularly. However, the idea is that I'm fixing the software, and on a client's request, the support technicians can update said software to fix an issue or as good measure (there's no built-in update function). The support technicians also keep a copy on their machine, or rather, various copies of past versions. This is where it gets ugly.

I get, irregularly, reports of bugs for things I might have already fixed on previous versions. When they find a bug, the support techs spend a lot of time going backwards in versions, trying to get to a version where the bug isn't there. At this point they either throw it in my face ("Why did you break this?") or install older versions at the clients'. Which can obviously break other things.

In order to resolve this I've:

pleaded with them

pleaded with their supervisor

pleaded with the CEO

refused to work on older versions until new versions are installed, even if they demonstrate the bug is still present

threatened to remove support altogether (which is moot, since it's still my job)

No dice.

The last option I see is to setup something with SVN where they can only get the latest version and not revert (if that's doable)... And hope they don't learn to make copies.

Is there some other approach, human, organizational, technical, or otherwise that can help me and keep these guys on the latest version?

答:
If updates are paid or if newer versions break old functionality, there is nothing you can do. Customers will have older versions, and so the support technicians, so those technicians will continue to search for an older version where some bug wasn't here and push it to the customers' machines.

Otherwise, work on the auto-update process:

Updates should be pushed to customers and technicians automatically as they are released, so everyone will use the latest version at every moment,

Technicians shouldn't be able to install older version neither on the customers', nor on their own machines,

The user agreement should explicitly specify that the technical support is provided for the latest version only,

Whenever the customer is contacting the support, the first thing the support people should do is to verify that the customer has the latest version.

Note that the user agreement point is important: even if technically, you does everything possible to push the latest version and even if it's free, there would still be some customers who will find themselves with an older one, either because they are not connected to the internet, or because they blocked automatic updates. The support people should understand that and take in account that and convince/help the customers to get the latest software.


问:
Services or Shared Libraries?
I work in an environment where we have several different web applications, where each of them have different features but still need to do similar things: authentication, read from common data sources, store common data, etc.

Is it better to build the shared functionality into a set of services, to be called by the web apps, or is it better to make a shared library, which the webapps include?

The services or libraries would need to access various databases, and it seems like keeping that access in a single place (service) is a good idea.  It would also reduce the number of database connections needed.  A service would also keep the logic in a single place, but then it could be argued that a shared library can do the same thing.  Are there other benefits to be gained from using services over shared libraries?

答:
Library Advantages:

Native code = higher performance

Simplest thing that could possibly work

No risk of centralized service going down and impacting all consumers

Service Advantages:

Everyone gets upgrades immediately and transparently (unless versioned API offerred)

Consumers cannot decompile the code

Can scale service hardware separately

Technology agnostic. With a shared library, consumers must utilize a compatible technology.

More secure. The UI tier can call the service which sits behind a firewall instead of directly accessing the DB.

Title: Services or Shared Libraries?


问:
Why use services (REST/SOAP) instead of a library?
Let's say you're looking at breaking up your applications into services.  Are there any good reasons to adopt a SOA approach vs. just creating a library API that can be loaded by the applications that need it.</p>

答:
Library Advantages:

Lower overhead per call (only jump or even inlined) = may increase performance

Simplest thing that could possibly work

No risk of centralized service going down and impacting all consumers

Service Advantages:

Everyone gets upgrades immediately and transparently (unless versioned API offerred)

Consumers cannot decompile the code

Can scale service hardware separately

Technology agnostic. With a shared library, consumers must utilize a compatible technology.

More secure. The UI tier can call the service which sits behind a firewall instead of directly accessing the DB.


答:
What is the purpose of a GIL?

The CAPI documentation has this to say on the subject:

The Python interpreter is not fully thread-safe. In order to support multi-threaded Python programs, there’s a global lock, called the global interpreter lock or GIL, that must be held by the current thread before it can safely access Python objects. Without the lock, even the simplest operations could cause problems in a multi-threaded program: for example, when two threads simultaneously increment the reference count of the same object, the reference count could end up being incremented only once instead of twice.

In other words, the GIL is prevents corruption of state. Python programs should never produce a segmentation fault, because only memory safe operations are permitted. The GIL extends this assurance to multi-threaded programs.

What are the alternatives?

If the purpose of the GIL is to protect state from corruption, then one obvious alternative is lock at a much finer grain; perhaps at a per object level. The problem with this is that although it has been demonstrated to increase the performance of multi-threaded programs, it has more overhead and single-threaded programs suffer as a result.

Title: Why Was Python Written with the GIL?


问:
What should junior developer expect from their senior team lead
Disclaimer: Opinions expressed are solely my own and do not express the views or opinions of my employer.

I work for a small company, in which few people are  developers, others are QA/Test and 1 is a Manager. I joined this company 1.5 years ago. 3 senior developers have 8+ years of experience.

These are the observations which I made about the team lead. (considering me as a fresher with less experience compared to them in all aspects )

They never discuss 1:1 or they never consider the junior suggestion (I agree that it's up to them, whether they accept it or not, at least they should consider an opinion).

As senior team leader they can try to refactor the codebase with new technologies ( including the factor of rolling out new technologies is possible and other developer and infrastructure also ready), but these team leader feel less in-secure to work with new technologies, as they are not up to date. (reason I am telling, they don't know what current programming trend, *(such as popular open source projects like modernizr, bootstrap and many others).

In our codebase more than 10000+ lines are repeated, so I told them  about DRY: Don't Repeat yourself.  Their reply was : "It is a fascinating article, but never works in practice".  I just told them if we do not make it 100% DRY, we can at least use interfaces, but that also was not considered. *(interfaces can be added for new features, not touching the previous codebase, if they are not ready to refactor)

All senior developers do maintenance and hot fixing of patches. The rest of the time they just spend on entertainment sites. They are just happy to finish the task.

Introducing new technology is bad? *(including factor of feasibility can be done).

Manager also least concerned about the things which I am talking about.

Junior expects they can learn many things from team lead. *(not by asking help or senior coding for them).

My questions are:

Am I too aggressive about the changes which I am proposing?

What should I expect from senior dev leads who have 8+ years experience?

Am I wrong to expect to learn and gain experience from a company?

Update :

Why they feel DRY is impractical: because they don't want get involved with OOP concepts. They are happy with repeating tasks.

New technologies I am proposing:

Usage of Minification of CSS, JS, SPrite images

Usage of Interfaces and .net framework 4, generics and many others.

Client side libraries such as modernizr, knockout js, bootstrap for responsive,

答:
If somebody is working as programmer for +8 years, it doesn't mean he is a good programmer. What makes good programmer serior programmer in my opinion?
It is will to share not just experiences, but also to learn new thinks, techniques, technologies, etc. It is will to get better all the time and improve. Many so called "senior" programmers are stacked in old patterns of funcitonal programming from long gone languages. Something like new concepts and ideas are just not for them, because they don't need it. They got their "experience".

Will to improve and learn is far more important than years of experiences. Junior developer who wants to learn is far more better for any company then old "senior" developer who already "knows" it all.


答:
First, you should try to see it from their point of view: if there is a serious bug, and the support technicians can fix this by going back to a previous version in 1 to 2 hours, the customer has a solution for his actual problem. Debugging and fixing the real bug cause may need 1 to 2 days (when you have enough time), but may also take 1 or 2 weeks (perhaps you have other, more important duties, perhaps you are on vacation etc) - do you really expect the customer or technicians to wait so long?

So, what can you do to improve the situation? Here are some suggestions:

write a detailed changelog, but not what you write into your SVN log, but from the users point-of-view, what visible behaviour did you change from version to version, which bugs did you fix. Make this changelog easily available for your technicians and your customers. So when your technicians install an older version, they and the customer should know exactly which older bugs they are going to introduce, which features won't work any more and so on. That gives them a better basis to decide if going to an older version is really worth the hassle.

Avoid producing newer versions containing bugs which were not there in older versions. Seriously! I know sometimes this seems to be impossible, but if this situation shows up regularly, your QA has to be improved. Perhaps your technicians should take some QA duties, so when they ask you "why did you break this" you can answer "didn't you test that thorougly?". Additionally, automated regression testing can help a lot - at least it can save you from introducing the same bug again after you fixed it once.

If your application depends on a certain version of the database, make sure it checks that version number somewhere and refuses to work if the database does not fit to the application. Same advice for third-party components your application depends on and for which your app expects a specfic version to be installed. This makes sure your technicians cannot mix up components which don't fit together. The IMHO better option, however, is to make your application upwards compatible to some degree, so an older version of the application does run without flaws against a newer version of the database (you might differentiate between minor and major releases). For example, when you have to change the database scheme, do only add optional (nullable) columns (at least, between minor releases). That way, installing an older version of your application (hopefully) won't cause any hard technical problems, except the ones described in your changelog.

So instead of complaining about the installation of older versions, make this work to some degree, within clearly defined limits. That does not mean that you have to maintain that older versions - if a bug pops up, let the technicians install an older version as a workaround if they think it will solve the situation. Meanwhile fix the bug in the newest version (and only there), and make sure that (after a test phase) the technicians don't forget to deliver that version to the customer.

Title: Keeping tech support on the latest software version

Body:
I'm the only software developer maintaining a subset of products at a small company. The main product I'm concerned with here is a web app which is installed on various clients' machines, with a database and background processes.

I make changes on a need-to basis for this program. It's not the company's flagship product, it's not my main project, but it needs maintenance. I have 2 and a half support technicians who take in questions from customers. When they don't know how to fix things, I'm their support.

Because I do some maintenance here and there, I release updates irregularly. However, the idea is that I'm fixing the software, and on a client's request, the support technicians can update said software to fix an issue or as good measure (there's no built-in update function). The support technicians also keep a copy on their machine, or rather, various copies of past versions. This is where it gets ugly.

I get, irregularly, reports of bugs for things I might have already fixed on previous versions. When they find a bug, the support techs spend a lot of time going backwards in versions, trying to get to a version where the bug isn't there. At this point they either throw it in my face ("Why did you break this?") or install older versions at the clients'. Which can obviously break other things.

In order to resolve this I've:

pleaded with them

pleaded with their supervisor

pleaded with the CEO

refused to work on older versions until new versions are installed, even if they demonstrate the bug is still present

threatened to remove support altogether (which is moot, since it's still my job)

No dice.

The last option I see is to setup something with SVN where they can only get the latest version and not revert (if that's doable)... And hope they don't learn to make copies.

Is there some other approach, human, organizational, technical, or otherwise that can help me and keep these guys on the latest version?


答:
API = Standardisation (to a much larger extent than text files)

Having spent a couple of years developing an application that a particular client wanted to interact with MYOB I would seriously recommend a GL with API.

Text file import/ export is an horrendous way to run a company.

(IF) you ever need any customisation of the product/module the first thing any developer is going to do is build some kind of API if you dont already have one. Then 6 months later, she is unfortunately killed in a car accident... and you need some more customisation. So the next developer looks at the scratch of an API started by the first and then modifies/appends to that for the purpose at hand... and so on.. and before long you have a frankenstein on your hands.... because as you say you dont develop in house and whose to say any of these developers are experts in the GL module anyway. So they start creating their own API's according to what they think is the GL module, not neccessarily  what it actually is.

Whereas a product with a prebuilt API is straight form the horses mouth. The people who built the GL module are saying this is how you should interact with our product programmatically. Then you can go out and get a developer who actually already knows the API.... from that last job they did. i.e. they dont have to learn your company's frankenstein first.

Also with a pre built API, add on modules/upgrades etc from 3rd party vendors become more feasible. Again because the GL's API is standardised and known outside of your company and therefore represents a market opportunity to hungry developers.

Security: With an API you can more securely communicate with your GL. It's much harder to hack a systems process memory to mess with GL API based imports/exports, than it is to open and modify a bunch of text files sitting in some folder on the file system.

Your argument seems to be we dont need programmatic access to the product and we never will, well good luck with that. ;)

If you've recently under taken a full strategic review of how IT is used in your company and can honestly say they you will never need to modify either how you get data into your GL and how you shape data coming out of your GL then go ahead and by pass the requirement for a new GL module to have an API.

That said the future is the great unknown. I personally would NEVER recommend a GL module without an API.... simply because I know whats out there.... and no accounting package that I'd be looking at for our customers (SME's) going forward is without an API.... especially given the uptake on cloud computing.

Title: Management wants an API in purchased software

Body:
My company wants to purchase new software for our General Ledger.  We want to be able to interface it with various other sytems, all purchased.  Nothing is custom built.  The software our Accountants like does not have any APIs.  However it does allow for imports and exports through various file formats.

The imports (which are most import to us) can be triggered by an import file being placed in a folder.  A "steering committee" that is involved in this purchasing decision is made up of people who are not either IT people or programmers.  They're lawyers, a chief executives, a compliance officer and a few others in similar roles.  They are fixated on this software having an API, or APIs, I don't which is more proper.

It seems to me that with the import and export functionality we can do what we need to do.  Since we don't write our own software we couldn't code to an API.  But, I don't have enough experience to really know what an API might offer that the software in question couldn't deliver.  I chair the steering committee and would like us not to get side tracked by something that I suspect is irrelevant.  Can anyone help me to understand what I might be missing, or rather how an API would be advantageous?


问:
Formatting Dynamic Web Pages
A page built so that is has server side scripts implemented on the page.

Should indentation of the code be according to the server side logic (making it easier to read while coding) or according to the HTML/ASP.NET markup (making it easier to read while debugging etc.)?

答:
For "pure" ASP.NET, there isn't really much of an issue because by design, the aspx page and the code-behind document are separated: the code-behind document follows the indentation rules of the language used (C#, VB.NET, ...), the aspx page follows HTML markup.

If your ASP.NET pages contain e.g. JavaScript-like scripts, then I try to minimize their occurrence on the aspx page itself and try to isolate as much of it as possible in external files (that would then follow their own indentation).

Apart from this, I always let every language have and keep its own "default" indentation. But let's be honest: this is about more than ASP.NET. It's about making consistent choices in your programming habits. It's not about writing code you can print out and frame. It's about consistency. Choose a set of rules within the range of established possibilities and stick with them.

Check out articles like Top 15+ Best Practices for Writing Super Readable Code. It's packed with good advice. Undoubtedly, there are many others, that can offer valuable insight as well.

(If you're in a work environment, team habits or team rules may apply: dear employee, please do as we do. That makes sense.)

Title: Formatting Dynamic Web Pages


问:
How to do unit tests on a method that takes the elapsed time into account?
I'm currently in the middle of refactoring an important method in a legacy-system. There were almost zero test until I've started working on it, and I've added quite a lot to ensure the correct work after my refactorings.

Now I've came across the most crucial part: the algorithm that calculates an indicator. It's something like

```<code>indicator = (OneNumberFromA + AnotherNumberFromB) / elapsedTime;
</code>```

How can I test the correct behavior for this Function with Unit tests?

There are also some slightly different algorithms in the functions, that the program reaches in some cases - but in all of them, the elapsedTime is vital to the outcome.

答:
The same way you solve almost every issue with unit tests: you mock the elapsed time.

I advise using a standardized method to obtain the system time throughout a system, and then making that method overridable, so your unit tests have total control. The tests will then contain lots of nifty calls like Time.fake(timeA), or even Time.stop().


答:
Time measurement & indicator evaluation should be in different functions. In your case, elapsedTime should be an input of the evaluation function. That way, your evaluation code can be tested, and is easier to understand.

Now you still have the problem of testing the time measurement function, but this is beyond the scope of this question.

Title: How to do unit tests on a method that takes the elapsed time into account?

Body:
I'm currently in the middle of refactoring an important method in a legacy-system. There were almost zero test until I've started working on it, and I've added quite a lot to ensure the correct work after my refactorings.

Now I've came across the most crucial part: the algorithm that calculates an indicator. It's something like

```<code>indicator = (OneNumberFromA + AnotherNumberFromB) / elapsedTime;
</code>```

How can I test the correct behavior for this Function with Unit tests?

There are also some slightly different algorithms in the functions, that the program reaches in some cases - but in all of them, the elapsedTime is vital to the outcome.


答:
Would including the bug number inside of the method name for a temporary workaround be considered bad practice?

Yes.

Ideally, your class should best map to/implement a concept in your application flow/state. The names of APIs of this class should reflect what they do to the state of the class, so that client code can easily use that class (i.e. not specify a name that literally doesn't mean anything unless you specifically read about it).

If part of the public API of that class basically says "perform operation Y described in document/location X" then other people's ability to understand the API will depend on:

them knowing what to look for in external documentation

them knowing where to look for the external documentation

them taking the time and effort and actually looking.

Then again, your method name doesn't even mention where "location X" is for this defect.

It just assumes (for no realistic reason whatsoever) that everybody who has access to the code, also has access to the defect tracking system and that the tracking system will still be around for as long as the stable code will be around.

At the very least, if you know the defect will always be accessible in the same location and this won't change (like a Microsoft defect number that's been at the same URL for the last 15 years), you should provide a link to the issue in the API's documentation.

Even so, there may be workarounds for other defects, that affect more than the API of one class. What will you do then?

Having APIs with the same defect number in multiple classes (data = controller.get227726FormattedData(); view.set227726FormattedData(data); doesn't really tell you much and just makes the code more obscure.

You could decide that all other defects are solved by using names descriptive of the operation(data = controller.getEscapedAndFormattedData(); view.setEscapedAndFormattedData(data);), except in the case of your 216147 defect (which breaks the design principle of "least surprize" - or if you want to put it that way, it increases the measurement of "WTFs/LOC" of your code).

TL;DR: Bad practice! Go to your room!


问:
How to deal with Ghost bugs which appears in undocumented test-case scenarios?
There are instances which cane be seen while testing the application, both by developers and testers, some NullPointerExceptions arriving while clicking on a node in the table, or while doing an action too fast or under a zillion test-cases which do not come under the Test Cases document used in testing the application.

Most times we try to ignore these Ghosts ( i like Phantom bugs) which appear while testing. But the Quality assurance team won't be ready to accept a Phantom exception to occur while using the application. So what they do, they will file a bug along with the test case and the stack trace which occurred while the bug appeared.

When the developer tries to recreate the bug with all sorts of test cases and breakpoints everywhere the bug doesn't appear.

It feels like reading stories of UFO's spotted in some random area at some random time with a weird appearance.

How can a developer deal with these kind of issues before closing the bug or approaching the tester to recreate the bug  which never can be recreated ?

答:
Here's a few things you can do to increase your chances of reproduction:

use actual production data in your test case

reproduce the order in which actions occur in production (especially important for web applications where requests are sent asynchronously)

this may require increased logging in the deployed system, which is also a good idea on its own to find out where your two environments differ

reason backwards: why is this reference null? Was that supposed to be possible? If not, how could you be mistaken?


答:
To tackle ghost-bugs:

Insert logging.

Insert extra logging.

Insert even more logging.

Actually one of the main things I use to resolve ghosts bugs is removing dependencies and making sure that the part in your program where it occurs is as isolated from the rest as possible. This action would often resolve the issue.

Title: How to deal with Ghost bugs which appears in undocumented test-case scenarios?

Body:
There are instances which cane be seen while testing the application, both by developers and testers, some NullPointerExceptions arriving while clicking on a node in the table, or while doing an action too fast or under a zillion test-cases which do not come under the Test Cases document used in testing the application.

Most times we try to ignore these Ghosts ( i like Phantom bugs) which appear while testing. But the Quality assurance team won't be ready to accept a Phantom exception to occur while using the application. So what they do, they will file a bug along with the test case and the stack trace which occurred while the bug appeared.

When the developer tries to recreate the bug with all sorts of test cases and breakpoints everywhere the bug doesn't appear.

It feels like reading stories of UFO's spotted in some random area at some random time with a weird appearance.

How can a developer deal with these kind of issues before closing the bug or approaching the tester to recreate the bug  which never can be recreated ?


问:
How to solve circular package dependencies
I am refactoring a large codebase where most of the classes are located in one package. For better modularity, I am creating subpackages for each functionality.

I remember learning somewhere that a package dependency graph should not have loops, but I don't know how to solve the following problem: Figure is in package figure, Layout is in package layout, Layout requires the figure to perform layout, so package layout depends on package figure. But on the other hand, a Figure can contain other Figures inside it, having its own Layout, which makes package figure dependent on package layout.

I have though of some solutions, like creating a Containerinterface which Figure implements and putting it in the Layout package. Is this a good solution? Any other possibilities?

Thanks

答:
You should think about Inversion of Control

You basically define an interface for your Layout which is located somewhere near your Layout class in an own package so you would have an implementation package and a public interface package - for instance call it Layoutable (I don't know if that's proper English). Now - Layout won't implement that interface but the Figure class.
Likewise you would create an interface for Figure that's Drawable for instance.

So

```<code>my.public.package.Layoutable
my.implementation.package.Layout
my.public.package.Drawable
my.implementation.package.Figure
</code>```

Now - Figure implements Layoutable and thus can be used by Layout and (I'm not sure yet if that is what you wanted) - Layout implements Drawable and can be drawn in a Figure. The point is, that the class that exposes some service makes it available by an interface (here: Layout and Layoutable) - the class that wants to use that service has to implement the interface.

Then you would have something like a creator object that binds both together. So the creator would have a dependency to Layout as well as to Figure, but Layout and Figure themselves would be independent.

That's the rough idea.

An excellent source for solutions to this problems is the book Java Application Architecture by Kirk Knoernschild.

Body:
You should think about Inversion of Control

You basically define an interface for your Layout which is located somewhere near your Layout class in an own package so you would have an implementation package and a public interface package - for instance call it Layoutable (I don't know if that's proper English). Now - Layout won't implement that interface but the Figure class.
Likewise you would create an interface for Figure that's Drawable for instance.

So

my.public.package.Layoutable
my.implementation.package.Layout
my.public.package.Drawable
my.implementation.package.Figure

Now - Figure implements Layoutable and thus can be used by Layout and (I'm not sure yet if that is what you wanted) - Layout implements Drawable and can be drawn in a Figure. The point is, that the class that exposes some service makes it available by an interface (here: Layout and Layoutable) - the class that wants to use that service has to implement the interface.

Then you would have something like a creator object that binds both together. So the creator would have a dependency to Layout as well as to Figure, but Layout and Figure themselves would be independent.

That's the rough idea.

An excellent source for solutions to this problems is the book Java Application Architecture by Kirk Knoernschild.


答:
I'm not too clear on what a Figure is, but perhaps it should be in the same package as Layout?

Your proposed Container interface solution wouldn't work - unless you put the Container interface in a 3rd package then you would still have a circular dependency between the two packages. See michael_s's answer for something which would work.

Another thing, as others have mentioned - it will probably never be an issue. You're only going to run into problems in future if Figure and Layout want to be in separate modules. You can deal with this if and when that becomes necessary, but given that the two classes seem quite closely related this seems highly unlikely.

Title: How to solve circular package dependencies

Body:
I am refactoring a large codebase where most of the classes are located in one package. For better modularity, I am creating subpackages for each functionality.

I remember learning somewhere that a package dependency graph should not have loops, but I don't know how to solve the following problem: Figure is in package figure, Layout is in package layout, Layout requires the figure to perform layout, so package layout depends on package figure. But on the other hand, a Figure can contain other Figures inside it, having its own Layout, which makes package figure dependent on package layout.

I have though of some solutions, like creating a Containerinterface which Figure implements and putting it in the Layout package. Is this a good solution? Any other possibilities?

Thanks


问:
Unable to convince on data hiding
I am working on a Selenium + java project where all Web Element in a class are declared as -

```<code>public class CheckoutPaymentConfirmpage extends WebPage{

public final Button btnPrintorder = new Button("//input[@id='but_Print']");
public final TextField txtpassword = new TextField("password", "//input[@id='pass']");

    // Some more elements here
    // Some page object methods here
}
</code>```

Now when ever test need to access these elements they are directly invoked over the object of CheckoutPaymentConfirmpage class
What ever little java (or OOPS) I know, has taught me that members should be as hidden as possible. Hence I would have had btnPrintorder and txtpassword declared private and would access them using getters or would have created methods in page object class to be used by tests.

But when I convey this to others they don't see much value in it as state of instance variable (i.e. btnPrintorder etc) would not be changed from one object to another for page object class (i.e. CheckoutPaymentConfirmpage etc)

Hence in this situation, is it ok to leave instance variable as public?

答: Page Object elements should be private.  The issue, especially with respect to the Page Object pattern, is that public objects expose their methods, not the page object's methods.  If the page object's method would just be clickPrintButton(), there's not much difference, but imagine instead a printOrder() method that needs to click the button and wait for a confirmation message to appear.  And even in the simple case, ask yourself what other methods can be applied to a Button object, and do you want the consumer of the CheckoutPaymentConfirmpage to use them.

Title: Unable to convince on data hiding


问:
How to manage single software product to multiple customers?
We have developed one product for payroll processing. We have 10+ customers who are using this software product.

Our existing and new customers are giving us customization changes w.r.t. their needs, and now we are facing the problem of product management. Please give some guidelines to us.

How to manage single software product to multiple customers?

Software developement details :

Front End Tools : Visual Studio 2008 (ASP.net web application)

Source Code Mangement : Visual Source Safe (VSS)

Back End : Sql Server 2005

Team Size: 12

答:
In such an application it would be wise to separate the code into generic parts (database driver, widget library), and a configuration part which describes the specific implementation of those generic parts. I would strive to keep the dynamic part as small as possible, and reuse as much as possible. Each customer would have a joint generic part, and a custom configuration part. If any changes are needed to the basic infrastructure, these changes can also be applied to the other customers.

In practice, you could split the software into two repositories, one for the generic part and one for the configuration part, this last one unique for each customer.


答:
Changes that customers need will fall into one of 4 categories in my experience:

Changes which other customers will find useful but the "initial" customer is willing to pay for.

Changes which other customers will find useful but the "initial" customer is not willing to pay for.

Changes which other customers will not find useful but the "initial" customer is willing to pay for.

Changes which other customers will not find useful but the "initial" customer is not willing to pay for.

For 1, make the changes in the core product and release an updated version to all your customers (you get paid for developing it and you get goodwill going forward).

For 2, make a business decision on if the change is valuable enough to generate further sales to make it worthwhile, if so, make the change in the core product.

For 3, Create some kind of plugin system where you can create a custom add-in component for specific customers.

For 4, I'd recommend not doing this at all.

Body:
We have developed one product for payroll processing. We have 10+ customers who are using this software product.

Our existing and new customers are giving us customization changes w.r.t. their needs, and now we are facing the problem of product management. Please give some guidelines to us.

How to manage single software product to multiple customers?

Software developement details :

Front End Tools : Visual Studio 2008 (ASP.net web application)

Source Code Mangement : Visual Source Safe (VSS)

Back End : Sql Server 2005

Team Size: 12


问:
Mixing jQuery with JavaScript
I just asked this question at SO about some bugginess I am experiencing with jQuery and IE8, and someone commented that he was appalled that I would mix JavaScript with jQuery (he has since deleted his comment for some reason).

This person had a high reputation, relative to mine (3000+), so I don't want to ignore his criticism. I'm still relatively new to web development, and I mostly work alone, so I wasn't aware that this could be a problem. Why should mixing the two be avoided?

答:
First of all, it's not jQuery vs. JavaScript. It's jQuery vs the DOM API as-is which is crufty and ugly and kind of obtuse but traditionally most-importantly, unevenly supported in a big way in Microsoft browsers before IE9. But it's all JavaScript. If you're thinking about it any other way you need to lift open the hood and learn what JQ's internals are actually doing.

And no I honestly don't see what the problem with using both is. If you're mucking with the DOM you should know the DOM. One of the things I like about jQuery is that it gets the hell out of my way. Why should I fire a method to get a property I know is available in all browsers when I can just reference it via [0].someProperty instead for instance? Using both shouldn't make it harder for another UI dev to tweak your stuff if jQuery is in the mix because it's never going to have a problem with you doing that. At any time you can wrap any dom collection or object in a $ produced object wrapper by just tossing it in as an argument of the $ function and you're back in jQuery-land so it's not like you've made your code harder for somebody else to modify because that person was less comfortable with the native API.

But they should be able to read plain vanilla DOM API stuff if it's their business to tweak things at that level, regardless of their comfort-level using it. That's just the threshold of technical literacy for a proper entry-level UI-dev as far as I'm concerned. Generally speaking, of course, it can make code more legible to be consistent in the things that you do, but when you feel there's a sensible reason to go one way or the other, there's no reason not to. The key to making that decision is to know a lot about both.

In the scenario where somebody is really freaked out when they see a mix of things happening both the JQ way and the DOM API way, that's often a server-side dev not wanting to wade through stuff they don't really understand in order to re-use your code when you get smacked by the prodigal programmer-murdering bus. In that scenario, they shouldn't even be looking at this stuff in order to understand how to re-use your code for implementation on other pages or to set some alternate behavior. They should be looking at generic JavaScript objects, methods, and factories that expose a consistent/easily-documented API of your own for doing things like sticking a bunch of UI widgets of a given type on a page or setting all the combo boxes in a table to stop doing the auto-filtering thing when you type. All the DOM stuff should be buried and hidden from people who don't need to know it.

And that shouldn't be hard for you to do if ultimately it's all just JavaScript to you.

Title: Mixing jQuery with JavaScript


答:
Fundamentally there are two ways to approach this:

Have a single product that can be customised principally via configuration to suit an individual client's requirements

Build a product for each client based on a standard framework and a common core set of libraries.

The problem with the former is reconciling conflicting requirements from different customers the problem with the latter is that you're now supporting a product per client and that things will drift apart over time. In both cases you want to have mechanisms for managing the specific configuration data for each client.

My personal view is that (without a lot more detail) you're almost certainly better off dealing with a single application - certainly I had reasonable success with feature toggles in a multi-client web application but keeping track was challenging.

Looking at your toolset, there's reasonable support for Themes within ASP.NET and lots of scope for plug-in systems - but you should be looking at updating your tools and especially getting a more reliable/more capable version control system.

Title: How to manage single software product to multiple customers?


问:
What is the most egregious waste of money you have seen, and what did you do about it?
Often we as programmers see large organisations wasting huge sums of money on bloated and inefficient solutions to problems. This pains me greatly because I like organisations to benefit from best of breed solutions. However, my abilities as a programmer are limited when it comes to influencing the key decision makers and often my perspective on the matter is constrained to my own little technical world.

So, my question is this. After encountering an egregious waste of money on some software and/or hardware that really got your goat, what did you do about it to get it fixed or were you doomed to bite the bullet and mutter forever under your breath? I'm interested in hearing your overall experiences and especially what lessons you learned about how to tackle this sort of thing in the future. Let's not name names, the experience of how to tackle the problem is more important than the actual offending product.

答: I've been working with a few state institutions and they are amazing at wasting money on IT.  From buying bloated middleware to solve extremely simple problems to paying thousands and thousands of dollars to a vendor to have them create a CSV.  Without in-house people with sufficient experience it seems they either get fleeced on the upfront cost or on the maintenance.


问:
How much times command executed? Looking for mistake
I have following piece of code:

```<code>int sum = 0;
for (int i = 1; i <= N; i++)
    for (int j = 1; j <= N; j++)
        for (int k = 1; k <= N; k = k*2)
            for (int h = 1; h <= k; h++)
                sum++;
</code>```

So I'v calculated how much does each cycle executes and then whole script, and I think I might be wrong for the last one.

```<code>1. N
2. N
3.  1 + log2N( means log N to the base 2)
4. N
</code>```

So the total execution amount of inner cycle would be N^3 * (1 + log2N).

Am I right? How I can transform this statement?

UPDATE 1

I have another solution which seems monstrous:

```<code>1. N
2. N
3. LOG2(N) + 1
4. 2^(LOG2(2N)) - 1
</code>```

So total cycles amount would be n^2 * (LOG2(N) + 1) * 2^(LOG2(2N)) - 1.

Which transforms to n^2 order of growth.

UPDATE 2

I wrote simple test app to check my assumption.

it seems that third cycle is already calculated for some reason is fourth one. At least this is the result of test app. I threw away (LOG2(N) + 1).

As the result of several transformations I have following equation for total amount of sum++ calls:

```<code>N*N*(2*N - 1) = 2 * N^3 - N^2 ~ N^3
</code>```

答:
The first two loops are not interesting - they just give N^2 multiplier.

The fourth loop inside of third loop gives a geometrical progression: 1,2,4,8,...

Totally it will increase sum by 2M-1 where M is the largest power of 2 less than N.

So totally: N^2*(2*M-1)

In terms of big-O that's O(N^3).


问:
Trailing slash in RESTful API
I have been having a debate about what to do with a trailing slash in a RESTful API.

Lets say I have a resource called dogs and subordinate resources for individual dogs. We can therefore do the following:

```<code>GET/PUT/POST/DELETE http://example.com/dogs
GET/PUT/POST/DELETE http://example.com/dogs/{id}
</code>```

But what do we do with the following special case:

```<code>GET/PUT/POST/DELETE http://example.com/dogs/
</code>```

My personal view is that this is saying send a request to an individual dog resource with id = null. I think the API should return a 404 for this case.

Others say the request is accessing the dogs resource i.e. the trailing slash is ignored.

Does anyone know the definitive answer?

答:
```<code>Does anyone know the definitive answer?
</code>```

There isn't one as there isn't an official document on what is required for a service to be considered RESTful.

That said I would allow the trailing slash simply for ease of use. While technically speaking this could be seen as attempting to access a dog with a null ID; I do not see a user making this jump unless they have read it in your documentation. I can see a user attempting to write code against your API and including the trailing slash simply from habit and wondering why they get a 404 response when they want a list of dogs.

Title: Trailing slash in RESTful API

Body:
Does anyone know the definitive answer?

There isn't one as there isn't an official document on what is required for a service to be considered RESTful.

That said I would allow the trailing slash simply for ease of use. While technically speaking this could be seen as attempting to access a dog with a null ID; I do not see a user making this jump unless they have read it in your documentation. I can see a user attempting to write code against your API and including the trailing slash simply from habit and wondering why they get a 404 response when they want a list of dogs.