问:
Concurrency: How do you approach the design and debug the implementation?
I've been developing concurrent systems for several years now, and I have a pretty good grasp on the subject despite my lack of formal training (i.e. no degree).  There's a few new languages that have become popular to at least talk about lately that are designed to make concurrency easier such as Erlang and Go.  It appears that their approach to concurrency echoes my own experience as to how to make systems scalable and take advantage of multiple cores/processors/machines.

However, I find that there are very few tools to help visualize what you intend to do, and verify that you are at least close to your original vision.  Debugging concurrent code can be a nightmare with languages that are not designed for concurrency (like C/C++, C#, Java, etc.).  In particular, it can be near impossible to recreate conditions that happen readily on one system in your development environment.

So, what are your approaches to designing a system to deal with concurrency and parallel processing?  Examples:

How do you figure out what can be made concurrent vs. what has to be sequential?

How do you reproduce error conditions and view what is happening as the application executes?

How do you visualize the interactions between the different concurrent parts of the application?

I have my own answers for some of these, but I'd also like to learn a bit more.

Edit

So far we have a lot of good input.  Many of the articles linked to are very good, and I've already read some of them.

My personal experience with concurrent programming leads me to believe you need a different mindset than you do with sequential programming.  The mental divide is probably as wide as the difference between object oriented programming and procedural programming.  I'd like this set of questions to focus more on the thought processes necessary (i.e. theory) to systematically approach the answers.  When providing more concrete answers, it helps to provide an example--something you went through personally.

Goal for the Bounty

Don't tell me what I should do.  I already have that under control.  Tell me what you do.  Tell me how you solve these problems.

答:
To me is all about the data. Break your data right, and parallel processing is easy. All the problems with retention, deadlocks, and so go away.

I do know that this is not the only way to parallelize, but for me is far the most useful.

To illustrate, a (not-so-quick) story:

I did work on a big financial (stock-market control) system on 2007 through 2009, and the processing volume of the data was very big. To illustrate, all calculations done to 1 single account of a client took about 1~3 seconds on their average workstation, and there were more than 30k accounts. Every night, closing the system was a big pain to the users (usually more than 6 hours processing, without any error-margin for them).

Studying the problem further revealed that we could paralelize the calculations among several computers, but we would still have a huge bottleneck on the old database server (an SQL 2000 server emulating SQL 6.5).

It was pretty clear that our minimum processing packet was the calculation of single account, and the major bottleneck were the database server retention (we could see on the "sp_who"s several connections waiting to do the same processing). So the parallel process went like this:

1) One single producer, responsible for either reading the database or writing on it, sequentially. No concurrency allowed here. The producer prepared a queue of jobs, for the consumers. The database belonged solely to this producer.

2) Several consumers, on several machines. Each one of the consumers received a whole packet of data, from the queue, ready to calculate. Each deqeue operation is synchronized.

3) After the calculation, each consumer sent back the data to an in-memory synchonized queue to the producer, in order to persist the data.

There were several check-points, several mechanisms to assure the transactions were correctly saved (none was left behind), but the whole work was worth of it. In the end, the calculations spread among 10 computers (plus the producer/queue computer) took down the closing time os the whole system to 15 minutes.

Just taking away the retention problems caused by the poor concurrency management SQL 6.5 had gave us a big advantage. The rest was pretty much linear, each new computer added to the "grid" made the processing time down, until we reached the "maximum efficiency" of the sequential read/write operations on the database.


问:
OOP principles and method names
```<code>class Boxer:

    def punch(self, punching_bag, strength):
        punching_bag.punch(strength)

class PunchingBag:

    def punch(self, strength):
        print "Punching bag punched with strength", strength

boxer = Boxer()
punching_bag = PunchingBag()

boxer.punch(punching_bag, 2)
</code>```

No doubts that punch is a good method name in case of a boxer.
But is name punch also good for the method of punching bag?
In both cases I mean punch as a command (i.e. do punch).

答:
The boxer punches the punchingbag -> boxer.punch

The punchingbag gets punched by the boxer -> punchingbag.get_punch

ContentLicense: CC BY-SA 3.0

Title: OOP principles and method names


问:
Where and when does firmware of a device run?
Does firmware of a device run in the device or the device's controller?

When does firmware of a device run? Does it run if and only if the cpu sends commands and/or data to the device's controller?

For example,

for a hard drive and its controller and firmware, does its firmware run in its controller and if and only if the cpu reads/writes to the hard drive?

for a wireless adapter and its firmware, does its firmware run if and only if the computer is connecting or connected to the wireless internet?

for BIOS, is it firmware for the bare computer system. Does it run in the cpu? Does it still run after the OS fully started?

Thanks.

I don't think the linked question is about firmware.

答:
Does firmware of a device run in the device or the device's
  controller?

When does firmware of a device run? Does it run if and only if the cpu
  sends commands and/or data to the device's controller?

It depends entriely on the device, and it's not either/or.

For example, your garden variety SATA disk drive has one or more processors of its own, and much of the disk drive's firmware is executed on those. Among other chores, the disk drive's processors are constantly monitoring the disk for errors, and reporting back to the host CPUs when requested. This is called Self-Monitoring, Analysis and Reporting Technology (SMART).

Devices can also have Option ROM which contain support code for the device that can be executed by the host CPUs.

For BIOS, is it firmware for the bare computer system. Does it run in
  the cpu? Does it still run after the OS fully started?

Yes, it runs on the computer CPU, but I get the impression that you think it runs in some sort of separate execution context. It's really just a library of code that the OS can call as needed to perform some sort of low level IO (BIOS stands for basic input/output system). The OS may or may not ignore the BIOS if it has some alternative library of code for the same task.

Firmware is really just a type of storage. It can contain code for use by a host CPU, it can contain code for the onboard device controllers, or it can just contain data.


问:
Open source License that doesn't require credit
Is there a known open-source license where the user who reuses or redistributes the code is not required to give credit to the author?  This is actually the same as just assuming copyright to the collection but placing the contents on the public domain.

P.S.

For me that is the real "open" and real "free" software, for not only everyone that uses it but also everyone that reads it and contributes to it is not bound to and is free in mind from any conditions that could prevent from them doing anything on the software (including parts of software that already resides within their brains) .  No forced or not-so-obvious or tempted viral injection of philosophies.

答:
Licenses in this category include:

WTFPL - Due to its language, some people think it's not a valid license; I've also heard lawyers say that it's not a good license because it lacks an indemnity clause.

Many licenses in the general category of Beerware - In some variations, the only real license stipulation is "if we meet, feel free to buy me a beer."

Creative Commons CC0 - This is the only real "Public Domain dedication" license out there, because it's crafted to be valid in nearly every country that has Copyright laws, and it functions like a Public Domain dedication in those countries that don't actually have Public Domain.

The zlib/libpng license, which only requires that you don't misrepresent the source of the software - using it in a larger work doesn't require attribution.

There are several other examples I've seen, most of which fall in the "beerware" category.


答:
There is no license that does not claim copyright of the work.  Those are two contradictory concepts. The ability to grant permission to create derivative works and distribute is what the copyright provides the original copyright holder. The license allows you to do these things.

Setting that aside...

Licenses that don't require attribution and provide the appropriate disclaimer of warranty are very dangerous for a company to use (I wouldn't use one) and possibly for the author to release.  The lack of disclaimer of warranty means that in some jurisdictions, if someone hooks it up to a rocket that explodes, they can sue you (note that most places anyone can sue anyone for anything). Whether or not they will prevail is up in the air... but the issue remains.

Furthermore, there are jurisdictions that don't acknowledge public domain. In these jurisdictions, you can't use "public domain" software as it is equivalent to all rights reserved.

The right thing to do is to release your software under a permissive license that has the disclaimer of warranty, claim of copyright and appropriate license. The licenses are there to protect you and those who use your software by explicitly stating what you are granting and what they may do with it.

If that license isn't there, I wouldn't touch it with a 10 foot pole, and I'm fairly sure any legal department wouldn't let developers at their companies do anything with it either.

The essence of a license is "I, ${name}, own said work and provide it under such and such terms."  If I do not have documentation of what terms you grant the use of the software under, I risk not following them and legal repercussions.  If you have patents (or trademark) in the software and don't release it under something that grants me patent (or trademark) use (such as the Apache 2.0 License), I can get in big trouble.

Thus, trying to get away with a "do whatever" license, it limits the people who would use it to only those who don't care about the repercussions of possibly stepping on a patent (whatever your feeling of them, it is a risk) or if you get a lawyer to state a different interpretation of a lesser known license than the one that I hire.

If you want something to be as free (libre) as possible and without restriction, it is best to use a well known license that follows the proper protocols for being a good license such as the Apache 2.0, MIT, BSD 2 clause or similar.

You can't give it away, because people who are aware of these issues won't touch it if you try.

When I say that its dangerous to use - its dangerous for me to use software that doesn't have a license (or one that I don't understand the nuances of).

If there is no license on the software saying how I may use it, when you die your estate (the owners of the copyright then) may change the license. If there is nothing saying that I may use it, I've got to stop using it right then.  For that matter, if the license is legally dubious (such as the beerware or wtfpl) there may be difficulties for me saying "nope, that isn't legal and is reverting to all rights reserved."

There is also the possibility that another party may claim that the source code that I am using (that I got from you) is theirs.  Without a license saying "this is where I got it and how I may use it" it becomes problematic for me.

Lastly, there are the patents that may be hidden behind source code that some licenses won't protect me from.  If you have a patent on some aspect of the software that is there and release it with something that doesn't have a patent grant (such as the Apache), I can get in big trouble.

For me, the risks of using software that isn't a well understood license aren't worth it. Many legal departments at companies won't touch licenses that aren't on their approved list (or spend the appropriate amount of time to properly understand the legal implications of it).  And they are serious about this.

If you want your source code to be useably by everyone, chose a license that people understand, has the appropriate grants of permission and states clearly what I may do with it.  If you don't want to claim the copyright on it, it is too risky for me to use.

Title: Open source License that doesn't require credit

Body:
Is there a known open-source license where the user who reuses or redistributes the code is not required to give credit to the author?  This is actually the same as just assuming copyright to the collection but placing the contents on the public domain.

P.S.

For me that is the real "open" and real "free" software, for not only everyone that uses it but also everyone that reads it and contributes to it is not bound to and is free in mind from any conditions that could prevent from them doing anything on the software (including parts of software that already resides within their brains) .  No forced or not-so-obvious or tempted viral injection of philosophies.


问:
Domain names vs URL path for web services
A team at the office is developing web micro-services intended to support sales sites and mobile apps with total combined orders count of less than 100K (not sure how much less but greater than 10K) per month.

They are using NodeJS, Docker and AWS. Their idea is that each service will only have one or two endpoints and its own DB.

For example there would be a Tax service that only GETs the tax calculated for an Order object, then another PlaceOrder service receives a POST with an Order object, possibly another CheckStatus service would return current status for an Order object or ID etc.

Each of these services is actually a completely separate NodeJS project, hosted in a separate repo, compiled by a separate Jenkins project and put in its own Docker container, which is then deployed on a server of its own (Beanstalk)

Each of these servers then gets a domain name for each of its deployment phases (DEV, QA, INT, STAGE, PROD), so for the two services we have in the example there are 10 domain names: PHASE.taxService.api.company.com
and PHASE.orderService.api.company.com

Question is:  is this a normal practice, do you see benefits or issues with this scenario. Is there a reason to prefer either dev.taxService.api.company.com or dev.company.com/api/taxService?

答:
Is there a reason to prefer either
  dev.taxService.api.company.com or dev.company.com/api/taxService?

It seems basically your question boils down to whether it's better to use sub-domains or sub-directories to separate services.

It seems there's plenty of people on either side of the fence, for example:

Google seems to prefer sub-directories, here's two examples of different services:

Gmail service: https://www.googleapis.com/upload/gmail/v1/users/userId/drafts

Analytics service: https://www.googleapis.com/analytics/v3/data/mcf

Amazon seems to prefer sub-domains, for example:

SQS: http://sqs.eu-west-1.amazonaws.com/

S3: http://s3-sa-east-1.amazonaws.com/

Personally I generally prefer sub-domains because:

They don't require a load balancer / reverse proxy to map the sub-directory to a service.

Sub-directories make sense in the context of HTTP, but if your service involves other protocols then it may not.

It's usually easier to split services between infrastructure providers using sub-domains which is useful during a migration. ie. you can easily move service 1 to provider B by pointing the sub-domain there, while service 2 remains on provider A. Doing that with a sub-directory will probably require you to reverse proxy to a totally separate data centre.


问:
Programming with voice recogition software
I used Dragon Naturally Speaking very briefly a few years ago and was thinking if it would be a viable solution for programming?

I was thinking more so if you break your arm or something that would be a major hinderance to programming.

This same question on SO but was never answered.

答:
You can indeed build a programming by voice solution using Dragon NaturallySpeaking, but Dragon NaturallySpeaking is going to be only a small piece of the overall solution.

You need a lot of technology beyond simply turning voice into words in order to program by voice successfully.  Some examples of the issues that must be addressed:

How do you enter unpronounceable words like ostreambuf_iterator?  How do you handle the heavy levels of punctuation in programming languages? How will you switch between windows?

Generally it takes several months to build and learn a programming by voice solution.  People like Joe that expect to get something working in a day or two are going to be sorely disappointed.

Moving back and forth works fine with voice given a reasonable set of commands. For example, you can easily specify the target line using its displayed line number mod 100. Moving by words or punctuation characters works well with programming languages for moving within a line.

You can find a lot more information about these issues in the programming by voice FAQ located at http://vocola.net/programming-by-voice-FAQ.html


问:
What are the real benefits of static code analysis?
Tools like pc-lint or QAC can be used to perform static code analysis on a code base.

In my experience the static analysis often yields a huge amount of noise, i.e. warnings on things that are not real bugs but somehow violate one of the rules in a given rule set. Turning off certain rules (either for good in the rule set or via special comments in the code) can be a real cumbersome process.

What are the real benefits of static code analysis?

答:
I worked at a place that used a commercial static code analysis system called Coverity Prevent, and it was freaking amazing! It's really sophisticated and intelligent.

We threw about 18 GB of both open-source and proprietary C and C++ code at it, and it would trace through the code paths and quickly find subtle bugs that would take a human forever to track down. It was also great at pinpointing things that would usually be Heisenbugs.

It ran every few days against our code base, and a nice feature was that we could tell it, "This isn't really a bug," and it would remember that in the future.

The gotcha is, Coverity is really expensive. They don't publish the costs, but I get the sense that for commercial projects, it starts in the hundreds of thousands of dollars per year. But it probably saved us having to hire a whole bunch of developers and QA staff, so on the whole our management seemed to think it was a good buy.

Having had that experience, I look quite favorably on static code analysis.

ContentLicense: CC BY-SA 2.5


问:
How much to encapsulate when objects being dealt with are pretty similar
As I have been answering questions related to object-oriented design and how to go about reducing the amount of classes to make sure that there is not a lot of "class clutter" and code repetition I have started doubting myself as to how much encapsulation is too much encapsulation and by the same token how much encapsulation is not enough encapsulation.

Here is a specific scenario. One of the most painful ones, which I have come across a few times already, is when one is trying to retrieve few pieces of similar data from the database and as a result the row objects and repositories look very similar as well.

This begs a question as to how much should one encapsulate. I guess for the entity objects one could create a base class, but what about the repositories?

Most of the mapping code is going to be similar but are you really going to put half of mapping in the base class and half of it in the subclasses? Not that you can't but for me personally it is a code smell in a sense that your base class is supposed to facilitate the creation of its derived classes but not help them with their method implementation. It should allow them to override methods but not give them half of the mapping logic and then let them implement the rest.

Would you rather completely separate the repositories even if they were a bit similar in data mapping (the entity objects would be different for each repository) or would you try to base class some of it?

Basically my struggle is this:

Would you rather let each repository encapsulate all that it needs for itself even if some of it might be similar to other repositories?

Or

Would you rather base class it by getting rid of the duplication and as a result have that strange design where a base class provides half the logic and the subclasses take care of the rest?

Example:

```<code>public class RepositoryA
{
    private EntityObjectA load()
    {
         // load from db by calling a stored procedure
         // once loaded we do mapping
     }
 }

public class RepositoryB
{
    private EntityObjectB load()
    {
        // load from db by calling a stored procedure
        // once loaded we do mapping
    }
}

public class RepositoryC
{
    private EntityObjectC load()
    {
        // load from db by calling a stored procedure
        // once loaded we do mapping
    }
}

public class EntityObjectA
{
    public string field1 { get; set; }
    public string field2 { get; set; }
    public string field3 { get; set; }
}

public class EntityObjectB
{
    public string field1 { get; set; }
    public string field2 { get; set; }
    public string field3 { get; set; }
    public string field4 { get; set; }
    public string field5 { get; set; }
}

public class EntityObjectC
{
    public string field1 { get; set; }
    public string field2 { get; set; }
}
</code>```

Now then would you make a baseclass as an EntityObjectBase?

That I can still understand but what about the repositories?

I mean you can pretty much see mapping is going to be pretty similar but does it worth trying to combine them?

How far do you go with encapsulation because in this case there will be some code repeat if we don't, but if we do we get a weird type of design.

答:
Not that you can't but for me personally it is a code smell in a sense
  that your base class is supposed to facilitate the creation of its
  derived classes but not help them with their method implementation.

I'm not sure if this assertion is necessarily true.

I can think of many examples where it's accepted for base classes to provide functions which are useful to the internal implementation of classes extending them. Perhaps a trivial example would be something like a toString() or equals() method which is often useful to the internal implementation of child classes. Also, the protected access modifier is explicitly intended for the scenario where a function should be accessible to a child internally but not externally.

In your case I think a combination of a template method pattern and generics could be used. The load function would belong to the abstract class, it would call a protected getStoredProc() function (not implemented in the abstract class), and return a generic type. Then the actual implementation only has to implement the getStoredProc() method and define the type.


问:
Is it bad to use POST only on an API?
I'm about to develop a new API for our website. Part of the design I've considered to use the POST and GET methods but after reading some security stuff I realise that GET is a bit less secure(i.e. allows hotlinking) than POST.

So my question is why people use GET in an API if is less secure? Is it just a legacy conception that "GET" should be used to read and POST to write (i.e. forms).  The GET method still makes sense to me for an image URL or a website page which you can bookmark but does it make sense for an API? Using the same method (i.e. POST) would make the API more consistent too as you don't need to worry about the method.

I should mention that I don't want to argue against the HATEOS/RESTful thing because I'm planning a RPC api (i.e. like twitter, facebook etc).

答:
So my question is why people use GET in an API if is less secure?

People often think using POST requests are a solution to CSRF but POST requests are still vulnerable and if CSRF prevention is your goal then you should implement a CSRF token.

However, CSRF is not usually considered a threat to an API because the fundamental premise of a CSRF attack (ie. one site making a request to another without human action) is actually the intention. To give a really simple example, a malicious site which submits a form to mybank.com/transfermoney works because the user already has an authentication cookie set for mybank.com. However, if an AJAX request was made to mybank.com/transfermoney it wouldn't work because the cookie won't be sent and therefore the user won't already be authenticated.

To authenticate with an API you usually have to pass something like an authentication token/key which an attacker would have to know, compared to the other example where the attacker didn't have to know the cookie value to invoke an authenticated action.

With regard to GET vs. POST, if you're trying to achieve a RESTful interface then GET and POST have different functions. GET should be used for retrieving (reading) a resource, whereas POST should be used for submitting a new one.

Title: Is it bad to use POST only on an API?


问:
Tags DB structure - tags table using one join and GROUP BY, or pivot (join) table using two joins?
I'm implementing tags into my question and answer application. Users will be limited to the tags available by the app, so they can't choose their own. So maybe only 30-50 tags will be available. This could change in the future though but for now that's the deal.

I'm considering two options:

Option 1:

questions table: id, title, etc

tags table: id, name, question_id

Here the questions-tags relationship is questions has many tags, and tags belongs to questions. This way, only one join is required. However, this tags table may have many duplicates if more than one user chooses e.g. "hotels" tag. In which case, when fetching a list of tags I'll do a GROUP BY in the SELECT statement. This way, only one table join is required.

Options 2:

questions table: id, title, etc

questions_tags table: id, question_id, tag_id

tags table: id, name

This way will eliminate duplication I guess, so if two users select "hotels" tables then "hotels" isn't stored twice.. but, it requires two joins: questions (join) questions_tags (join) tags.

From a performance point of view (and without having to spend time to create tests using thousands of questions/ tags for both cases), is one preferred over the other? Is GROUP BY with only one table join generally going to be faster than two table joins where there may be thousands of questions, each with a few tags of their own?

答:
I would go with Option #2 to eliminate the duplication, as you mentioned. I am not sure of the performance implications of joins and grouping here but I do believe it's a cleaner representation of the data.

That said, I would consider using a graph database like Neo4J or Titan. It simplifies querying these types of relationships.


答:
Is there a known open-source license where the user who reuses or redistributes the code is not required to give credit to the author?

Sure ... lots of them!

This is actually the same as just assuming copyright to the collection but placing the contents on the public domain.

I don't know where you got that notion from.  It is completely wrong ... and would be unworkable if it was correct.

The copyright of an open source licensed product X remains with the authors of X

The copyright of a product Y that uses an existing open source product X remains with the authors of Y.

The only issue is whether the authors of Y have permission (granted by the copyright-based license of X) to do what they want / need to do.

Giving credit is an orthogonal issue.  It is nothing to do with granting or receiving a grant of copyright.  Indeed giving credits to someone gives them no rights of any kind. It is just like saying "thank you" to the people whose work you are building on.

MIT license requires "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.". BSD 2-clause requires "Redistributions of source code must retain the above copyright notice". And as for GPL, I'm not sure how "publish on each copy an appropriate copyright notice" would mean - it's not clear if it would be necesseray to still retain the copryright information from the original author.

These are not requirements for giving credit.

They are actually requirements on you to not take away the author's statement of his / her rights, and claim of copyright.  And why should you?  If you want the original author's rights, get out your chequebook and pay for them!!

For me that is the real "open" and real "free" software, for not only everyone that uses it but also everyone that reads it and contributes to it is not bound to and is free in mind from any conditions that could prevent from them doing anything on the software (including parts of software that already resides within their brains) .

Fair enough.  But it is interesting that most people who publish open source software for free do actually require something in return.  If you don't like that, you need to find code that matches your philosophy.  But don't expect / demand other developers to conform to >>your<< notion of freedom :-).

However, the notion that a copyright-based license could have any legal hold over software that (somehow) resides in someone's brain is ... fanciful.


问:
What are useful metrics for source code?
What are useful metrics to capture for source code?

How can metrics, like for example (Executable?) Lines of Code or Cyclomatic Complexity help with quality assurance or how are they beneficial in general for the software development process?

答:
Take a look on Jeff's posts on the subject:

A Visit from the Metrics Maid

Software Engineering: Dead?

There is an old, but good, post from Joel too, closely related to software metrics, and I strongly recommend its reading:
The Econ 101 Management Method

The key point, for me, is this, quoting Jeff:
"Responsible use of the metrics is just as important as collecting them in the first place."


问:
Function naming design in a C Library
I'm writing a C (c99) library that operates on strings. I'm having a design problem writing functions that will perform in different modes.

For example; the Find function can search for:

the first, last, n-th element

different letter case

return position before or after the found element

search in a substring

Those modes cause exponential function naming. My solution is a function for each combination of modes:

Find(), FindCase(), FindSubstring(), FindSubstringCase(), FindSubstringCaseEnd(), FindEnd(),  ...

and so on until every combination is made. I have written the find functions in a way where each mode is just a wrapper to a generic find function that is called internally to avoid duplication. This made adding new function modes easy, the only downside is the unusual function count.

I don't think any more modes will be added, so the current function count is within double digits. Still I'm unsure if that is the best solution.

Alternate solutions I considered and didn't find worthy are:

Having one generic function with a lot of parameters. This is inferior because it is easier to remember the function name than its parameters. It is also error prone and puts an unecessary burden on the user.

Have a function that takes a string of modes( like fopen() ). Same problems as above.

Variable arguments functions are just not worth considering.

I think my solution is decent, since the user only has to remember the name, naming is consistent, so you can "guess" the name, and cannot really make a mistake. In the worst case you have to look-up the name and the name could be up to ~20 characters, which still takes less space than additional parameters.

Also note that this problem applies to other functions( insert, erase, ... ) to a lesser degree.

Still, I'm looking for better solutions if there are any.

答:
The amount of variables (and hence, the magnitude of the combinatorial explosion) can be reduced with a more general and modular API. For example, instead of making Find support substrings, create a separate function that takes a substring out of a string. Instead of returning either the start of the end of the match, always return the start and make it easy and cheap to compute the end from that.

If there is a generic implementation that all the variants would delegate to, you should probably expose it, if only to allow client code to call that function with run-time configuration (e.g., either ignore case or not depending on the value of a variable). Then you can still add convenience functions for common cases while culling the uncommon ones. printf is just fprintf with the first argument fixed to stdout.

Title: Function naming design in a C Library


问:
How can QA staff test caching logic that they can't see?
I just implemented a caching layer in my web application, and now I'm wondering how QA is supposed to test it, since caching is transparent to the user.

One idea I have is to put logging in the methods that invoke the code that populate the cache, and record when an object is pulled from cache and when it requires recreation from the database, and then the testers could view the logs to see if, for example, a certain object is reloaded from the db every 10 minutes, instead of every page view.

But can anyone suggest some better practices for this situation?

答:
Caching logic is something that should be unit tested by the developer as QA mainly does black-box testing.

QA would only care about the performance aspects or whatever fix you implemented thus, you can provide QA with a mechanism to enable/disable caching or whatever mechanism you used to improve performance, and then they can verify the performance difference.  Of course QA could also just verify an old release against your performance-improved one as well.


问:
When is it a good idea to force garbage collection?
So I was reading a question about forcing the C# garbage collector to run where almost every single answer is the same: you can do it, but you shouldn't - except for some very rare cases. Sadly, nobody there elaborates on what are such cases.

Can you tell me in what sort of scenario it is actually a good or reasonable idea to force garbage collection?

I'm not asking for C# specific cases but rather, all programing languages that have a garbage collector. I know that you can't force GC on all languages, like Java, but let's suppose you can.

答:
A real-world example:

I had a web application that made use of a very large set of data that rarely changed and which needed to be accessed very quickly (quick enough for per-keystroke response via AJAX).

The obvious enough thing to do here is to load the relevant graph into memory, and access it from there rather than the database, updating the graph when the DB changes.

But being very large, a naïve load would have taken up at least 6GB of memory with the data due to grow in the future. (I don't have exact figures, once it was clear that my 2GB machine was trying to cope with at least 6GB I had all the measurements I needed to know it wasn't going to work).

Luckily, there was a large number of popsicle-immutable objects in this set of data that were the same as each other; once I'd worked out that a certain batch was the same as another batch, I could alias one reference to the other allowing lots of the data to be collected and therefore fit everything into less than half a gig.

All well and good, but for this still churning through over 6GB of objects in the space of about half a minute to get to this state. Left to its own, GC didn't cope; the spike in activity over the usual pattern of the application (much less heavy on deallocations per second) was too sharp.

So periodically calling GC.Collect() during this build process meant that the whole thing worked smoothly. Of course, I did not manually call GC.Collect() the rest of the time the application runs.

This real-world case is a good example of the guidelines of when we should use GC.Collect():

Use with a relatively rare case of lots of objects being made available for collection (megabytes worth was being made available, and this graph-building was a very rare case over the lifetime of the application (about one minute per week).

Do it when a loss in performance is relatively tolerable; this happened only on application start-up. (Another good example of this rule is between levels during a game, or other points in a game where players won't be upset by a bit of a pause).

Profile to be sure there really is an improvement. (Pretty easy; "It works" almost always beats "it doesn't work").

Most of the time when I've thought I might have a case where GC.Collect() is worth calling, because point 1 and 2 applied, point 3 suggested it made things worse or at least made things no better (and with little or no improvement I'd lean toward not calling over calling as the approach more likely to prove better over the lifetime of an application).


答:
Using function names to differentiate among n true/false behaviors will result in 2n functions.  This is easy to manage when n is a small value like 2 or 3, but it gets out of hand very quickly with anything greater.  The POSIX open(2) call has nine true/false variants, and if that were written as one function per  combination, you'd be staring down 512 functions to choose from.

Choose-by-name makes a lot of work for your function's callers.  If my program has a dialog box with a text box for the user to enter a string and two check boxes to enable your "case" and "end" variants, my code ends up having to look like this:

```<code>char * string = get_pointer_to_string_typed_in_dialog_box();
_bool case_checked = dialogbox_case_checked();
_bool end_checked = dialogbox_end_checked();

if ( !case_checked && !end_checked ) { Find(string); }
else if ( case_checked && !end_checked ) { FindCase(string); }
else if ( !case_checked && end_checked ) { FindEnd(string); }
else if ( case_checked && end_checked ) { FindCaseEnd(string); }
else { assert(false);  // This shouldn't happen. }
</code>```

Add a third check box and the size of that else if ladder doubles and adds one additional check to each condition.  Multiply that by the number of times the function is called and you can pretty much see where that's headed.

One thing that's practically idiomatic in C (and the assembly language from which it descended) is the use of single-bit flags ORed together into an integer to enable one or more behaviors:

```<code>typedef size_t FindFlags;

#define FIND_CASE        ((FindFlags)1 << 0)
#define FIND_SUBSTRING   ((FindFlags)1 << 1)
#define FIND_END         ((FindFlags)1 << 2)
// Should do a static assertion to make sure the highest bit
// used isn't beyond what FindFlags can hold.

SomeReturnType find(char * string, FindFlags flags);
</code>```

Someone wanting to call your function uses the same identifier every time and assembles the flags they need:

```<code>void find(some_string, FIND_END | FIND_CASE);
</code>```

The hidden benefit in this is that it enables building up a set of flags programmatically without the else if monstrosity shown above:

```<code>char * string = get_pointer_to_string_typed_in_dialog_box();
FindFlags flags = 0;
if ( dialogbox_case_checked() ) { flags |= FIND_CASE; }
if ( dialogbox_end_checked()  ) { flags |= FIND_END; }
find(string, flags);
</code>```

In the worst case you have to look-up the name...

That's a much worse case than you think it is.  You'd have to establish a convention for how the combinations are strung together.  Alphabetical order (FindCase(), FindCaseEnd(), FindCaseEndSubstring()) would be intuitive.  If you're following the guideline that says you should write your code as if the people using it are psychotic and know where you live, forcing them to alphabetize their desired list of behaviors just to figure out the name of the function is a recipe for getting visits from axe-wielding developers.

... and the name could be up to ~20 characters, which still takes less space than additional parameters.

Unless you're planning to run this code in 1963, whether or not the developer has to key an additional dozen characters for a function call shouldn't even be on your radar.  Make it readable and easy for your callers to use.

Title: Function naming design in a C Library

Body:
I'm writing a C (c99) library that operates on strings. I'm having a design problem writing functions that will perform in different modes.

For example; the Find function can search for:

the first, last, n-th element

different letter case

return position before or after the found element

search in a substring

Those modes cause exponential function naming. My solution is a function for each combination of modes:

Find(), FindCase(), FindSubstring(), FindSubstringCase(), FindSubstringCaseEnd(), FindEnd(),  ...

and so on until every combination is made. I have written the find functions in a way where each mode is just a wrapper to a generic find function that is called internally to avoid duplication. This made adding new function modes easy, the only downside is the unusual function count.

I don't think any more modes will be added, so the current function count is within double digits. Still I'm unsure if that is the best solution.

Alternate solutions I considered and didn't find worthy are:

Having one generic function with a lot of parameters. This is inferior because it is easier to remember the function name than its parameters. It is also error prone and puts an unecessary burden on the user.

Have a function that takes a string of modes( like fopen() ). Same problems as above.

Variable arguments functions are just not worth considering.

I think my solution is decent, since the user only has to remember the name, naming is consistent, so you can "guess" the name, and cannot really make a mistake. In the worst case you have to look-up the name and the name could be up to ~20 characters, which still takes less space than additional parameters.

Also note that this problem applies to other functions( insert, erase, ... ) to a lesser degree.

Still, I'm looking for better solutions if there are any.

Body:
Using function names to differentiate among n true/false behaviors will result in 2n functions.  This is easy to manage when n is a small value like 2 or 3, but it gets out of hand very quickly with anything greater.  The POSIX open(2) call has nine true/false variants, and if that were written as one function per  combination, you'd be staring down 512 functions to choose from.

Choose-by-name makes a lot of work for your function's callers.  If my program has a dialog box with a text box for the user to enter a string and two check boxes to enable your "case" and "end" variants, my code ends up having to look like this:

char * string = get_pointer_to_string_typed_in_dialog_box();
_bool case_checked = dialogbox_case_checked();
_bool end_checked = dialogbox_end_checked();

if ( !case_checked && !end_checked ) { Find(string); }
else if ( case_checked && !end_checked ) { FindCase(string); }
else if ( !case_checked && end_checked ) { FindEnd(string); }
else if ( case_checked && end_checked ) { FindCaseEnd(string); }
else { assert(false);  // This shouldn't happen. }

Add a third check box and the size of that else if ladder doubles and adds one additional check to each condition.  Multiply that by the number of times the function is called and you can pretty much see where that's headed.

One thing that's practically idiomatic in C (and the assembly language from which it descended) is the use of single-bit flags ORed together into an integer to enable one or more behaviors:

typedef size_t FindFlags;

#define FIND_CASE        ((FindFlags)1 << 0)
#define FIND_SUBSTRING   ((FindFlags)1 << 1)
#define FIND_END         ((FindFlags)1 << 2)
// Should do a static assertion to make sure the highest bit
// used isn't beyond what FindFlags can hold.

SomeReturnType find(char * string, FindFlags flags);

Someone wanting to call your function uses the same identifier every time and assembles the flags they need:

void find(some_string, FIND_END | FIND_CASE);

The hidden benefit in this is that it enables building up a set of flags programmatically without the else if monstrosity shown above:

char * string = get_pointer_to_string_typed_in_dialog_box();
FindFlags flags = 0;
if ( dialogbox_case_checked() ) { flags |= FIND_CASE; }
if ( dialogbox_end_checked()  ) { flags |= FIND_END; }
find(string, flags);

In the worst case you have to look-up the name...

That's a much worse case than you think it is.  You'd have to establish a convention for how the combinations are strung together.  Alphabetical order (FindCase(), FindCaseEnd(), FindCaseEndSubstring()) would be intuitive.  If you're following the guideline that says you should write your code as if the people using it are psychotic and know where you live, forcing them to alphabetize their desired list of behaviors just to figure out the name of the function is a recipe for getting visits from axe-wielding developers.

... and the name could be up to ~20 characters, which still takes less space than additional parameters.

Unless you're planning to run this code in 1963, whether or not the developer has to key an additional dozen characters for a function call shouldn't even be on your radar.  Make it readable and easy for your callers to use.


问:
How do you handle shared concepts in a microservice architecture?
I am researching architectural patterns for an application I'm developing and a microservice approach seems like it would be a good choice but I am not sure how to handle interactions between the services.

The application primarily deals with users, profiles owned by users, photos, and tags that represent one to many profiles in a photo. There would conceivably be methods to return photos uploaded by a user, return photos that contain a certain tagged profile, etc.

This is my first stab at designing a microservice-based architecture and I come from a monolithic-esque domain model inspired history. In that world, controllers would stitch these domain objects together but I am having trouble wrapping my head around how this would work in a microservcey way.

答:
The application primarily deals with users, profiles owned by users,
  photos, and tags that represent one to many profiles in a photo. There
  would conceivably be methods to return photos uploaded by a user,
  return photos that contain a certain tagged profile, etc.

Well, profile service should not work with user object. It may know only the ID of the user for which it is asked to return data, no more. This way you will not require interaction between user service and profile service.

If that doesn't answer your question, could you please clarify it by describing the exact situation you are dealing with?


问:
How hidden classes allows faster access to properties in google's V8?
As Lars Bak and Jay Conrod described in several videos and papers, the main idea of hidden classes in V8 is to store concrete offset or transition to another hidden class which probably contains this offset for every object's property, instead of doing "slow" lookup in hashtable which contains all properties.

In old-fashioned way of property access, for example to get point.x, we need to calculate the hashcode from x and then go through array (if there wasn't hashcode-collision when property was added we'll get the value instantly). But in new-fashioned way we have a hidden class (just a Map?) and need to iterate through it to find out contains it the x key or not and only after that we can take property value by offset in x field. Or in more complicated case we need to do some additional steps through transitions to another hidden classes. So I don't see a difference between storing all properties in hashtable and using hidden classes. Maybe there is some assembly trick that I don't understand?

答:
V8 and other language implementations using similar techniques are just-in-time compilers. They generate code, and that generated code is speculatively optimized (with checks to fall back to slower, more general code if the specialization turns out to be invalid). So when generating code, the JIT compiler often has a good guess at what the hidden class of an object is — from type inference or from data collected while running the program — and it generates code like this:

```<code>compare hidden class pointer to address of assumed
if not equal, de-optimize, otherwise:
access the property at a hard-coded offset
</code>```

Each line of the above can be a single assembler instruction on x86. Since it assumes a hidden class when generating this code, the JIT compiler can retrieve the offset from the hidden class at JIT compile time and hard-code it in the code, so the code that runs often never even touches the hidden class.

Body:
V8 and other language implementations using similar techniques are just-in-time compilers. They generate code, and that generated code is speculatively optimized (with checks to fall back to slower, more general code if the specialization turns out to be invalid). So when generating code, the JIT compiler often has a good guess at what the hidden class of an object is — from type inference or from data collected while running the program — and it generates code like this:

compare hidden class pointer to address of assumed
if not equal, de-optimize, otherwise:
access the property at a hard-coded offset

Each line of the above can be a single assembler instruction on x86. Since it assumes a hidden class when generating this code, the JIT compiler can retrieve the offset from the hidden class at JIT compile time and hard-code it in the code, so the code that runs often never even touches the hidden class.


答:
The key is that this is being used in a JIT which produces specialized code.

Let's say that have a function something like this:

```<code>function add_points(a, b) {
   return new Point(a.x + b.x, a.y + b.y);
}
</code>```

V8 will actually generate different versions of this function, for different possible arguments that you pass in. For example, it would generate a version of the function that is only used when a and b are both members of a hidden Point class.

```<code>Point add_points(Point a, Point b) {
   return new Point(a.x + b.x, a.y + b.y);
}
</code>```

The trick then is that since we know that this function will only actually be used for objects with the Hidden point class, x and y are always going to be at the same offset. So we don't have to look it up each time, the compiler looked it up once while building this function, and inserted the offset into the generated code.

Title: How hidden classes allows faster access to properties in google's V8?

Body:
As Lars Bak and Jay Conrod described in several videos and papers, the main idea of hidden classes in V8 is to store concrete offset or transition to another hidden class which probably contains this offset for every object's property, instead of doing "slow" lookup in hashtable which contains all properties.

In old-fashioned way of property access, for example to get point.x, we need to calculate the hashcode from x and then go through array (if there wasn't hashcode-collision when property was added we'll get the value instantly). But in new-fashioned way we have a hidden class (just a Map?) and need to iterate through it to find out contains it the x key or not and only after that we can take property value by offset in x field. Or in more complicated case we need to do some additional steps through transitions to another hidden classes. So I don't see a difference between storing all properties in hashtable and using hidden classes. Maybe there is some assembly trick that I don't understand?

Body:
The key is that this is being used in a JIT which produces specialized code.

Let's say that have a function something like this:

function add_points(a, b) {
   return new Point(a.x + b.x, a.y + b.y);
}

V8 will actually generate different versions of this function, for different possible arguments that you pass in. For example, it would generate a version of the function that is only used when a and b are both members of a hidden Point class.

Point add_points(Point a, Point b) {
   return new Point(a.x + b.x, a.y + b.y);
}

The trick then is that since we know that this function will only actually be used for objects with the Hidden point class, x and y are always going to be at the same offset. So we don't have to look it up each time, the compiler looked it up once while building this function, and inserted the offset into the generated code.


问:
Include system timer in use case diagram

Here in my use case diagram, an sms will be sent to a referenced person by the applicant automatically by the system when an applicant fills up and submits a form. Here as the SMS sending is performed by the system, is it right to include system timer performing sms sending in the use case diagram shown below? If not, what should I replace it with.?

答:
is it right to include system timer performing sms sending in the use
  case diagram shown below? If not, what should I replace it with.?

Actors in use case diagrams don't have to be humans. It may as well be another system or the system itself.

I would replace the "system timer" box with an actor labelled "Alerting system" (or whatever your system is called).


答:
Usually, services call other services when they need to access their data. Each piece of data should belong to a particular service which will be the only entry point to accessing this data and modifying it. Some services will be simple and usually correspond closely to your domain model (e.g. a service for handling users) while others will be high-level and use data from other services (e.g. displaying a list of photos together with information about the users who uploaded them).

In your use case, you should start from the outside and think of what operations you want to make available to your user via an API (if it's a backend service) or what operations should be available in the GUI if it's a web application. Note that the GUI part is often a regular application with its own controllers: operations may be called via REST (like in AngularJS), but these endpoints are desinged only for the GUI application's use and are not microservices in the common sense.

Suppose you want to display photos together with information about uploaders. You could have a user service that returns information about a user given the user's ID and a photo service which can list photos (e.g. by searching by some criteria). The list of photos would contain for each photo the ID of the uploading user. This way these two services are not coupled - the photo service only knows about user IDs but nothing about the user data themselves. On top of these two services you could create a third service with an operation such as "list photos with information about uploaders" which would call the two other services and combine the data they return. Alternatively, this operation could be performed by your web application instead of a service.

Title: How do you handle shared concepts in a microservice architecture?

Body:
I am researching architectural patterns for an application I'm developing and a microservice approach seems like it would be a good choice but I am not sure how to handle interactions between the services.

The application primarily deals with users, profiles owned by users, photos, and tags that represent one to many profiles in a photo. There would conceivably be methods to return photos uploaded by a user, return photos that contain a certain tagged profile, etc.

This is my first stab at designing a microservice-based architecture and I come from a monolithic-esque domain model inspired history. In that world, controllers would stitch these domain objects together but I am having trouble wrapping my head around how this would work in a microservcey way.


问:
Is it okay to expose implementation components in a library?
I'm writing a library for general consumption (It's free software and open source). Is it okay to have a visible namespace (e.g. Library.Implementation) for implementation-only components that remain public for technical reasons (sharing between multiple packages/assemblies), but that aren't part of the library proper, and the user should avoid using?

I have mechanisms that could allow me to share the components while hiding them from users, but they're difficult to use due to technical reasons.

This wouldn't harm the integrity of the library, as the components are mainly utility code, and the library properly follows information hiding. Examples of the components include various conversion functions, a special variety of tuple, and some comparers. Users might even find the components useful, but they're not what the library is about.

答:
In proprietary software you want to hide implementation details, while in free software you don't care (and you would accept someone extending your library in unexpected ways using the implementation datails). I also think it is related to the notion of leaky abstractions, and since you commented that your library will be free software, I would suggest putting the implementation part in some delimited "implementation" name space (or whatever your programming language supports).

You may add a comment saying that the implementation specific code is some unstable API which might change without notice.

Besides, a user of your library might both use the library for the intended main use and also use the implementation details for some other goals (of his main program).

That was originally a comment, that I slightly expanded to an answer per your request.


问:
Is higher-rank parametric polymorphism useful?
I'm pretty sure everyone is familiar with generic methods of the form:

```<code>T DoSomething<T>(T item)
</code>```

This function is also called parametrically polymorphic (PP), specifically rank-1 PP.

Let's say this method can be represented using a function object of the form:

```<code><T> : T -> T
</code>```

That is, <T> means it takes one type parameter, and T -> T means that it takes one parameter of type T and returns a value of the same type.

Then the following would be a rank-2 PP function:

```<code>(<T> : T -> T) -> int
</code>```

The function takes no type parameters itself, but takes a function which takes a type parameter. You can continue this iteratively, making the nesting deeper and deeper, getting PP of higher and higher rank.

This feature is really rare among programming languages. Even Haskell doesn't allow it by default.

Is it useful? Can it describe behaviors that are difficult to describe otherwise?

Also, what does it mean for something to be impredicative? (in this context)

答:
Higher rank polymorphism is extremely useful. In System F (the core language of typed FP languages you're familiar with), this is essential for admitting "typed Church encodings" which is actually how System F does programming. Without these, system F is completely useless.

In System F, we define numbers as

```<code>Nat = forall c. (c -> c) -> c -> c
</code>```

Addition has the type

```<code>plus : Nat -> Nat -> Nat
plus l r = Λ t. λ (s : t -> t). λ (z : t). l s (r s z)
</code>```

which is a higher rank type (the forall c. appears inside those arrows).

This comes up in other places too. For example, if you want to indicate that a computation is a proper continuation passing style (google "codensity haskell") then you'd right this as

```<code>type CPSed A = forall c. (A -> c) -> c
</code>```

Even talking about an uninhabited type in System F requires higher rank polymorphism

```<code>type Void = forall a. a
</code>```

The long and short of this, writing a function in a pure type system (System F, CoC) requires higher rank polymorphism if we want to deal with any interesting data.

In System F in particular, these encodings need to be "impredicative". This means that a forall a. quantifies over absolutely all types. This critically includes the very type we're defining. In forall a. a that a could actually stand for forall a. a again! In languages like ML this isn't the case, they're said to be "predicative" since a type variable quantifies only over the set of types without quantifiers (called monotypes). Our definition of plus required impredicativity as well because we instantiated the c in l : Nat to be Nat!

Finally, I'd like to mention one last reason where you'd like both impredicativity and higher rank polymorphism even in a language with arbitrarily recursive types (unlike System F). In Haskell, there's a monad for effects called the "state thread monad". The idea is that the state thread monad lets you mutate things but requires to escape it that your result not depend on anything mutable. This means that ST computations are observably pure. To enforce this requirement we use higher rank polymorphism

```<code>runST :: forall a. (forall s. ST s a) -> a
</code>```

Here by ensuring that a is bound outside the scope where we introduce s, we know that a stands for a wellformed type which doesn't rely on s. We use s to parameritize all the mutable things in that particular state thread so we know that a is independent of mutable things and thus that nothing escapes the scope of that ST computation! A wonderful example of using types to rule out ill-formed programs.

By the way, if you're interested in learning about type theory I'd suggest investing in a good book or two. It's hard to learn this stuff in bits and pieces. I'd suggest one of Pierce or Harper's books on PL theory in general (and some elements of type theory). The book "Advanced topics in types and programming languages" also covers a good amount of type theory. Finally "Programming in Martin Lof's type theory" is a very good exposition into the intensional type theory Martin Lof outlined.

Body:
Higher rank polymorphism is extremely useful. In System F (the core language of typed FP languages you're familiar with), this is essential for admitting "typed Church encodings" which is actually how System F does programming. Without these, system F is completely useless.

In System F, we define numbers as

Nat = forall c. (c -> c) -> c -> c

Addition has the type

plus : Nat -> Nat -> Nat
plus l r = Λ t. λ (s : t -> t). λ (z : t). l s (r s z)

which is a higher rank type (the forall c. appears inside those arrows).

This comes up in other places too. For example, if you want to indicate that a computation is a proper continuation passing style (google "codensity haskell") then you'd right this as

type CPSed A = forall c. (A -> c) -> c

Even talking about an uninhabited type in System F requires higher rank polymorphism

type Void = forall a. a

The long and short of this, writing a function in a pure type system (System F, CoC) requires higher rank polymorphism if we want to deal with any interesting data.

In System F in particular, these encodings need to be "impredicative". This means that a forall a. quantifies over absolutely all types. This critically includes the very type we're defining. In forall a. a that a could actually stand for forall a. a again! In languages like ML this isn't the case, they're said to be "predicative" since a type variable quantifies only over the set of types without quantifiers (called monotypes). Our definition of plus required impredicativity as well because we instantiated the c in l : Nat to be Nat!

Finally, I'd like to mention one last reason where you'd like both impredicativity and higher rank polymorphism even in a language with arbitrarily recursive types (unlike System F). In Haskell, there's a monad for effects called the "state thread monad". The idea is that the state thread monad lets you mutate things but requires to escape it that your result not depend on anything mutable. This means that ST computations are observably pure. To enforce this requirement we use higher rank polymorphism

runST :: forall a. (forall s. ST s a) -> a

Here by ensuring that a is bound outside the scope where we introduce s, we know that a stands for a wellformed type which doesn't rely on s. We use s to parameritize all the mutable things in that particular state thread so we know that a is independent of mutable things and thus that nothing escapes the scope of that ST computation! A wonderful example of using types to rule out ill-formed programs.

By the way, if you're interested in learning about type theory I'd suggest investing in a good book or two. It's hard to learn this stuff in bits and pieces. I'd suggest one of Pierce or Harper's books on PL theory in general (and some elements of type theory). The book "Advanced topics in types and programming languages" also covers a good amount of type theory. Finally "Programming in Martin Lof's type theory" is a very good exposition into the intensional type theory Martin Lof outlined.


问:
Ideal way of updating app's views when data changes
Okay this is not platform specific question. But any answer related to iOS,Android or Windows Phone will help. So I am building a chat application (yes another one) but I am really confused about how you pros handle GUI update when a chat message arrives. I am not really concerned about performance issues but how devs update various part of app's GUI showing updated data.

For example Whatsapp has one master list where all the open chats are listed and then a separate chat display window(activity in case of Androids).

So when some message arrives, how do they update both views at the same time? Like if I am already chatting with someone and I receive a new message, the list gets updated as soon as the message arrives. I get this part but how is master list updated. Are they constructing whole of master view again after each and every single message? I just wanted to know the ideal mechanism to deal with this scenario.

答:
Generally, UI code is based on redrawing at least an entire component from an underlying data structure that describes what it should contain (e.g., a list of strings and icons becomes a list view, a string for a text field, etc). Sometimes data structures cannot receive incremental updates (e.g., String in Java). Other times they can. It's case-by-case. Sometimes an otherwise usable built-in UI component doesn't support incremental updating of its underlying data structure, and a custom UI component must be written that does almost the same thing but supports incremental updating.

For a typical chat application, I'm pretty sure it won't be a performance problem if incremental updating is not used.


问:
How can I add more classes in C# Windows Forms project?
When you program in Java, you have a package, and in that package you put class files, where you write your logic, you have one main file, and you spread your code in the rest of the classes, for example, I have one class which I use only for static variables, like this:

```<code>package com.mypackage.models;

public class MyConsts {

    public static final boolean DEBUG = true;
    // bla bla bla
}
</code>```

and then, from whichever class I can call that variable like this

```<code>MyConsts.DEBUG
</code>```

Now, how do you make more classes just like in Java, but in C# for a Windows Forms application, currently I only have this, and I only write the code in Form1.cs:

答:
To add more classes, just create additional files. You may have noticed that you have not one, but two classes: Form1 and Program: the last one corresponds to the Program.cs at the bottom on your screenshot.

In order to use those additional classes from your form:

Either initialize an instance of the class within the form. If it shares the same namespace than your form class, you can do it by name. Otherwise, you'll have to import the namespace with using statement.

Or call the static members of the class directly. For instance, if you have public static class MyConsts in your project with public static bool IsDebug { get { ... } } in it, you can simply do:

```<code>if (MyConsts.IsDebug)
{
    ...
}
</code>```

in your form file.

A few remarks which may help you through your migration from Java to C#:

Your application is not a WPF application. It's Windows Forms. Comparing WPF to Windows Forms is more or less like comparing Swing to AWT; WPF is newer and much more powerful, but you may not necessarily need this power, in which case Windows Forms is a perfectly valid choice. One major benefit of WPF for any application is data binding.

C# has properties. Use them. This is similar to getSomething and setSomething in Java, but provides a more concise syntax. Never access fields directly.

C# coding standards slightly differ from Java's; for instance, methods start with an uppercase letter. You can find them on MSDN, but you may also consider using StyleCop which checks whether your code matches the style rules.

If you want your application to behave differently in debug mode than in release mode, you can simply use the #if DEBUG. If you want to provide more verbose logging in debug mode, .NET Framework's logging already differentiates between debug and release mode, so you don't need to implement anything at code level.

Body:
To add more classes, just create additional files. You may have noticed that you have not one, but two classes: Form1 and Program: the last one corresponds to the Program.cs at the bottom on your screenshot.

In order to use those additional classes from your form:

Either initialize an instance of the class within the form. If it shares the same namespace than your form class, you can do it by name. Otherwise, you'll have to import the namespace with using statement.

Or call the static members of the class directly. For instance, if you have public static class MyConsts in your project with public static bool IsDebug { get { ... } } in it, you can simply do:

if (MyConsts.IsDebug)
{
    ...
}

in your form file.

A few remarks which may help you through your migration from Java to C#:

Your application is not a WPF application. It's Windows Forms. Comparing WPF to Windows Forms is more or less like comparing Swing to AWT; WPF is newer and much more powerful, but you may not necessarily need this power, in which case Windows Forms is a perfectly valid choice. One major benefit of WPF for any application is data binding.

C# has properties. Use them. This is similar to getSomething and setSomething in Java, but provides a more concise syntax. Never access fields directly.

C# coding standards slightly differ from Java's; for instance, methods start with an uppercase letter. You can find them on MSDN, but you may also consider using StyleCop which checks whether your code matches the style rules.

If you want your application to behave differently in debug mode than in release mode, you can simply use the #if DEBUG. If you want to provide more verbose logging in debug mode, .NET Framework's logging already differentiates between debug and release mode, so you don't need to implement anything at code level.


问:
How much data from a web service should I expose in a library?
I'm working on a personal project, a library that can access the weather forecasts and other weather related data from it.

However, a lot of the returned data is sometimes quite redundant or simply doesn't make sense to have certain data within that particular XML element etc. Consider this XML data I get from the service, which contains the hourly forecast:

```<code><hour>20</hour>
<hour_padded>20</hour_padded>
<min>00</min>
<min_unpadded>0</min_unpadded>
<sec>0</sec>
<year>2015</year>
<mon>3</mon>
<mon_padded>03</mon_padded>
<mon_abbrev>Mar</mon_abbrev>
<mday>21</mday>
<mday_padded>21</mday_padded>
<yday>79</yday>
<isdst>0</isdst>
<epoch>1426968000</epoch>
<pretty>8:00 PM GMT on March 21, 2015</pretty>
<civil>8:00 PM</civil>
<month_name>March</month_name>
<month_name_abbrev>Mar</month_name_abbrev>
<weekday_name>Saturday</weekday_name>
<weekday_name_night>Saturday Night</weekday_name_night>
<weekday_name_abbrev>Sat</weekday_name_abbrev>
<weekday_name_unlang>Saturday</weekday_name_unlang>
<weekday_name_night_unlang>Saturday Night</weekday_name_night_unlang>
<ampm>PM</ampm>
</code>```

As you can see there is a lot of data that you probably don't need, because you can calculate/convert the time/date information into a simple DateTime etc. Another useless series of fields is the "padded" ones. There a lot of other examples of this redundancy with other types of weather data as well.

So how should I approach this, have literally every field in the XML available to the user of the library, or just stick to having only the parts that make sense available to the user? I'm leaning towards only the parts that make sense, but wanted to ask the opinion of others.

答:
Is your library a weather api that uses existing web services to get data?

In that case you should probably hide the details of the actual ws, and define your own set of attributes for weather data. That way you encapsulate the external dependency from the users of the api.

You may also want to watch how you get data from the xml. Try to only bind your code to the specific elements/tags you actually need. That gives you a bit of forward compatibility in case tags are added to the ws xml schema.
If you just serialise the whole xml to a class (ie add service reference), you create a much larger coupling.


问:
eBook editions of programming books
(I'll get my justification for why this is on topic in early: programming books tend to have fairly specific formatting needs - code samples, tables, images and graphs - which are not common to all book types and are not necessarily well handled by eBook readers.  Similarly they're used in different ways - you often dip in and out rather than read cover to cover.)

I've just noticed that Don't Make Me Think by Steve Krug is available as an eBook edition for the Kindle (and presumably also for other readers) which set me thinking.

There are certain advantages to eBook readers for tech books - primarily that you can carry a massive library of what would be heavy physical books around very easily.  The downside is that certain eBook readers allegedly aren't particularly well equipped to cope with tables, code samples and so on and a book like Don't Make Me Think presumably makes extensive use of these sorts of things.

So, the question, what are your experiences of reading and using programming books on an eBook reader and would you recommend it? I'm specifically interested in the latest generation Kindle but happy to hear about all devices - might be useful to state which one you use in the answer.

答:
I use the Kindle app on an iPad pretty religiously. I have the Krug book that you'd mentioned (2nd ed.) and although I've yet to complete it, I've had no problems with  images or graphics so far. I also use iBooks quite a bit and have effectively rebuilt my O'Reilly library (not to shill, but they come out with some pretty good deals - and if you already own a dead-tree edition then the ebook only costs around $5).

There's nothing quite like having an entire library of programming and reference materials at your fingertips. Occasionally you'll encounter a ebook that looks like it's been through the wringer. It's not too common but it happens. More recently it seems like I've noticed this less and less. I suppose that as the formats become a bit more standard and ubiquitous, and as the medium takes off, people seem to be putting more effort into generating better ebooks.

I'm convinced that these little devices (Kindle, iPad, etc) are built for programming books.

Note: PDFs are generally a crapshoot in my experience. I have quite a collection on my device. Some a are good, most are adequate. Given a choice between a PDF and an ebook format I'd go with the ebook every time.

Title: eBook editions of programming books


答:
As others have said, you should return only a single representation of each value. It's just simpler and easier for everyone. How to format those values for display is up to the presentation logic, not the service logic. If formatting a dateTime value or padding an integer with zeros is too hard for the presentation logic to do on its own, something is seriously wrong with whatever framework/language the client is using for that logic.

But the other answers didn't really address which representation to pick. So I wanted to add that you should pick a representation which:

Contains all of the actual information. For instance, the month should be in there somewhere, but not ten different ways of specifying it.

Uses the simpler/more concise representation when multiple options exist. For instance, if you use the 24-hour clock, you won't need an AM/PM field. This is so trivial to add in clientside code that it's simply not worth complicating your API.

Is a structured object rather than a string. Otherwise all your clients have to write parsing utilities before they can start on the actual formatting. (Big exception for standard, widely-used formats like ISO 8601 which are exceptionally easy to parse and have many parsers already available. In fact, returning a single ISO 8601 string might be ideal for you.)

Either avoids localization issues entirely or explicitly handles them. By that I mean, either the month/weekday/etc are represented by numbers/enums, or your service requests all have a language parameter so they can return properly localized strings. Whichever one you pick, be consistent.

Finally, if there is a legitimate reason for you to be doing the formatting in your service (eg, you're generating a .pdf with a table containing three thousand dateTime values) then the client should be required to provide a format specifier in their request, and this needs to be very thoroughly documented. And the localization thing applies again.

Title: How much data from a web service should I expose in a library?

Body:
I'm working on a personal project, a library that can access the weather forecasts and other weather related data from it.

However, a lot of the returned data is sometimes quite redundant or simply doesn't make sense to have certain data within that particular XML element etc. Consider this XML data I get from the service, which contains the hourly forecast:

```<code><hour>20</hour>
<hour_padded>20</hour_padded>
<min>00</min>
<min_unpadded>0</min_unpadded>
<sec>0</sec>
<year>2015</year>
<mon>3</mon>
<mon_padded>03</mon_padded>
<mon_abbrev>Mar</mon_abbrev>
<mday>21</mday>
<mday_padded>21</mday_padded>
<yday>79</yday>
<isdst>0</isdst>
<epoch>1426968000</epoch>
<pretty>8:00 PM GMT on March 21, 2015</pretty>
<civil>8:00 PM</civil>
<month_name>March</month_name>
<month_name_abbrev>Mar</month_name_abbrev>
<weekday_name>Saturday</weekday_name>
<weekday_name_night>Saturday Night</weekday_name_night>
<weekday_name_abbrev>Sat</weekday_name_abbrev>
<weekday_name_unlang>Saturday</weekday_name_unlang>
<weekday_name_night_unlang>Saturday Night</weekday_name_night_unlang>
<ampm>PM</ampm>
</code>```

As you can see there is a lot of data that you probably don't need, because you can calculate/convert the time/date information into a simple DateTime etc. Another useless series of fields is the "padded" ones. There a lot of other examples of this redundancy with other types of weather data as well.

So how should I approach this, have literally every field in the XML available to the user of the library, or just stick to having only the parts that make sense available to the user? I'm leaning towards only the parts that make sense, but wanted to ask the opinion of others.


答: You will probably want to expose it in an easily consumable format like a timestamp and let the consumer choose how to interpret it. Something else that might help is to assume that this is what your API returns and attempt to code to it in a couple different use cases. If it feels messy, try returning the data in a different format and see if it becomes easier to use.</p>


问:
What is the meaning of "inversion" in Dependency Inversion design principle?
I'm reading about design patterns. I know what this principle does.

High-level and low-level classes depend on abstractions. But why we say this is inversion?

答:
Traditionally, your dependencies would descend downwards in your application.

That is, you would have a high level class A, which depends on a lower level class B.

Consider a car.  In traditional programming, your car object would depend on your steering wheel object, which would depend on your two front wheel objects.  This means that if your wheels change, your steering wheel class needs to change, and your car class might even need to change.

```<code>Car -> SteeringWheel -> Wheels
</code>```

Dependency inversion gets rid of these dependencies and adds two new dependencies:

```<code>Car -> ISteeringWheel
SteeringWheel implements ISteeringWheel
SteeringWheel -> IWheels
Wheels implements IWheels
</code>```

This change means that we can now test the car independently from the SteeringWheel, the SteeringWheel independently from the wheels.  We can also change the implementation of the Wheels or the SteeringWheel without needing to make changes to one of the parent classes.

This makes for a much more flexible architecture and helps us ensure that the other SOLID principles (particularly the SRP) are not violated.

The inversion is not a reversing of the dependencies (after all, the Wheels are not dependent on the SteeringWheel now) but is turning the dependencies 90 degrees to a new abstraction.  Inversion is possibly a poor choice of word.  A more descriptive choice might be "Dependency Right Angled Turn".  But that's not as catchy.

OwnerDisplayName: Khajavi

Body:
Traditionally, your dependencies would descend downwards in your application.

That is, you would have a high level class A, which depends on a lower level class B.

Consider a car.  In traditional programming, your car object would depend on your steering wheel object, which would depend on your two front wheel objects.  This means that if your wheels change, your steering wheel class needs to change, and your car class might even need to change.

Car -> SteeringWheel -> Wheels

Dependency inversion gets rid of these dependencies and adds two new dependencies:

Car -> ISteeringWheel
SteeringWheel implements ISteeringWheel
SteeringWheel -> IWheels
Wheels implements IWheels

This change means that we can now test the car independently from the SteeringWheel, the SteeringWheel independently from the wheels.  We can also change the implementation of the Wheels or the SteeringWheel without needing to make changes to one of the parent classes.

This makes for a much more flexible architecture and helps us ensure that the other SOLID principles (particularly the SRP) are not violated.

The inversion is not a reversing of the dependencies (after all, the Wheels are not dependent on the SteeringWheel now) but is turning the dependencies 90 degrees to a new abstraction.  Inversion is possibly a poor choice of word.  A more descriptive choice might be "Dependency Right Angled Turn".  But that's not as catchy.


答:
In general, you use higher-rank polymorphism when you want the callee to be able to select the value of a type parameter, rather than the caller. For example:

```<code>f :: (forall a. Show a => a -> Int) -> (Int, Int)
f g = (g "one", g 2)
</code>```

Any function g that I pass to this f must be able to give me an Int from a value of some type, where the only thing g knows about that type is that it has an instance of Show. So these are kosher:

```<code>f (length . show)
f (const 42)
</code>```

But these are not:

```<code>f length
f succ
</code>```

One particularly useful application is in using the scoping of types to enforce the scoping of values. Suppose we have an object of type Action<T>, representing an action we can run to produce a result of type T, such as a future or callback.

```<code>T runAction<T>(Action<T>)

runAction :: forall a. Action a -> a
</code>```

Now, suppose that we also have an Action that can allocate Resource<T> objects:

```<code>Action<Resource<T>> newResource<T>(T)

newResource :: forall a. a -> Action (Resource a)
</code>```

We want to enforce that those resources are only used inside the Action where they were created, and not shared between different actions or different runs of the same action, so that actions are deterministic and repeatable.

We can use higher-ranked types to accomplish this by adding a parameter S to the Resource and Action types, which is totally abstract—it represents the “scope” of the Action. Now our signatures are:

```<code>T run<T>(<S> Action<S, T>)
Action<S, Resource<S, T>> newResource<T>(T)

runAction :: forall a. (forall s. Action s a) -> a
newResource :: forall s a. a -> Action s (Resource s a)
</code>```

Now when we give runAction an Action<S, T>, we are assured that because the “scope” parameter S is fully polymorphic, it cannot escape the body of runAction—so any value of a type that uses S such as Resource<S, int> likewise cannot escape!

(In Haskell, this is known as the ST monad, where runAction is called runST, Resource is called STRef, and newResource is called newSTRef.)

Title: Is higher-rank parametric polymorphism useful?

Body:
I'm pretty sure everyone is familiar with generic methods of the form:

```<code>T DoSomething<T>(T item)
</code>```

This function is also called parametrically polymorphic (PP), specifically rank-1 PP.

Let's say this method can be represented using a function object of the form:

```<code><T> : T -> T
</code>```

That is, <T> means it takes one type parameter, and T -> T means that it takes one parameter of type T and returns a value of the same type.

Then the following would be a rank-2 PP function:

```<code>(<T> : T -> T) -> int
</code>```

The function takes no type parameters itself, but takes a function which takes a type parameter. You can continue this iteratively, making the nesting deeper and deeper, getting PP of higher and higher rank.

This feature is really rare among programming languages. Even Haskell doesn't allow it by default.

Is it useful? Can it describe behaviors that are difficult to describe otherwise?

Also, what does it mean for something to be impredicative? (in this context)

Body:
In general, you use higher-rank polymorphism when you want the callee to be able to select the value of a type parameter, rather than the caller. For example:

f :: (forall a. Show a => a -> Int) -> (Int, Int)
f g = (g "one", g 2)

Any function g that I pass to this f must be able to give me an Int from a value of some type, where the only thing g knows about that type is that it has an instance of Show. So these are kosher:

f (length . show)
f (const 42)

But these are not:

f length
f succ

One particularly useful application is in using the scoping of types to enforce the scoping of values. Suppose we have an object of type Action<T>, representing an action we can run to produce a result of type T, such as a future or callback.

T runAction<T>(Action<T>)

runAction :: forall a. Action a -> a

Now, suppose that we also have an Action that can allocate Resource<T> objects:

Action<Resource<T>> newResource<T>(T)

newResource :: forall a. a -> Action (Resource a)

We want to enforce that those resources are only used inside the Action where they were created, and not shared between different actions or different runs of the same action, so that actions are deterministic and repeatable.

We can use higher-ranked types to accomplish this by adding a parameter S to the Resource and Action types, which is totally abstract—it represents the “scope” of the Action. Now our signatures are:

T run<T>(<S> Action<S, T>)
Action<S, Resource<S, T>> newResource<T>(T)

runAction :: forall a. (forall s. Action s a) -> a
newResource :: forall s a. a -> Action s (Resource s a)

Now when we give runAction an Action<S, T>, we are assured that because the “scope” parameter S is fully polymorphic, it cannot escape the body of runAction—so any value of a type that uses S such as Resource<S, int> likewise cannot escape!

(In Haskell, this is known as the ST monad, where runAction is called runST, Resource is called STRef, and newResource is called newSTRef.)


问:
How are basic functions implemented in a programming language if they are not built in?
The lowest levels of a programming language's library functions are always obscure and often have no code that looks like it even remotely does anything. Some languages have these functions like getting substrings, converting between data types, querying a variable's data type, and so forth implemented as part of their standard libraries, but I can't imagine how these low-level functions can be expressed using said language. How are these things achieved? I'm not asking for how it is done with all languages, but rather what the general method of doing this is conceptually.</p>

答:
"I'm incapable of imagining things like how the code to convert a string to a number or a number to a string would be written."

Below is simple C code that converts binary to decimal and back again.  I wrote it long ago for a project in which the target was an embedded processor and the development tools had a stdlib that was way too big for the firmware ROM.

We had a C compiler/linker that could generate executables and we needed to do what we could do without any stdlib (which was a pig).  So no printf() nor scanf().  Not even an sprintf() nor sscanf().  But we still had a user interface and had to convert base-10 numbers into binary and back.  (We made up our own malloc()-like utility also and our own transcendental math functions too.)

So this was how I did it (the main program and calls to stdlib were there for testing this thing on my mac, not for the embedded code).  Also, because some older dev systems don't recognize "int64t" and "uint64t" and similar types, the types long long and unsigned long long are used and assumed to be the same.  And long is assumed to be 32 bits.  I guess I could have typedefed it.

#include <stdlib.h>
#include <stdio.h>

// returns an error code, 0 if no error,
// -1 if too big, -2 for other formatting errors
int decimal_to_binary(char *dec, long *bin)
    {
    int i = 0;

    int past_leading_space = 0;
    while (i <= 64 && !past_leading_space)        // first get past leading spaces
        {
        if (dec[i] == ' ')
            {
            i++;
            }
         else
            {
            past_leading_space = 1;
            }
        }
    if (!past_leading_space)
        {
        return -2;                                // 64 leading spaces does not a number make
        }
    // at this point the only legitimate remaining
    // chars are decimal digits or a leading plus or minus sign

    int negative = 0;
    if (dec[i] == '-')
        {
        negative = 1;
        i++;
        }
     else if (dec[i] == '+')
        {
        i++;                                    // do nothing but go on to next char
        }
    // now the only legitimate chars are decimal digits
    if (dec[i] == '\0')
        {
        return -2;                              // there needs to be at least one good
        }                                       // digit before terminating string

    unsigned long abs_bin = 0;
    while (i <= 64 && dec[i] != '\0')
        {
        if ( dec[i] >= '0' && dec[i] <= '9' )
            {
            if (abs_bin > 214748364)
                {
                return -1;                                // this is going to be too big
                }
            abs_bin <<= 1;                                // an efficient way
            abs_bin += (abs_bin<<2);                      //  to multiply by 10
//          abs_bin *= 10;                                // previous value gets bumped to the left one digit...
            abs_bin += (unsigned long)(dec[i] - '0');     // ... and a new digit appended to the right
            i++;
            }
         else
            {
            return -2;                                    // not a legit digit in text string
            }
        }

    if (dec[i] != '\0')
        {
        return -2;                                // not terminated string in 64 chars
        }

    if (negative)
        {
        if (abs_bin > 2147483648)
            {
            return -1;                            // too big
            }
        *bin = -(long)abs_bin;
        }
     else
        {
        if (abs_bin > 2147483647)
            {
            return -1;                            // too big
            }
        *bin = (long)abs_bin;
        }

    return 0;
    }

void binary_to_decimal(char *dec, long bin)
    {
    unsigned long long acc;                // 64-bit unsigned integer

    if (bin < 0)
        {
        *(dec++) = '-';                    // leading minus sign
        bin = -bin;                        // make bin value positive
        }

    acc = 989312855LL*(unsigned long)bin;        // very nearly 0.2303423488 * 2^32
    acc += 0x00000000FFFFFFFFLL;                 // we need to round up
    acc >>= 32;
    acc += 57646075LL*(unsigned long)bin;
    // (2^59)/(10^10)  =  57646075.2303423488  =  57646075 + (989312854.979825)/(2^32)

    int past_leading_zeros = 0;
    for (int i=9; i>=0; i--)            // maximum number of digits is 10
        {
        acc <<= 1;                      // an efficient way
        acc += (acc<<2);                //  to multiply by 10
//      acc *= 10;

        unsigned int digit = (unsigned int)(acc >> 59);        // the digit we want is in bits 59 - 62

        if (digit > 0)
            {
            past_leading_zeros = 1;
            }

        if (past_leading_zeros)
            {
            *(dec++) = '0' + digit;
            }

//      printf(" i = %d, acc = 0x%016llx \n", i, acc<<1);    // put digit into upper 4 bits to be easily read

        acc &= 0x07FFFFFFFFFFFFFFLL;    // mask off this digit and go on to the next digit
        }

    if (!past_leading_zeros)            // if all digits are zero ...
        {
        *(dec++) = '0';                 // ... put in at least one zero digit
        }

    *dec = '\0';                        // terminate string
    }

#if 1

int main (int argc, const char* argv[])
    {
    char dec[64];
    long bin, result1, result2;
    unsigned long num_errors;
    long long long_long_bin;

    num_errors = 0;
    for (long_long_bin=-2147483648LL; long_long_bin<=2147483647LL; long_long_bin++)
        {
        bin = (long)long_long_bin;
        if ((bin&0x00FFFFFFL) == 0)
            {
            printf("bin = %ld \n", bin);        // this is to tell us that things are moving along
            }
        binary_to_decimal(dec, bin);
        decimal_to_binary(dec, &result1);
        sscanf(dec, "%ld", &result2);            // decimal_to_binary() should do the same as this sscanf()

        if (bin != result1 || bin != result2)
            {
            num_errors++;
            printf("bin = %ld, result1 = %ld, result2 = %ld, num_errors = %ld, dec = %s \n",
                bin, result1, result2, num_errors, dec);
            }
        }

    printf("num_errors = %ld \n", num_errors);

    return 0;
    }

#else

int main (int argc, const char* argv[])
    {
    char dec[64];
    long bin;

    printf("bin = ");
    scanf("%ld", &bin);
    while (bin != 0)
        {
        binary_to_decimal(dec, bin);
        printf("dec = %s \n", dec);
        printf("bin = ");
        scanf("%ld", &bin);
        }

    return 0;
    }

#endif
```

ContentLicense: CC BY-SA 4.0


问:
For a concrete SQL Repository, should I encapsulate the SQL logic inside or outside the repository methods?
If I have a concrete repository based on SQL data access, should I pass in SQL to the repository methods or encapsulate them within the methods.  I feel if I pass them in, then I am coupling my repository with SQL data access, so I am leaning toward putting the SQL in the methods?  Here are my two options:

```<code>public GetPeople(string sql)
{
   //Query people with passed in sql
}

public GetPeople()
{
  //Query people with sql logic here, possibly conditional logic
}
</code>```

答: Passing SQL into the repository is definitely not a good way to go about things. It violates the single responsibility principle because the client uses the repository and also tells it how to work instead of it using the repository and the repository knowing how to work itself.


答:
I can do with Ebooks even in PDF as long as I have a big screen - and my workstation is just fine for that.

It's much easier to search, jump to different sections and basically navigate the entire ebook compared to the physical counterpart. It also somehow feels less laborious than actually reading a fat physical book (at least to me!).

The only downside, is that I don't have a bookshelf to show off for the money that I have spent on them.

Title: eBook editions of programming books

Body:
(I'll get my justification for why this is on topic in early: programming books tend to have fairly specific formatting needs - code samples, tables, images and graphs - which are not common to all book types and are not necessarily well handled by eBook readers.  Similarly they're used in different ways - you often dip in and out rather than read cover to cover.)

I've just noticed that Don't Make Me Think by Steve Krug is available as an eBook edition for the Kindle (and presumably also for other readers) which set me thinking.

There are certain advantages to eBook readers for tech books - primarily that you can carry a massive library of what would be heavy physical books around very easily.  The downside is that certain eBook readers allegedly aren't particularly well equipped to cope with tables, code samples and so on and a book like Don't Make Me Think presumably makes extensive use of these sorts of things.

So, the question, what are your experiences of reading and using programming books on an eBook reader and would you recommend it? I'm specifically interested in the latest generation Kindle but happy to hear about all devices - might be useful to state which one you use in the answer.