答:
After jumping through hoops, this is my end solution (far from perfect):

```<code>data NetException = NetNoException | NetTimeOut | NetRefused | NetHostUnreach
                    | NetANotAvail
                    deriving (Show, Eq)

diffExcept :: Either SomeException Handle -> Either NetException Handle
diffExcept (Right h) = Right h
diffExcept (Left (SomeException m))
    | err == "WSAETIMEDOUT" = Left NetTimeOut
    | err == "WSAECONNREFUSED" = Left NetRefused
    | err == "WSAEHOSTUNREACH" = Left NetHostUnreach
    | err == "WSAEADDRNOTAVAIL" = Left NetANotAvail
    | otherwise = error $ show m
    where
        err = reverse . dropWhile (== ')') . reverse . dropWhile (/='W') $ show m
</code>```

So the error will have to be passed to diffExcept, then the result of that can be pattern matched against.

Note that this isn't that safe in it's current form. It's assuming that every error will start with a 'W' (all net errors seem to so far), and the message will end in only ')''s. Anyone using this should probably fix it up prior, but it gives the general idea.

Title: How do you handle specific networking exceptions in Haskell?

Body:
I have the following to try and connect to a server:

```<code>testAddress :: HostName -> Int -> IO (Maybe Handle)
testAddress host iPort = do
    let port = PortNumber $ fromIntegral iPort
    putStrLn $ "Testing - Host: " ++ host ++ ", Port: " ++ show iPort
    result <- try $ connectTo host port
    case result of
        Left (SomeException e) -> return Nothing
        Right h -> do
            putStrLn $ "Connected to " ++ host
            return $ Just h
</code>```

I made the exception to catch "SomeException", but I know that's not the proper way to do it; as it will catch everything, and you can't handle individual cases. I can't find the names of specific network exceptions though. There doesn't appear to be any documentation for the Network package, and a every example I can find on google just uses "SomeException". If I try and connect to a random host and port, and I don't attempt to catch anything, I get the error:
"* Exception: connect: failed (Connection timed out (WSAETIMEDOUT))"
But it doesn't seem to give me the exact name of the exception to try and catch. I thought it might be "WSAETIMEOUT", but when I tried catching that, I got a compilation error saying that it couldn't find the constructor for "WSAETIMEOUT".
What should I do. I don't want to just catch everything and treat it the same, because then I don't know whats going on.

Thank you

Body:
After jumping through hoops, this is my end solution (far from perfect):

data NetException = NetNoException | NetTimeOut | NetRefused | NetHostUnreach
                    | NetANotAvail
                    deriving (Show, Eq)

diffExcept :: Either SomeException Handle -> Either NetException Handle
diffExcept (Right h) = Right h
diffExcept (Left (SomeException m))
    | err == "WSAETIMEDOUT" = Left NetTimeOut
    | err == "WSAECONNREFUSED" = Left NetRefused
    | err == "WSAEHOSTUNREACH" = Left NetHostUnreach
    | err == "WSAEADDRNOTAVAIL" = Left NetANotAvail
    | otherwise = error $ show m
    where
        err = reverse . dropWhile (== ')') . reverse . dropWhile (/='W') $ show m

So the error will have to be passed to diffExcept, then the result of that can be pattern matched against.

Note that this isn't that safe in it's current form. It's assuming that every error will start with a 'W' (all net errors seem to so far), and the message will end in only ')''s. Anyone using this should probably fix it up prior, but it gives the general idea.


问:
Implementing state-driven agents within an Entity-Component-System approach
A state-driven agent is an agent that performs an action based on its current state.  The logic can be  implemented through the use of a D-FSM that changes state depending on the Agent's "perception" and "stimuli" and perform actions on entering, being in, and exiting a state.

I'm trying to implement this type of design in a Entity-Component-System (ECS) architecture.

My first thought was to implement an "FSM" component containing a current_state and a rulebook, a System that updates the FSM component current_state depending on its rulebook and a System that implements the actions of an Entity ( and modify its components accordingly ) depending on the state of the FSM component.

I'm not sure this is a correct ECS implementation and that it can cleanly represent the enter_state/exit_state -> perform an action behaviour.

So, how should SDA be implemented in a ECS architecture?

答:
It depends on what the actual entity is and what the actual thing is you're modeling as a state machine.

In an ideal world, the state machine would live wholly contained within the component. The component would expose some interface, which the end user could work with and not know/care that the internals are actually moving a state machine around. This is good when the thing you're modeling is a "thing" that exists as part of the larger entity and when the state machine is relatively static - known inputs, with known outputs and known state transitions.

But sometimes, the entity itself acts as a sort of aggregation mechanism for the state machine. This happens more frequently when the state machine is dynamic. The inputs/outputs/state transitions can change depending on what components live in the entity. In this case, you may want to separate the state machine based on what bits you want to change and where the dependencies lie.

The big thing to focus on here is the spirit of the Single Responsibility Principle: "a class or module should have one and only one reason to change". Where you draw the lines to make that true depends on how you expect your system to change over time.

ContentLicense: CC BY-SA 4.0

ContentLicense: CC BY-SA 3.0


问:
Is immutability very worthwhile when there is no concurrency?
It seems that thread-safety is always/often mentioned as the main benefit of using immutable types and especially collections.

I have a situation where I would like to make sure that a method will not modify a dictionary of strings (which are immutable in C#). I’d like to constrain things as much as possible.

However I am not sure whether adding a dependency to a new package (Microsoft Immutable Collections) is worth it. Performance is not a big issue either.

So I guess my question is whether immutable collections are strongly advised for when there are no hard performance requirements and there are no thread safety issues? Consider that value semantics (as in my example) might or might not be a requirement as well.

答:
Immutability can also greatly simplify the implementation of garbage collectors. From GHC's wiki:

[...]
  Data immutability forces us to produce a lot of temporary data but it also helps to collect this garbage rapidly. The trick is that immutable data NEVER points to younger values. Indeed, younger values don't yet exist at the time when an old value is created, so it cannot be pointed to from scratch. And since values are never modified, neither can it be pointed to later. This is the key property of immutable data.

This greatly simplifies garbage collection (GC). At anytime we can scan the last values created and free those that are not pointed to from the same set (of course, real roots of live values hierarchy are live in the stack).
  [...]
   So it has a counter-intuitive behavior: the larger percent of your values are garbage - the faster it works.
  [...]


问:
Where to keep global variables in Windows Forms App
I have here a Vb.Net employee management application.
It has employees, managers, teams, trainings and so on.

The way the application is set up now, data is read from the database in the startup form (frmMain) load event and kept in that forms public properties. After that all other forms (and there is many of them) reference those lists (list (of employee), list of (team)) usging those properties. For example

```<code>dim emp = frmMain.Employees.Find(Function(x) x.ID = 128) , or
dim team1 as new Team
frmMain.Teams.Add(team1)
</code>```

I feel that this is a very bad way to solve this problem, but I'm stuck on deciding how this should be done.

Some singleton class that would keep all those lists (there is lots of them) instantiated on application startup, or is there a better way to do this?

答:
I have solved this in the past by creating a public module called Globals.vb that contains one or more VB Structure types that logically group variables together.  You can then create a single public instance of each structure.  For example, an ApplicationState structure variable could have collection-oriented properties for your employees and teams.   This lets you write code like this:

```<code>if ApplicationState.Teams.Contains(thisTeam) then ...
</code>```

Or, from your example:

```<code>Dim emp = ApplicationState.Employees.Where(function(z) z.ID = 128).FirstOrDefault
</code>```

This puts all global variables into a single, (relatively) easy to understand place and format.  It also lets you use the Structure's constructor to initialize your values.

Body:
I have solved this in the past by creating a public module called Globals.vb that contains one or more VB Structure types that logically group variables together.  You can then create a single public instance of each structure.  For example, an ApplicationState structure variable could have collection-oriented properties for your employees and teams.   This lets you write code like this:

if ApplicationState.Teams.Contains(thisTeam) then ...

Or, from your example:

Dim emp = ApplicationState.Employees.Where(function(z) z.ID = 128).FirstOrDefault

This puts all global variables into a single, (relatively) easy to understand place and format.  It also lets you use the Structure's constructor to initialize your values.


问:
Integrating a mobile website into a mobile app
I'm trying to redevelop a mobile website so we can integrate it into a mobile app that is being developed by another department, but still keep it functional on the web. The app has its own menu, so it's redundant to leave the menu on the mobile site.

We considered simply removing the menu, headers and footers from the site, and provide the links to the pages to the other department so they can add them to the app menu. This obviously leaves our website menu-less.

I've considered creating a new front page, that has a similar menu to the app, and loading the pages either in frames, or using jquery .load(), or ASP includes... Frames would give me the functionality I want that is most similar to the app opening pages in a browser using it's native menu, but frames are so... 1990's.

What is best solution that uses modern standards?

答:
Dont use frames ;)
What you could do is to provide the links to the other departement and in the end of the url set some kind of GET variable ex mysite.com?commingFromApp=true
And then on the website you could make a method the prints the menu to the website, and if commingFromApp is not true then print out the menu, and if its true dont print it because the user is comming from the app and should not see the menu</p>


问:
Should temporary code be put under version control and how?
Here are some examples of temporary/local code. It is needed in order to work with the codebase, but would be harmful to be part of it:

Project files. Paths may need to be edited in order to reflect the layout on the current PC.

Makefiles. For example optimization may need to be turned off during debugging, but not for the CI server.

Dirty ugly hacks. For example return 7 in the middle of a function, in order to test something, depending on the function, and suspected to break at value of 7. Or 7 is the code of the not yet implemented button, that I am implementing and need to test throughout the life of my branch.

I have tried keeping those in a git commit that I always rebase to the top before pushing to the repo and then push HEAD~. This is quite inconvenient and doesn't work with svn. Stashing scares me even more - "did I remember to pop after pushing??".

Keeping the code out of version control introduces unpleasant noise everytime a commit is being assembled plus it might accidentally get introduced into a commit some friday evening.

What would be a sane solution for such throw-away code?

答:
2 HAMSTER solutions:

You can use a pre-commit hook to check your code for some unusual keyword like HAMSTER. Just don't let people commit code that has been HAMSTERed and use it whenever you do dirty hacks.

Another option for example in C is to use #ifdef HAMSTER, then the code will only run on your machine where you have a compiler flag HAMSTER.


问:
How should I remember what I was doing and why on a project three months back?
I was working on a project three months back, and then suddenly another urgent project appeared and I was asked to shift my attention.

Starting tomorrow, I'll be heading back to the old project. I realize that I do not remember what exactly I was doing. I don't know where to begin.

How can I document a project such that anytime I look back it shouldn't take me more than a few minutes to get going from wherever I left. Are there best practices?

答:
In addition to the comments / todo lists / commits, it is important to be realistic.

Depending on the size, complexity and the state you left your work at, getting started again on a project could take a while. For a substantial codebase of many interacting components, it could take days to get up to full speed.

Good old patience will be useful.

When overwhelmed after coming back to a project after a while, I generally pick up the simplest and smallest unit of task and implement it. It keeps me from getting lost trying to remember a lot of things at once and bumps up the confidence a little bit. More often than not, I find myself automatically picking up increasingly bigger tasks in a few hours.


问:
Is SourceSafe really safe?
Having spent all morning trying to check something in - I now realise I've lost a couple of days worth of work.

Its happened before - and is apparently common occurrence with SourceSafe.  Can SourceSafe be used successfully, without problems, and if so, how?

答:
Not only do you suffer from the problem of potential corruption of source (which should be argument enough for management to replace it), but you also have to live with awkward backup  and an inability to work effectively as a team on different streams of work.

Find another SCM (any other one) and look at how easy branching and merging can be.  Think about those times when you've had to copy files out of your VSS solution and hold them somewhere else while you went back to fix a bug on 'production' code.

For kicks, just install GIT - point it at your VSS files and see how easy it is for GASP two programmers to work on different parts of the same file AT THE SAME TIME, and then have the software intelligently merge your changes...  SCM tools should be more than just source backup.

Title: Is SourceSafe really safe?

ContentLicense: CC BY-SA 2.5


答:
We put everything under source control needed to build and test the current binaries and understand why things were designed/implemented/tested the way they are.

That even holds for spikes http://www.extremeprogramming.org/rules/spike.html, like the ones you described; we just host them in a different sub-tree.

Title: Should temporary code be put under version control and how?

Body:
Here are some examples of temporary/local code. It is needed in order to work with the codebase, but would be harmful to be part of it:

Project files. Paths may need to be edited in order to reflect the layout on the current PC.

Makefiles. For example optimization may need to be turned off during debugging, but not for the CI server.

Dirty ugly hacks. For example return 7 in the middle of a function, in order to test something, depending on the function, and suspected to break at value of 7. Or 7 is the code of the not yet implemented button, that I am implementing and need to test throughout the life of my branch.

I have tried keeping those in a git commit that I always rebase to the top before pushing to the repo and then push HEAD~. This is quite inconvenient and doesn't work with svn. Stashing scares me even more - "did I remember to pop after pushing??".

Keeping the code out of version control introduces unpleasant noise everytime a commit is being assembled plus it might accidentally get introduced into a commit some friday evening.

What would be a sane solution for such throw-away code?


问:
How many bytes can I fit into a QR code, with low error correction?
I need to fit at least 300 bytes (or much much more) into a QR code and think I can do this by mapping each byte into the associated ISO/IEC 8859-1 character located here.

Since each byte (1-255) will only have one character associated with it, I can test the utility of the idea with this demo  (the Email link has the dense QR I'm referring to)

Since I know that camera resolution plays a factor here, among other things I'm unaware of, I'd like to get a sense of how many individual characters I can put into a QR code before running into issues.  Any sizing, or resolution tips would be helpful.

The other assumption I have is that a QR reader can read every ISO/IEC 8859-1 character and pass it to my app

答:
A QR Code has a version range from 1 to 40.  This information tells about how much data is stored within it.  Version 40 has 177 rows and 177 columns (in some decimation called 'modules') for 31,329 pixels.  It should be immediately clear at this point that this is the hypothetical maximum that doesn't take into account the error correcting or any of the other infrastructure of the QR code itself.

Once error correcting, infrastructure (the fixed patterns, for amount of error correction, targeting, frequency, mask patterns and such) and minimal error correcting get added, this is maxes out at 23,648 bits (2956 bytes - high level error correcting on version for is 10,208 bits 1276 bytes).

A version 40 barcode with 1276 bytes of data:

Once you get into the high capacity barcode area, you get into color 2d barcodes.  The back and white barcode technology tends to max out fairly quickly (data matrix can only hold 2,335 alphanumeric characters (not bytes)).

To go beyond the size limitations of version 40 in a QR code, one can used the Structured Append (encoding mode 0011), though a quick search of various QR code reading libraries suggests that it is not something that any of them support.

A not uncommon approach for an alternative is instead to store a tag of data in the barcode which then references an online resource that has the full information.  Note that this works poorly in offline situations.

For dealing with much smaller chunks of data (300 bytes), 2400 bits of data can fit into a low error correcting version 11 QR code (it has 2592 bits of data to use for 321 bytes)

At this point, with lots more data space between version 11 and version 40, there are a number of encoding options if there are difficulties of getting the byte[] out of the data.  One could encode it in the alphanumeric character set that QR code allows (44 characters designed for web addresses - 11 bits for 2 characters in versions 10-26), or numeric (12 bits for 3 digits in versions 10-26) as the two easiest ones to work with.


问:
How much data should exceptions hold?
Almost all the exceptions I have ever written have been very lightweight, containing a String message and optionally a throwable. In some situations I have included some application specific enum or some other field.

```<code>public class MySpecialException()
{
    private MyErrorCode errorCode;

    public MySpecialException(String message, Throwable cause, MyErrorCode errorCode)
    {
        super(message, cause);
        this.errorCode = errorCode;
    }

    ....
}
</code>```

Now I face a situation where I need to put in 5 or 6 fields in the exception because the error handler that catches them needs them to generate the output.

Would you consider that to be bad code? Can an exception be too big?

```<code>public class MySpecialException()
{
    private String name;
    private int age;
    private int id;
    private int height;
    private String duck;
    private String whatever;

    ....
}
</code>```

答:
An exception can be too big, especially if you are going to serialize it and transfer over wire (to a remote client/server or a database for instance).

If it is on the same machine, and you are not pushing it, put those 5-10 values there. Or maybe it makes more sense to put them into their own class(es). Maybe you are not dealing with one exception here, but one exception carrying information about one person and one duck.

Title: How much data should exceptions hold?


答:
No,  an exception cannot be too big (well, obviously it could but I'm assuming common sense here). What an exception can definitely be is far too much coupled to normal program logic.

Exceptions should never be used to pass information around in your program. they should be used solely for error conditions that you didn't expect to ever have to deal with (again, common sense says this will include errors you did expect, but ones that do not occur very often at all).

So when you push all this information into an exception, ask what you're going to do with it.  If the exception is driver only from exceptional circumstances, then you generally want it to be as generic and simple as possible - its job is to tell you what went wrong, and possibly some more information that you could display to the user. Trying to use the information for any other purpose smells like you're trying to use exceptions to manage cases.

Adding a exception handler that understand every exception you might throw means your handler becomes very much tied to your exception classes, and that means your handler cannot be in a self-contained library without referencing the application! When projects grow, you'll find this becomes an annoying problem.

So, I wouldn't. I'd stick to throwing exceptions as strings and codes. If you really must pass information about the error (eg which user was being processed) then keep an error (or transaction) log containing the data and use that after the exception is handled to manage the data - you can hopefully put the display generator in your application code, and have it kept separate from external systems.

Title: How much data should exceptions hold?

Body:
Almost all the exceptions I have ever written have been very lightweight, containing a String message and optionally a throwable. In some situations I have included some application specific enum or some other field.

```<code>public class MySpecialException()
{
    private MyErrorCode errorCode;

    public MySpecialException(String message, Throwable cause, MyErrorCode errorCode)
    {
        super(message, cause);
        this.errorCode = errorCode;
    }

    ....
}
</code>```

Now I face a situation where I need to put in 5 or 6 fields in the exception because the error handler that catches them needs them to generate the output.

Would you consider that to be bad code? Can an exception be too big?

```<code>public class MySpecialException()
{
    private String name;
    private int age;
    private int id;
    private int height;
    private String duck;
    private String whatever;

    ....
}
</code>```


问:
How do you wrestle the DRY principle with configs?
For instance, lets say we have an nginx config pointing at foo1, foo2, and foo3, as well as a haproxy config pointing at foo1, foo2, and foo3, and finally, a deployment tool pointing at the same respective servers.

How does one reconcile this?  Build some sort of configuration generator for nginx and haproxy based on the hosts?  It seems as though this would make grepping difficult and potentially hinder readability of the configuration files in general.

答:
In general, the only config that I'm going to be interested in is the one I'm currently looking at.  Unless the two systems are intimately tied together, it's two diffrrent configs, and it doesn't matter that they are pointing to the same group of servers. </p>

<p>If it's essentially the same system, then naturally it's the same config. Consolidation of the settings becomes possible, provided there are no backward compatibility concerns.   </p>

Body:
In general, the only config that I'm going to be interested in is the one I'm currently looking at.  Unless the two systems are intimately tied together, it's two diffrrent configs, and it doesn't matter that they are pointing to the same group of servers.

If it's essentially the same system, then naturally it's the same config. Consolidation of the settings becomes possible, provided there are no backward compatibility concerns.


问:
How exactly to use the MVC design pattern
I have read the documentation on the apple's developer website which refer following guidelines

A view class shouldn't depend on a model class (although this may be unavoidable with some custom views).

A view class shouldn't have to depend on a mediating controller class.

A model class shouldn't depend on anything other than other model classes.

A mediating controller class shouldn’t depend on a model class (although, like views, this may be necessary if it's a custom controller class).

A mediating controller class shouldn't depend on view classes or on coordinating controller classes.

A coordinating controller class depends on classes of all MVC role types.

Consider this scenario:

I have a view controller class called EmployeeViewController.
I have some minor components of which are some are programmatically created and some are created through xib.

What exactly I am doing is creating all the subviews inside the EmployeeViewController class and adding them to the EmployeeViewController's view, e.g. [self.view addSubView:…]

Is it a better option for me to create a seperate UIView Subclass which consists of all the components and initialize it once and add it in the EmployeeViewController?

What exactly is the correct way to implement MVC? Am I supposed to create separate components for view and controller or should I stack subviews inside the EmployeeViewController?

答:
So to me MVC is all about project structure, and here's how I break down MVC.

M for Model: This is everything that has to do with data. From your Core Data, to your network calls, to objects that reformat or translate data to get it ready for the app. Basically where all the cool logic goes.

V for View: This area if for stuff that directly interacts with the user such as storyboards and xibs. That's pretty much it.

C for Controller: This code is code that accepts data from the Model layer (with the data readily formatted), and then transforms it into something that can be presented in the View layer. Basically this is all of your ViewControllers.

The key thing about this approach is that your Model layer should be able to be pulled out and applied to, say, a Mac app with minimal modifications, where as the V & C should be explicitly pertinent to iOS.

That's the way I was taught MVC but I'm sure there are more interpretations.

Now for implementation, it's hard to give you exact advice without sample code but generally, it seems like most of your View stuff is programmatic which you should avoid if you can. Take advantage of storyboards and xibs to take care of static content.

Regarding the UIViews, this isn't so much of an MVC question as it is a software design question. It all depends on the complexity of that view. If it is an extremely intricate and detailed subview, then yes pull it out into it's own class. But if it is just a basic UIView that has a few labels, then just build that in the ViewController. Try to adhere to the Unix philosophy that every class should do only one thing, and do it extremely well. Don't worry if your class only has one function in it. If it is an important and unique function, then it would actually be preferred to have that decoupled out of the Controller layer and into the Model layer. I see too many people afraid to break down their code into simple classes, but that is actually the best way to go, have everything decoupled and thus easily plug-n-play.

So in conclusion, its your call. How complex is this UIView? If it requires a couple of helper functions and global variables, pull it out into a subview.


问:
What is the best use case for selenium?
I've been trying to develop web applications while at the same time creating the testing. I understand unit testing, I can declare a test method and test specific methods in my application.

But I don't see what is the best way to use selenium web driver for testing. I tried to test the a specific site for broken links or broken images and I had to use an external http connection library since selenium doesn't  provide header results etc. It is very slow to traverse a whole site. While you can just pass the URL to W3C link checker and you're done.

Are most developers creating a class for each page and testing individual ui elements since traversing the whole site is a lot more complicated.

What are the benefits selenium brings or ui testing that can't be tested for with unit testing?

答:
Unit testing is just one of the multiple types of testing. Basically, you'll find three types of tests:

Unit tests.

Each of those tests ensure that a tiny piece of application is working as expected. For example, a unit test will ensure that if, on an e-commerce website, I create an instance of a Product class with a price inferior to zero, an exception will be thrown.

Integration tests.

This is similar to unit tests, but with a larger scope. Once you created the blocks of the application and test them, you start to assemble them into something bigger. Integration tests ensure that those blocks work as expected when assembled.

For example, your product management block was unit tested to prevent creating products with a price inferior to zero, and your administrative interface block was tested to prevent invalid values from being entered by the users, but what about those two blocks interacting one with another?

System tests.

The scope of those tests is even larger. While integration tests are more concerned with interfaces between two blocks, system tests are run on the whole system.

For example, what happens when two administrators attempt to modify the product with the same ID, while the primary database goes down for a few seconds, letting the mirror database to handle the operation?

To complicate things a bit, there are additional types of testing, such as:

Functional tests.

While the earlier tests are often conducted by developers themselves, functional tests are usually done by QA department to ensure that the product corresponds to the requirements. While unit, integration and system tests are focused on the actual blocks and their interaction, functional tests are focused on requirements, which means that they treat the application as a black box.

For example, if a requirement specifies that the product cannot be purchased more than once per ten seconds by the same user, the test would consist of ordering the product twice in a period of ten seconds and check that the second order failed. Here, the QA tester doesn't care about how the functionality is implemented and what parts of the app are interacting to prevent the frequent purchase.

There is also security testing, A/B testing, regression testing, acceptance testing, non-functional testing, etc., but let's focus on system and functional tests above.

A functional test such as:

Ensure credit card information is remembered by the website.

Go to the product 123.

Add it to cart.

Go to cart.

Make the one-click purchase.

Repeat steps 2 to 5, given that the entire test should take less than ten seconds.

Ensure the last step fails and the user is informed that:

The purchase was not made because there is a risk of mistake from the user,

The IP address was saved in case of abuse,

The e-mail was sent to inform the user about the risk of abuse,

The credit card was not debited.

is:

Impossible to make by hand (unless you have a really fast tester),

Is just too painful to do by hand anyway (especially in a context of Continuous Integration, where it may need to be done dozens of times per day, among several thousand of other tests),

Is quite difficult to implement using "ordinary" programming, such as a bunch of HTTP requests and responses checking,

Would be unmaintainable if implemented using "ordinary" programming.

This is when Selenium is useful. You create your scenario, and Selenium runs it again and again, checking that the test still passes. A similar scenario concerns system testing; although I don't expect Selenium to be very present here, it's not excluded that some teams rely on Selenium for this sort of testing.

If your project has requirements, a bunch of Selenium tests will be organized around those requirements, like in the example in my answer.

If not, each of those tests will just be a possible scenario which could get terribly wrong, similarly to what you do when choosing what unit tests to create. Just like in unit tests, you will test some method for input value 3 (ordinary case), 0 (edge case), -1 (exceptional case) and NaN (exceptional case), Selenium tests can encompass very diverse situations, such as:

The user purchases a product. That's all.

This is also probably the most crucial test one can have for an e-commerce website: if users can't purchase, it would be slightly problematic.

The user adds a product to the cart, waits until the product is not available any longer, and then tries to purchase it.

The user adds a product, then removes it, then presses Back, and tries to purchase.

The user bruteforces the website by adding every available product with maximum quantities in the shortest possible amount of time, and tries to purchase that.

The user starts purchasing a product, but leaves when the transaction is running, and never returns.

Title: What is the best use case for selenium?


答:
UI testing is hard.  For the most part, it doesn't lend itself well to unit testing.

Tools like Selenium are designed to fill this gap.  For the most part, they do this by automating the user interface, simulating the operations that a user might perform via mouse clicks and typing.  But these tests tend to be brittle, and they are generally not comprehensive.

One approach commonly practiced is to push as much of the UI logic as possible out of the View and into a View Model object.  View Models can be unit tested, and the UI surface logic is correspondingly simplified for Selenium.

Title: What is the best use case for selenium?

Body:
I've been trying to develop web applications while at the same time creating the testing. I understand unit testing, I can declare a test method and test specific methods in my application.

But I don't see what is the best way to use selenium web driver for testing. I tried to test the a specific site for broken links or broken images and I had to use an external http connection library since selenium doesn't  provide header results etc. It is very slow to traverse a whole site. While you can just pass the URL to W3C link checker and you're done.

Are most developers creating a class for each page and testing individual ui elements since traversing the whole site is a lot more complicated.

What are the benefits selenium brings or ui testing that can't be tested for with unit testing?


问:
An algorithm for finding subset matching criteria?
I recently came up with a problem which I would like to share some thoughts about with someone on this forum. This relates to finding a subset. In reality it is more complicated, but I tried to present it here using some simpler concepts.

To make things easier, I created this conceptual DB model:

Let's assume this is a DB for storing recipes. Recipe can have many instructions steps and many ingredients.

Ingredients are stored in a cupboard and we know how much of each ingredient we have.

Now, when we create a recipe, we have to define how much of each ingredient we need. When we want to use a recipe, we would just check if required amount is less than available amount for each product and then decide if we can cook a dinner - if amount required for at least one ingredient is less than available amount - recipe cannot be cooked. Simple sql query to get the result.

This is straightforward, but I'm wondering, how should I work when the problem is stated the other way round, i.e. how to find recipies which can be cooked only from ingredients that are available?

I hope my explanation is clear, but if you need any more clarification, please ask.

答:
Reasonably simple, using a subquery join.

JOIN Recipeingredients on Ingredients where RequiredQuantity less or equal AvailableQuantity. Test this to make sure it works as expected.

JOIN Recipe IN above subquery to find those you can make.

I'll leave you to write the actual SQL.


答:
One huge advantage is that in many cases you can use your selenium tests against the production codebase and deployment. They are certainly brittle and non-comprehensive tests in many ways. On the other hand they can actually hit all of the moving parts moving together which is a space traditional unit tests just can't hit.

You can even extend this out to production uptime, performance monitoring and even load testing -- we were a longtime browsermob user [now Neustar Web Performance] and it flat out rocks. On the one hand you could hit the fully configured stack and see what kind of traffic you can take on real-world infrastructure [load testing] and on the other hand you can monitor the uptime -- including cruical infrastructure like general network connectivity and DNS resolution as well as app specific 3rd party services.

Also, from a pure development perspective, I've used it many times for quick automated validation tests of underlying application changes like major library upgrades. On many platforms just checking if pages can be rendered at all will check a lot of boxes and having something that can mechanically request them is worth it's weight in gold.

Title: What is the best use case for selenium?


问:
Are RSpec and Cucumber really worth it?
I know most RoR programmers are testing addicts and I understand the advantages of a large testing suite but when I start testing, I never get such a large suite and I always wonder "Am I testing the right way? Are there really efficient?". I'm often dealing with integration tests testing only the way the application behave.

First, is testing really worth it? I mean, is the time spent on writing tests really worth it?

Then, I use RSpec, I've recently discovered Cucumber, used it for a while but I don't know if writing all these steps is really worth the trouble? I know I can reuse steps but I never know if these steps are too complete or not: For instance, I've been using a Given I am logged in as (.+) but I don't know if I must say in its definition Given there's a user called $1 because it can duplicate the user if ever created but that's not worthwhile always having a step before Given I am logged in as (.+). It's quite a lot of code that will maybe rarely be useful. I guess there are not new bugs on the parts tested every day...
So is Cucumber really worthwhile compared to RSpec?

答:
What I personally believe is that RSpec testing is a definite must. Let's say for example that you want to write a new feature, and which also has reference to some other feature, and that feature might be referenced with some other module or methods. So how can you make sure that what you are writing is not breaking any other part of the application?

Assume that you have a big application and that you have coded something trivial compared to the overall application, will you retest the entire application by clicking every link in the application to make sure it works everytime you change a single line of code?

However, I believe that Cucumber testing is not a must. I think that integration testing using RSpec itself makes more sense until and unless you have to get tests checked by your client. Which in my experience is RARE. If your team consists entirely of developers then I think that you should rather replace the Cucumber steps for RSpec feature testing. And I think after the RSpec 3 DSL, the tests are pretty much readable.

Ex :

Cucumber Step Definition :

```<code>Given /^I am logged in$/ do
  visit login_path
  fill_in :name, :with => 'Joe'
  fill_in :password, :with => 'Password'
  click_button 'submit'
end
</code>```

RSpec Feature test :

```<code>feature 'Given the user is logged in' do
      visit login_path
      fill_in :name, :with => 'Joe'
      fill_in :password, :with => 'Password'
      click_link_or_button 'submit'
end
</code>```

I think that rather than having Cucumber features, RSpec features do the same thing without the extra headache of writing another step definitions.

Other than that it is also purely your own preference.

Hope this could help you understand a little bit.

Title: Are RSpec and Cucumber really worth it?

Body:
What I personally believe is that RSpec testing is a definite must. Let's say for example that you want to write a new feature, and which also has reference to some other feature, and that feature might be referenced with some other module or methods. So how can you make sure that what you are writing is not breaking any other part of the application?

Assume that you have a big application and that you have coded something trivial compared to the overall application, will you retest the entire application by clicking every link in the application to make sure it works everytime you change a single line of code?

However, I believe that Cucumber testing is not a must. I think that integration testing using RSpec itself makes more sense until and unless you have to get tests checked by your client. Which in my experience is RARE. If your team consists entirely of developers then I think that you should rather replace the Cucumber steps for RSpec feature testing. And I think after the RSpec 3 DSL, the tests are pretty much readable.

Ex :

Cucumber Step Definition :

Given /^I am logged in$/ do
  visit login_path
  fill_in :name, :with => 'Joe'
  fill_in :password, :with => 'Password'
  click_button 'submit'
end

RSpec Feature test :

feature 'Given the user is logged in' do
      visit login_path
      fill_in :name, :with => 'Joe'
      fill_in :password, :with => 'Password'
      click_link_or_button 'submit'
end

I think that rather than having Cucumber features, RSpec features do the same thing without the extra headache of writing another step definitions.

Other than that it is also purely your own preference.

Hope this could help you understand a little bit.


答:
In my opinion the first thing its to differentiate between practices and concrete frameworks. Cucumber its not BDD, RSpec its not TDD.

If you want to test your system RSpec its a good tool, you can do TDD or BDD with RSpec, in fact TDD and BDD are the same thing. Someone says "BDD its TDD done right" and i'm totally agree with that, BDD primarily its about testing features/behaviors instead of testing methods/classes. In fact the TDD that Kent Beck describes its about features, but BDD help a lot of people in understand this key difference and its a great contribution from Dan North to the development community.

Use Cucumber if you feel that you need a better tool to communicate with business people, for example if cucumber allow that your business people or Product owner helps the team in writing or revising scenarios. Other people like cucumber because this scenarios are a really good live-documentation of a system, if you feel that you need this type of documentation try cucumber.

In Summary:

If you want to do TDD/BDD yourself or you team -> try RSpec

If you want a better way to communicate with business with User Histories and Scenarios -> try cucumber

If you want live documentation of your system features -> try cucumber.

Of course the last two have a hight cost associated, you need to evaluate if you really need that and worth the effort, this off course depends totally on your project and your environment and the decision its up to you.

But always remember that RSpec and Cucumber are only tools, and tools solve concrete problems, what problem you want to solve?, ask yourself this question and you probably are in a better position to select the right tool. Be a better programmer its about taking this decisions not about using X or Y framework/tool/library/technology.

Title: Are RSpec and Cucumber really worth it?

Body:
I know most RoR programmers are testing addicts and I understand the advantages of a large testing suite but when I start testing, I never get such a large suite and I always wonder "Am I testing the right way? Are there really efficient?". I'm often dealing with integration tests testing only the way the application behave.

First, is testing really worth it? I mean, is the time spent on writing tests really worth it?

Then, I use RSpec, I've recently discovered Cucumber, used it for a while but I don't know if writing all these steps is really worth the trouble? I know I can reuse steps but I never know if these steps are too complete or not: For instance, I've been using a Given I am logged in as (.+) but I don't know if I must say in its definition Given there's a user called $1 because it can duplicate the user if ever created but that's not worthwhile always having a step before Given I am logged in as (.+). It's quite a lot of code that will maybe rarely be useful. I guess there are not new bugs on the parts tested every day...
So is Cucumber really worthwhile compared to RSpec?


问:
Trying to understand how MySQL license applies to code I wrote
I have an ERP, coded with Java and the database in MYSQL Community edition. When I was going to sell it to a client he asked me for the sources to my application (with the belief that it is GPLed). I already got an upfront payment from him.  But now he asks me to deliver the source code for my ERP with the executable.

When I told him no, he responds that as I am using MySQL community edition the project must be open source, and I must give him the sources. He is not willing pay extra for the source for what I wrote.

It doesn't seem like the MySQL license should affect the license of the code I have written.  But is that true?

答: Honestly, these aren't questions best posed to programmers. Almost all of the issues you raise are matters of contract and intellectual property law. Consult a local lawyer who is familiar with the software industry in your jurisdiction. If you don't have a written agreement with your client (very foolish), s/he will be able to advise you of the “defaults” in your jurisdiction a lot better than some random programmer on the Internet in a different state/country.</p>


答:
Here are are a number of solutions I occasionally use myself under various circumstances, and that you might consider helpful when applied to your own workflows:

Lightweight branches that can be squashed.

Git is great at this. Hack on a branch, make lots of commits, and then rebase or squash your history to edit out the noise.

Use a patch queue on top of your SCM.

I often find myself using StGit to float patches to the top of my current branch. When I'm done with the branch, I can pop them back off the stack before merging, squashing, or rebasing, or I can merge them into the main codebase if I want to keep them around.

Use RCS as an "out-of-band" SCM for small experiments.

Sometimes you just want to checkpoint a file in progress in a disposable way, without having to clean up history afterwards. I typically use RCS for this inside of Git or SVN. I tell Git to ignore RCS artifacts, checkpoint my work in progress in RCS, and when I like the results I just toss the *,v files or the whole RCS directory. Just don't run git clean -fdx or similar until you've committed your work to your "real" SCM, or you'll regret it.

Named stashes.

Another Git-ism, but handy: git stash save --include-untracked <some-cool-title> can be useful in a pinch. You can save, pop, and apply work in progress this way, and view your various checkpoints through git stash list or git reflog --all. Other SCMs may have similar features, but your mileage may vary a lot with this one.


问:
What is the purpose of RESTful URIs for POST/PUT/PATCH/DELETE methods?
In the process of conceiving a web application framework, I spent some time pondering the notion of RESTful paths. If I wanted to create e.g. a new topic, I might send a POST request to /topics. The parameters thereof might be something like: { topic: { body: 'Body' } }

As such, the type of resource being created can be inferred from the parameters. Since there is the top-level item 'topic', we can logically ascertain that the request is to create a topic.

For me, the strange thing is that POST create is the one action that falls outside of the notion of either a singular resource or a collection. It is arguably neither. Sure, you're adding to a collection, but in contrast to say a GET index you are not retrieving any part of that collection, and the state of that collection to a large extent is irrelevant. In contrast to a GET, PUT/PATCH, or a DELETE, you are not retrieving a singular item based on an identifier. You are creating an item where one does not exist.

I conceived of a "master registrar" service that would respond to all incoming POSTrequests. Imagine every form POSTing to /, with the master registrar determining the intended resource based on the params, and deferring to services that exist for the purpose of persisting a resource based on those params.

In fact, for any non-GET action, the paths become irrelevant. They don't seem to have an important semantic purpose. A user is not going to link to a form's action URL. Even in the case of PUT, PATCH, or DELETE The type of resource being created or the resource being modified can be inferred from the parameters. For example, if we were editing a topic versus creating one, the parameters might be { topic: { id: 1, body: 'New Body'} }. The presence of an ID in the parameters indicates that the topic in question already exists and should be retrieved foremost.

I don't know if this is RESTful or not. Regardless, I cannot see why this approach is invalid or inadvisable. Given my caution and naivete, however, I'd like to know why it might be.

答:
The HTTP spec's definition of POST is very broad. There are two clauses that make it good to treat as the "create" verb.

It is the method for "append" to a database

It is the method for general "data processing"

So for REST, the sense of POST is that it's for appending to a collection of resources.

In your example, POST to "/topics" is perfectly valid -- because you're really creating a single item, but extending the collection of all items. Really the target is the collection. There's some data processing along the way.

POSTing to "/" and inferring the type may actually be OK according to the HTTP spec. In a sense, you'd be creating an item and appending it to the collection of all items (!). But IMHO it makes more sense to limit the action to the right resource & just post to /topic.

It's hard to pin down what you're not supposed to do with POST ... remember that the World Wide Web was built with GET and POST. There are cases where it's better to get with a POST than with a GET, if the query is long or uses structured data. Basically, if you want to sail a battleship through a loophole in REST, use post.

(Or, as Roy Fielding has posted, POST is the verb to use when you don't want to generalize the operation.)

Just be careful about confusing your clients. POST to "/topics" instead of "/" might make more sense.


答:
Some of that temporary code is really just a manifestation of improper build/test/development methodology, and hopefully their existence will motivate future improvement.

On git at least, you should be free to mess around with any number of feature branches until they are ready to be merged into master/trunk.

Version control is supposed to help you, and more often than not I appreciate the insights from the way mistakes (or maybe just less-than-intuitive decisions)  were made in the past, and make more informed decisions for the present.


问:
Should we test the values of objects returned from the methods being unit tested?
Being new to unit testing I would like to know if I am supposed to test the values of objects returned from methods when doing unit testing. As an example, consider the following classes:

```<code>public class Person
{
    public int Id { get; set }
    public int Age { get; set; }
    public string Name { get; set; }
    public Pet Pet { get; set; }
}

public class Pet
{
    public int Id { get; set; }
    public int Age { get; set; }
    public Breed Breed { get; set; }
}
</code>```

And a method with the following declaration:

```<code>public Person GetPerson(int id) { ... }
</code>```

I am now curious if I am supposed to create a test that checks to see if the various properties of the Person are correct (GetPerson_PersonFound_PersonHasCorrectName() and so on)? I suspect that I, under normal circumstances, should? All depends on the requirements?

If those properties should be tested, am I then supposed to dig into Pet and check those properties as well? What about going even further, down into Breed? Can add up to quite a few tests quite quickly.

答:
I would agree to test a lot. In TDD you normaly write a Test first and THEN Implement. So if you don't write a Test which checks if a Person has an Age, then you don't implement it.
TDD workflow:

Write a Test which is not running (Red).

Implement only that this Test and the others are running (Green).

Refactor.

Although I must say that I don't Test Properties. Only if they contain logic. The reason is that Properties don't fail. What you can test is user Input, so that Age is formatted correctly and so on.


问:
Modulo Operator Runtime
I am reading a review sheet for a class and the instructor said this of the modulo operator:

Remember that modulus (%) has a runtime of O((logn)^2).

He continued to display this piece of code:

//Assumes n > 1

```<code>public boolean isPrime2 (int n) {
    int sqrtN = (int) Math. sqrt (n) ;
    for(int i = 2; i < sqrtN + 1; i++) {
        if (n % i == 0) return false;
    }
    return true;
}
</code>```

He said of this code:

O(n) = sqrt(n) x n^2.  As you can see, this method of checking if a number is prime only iterates from 2 to sqrt(n). Since we loop over a quadratic operation sqrt(n) times, the runtime is O(sqrt(n)).

Two things I don't understand.  One, why is the inside the for loop now an n^2 operation rather than a (logn)^2 operation.  Two, even if it is only an n^2 operation, shouldn't the total runtime then be O(n)?

答:
I assume the review sheet you are reading is flawed:

Modulo/remainder is a O(1) operation (it's essentially just a variation on division, which takes constant time on fixed-sized numbers).

Therefore, the inside of the loop is an O(1) operation,

which makes the total complexity O(√n).

However, let's assume for a moment that % would denote a waste-time-operator with complexity O(log(n)²). In that case, we would end up with a complexity O(√n · log(n)²). The expression √n · log(n)² cannot be simplified. However, the complexity class O(√n · n²) includes O(√n · log(n)²):

```<code>   O(√n · n²) includes O(√n · log(n)²)
⇔    √n · n²      >      √n · log(n)²
⇔         n²      >           log(n)²   assuming n ≠ 0
⇔         n       >           log(n)    assuming n > 0
which is true for n > 1
</code>```

Of the three conditions n ≠ 0, n > 0, n > 1 the last one is the strongest, and is guaranteed by a comment in the code. It would therefore be correct to say that the code has O(√n · n²) complexity, although it is also true that it has O(√n · log(n)²) complexity, which is a stronger statement.

Note that the expression √n · n² can be simplified, but not to n:

```
   √n · n²
=  n<sup>1/2</sup> · n²
=  n<sup>1/2 + 2</sup>
=  n<sup>5/2</sup>
=  √(n<sup>5</sup>)
```

Title: Modulo Operator Runtime

Body:
I assume the review sheet you are reading is flawed:

Modulo/remainder is a O(1) operation (it's essentially just a variation on division, which takes constant time on fixed-sized numbers).

Therefore, the inside of the loop is an O(1) operation,

which makes the total complexity O(√n).

However, let's assume for a moment that % would denote a waste-time-operator with complexity O(log(n)²). In that case, we would end up with a complexity O(√n · log(n)²). The expression √n · log(n)² cannot be simplified. However, the complexity class O(√n · n²) includes O(√n · log(n)²):

   O(√n · n²) includes O(√n · log(n)²)
⇔    √n · n²      >      √n · log(n)²
⇔         n²      >           log(n)²   assuming n ≠ 0
⇔         n       >           log(n)    assuming n > 0
which is true for n > 1

Of the three conditions n ≠ 0, n > 0, n > 1 the last one is the strongest, and is guaranteed by a comment in the code. It would therefore be correct to say that the code has O(√n · n²) complexity, although it is also true that it has O(√n · log(n)²) complexity, which is a stronger statement.

Note that the expression √n · n² can be simplified, but not to n:

   √n · n²
=  n1/2 · n²
=  n1/2 + 2
=  n5/2
=  √(n5)


答:
Of course you must test the values of an object returned by the tested method - at least those that are necessary to fulfill that method's contract. What else are you supposed to test? Its class? That's already guaranteed by the type system. (And if your type system doesn't enforce strict types, all the more reason to test that a property of the returned object (1) exists and (2) has the expected value.

If you mean whether properties in the stricter sense, i.e. accessor methods, should be tested, in principle they should - but if they are all trivial or even auto-generated, obviously the potential for error is rather small, so those are not the most important tests you should write.

Title: Should we test the values of objects returned from the methods being unit tested?

Body:
Being new to unit testing I would like to know if I am supposed to test the values of objects returned from methods when doing unit testing. As an example, consider the following classes:

```<code>public class Person
{
    public int Id { get; set }
    public int Age { get; set; }
    public string Name { get; set; }
    public Pet Pet { get; set; }
}

public class Pet
{
    public int Id { get; set; }
    public int Age { get; set; }
    public Breed Breed { get; set; }
}
</code>```

And a method with the following declaration:

```<code>public Person GetPerson(int id) { ... }
</code>```

I am now curious if I am supposed to create a test that checks to see if the various properties of the Person are correct (GetPerson_PersonFound_PersonHasCorrectName() and so on)? I suspect that I, under normal circumstances, should? All depends on the requirements?

If those properties should be tested, am I then supposed to dig into Pet and check those properties as well? What about going even further, down into Breed? Can add up to quite a few tests quite quickly.


问:
I know JavaScript really well, but i bomb coding interviews
So I'm currently on a hunt for a new position as a Front-End Developer. I know JavaScript very well and can wax poetically about Closures, Currying, Prototypal Inheritance, Design Patterns, App performance and overall Front-End Architecture. But yet I still end up bombing job interviews. (FYI most of the jobs I'm interviewing for are for building SPA's with some sort of MVC framework)

Usually the coding tests are small code snippets of things I never come across professionally. Like write a function to solve some sort of math problem. Aside from the inherit awkwardness of trying to code while holding the phone in one hand and having a stranger see your screen and watch every character you type, I just don't usually see this kinda stuff in the real world.

Is this a serious skill set I'm lacking or are the interviewers asking me irrelevant questions. I guess I should work on my functional programming and algorithm chops but I haven't found many good resources on the web (or in print) any suggestions?

答:
Writing code is only a part of the interview process.

Actually solving the logical problem is only a part of the code writing task.

Interviewers want to be sure that:

You can write code. Many candidates with ten years professional experience in a language can't write any code at all, and this test is intended to reject those candidates.

You think about a problem before you write code. Many would jump to their keyboards, write tens of lines of code, then find that they misunderstood the original problem, because they didn't take time thinking about it.

You are able to adapt yourself when writing code. Say you found a solution, but when you started to implement it, it appeared that your first idea wasn't the best one; can you rapidly switch to a better one, eventually refactoring the code you wrote?

This also means that such interviews should be more interactive. Instead of typing with one hand, buy a hands-free kit or call through Skype and use a headset. Type as you are typing at work, while commenting and explaining what you do: it will suddenly become much less awkward.

Have you done pair programming? If yes, the interview situation is very similar, except that the interviewer may not give you his opinion, and you don't ask him to switch keyboards with you when you're finished.

Here are a few examples of a purely mathematical problem and how it shows non-mathematical skills of a developer.

Example 1: simple coding exercise

You need to implement Fibonacci number calculator in JavaScript. You should be able to change the index. The Fibonacci sequence follows those rules:

The first two numbers of the sequence are 0 and 1,

Each subsequent number is the sum of the previous two.

Example: F0 = 0, F1 = 1, F2 = 1, F3 = 2, F10 = 55.

You have three minutes.

Here, the interviewer wants you to think as fast as possible, find the solution and quickly implement it. Such exercise is unrelated to what actual developers do and is much closer to what you can find when doing a CS degree, but interviewers like this sort of things, so let's do it. Also, time constraint makes it impossible to do any automated testing, so the interviewer probably doesn't expect this from you.

“The description of the algorithm makes me think about recursion. The second rule leads to the following recursive function.”

```<code>var fibonacci = function (n) {
    return fibonacci(n - 2) + fibonacci(n - 1);
};

console.log(fibonacci(10));
</code>```

“To end the recursion, we will add the special cases by replacing the body of fibonacci function.”

```<code>switch (n) {
    case 0: return 0;
    case 1: return 1;
    default: return fibonacci(n - 2) + fibonacci(n - 1);
}
</code>```

“Done.”

Conclusion

As I said, such exercise is completely unrelated to an actual job of a developer. Does it make it meaningless? Not really, because at least, it shows that the person:

Is able to think about a problem. Some candidates will be totally lost, and under stress, will take more than the allocated time just to think about a possible way to approach the problem.

Knows recursion or is able to circumvent recursion through an ordinary loop. Later, the interviewer may ask if there were ways to use/not use recursion, and what are the benefits/drawbacks of recursion.

Knows the basics of the programming language. It doesn't matter if the person used switch, a guard clause, a conditional or a dictionary: depending on the background, different candidates will pick different tools to accomplish the same thing.

Keeps focused on the problem, without bringing things like unit tests, scalability or performance. The interviewer may then ask why performance-wise, the function above is terrible, expecting the candidate to explain what should be done to bring performance to a reasonable level.

Example 2: tricky questions

You need to implement Fibonacci number calculator in JavaScript. It should be as fast as possible. You should be able to change the index ranging from 0 to 100. The Fibonacci sequence follows those rules:

The first two numbers of the sequence are 0 and 1,

Each subsequent number is the sum of the previous two.

Example: F0 = 0, F1 = 1, F2 = 1, F3 = 2, F10 = 55.

You have three minutes.

Now, we have an interesting constraint which shows that the interviewer doesn't really care about the ability of the candidate to solve problems, but rather about his ability to guess which ways are faster than others.

Those tricky questions usually invite tricky answers. Here, given time constraint, there is no way to make multiple implementations, benchmark them, profile the fastest one and come with an optimal solution.

Instead, what about:

“Let me Google "First Fibonacci numbers"... This looks promising. With a <s>simple</s> (that would be an oxymoron) regular expression, we can build a comma-separated list of values.”

```<code>sed -e "s;\([0-9]*\) \([0-9]*\);'\2',;g" fbncc10.txt | tr '\n' ' '
</code>```

“Finally, the program itself.”

```<code>var map = ['0', '1', '1', '2', '3', '5', '8', '13', '21', '34', '55', '89', '144', '233', '377', '610', '987', '1597', '2584', '4181', '6765', '10946', '17711', '28657', '46368', '75025', '121393', '196418', '317811', '514229', '832040', '1346269', '2178309', '3524578', '5702887', '9227465', '14930352', '24157817', '39088169', '63245986', '102334155', '165580141', '267914296', '433494437', '701408733', '1134903170', '1836311903', '2971215073', '4807526976', '7778742049', '12586269025', '20365011074', '32951280099', '53316291173', '86267571272', '139583862445', '225851433717', '365435296162', '591286729879', '956722026041', '1548008755920', '2504730781961', '4052739537881', '6557470319842', '10610209857723', '17167680177565', '27777890035288', '44945570212853', '72723460248141', '117669030460994', '190392490709135', '308061521170129', '498454011879264', '806515533049393', '1304969544928657', '2111485077978050', '3416454622906707', '5527939700884757', '8944394323791464', '14472334024676221', '23416728348467685', '37889062373143906', '61305790721611591', '99194853094755497', '160500643816367088', '259695496911122585', '420196140727489673', '679891637638612258', '1100087778366101931', '1779979416004714189', '2880067194370816120', '4660046610375530309', '7540113804746346429', '12200160415121876738', '19740274219868223167', '31940434634990099905', '51680708854858323072', '83621143489848422977', '135301852344706746049', '218922995834555169026', '354224848179261915075'];

var fibonacci = function (n) {
    return map[n];
};

console.log(fibonacci(10));
</code>```

Conclusion

Tricky questions invite tricky answers. Don't be heroic, and don't start benchmarking and profiling when you only have three minutes. Think of clever ways to solve the problem while using your experience. My experience gives me a hint that using a map may be faster than computing the number. It may be wrong, but this attempt should be expected given the time constraint.

Knowing your tools also helps, and is an essential part of developer skills: without knowing regular expressions, I would either spend the allocated three minutes Googling for a comma-separated list, or would start writing a parser which will build the array I need.

Remember, a good developer is not one who starts coding right away, but who knows how to avoid coding when a better opportunity is available. Some interviewers won't hesitate to give you assignments which look like coding ones, but which require nearly no code at all.

Example 3: complete application development

You need to implement Fibonacci sequence in JavaScript. The length of the sequence is determined during the execution of the program. The sequence follows those rules:

The first two numbers of the sequence are 0 and 1,

Each subsequent number is the sum of the previous two.

Example: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89.

The application should be presented as a web page, allowing the user to specify the length of the sequence through an input field.

You have one hour.

Let's start.

“The example sequence is very helpful, since it will allow me to have a bunch of unit tests to ensure my implementation doesn't look completely wrong. In general, I use Mocha for node.js or QUnit for client-side JavaScript, but here, for the sake of simplicity, I'll just throw a bunch of test functions.”

“I start by creating index.htm and fib.js files. Then, I fill index.htm with really minimalistic and not W3C-compliant code (we can get back to this later if you're interested in my HTML skills as well).”

```<code><label>Length</label> <input id="length" value="15" />
<input id="compute" type="button" value="Compute" />
<div id="result" style="font-weight:bold;"></div>
<div id="tests"></div>
<script src="fib.js"></script>
</code>```

“Let's now write some code which will call the Fibonacci generator function and show the results.”

```<code>fibonacci = (function () {
    var compute,
        init;

    compute = function (length) {
        // TODO: Implement Fibonacci sequence.
        return [1, 2, 3];
    };

    init = function () {
        var button = document.getElementById('compute');
        button.addEventListener('onclick', function () {
            var length = parseInt(document.getElementById('length').value, 10),
                result;

            console.log(
                'Computing Fibonacci sequence of length ' + length + '.'
            );

            result = compute(length);
            document.getElementById('result').innerText = result.join(', ');
        });
    };

    return {
        compute: compute,
        init: init
    };
}());
</code>```

“It's time to run the code for the first time and... it doesn't work. Nothing happens. Why?”

“OK, I've forgotten the fibonacci.init(); at the end. I added it, and still, nothing happens, while it should at least display the message in the console. Wait, right, it's not onclick, but click; I use JQuery so often that I start to forget the names of the events in plain JavaScript.”

“Let's add some tests.”

```<code>ensureAreEqual = function (expected, actual) {
    var testResultsContainer = document.getElementById('tests');
    testResultsContainer.innerText += (expected.equals(actual) ?
            '.' :
            ('Actual [' + actual.join(', ') + '] is different from ' +
             'expected [' + expected.join(', ') + '].'));
};

test = function () {
    ensureAreEqual([0], compute(1));
};
</code>```

“Comparing arrays can be tricky, so I just copy-paste  Array.prototype.equals code from this answer.”

“Now that we run the application, it displays:”

Actual [1, 2, 3] is different from expected [0].

“The test failed, which was highly expected, given our actual implementation (return [1, 2, 3];) of Fibonacci sequence. It's time to change this.”

“From the original statement, Fibonacci sequence starts by [0, 1], so compute becomes:”

```<code>compute = function (length) {
    var fib = [0];
    return fib;
};
</code>```

“This makes it possible to pass the first test, and we can now write our second one.”

```<code>ensureAreEqual([0, 1], compute(2));
</code>```

“It fails, so we get back to compute and modify it.”

```<code>compute = function (length) {
    var fib = [0, 1];
    return length === 1 ? [0] : fib;
};
</code>```

“Now, both tests pass, and it's time to move to non-edge cases.”

```<code>switch (n) {
    case 0: return 0;
    case 1: return 1;
    default: return fibonacci(n - 2) + fibonacci(n - 1);
}
</code>```0

“All three tests pass now, except that the result doesn't look right for larger lengths such as 100. In order to get those results right, we should have used an arbitrary precision library. There are also things to improve. For example, naming conventions are sometimes too bad (what's fib?). HTML-related JavaScript code should also go to a different object, as well as testing code. Also, I haven't tested compute(0) and haven't checked the inputs.”

Conclusion

By walking through the example, you may see the interaction expected during an interview. Not everything was smooth (I did several mistakes at the beginning which lead me to an embarrassing situation where nothing happens when I run the application), and the original approach was lame if we have to support a large sequence length, but I've achieved to show that:

I can handle different issues,

I use test driven development, Fibonacci sequence being an excellent opportunity for this,

I copy-paste code when the source is trustworthy and writing it from scratch seems overwhelmingly complicated and error-prone,

I don't over-rely on libraries such as JQuery,

I chose the right scope: since the interviewer wants to check my JavaScript skills, I won't waste time writing perfect and clean HTML: not spending time here makes it possible to spend more time writing unit tests,

I know when to finish and tell that I'm done, while keeping in mind that a bunch of things are not perfect (like compute(0) which will fail, but it doesn't matter for the demo).

This is exactly what an interviewer should expect from you.

Body:
Writing code is only a part of the interview process.

Actually solving the logical problem is only a part of the code writing task.

Interviewers want to be sure that:

You can write code. Many candidates with ten years professional experience in a language can't write any code at all, and this test is intended to reject those candidates.

You think about a problem before you write code. Many would jump to their keyboards, write tens of lines of code, then find that they misunderstood the original problem, because they didn't take time thinking about it.

You are able to adapt yourself when writing code. Say you found a solution, but when you started to implement it, it appeared that your first idea wasn't the best one; can you rapidly switch to a better one, eventually refactoring the code you wrote?

This also means that such interviews should be more interactive. Instead of typing with one hand, buy a hands-free kit or call through Skype and use a headset. Type as you are typing at work, while commenting and explaining what you do: it will suddenly become much less awkward.

Have you done pair programming? If yes, the interview situation is very similar, except that the interviewer may not give you his opinion, and you don't ask him to switch keyboards with you when you're finished.

Here are a few examples of a purely mathematical problem and how it shows non-mathematical skills of a developer.

Example 1: simple coding exercise

You need to implement Fibonacci number calculator in JavaScript. You should be able to change the index. The Fibonacci sequence follows those rules:

The first two numbers of the sequence are 0 and 1,

Each subsequent number is the sum of the previous two.

Example: F0 = 0, F1 = 1, F2 = 1, F3 = 2, F10 = 55.

You have three minutes.

Here, the interviewer wants you to think as fast as possible, find the solution and quickly implement it. Such exercise is unrelated to what actual developers do and is much closer to what you can find when doing a CS degree, but interviewers like this sort of things, so let's do it. Also, time constraint makes it impossible to do any automated testing, so the interviewer probably doesn't expect this from you.

“The description of the algorithm makes me think about recursion. The second rule leads to the following recursive function.”

var fibonacci = function (n) {
    return fibonacci(n - 2) + fibonacci(n - 1);
};

console.log(fibonacci(10));

“To end the recursion, we will add the special cases by replacing the body of fibonacci function.”

switch (n) {
    case 0: return 0;
    case 1: return 1;
    default: return fibonacci(n - 2) + fibonacci(n - 1);
}

“Done.”

Conclusion

As I said, such exercise is completely unrelated to an actual job of a developer. Does it make it meaningless? Not really, because at least, it shows that the person:

Is able to think about a problem. Some candidates will be totally lost, and under stress, will take more than the allocated time just to think about a possible way to approach the problem.

Knows recursion or is able to circumvent recursion through an ordinary loop. Later, the interviewer may ask if there were ways to use/not use recursion, and what are the benefits/drawbacks of recursion.

Knows the basics of the programming language. It doesn't matter if the person used switch, a guard clause, a conditional or a dictionary: depending on the background, different candidates will pick different tools to accomplish the same thing.

Keeps focused on the problem, without bringing things like unit tests, scalability or performance. The interviewer may then ask why performance-wise, the function above is terrible, expecting the candidate to explain what should be done to bring performance to a reasonable level.

Example 2: tricky questions

You need to implement Fibonacci number calculator in JavaScript. It should be as fast as possible. You should be able to change the index ranging from 0 to 100. The Fibonacci sequence follows those rules:

The first two numbers of the sequence are 0 and 1,

Each subsequent number is the sum of the previous two.

Example: F0 = 0, F1 = 1, F2 = 1, F3 = 2, F10 = 55.

You have three minutes.

Now, we have an interesting constraint which shows that the interviewer doesn't really care about the ability of the candidate to solve problems, but rather about his ability to guess which ways are faster than others.

Those tricky questions usually invite tricky answers. Here, given time constraint, there is no way to make multiple implementations, benchmark them, profile the fastest one and come with an optimal solution.

Instead, what about:

“Let me Google "First Fibonacci numbers"... This looks promising. With a <s>simple</s> (that would be an oxymoron) regular expression, we can build a comma-separated list of values.”

sed -e "s;\([0-9]*\) \([0-9]*\);'\2',;g" fbncc10.txt | tr '\n' ' '

“Finally, the program itself.”

var map = ['0', '1', '1', '2', '3', '5', '8', '13', '21', '34', '55', '89', '144', '233', '377', '610', '987', '1597', '2584', '4181', '6765', '10946', '17711', '28657', '46368', '75025', '121393', '196418', '317811', '514229', '832040', '1346269', '2178309', '3524578', '5702887', '9227465', '14930352', '24157817', '39088169', '63245986', '102334155', '165580141', '267914296', '433494437', '701408733', '1134903170', '1836311903', '2971215073', '4807526976', '7778742049', '12586269025', '20365011074', '32951280099', '53316291173', '86267571272', '139583862445', '225851433717', '365435296162', '591286729879', '956722026041', '1548008755920', '2504730781961', '4052739537881', '6557470319842', '10610209857723', '17167680177565', '27777890035288', '44945570212853', '72723460248141', '117669030460994', '190392490709135', '308061521170129', '498454011879264', '806515533049393', '1304969544928657', '2111485077978050', '3416454622906707', '5527939700884757', '8944394323791464', '14472334024676221', '23416728348467685', '37889062373143906', '61305790721611591', '99194853094755497', '160500643816367088', '259695496911122585', '420196140727489673', '679891637638612258', '1100087778366101931', '1779979416004714189', '2880067194370816120', '4660046610375530309', '7540113804746346429', '12200160415121876738', '19740274219868223167', '31940434634990099905', '51680708854858323072', '83621143489848422977', '135301852344706746049', '218922995834555169026', '354224848179261915075'];

var fibonacci = function (n) {
    return map[n];
};

console.log(fibonacci(10));

Conclusion

Tricky questions invite tricky answers. Don't be heroic, and don't start benchmarking and profiling when you only have three minutes. Think of clever ways to solve the problem while using your experience. My experience gives me a hint that using a map may be faster than computing the number. It may be wrong, but this attempt should be expected given the time constraint.

Knowing your tools also helps, and is an essential part of developer skills: without knowing regular expressions, I would either spend the allocated three minutes Googling for a comma-separated list, or would start writing a parser which will build the array I need.

Remember, a good developer is not one who starts coding right away, but who knows how to avoid coding when a better opportunity is available. Some interviewers won't hesitate to give you assignments which look like coding ones, but which require nearly no code at all.

Example 3: complete application development

You need to implement Fibonacci sequence in JavaScript. The length of the sequence is determined during the execution of the program. The sequence follows those rules:

The first two numbers of the sequence are 0 and 1,

Each subsequent number is the sum of the previous two.

Example: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89.

The application should be presented as a web page, allowing the user to specify the length of the sequence through an input field.

You have one hour.

Let's start.

“The example sequence is very helpful, since it will allow me to have a bunch of unit tests to ensure my implementation doesn't look completely wrong. In general, I use Mocha for node.js or QUnit for client-side JavaScript, but here, for the sake of simplicity, I'll just throw a bunch of test functions.”

“I start by creating index.htm and fib.js files. Then, I fill index.htm with really minimalistic and not W3C-compliant code (we can get back to this later if you're interested in my HTML skills as well).”

<label>Length</label> <input id="length" value="15" />
<input id="compute" type="button" value="Compute" />
<div id="result" style="font-weight:bold;"></div>
<div id="tests"></div>
<script src="fib.js"></script>

“Let's now write some code which will call the Fibonacci generator function and show the results.”

fibonacci = (function () {
    var compute,
        init;

    compute = function (length) {
        // TODO: Implement Fibonacci sequence.
        return [1, 2, 3];
    };

    init = function () {
        var button = document.getElementById('compute');
        button.addEventListener('onclick', function () {
            var length = parseInt(document.getElementById('length').value, 10),
                result;

            console.log(
                'Computing Fibonacci sequence of length ' + length + '.'
            );

            result = compute(length);
            document.getElementById('result').innerText = result.join(', ');
        });
    };

    return {
        compute: compute,
        init: init
    };
}());

“It's time to run the code for the first time and... it doesn't work. Nothing happens. Why?”

“OK, I've forgotten the fibonacci.init(); at the end. I added it, and still, nothing happens, while it should at least display the message in the console. Wait, right, it's not onclick, but click; I use JQuery so often that I start to forget the names of the events in plain JavaScript.”

“Let's add some tests.”

ensureAreEqual = function (expected, actual) {
    var testResultsContainer = document.getElementById('tests');
    testResultsContainer.innerText += (expected.equals(actual) ?
            '.' :
            ('Actual [' + actual.join(', ') + '] is different from ' +
             'expected [' + expected.join(', ') + '].'));
};

test = function () {
    ensureAreEqual([0], compute(1));
};

“Comparing arrays can be tricky, so I just copy-paste  Array.prototype.equals code from this answer.”

“Now that we run the application, it displays:”

Actual [1, 2, 3] is different from expected [0].

“The test failed, which was highly expected, given our actual implementation (return [1, 2, 3];) of Fibonacci sequence. It's time to change this.”

“From the original statement, Fibonacci sequence starts by [0, 1], so compute becomes:”

compute = function (length) {
    var fib = [0];
    return fib;
};

“This makes it possible to pass the first test, and we can now write our second one.”

ensureAreEqual([0, 1], compute(2));

“It fails, so we get back to compute and modify it.”

compute = function (length) {
    var fib = [0, 1];
    return length === 1 ? [0] : fib;
};

“Now, both tests pass, and it's time to move to non-edge cases.”

compute = function (length) {
    var fib = [0, 1],
        i,
        next,
        current = 1,
        previous = 0;

    for (i = 2; i < length; i += 1) {
        next = current + previous;
        previous = current;
        current = next;
        fib.push(next);
    }

    return length === 1 ? [0] : fib;
};

“All three tests pass now, except that the result doesn't look right for larger lengths such as 100. In order to get those results right, we should have used an arbitrary precision library. There are also things to improve. For example, naming conventions are sometimes too bad (what's fib?). HTML-related JavaScript code should also go to a different object, as well as testing code. Also, I haven't tested compute(0) and haven't checked the inputs.”

Conclusion

By walking through the example, you may see the interaction expected during an interview. Not everything was smooth (I did several mistakes at the beginning which lead me to an embarrassing situation where nothing happens when I run the application), and the original approach was lame if we have to support a large sequence length, but I've achieved to show that:

I can handle different issues,

I use test driven development, Fibonacci sequence being an excellent opportunity for this,

I copy-paste code when the source is trustworthy and writing it from scratch seems overwhelmingly complicated and error-prone,

I don't over-rely on libraries such as JQuery,

I chose the right scope: since the interviewer wants to check my JavaScript skills, I won't waste time writing perfect and clean HTML: not spending time here makes it possible to spend more time writing unit tests,

I know when to finish and tell that I'm done, while keeping in mind that a bunch of things are not perfect (like compute(0) which will fail, but it doesn't matter for the demo).

This is exactly what an interviewer should expect from you.


问:
In plain English, what is recursion?
The idea of recursion is not very common in real world. So, it seems a bit confusing to the novice programmers. Though, I guess, they become used to the concept gradually. So, what can be a nice explanation for them to grasp the idea easily?</p>

答:
A nice explanaition of recursion is literally 'an action that reoccurs from within itself".

Consider a painter painting a wall, it's recursive because the action is "paint a strip from ceiling to floor than scoot over a little to the right and (paint a strip from ceiling to floor than scoot over a little to the right and (paint a strip from ceiling to floor than scoot over a little to the right and ( etc )))".

His paint() function calls itself over and over again to make up his bigger paint_wall() function.

Hopefully this poor painter has some kind of stop condition :)

Title: In plain English, what is recursion?


问:
Why would programmers ignore ISO standards?
One of the things I run into often is problems caused by programs which don't conform to ISO standardss.

One example would be not using the ISO country tables but making up their own shorthands, which goes okay for the United States (US), or the Netherlands (NL) but goes spectacularly wrong for the United Kingdom (GB, not UK) or Spain (ES, not SP) and a lot of other countries.

As another example, internal date notations. Why would anyone store a date as 01/02/2014 ever? It is completely unclear whether that is 1st February or January 2nd, whereas if you use the ISO standard you just store 2014-02-01* and it's unambiguously February 1st.

My question: When and why should a programmer make up their own constructs when there is an ISO standard available?

* Store 2014-02-01, and format the date accordingly when showing it to an end user.

答:
Never attribute to malice that which is adequately explained by stupidity.
  -- Robert J Hanlon.

That, and a lack of communication.

So, it's not a conspiracy of anti-ISO sentiment making people think "I know, I'll use UK instead of GB", nor is it an inclination that "they know better", or even a sense that the standard is no good. It'll be entirely because they just don't know it is there, and they should use it.

I mean, for some people, if it's not bundled into Visual Studio, it might as well not exist. For some others, maybe they just don't want the full set or it's too difficult to fetch the definitive list, so they just make up their own sub-set to solve their immediate situation. For others, the default is what gets used - so date formatting isn't "formatted in ISO, or even country locale", it's "formatted in whatever comes out" and if that suits them, then it's job done (this is usually a criticism of American programmers).


问:
Can I “just” create my own media type for a proprietary web/application communication
I read this question but it doesn't fully answer mine.

In the linked question, the OP asks what he must do to have his custom media type registered. I do not need that.

All I'm asking is, that if I am correct in assuming that, technically, all I have to do to create a custom media type is to, well.. just use it in my communication?

Basically, what I want to do is that my website offers a download of a file, described as application/x-my-custom-thing. On the client, the user has files ending with .my-custom-thing set as to open with the application I ship along.

So, what should happen is that, when the user clicks on the link, my application opens and reads the file and does stuff with it.

Are media types even the proper use case for this? Or, should I maybe "create" my own protocol in the sense of mycustomthing://example.com/the-file-to-use? Will that work with every (reasonably modern) browser?

答:
The primary purpose for media types used in HTTP communication is to tell the browser how they should treat the received content.

If you use the browser just to let the user to download the files to their computer, then you don't need to create your own media type. It will be sufficient to use the standard generic media type application/octet-stream.

If you want the browser to do more, then the user (or perhaps an installer) must associate your custom media type with your application. There is no automatic association and no relation between file extensions and media types (and some OSes don't even use the file extension to identify the type of file and how to open it).

Defining a custom protocol is unlikely to work. A protocol defines how the browser communicates with a server and browsers will not accept URIs with a protocol that they don't know.


答:
Recursion can be used to solve a lot of counting problems. For example, say you have a group of n people at a party (n > 1), and everyone shakes everyone else's hand exactly once. How many handshakes take place? You may know that the solution is C(n,2) = n(n-1)/2, but you can solve recursively as follows:

Suppose there are just two people. Then (by inspection) the answer is obviously 1.

Suppose you have three people. Single out one person, and note that he/she shakes hands with two other people. After that you have to count just the handshakes between the other two people. We already did that just now, and it is 1. So the answer is 2 + 1 = 3.

Suppose you have n people. Following the same logic as before, it is (n-1) + (number of handshakes between n-1 people). Expanding, we get (n-1) + (n-2) + ... + 1.

Expressed as a recursive function,

f(2) = 1

f(n) = n-1 + f(n-1), n > 2

Title: In plain English, what is recursion?

Body: The idea of recursion is not very common in real world. So, it seems a bit confusing to the novice programmers. Though, I guess, they become used to the concept gradually. So, what can be a nice explanation for them to grasp the idea easily?</p>


答:
In most REST APIs, the type of object is not embedded in the payload. That is the job of the resource resolver. Your "master registrar" is equivalent to the typical path resolver found in web servers, except for using embedded types instead of paths.

So instead of your format:

```<code>POST    /
{
    topic:
    {
        property1: "value1",
        property2: "value2",
        ...
    }
}
</code>```

use this one:

```<code>POST    /topics
{
    property1: "value1",
    property2: "value2",
    ...
}
</code>```

This will keep your design DRY while also leveraging standard built-in code as much as possible.

As far as the spec goes, POST is the "everything else" method, used for any processing which does not fit the semantics of GET, PUT, PATCH and DELETE. So you would not be violating the letter of the spec, but you may still end up confusing potential clients of your services because of the non-standard API.

Title: What is the purpose of RESTful URIs for POST/PUT/PATCH/DELETE methods?

Body:
In the process of conceiving a web application framework, I spent some time pondering the notion of RESTful paths. If I wanted to create e.g. a new topic, I might send a POST request to /topics. The parameters thereof might be something like: { topic: { body: 'Body' } }

As such, the type of resource being created can be inferred from the parameters. Since there is the top-level item 'topic', we can logically ascertain that the request is to create a topic.

For me, the strange thing is that POST create is the one action that falls outside of the notion of either a singular resource or a collection. It is arguably neither. Sure, you're adding to a collection, but in contrast to say a GET index you are not retrieving any part of that collection, and the state of that collection to a large extent is irrelevant. In contrast to a GET, PUT/PATCH, or a DELETE, you are not retrieving a singular item based on an identifier. You are creating an item where one does not exist.

I conceived of a "master registrar" service that would respond to all incoming POSTrequests. Imagine every form POSTing to /, with the master registrar determining the intended resource based on the params, and deferring to services that exist for the purpose of persisting a resource based on those params.

In fact, for any non-GET action, the paths become irrelevant. They don't seem to have an important semantic purpose. A user is not going to link to a form's action URL. Even in the case of PUT, PATCH, or DELETE The type of resource being created or the resource being modified can be inferred from the parameters. For example, if we were editing a topic versus creating one, the parameters might be { topic: { id: 1, body: 'New Body'} }. The presence of an ID in the parameters indicates that the topic in question already exists and should be retrieved foremost.

I don't know if this is RESTful or not. Regardless, I cannot see why this approach is invalid or inadvisable. Given my caution and naivete, however, I'd like to know why it might be.

Body:
In most REST APIs, the type of object is not embedded in the payload. That is the job of the resource resolver. Your "master registrar" is equivalent to the typical path resolver found in web servers, except for using embedded types instead of paths.

So instead of your format:

POST    /
{
    topic:
    {
        property1: "value1",
        property2: "value2",
        ...
    }
}

use this one:

POST    /topics
{
    property1: "value1",
    property2: "value2",
    ...
}

This will keep your design DRY while also leveraging standard built-in code as much as possible.

As far as the spec goes, POST is the "everything else" method, used for any processing which does not fit the semantics of GET, PUT, PATCH and DELETE. So you would not be violating the letter of the spec, but you may still end up confusing potential clients of your services because of the non-standard API.


问:
What is the best way for a programmer to handle being code reviewed?
I am fairly new to code review, but I have been coding for years during my PhD - which doesn't always make you a good programmer!

If the reviewer changes your code and goes through it with you line-by-line, what do you do if you disagree?  Sometimes you made choice X and the reviewer changes it to Y, and you had Y in your mind but decided not to do it because of the disadvantages, but the reviewer asserts that those disadvantages are not important. Should you verbalise your disagreement, or just not and listen to them?

Its difficult if you are not good at accepting criticism, and if the reviewer is a more senior person in the organisation.  It would not be good to come across as too defensive.

答:
Writing computer code is a prime example of making decisions under uncertainty. There are always conflicting pressures, and how you decide in any given question depends on what pressures you perceive and how big you consider them.

Therefore, when a reviewer disagrees with your decision, that means they see different pressures/risks than you do, or they consider some of them larger/smaller than you do. You must absolutely talk about these differences, because not doing so perpetuates the problems that led to disagreement in the first place.

If your reviewer is more senior, their experience may correctly tell them that this or that risk is not very relevant in practice, or they may know that some kind of error has a long history of occurring in your organisation, and it's worth being extra careful to avoid it. Conversely, if you feel that you know something your reviewer probably doesn't, you must absolutely express that; keeping silent amounts to a dereliction of duty on your part.

The most important part of handling the situation is to understand that criticism of design decisions is virtually always not a criticism of someone's personality. (In the rare cases where it actually is, you'll notice that soon enough, and if you truly cannot please somebody, nothing you do makes any difference, so where's the harm in following best practices? Far better to find a better position as soon as possible.) It is just a result of different people having different perceptions of the many risks and rewards involved in computer code, and given how complex modern computer code is, that is only to be expected. Talking about the differences helps improving the code and improving your cooperation in this case and in future cases.