答:
Is my understanding of average velocity and sprint commitments correct?

Yeah, you have the gist of it.

If not, what have I gotten wrong?

The thing you overlooked is that story points are the things you get done. It is nigh impossible for everyone to work on stories right up to the end of the sprint. If you're doing things right, most of your developers will be "idle" for a few days while the stories are being tested (and your testers in the middle of the sprint as development is in full swing).

I put idle in quotes because your developers aren't sitting around watching cat videos, they're fixing bugs, polishing up some code/unit tests, adding some documentation around processes, thinking about the design for stories in the backlog or one of the other dozens of useful things that a development team can benefit from but don't fit well into a story.

So while you will over-guess 50% of the time and under-guess 50% of the time, that doesn't mean you're going to fail the sprint or have to work overtime. It means that you won't have quite as much time to do this miscellaneous work (unless you really miss your estimates). But that's not a big deal, since the miscellaneous work isn't time sensitive, and things will even out in the long run.

Title: How to handle 50% of worse than average sprints?

Body:
My understanding of Scrum is that I determine the work my team can take on in the next sprint by averaging the number of completed points for the past several sprints.

This is an average, so if history repeats itself, this sprint it is 50% likely that we are taking on too few story points, and 50% likely that we are taking on too many story points.

In the case we have taken on too many story points we could:

Fail to complete the sprint. This means we will fail to meet our sprint commitment half the time.

Work extra to catch up. The problem is that this ratchets only one way. We will accomplish the sprint, and the number of story points completed will reflect that. Since we always finish, over time, our average will trend upward to the point where we are always accomplishing a large number of story points and staying late.

Is my understanding of average velocity and sprint commitments correct?

If so, what should we do for the 50% of sprints where we are behind average?

If not, what have I gotten wrong?


问:
Pick highest score sum, but at least X from each region
Can you think of a solution to the following seemingly simple algorithmic problem?

I am given a list of data points with scores and regions they belong to: [(9, A), (8, B), (7, A), (3, C),  ...]. Scores are floats and each regions can have multiple data points assigned.

For each number N I'd like to select N data points from this list to maximize the total sum of these N scores. Without any restriction, you would chose the top scores, of course.

But now I have the constraint that in each region you have to pick at least X points or none at all. Therefore I cannot have a "sparse" region.

How would you solve this? An algorithm should output for each N the number of points chosen from each region.

答:
I've used ideas from Gnasher's answer to write a Python script. It's undocumented and hard to read. But since this problem seems fairly standard and yet hard to solve, I'm posting this script for the desperate that might encounter this problem. The script misses an optimization for the exhaustive search. Instead it assumes a plain linear ordering A<B<C<... of regions in the variable possible_group_subsets.

```<code>from pprint import pprint
import random
from collections import Counter
import itertools as itoo
from operator import itemgetter
import cytoolz as tz

def merge_groupby(*datas, key=None):
    """
    datas should be sorted iterables

    returns [(key, [dat1, dat2, ...])] where key is ascending and dat* are data elements with that key
    key(dat) should be strictly increasing (not repeats) within each stream
    data will be iterated in data_iters as iterators
    it only needs to store len(datas) values

    Example:
    merge_groupby([1,2,3],[2]) -> [(1,[1]), (2,[2,2]), (3, [3])]
    """
    STOP_OBJ = object()
    if key is None:
        key = lambda x: x

    data_iters = [iter(d) for d in datas]
    head_values = []
    for d in data_iters:
        head_val = next(d, STOP_OBJ)
        head_key = key(head_val) if head_val is not STOP_OBJ else STOP_OBJ
        head_values.append((head_key, head_val))

    while not all(h[0] is STOP_OBJ for h in head_values):
        # print(head_values)
        min_key = min(filter(lambda x: x is not STOP_OBJ, tz.pluck(0, head_values)))
        result = []
        result_i = []
        for i in range(len(head_values)):
            head_key, head_val = head_values[i]
            if head_key == min_key:
                result.append(head_val)
                result_i.append(i)
        yield (min_key, result, result_i)

        # this needs to be at the end, so that the result is return before the next
        # element is read
        # otherwise groupby values groups might be automatically consumed/deleted if
        # the group advances
        for i in range(len(head_values)):
            head_key, head_val = head_values[i]
            if head_key == min_key:
                new_head_val = next(data_iters[i], STOP_OBJ)
                assert new_head_val is STOP_OBJ or new_head_val > head_val
                new_head_key = key(new_head_val) if new_head_val is not STOP_OBJ else STOP_OBJ
                head_values[i] = (new_head_key, new_head_val)

def pick(data, minsize):
    sum_groups_minsize = Counter()
    count_groups = Counter()
    for score, group, info in data:  # make one pass with sum and count
        if count_groups[group] < minsize:
            sum_groups_minsize[group] += score
        count_groups[group] += 1

    for group in list(sum_groups_minsize.keys()):  # remove small groups
        if count_groups[group] < minsize:
            del sum_groups_minsize[group]

    def group_select(groups):
        sum_score = sum(sum_groups_minsize[g] for g in groups)
        chosen_cnt = len(groups) * minsize
        seen_counter = Counter()
        for score, group, _info in data:
            if group not in groups:
                continue
            seen_counter[group] += 1
            if seen_counter[group] > minsize:
                sum_score += score
                chosen_cnt += 1
            yield chosen_cnt, sum_score, {g: max(seen_counter[g], minsize) for g in groups}

    # determine allowed group subsets
    sum_minsize_top = [group for group, summer in sorted(sum_groups_minsize.items(), key=lambda x: x[1], reverse=True)]
    possible_group_subsets = [sum_minsize_top[:num_groups_used] for
                              num_groups_used in range(1, len(sum_minsize_top) + 1)]

    # run algorithm
    group_iters0 = [group_select(group_subset) for group_subset in possible_group_subsets]
    group_iters1 = [itoo.groupby(g, key=itemgetter(0, 1)) for g in group_iters0]
    for chosen_cnt, head_group_iters, _head_group_idx in merge_groupby(*group_iters1, key=lambda x: x[0][0]):
        (best_group, best_score), best_grouper = max(head_group_iters, key=lambda x: x[0][1])
        _, sum_score, group_counts = list(best_grouper)[0]  # for tie scores just pick the first option
        yield (chosen_cnt, sum_score, group_counts)

res = list(pick(dat, minsize))
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I've used ideas from Gnasher's answer to write a Python script. It's undocumented and hard to read. But since this problem seems fairly standard and yet hard to solve, I'm posting this script for the desperate that might encounter this problem. The script misses an optimization for the exhaustive search. Instead it assumes a plain linear ordering A<B<C<... of regions in the variable possible_group_subsets.

from pprint import pprint
import random
from collections import Counter
import itertools as itoo
from operator import itemgetter
import cytoolz as tz

def merge_groupby(*datas, key=None):
    """
    datas should be sorted iterables

    returns [(key, [dat1, dat2, ...])] where key is ascending and dat* are data elements with that key
    key(dat) should be strictly increasing (not repeats) within each stream
    data will be iterated in data_iters as iterators
    it only needs to store len(datas) values

    Example:
    merge_groupby([1,2,3],[2]) -> [(1,[1]), (2,[2,2]), (3, [3])]
    """
    STOP_OBJ = object()
    if key is None:
        key = lambda x: x

    data_iters = [iter(d) for d in datas]
    head_values = []
    for d in data_iters:
        head_val = next(d, STOP_OBJ)
        head_key = key(head_val) if head_val is not STOP_OBJ else STOP_OBJ
        head_values.append((head_key, head_val))

    while not all(h[0] is STOP_OBJ for h in head_values):
        # print(head_values)
        min_key = min(filter(lambda x: x is not STOP_OBJ, tz.pluck(0, head_values)))
        result = []
        result_i = []
        for i in range(len(head_values)):
            head_key, head_val = head_values[i]
            if head_key == min_key:
                result.append(head_val)
                result_i.append(i)
        yield (min_key, result, result_i)

        # this needs to be at the end, so that the result is return before the next
        # element is read
        # otherwise groupby values groups might be automatically consumed/deleted if
        # the group advances
        for i in range(len(head_values)):
            head_key, head_val = head_values[i]
            if head_key == min_key:
                new_head_val = next(data_iters[i], STOP_OBJ)
                assert new_head_val is STOP_OBJ or new_head_val > head_val
                new_head_key = key(new_head_val) if new_head_val is not STOP_OBJ else STOP_OBJ
                head_values[i] = (new_head_key, new_head_val)

def pick(data, minsize):
    sum_groups_minsize = Counter()
    count_groups = Counter()
    for score, group, info in data:  # make one pass with sum and count
        if count_groups[group] < minsize:
            sum_groups_minsize[group] += score
        count_groups[group] += 1

    for group in list(sum_groups_minsize.keys()):  # remove small groups
        if count_groups[group] < minsize:
            del sum_groups_minsize[group]

    def group_select(groups):
        sum_score = sum(sum_groups_minsize[g] for g in groups)
        chosen_cnt = len(groups) * minsize
        seen_counter = Counter()
        for score, group, _info in data:
            if group not in groups:
                continue
            seen_counter[group] += 1
            if seen_counter[group] > minsize:
                sum_score += score
                chosen_cnt += 1
            yield chosen_cnt, sum_score, {g: max(seen_counter[g], minsize) for g in groups}

    # determine allowed group subsets
    sum_minsize_top = [group for group, summer in sorted(sum_groups_minsize.items(), key=lambda x: x[1], reverse=True)]
    possible_group_subsets = [sum_minsize_top[:num_groups_used] for
                              num_groups_used in range(1, len(sum_minsize_top) + 1)]

    # run algorithm
    group_iters0 = [group_select(group_subset) for group_subset in possible_group_subsets]
    group_iters1 = [itoo.groupby(g, key=itemgetter(0, 1)) for g in group_iters0]
    for chosen_cnt, head_group_iters, _head_group_idx in merge_groupby(*group_iters1, key=lambda x: x[0][0]):
        (best_group, best_score), best_grouper = max(head_group_iters, key=lambda x: x[0][1])
        _, sum_score, group_counts = list(best_grouper)[0]  # for tie scores just pick the first option
        yield (chosen_cnt, sum_score, group_counts)

res = list(pick(dat, minsize))


问:
How to handle 50% of worse than average sprints?
My understanding of Scrum is that I determine the work my team can take on in the next sprint by averaging the number of completed points for the past several sprints.

This is an average, so if history repeats itself, this sprint it is 50% likely that we are taking on too few story points, and 50% likely that we are taking on too many story points.

In the case we have taken on too many story points we could:

Fail to complete the sprint. This means we will fail to meet our sprint commitment half the time.

Work extra to catch up. The problem is that this ratchets only one way. We will accomplish the sprint, and the number of story points completed will reflect that. Since we always finish, over time, our average will trend upward to the point where we are always accomplishing a large number of story points and staying late.

Is my understanding of average velocity and sprint commitments correct?

If so, what should we do for the 50% of sprints where we are behind average?

If not, what have I gotten wrong?

答:
Agile methodology varies from company to company, in one implementation it could be vastly different from another. I've worked under Agile with two companies. In the first company I was in they took their metrics pretty seriously, in the second company not really at all. So for all you know nobody is paying attention to your metrics.

All that said, it sounds like you're concerned with not meeting your sprint goals, or what happens when you have an inaccurate estimate. I think this type of concern and outlook is common, but it's not particularly important. Agile, above all, is a software development system which does a few things:

Keeps developers moving

Increases transparency

Allows for reflection and gradual process improvement

At the end of the day, if you mis-estimate a sprint, or fail a sprint, it's not really that big of a deal. The people who are above your team in your company are likely more concerned that your team is consistently moving, and projects are being brought to their logical completion.

As an individual under Agile you should be most concerned with how much work you're effectively completing in reference to the rest of your team. If you're new, you can't be expected to be too productive, but at some point in your term of employment you should be around on par with at least some of your team. If you're not outputting work, you're not really doing your job.

ContentLicense: CC BY-SA 4.0


问:
Is it common practice to transform requirement specifications into predicate logic for functional programming?
I've recently been assigned to work on a small project which is being implemented in Haskell. Coming from an OO/imperative background, I'm used to converting requirements/user-stories into use-cases and sequence diagram prior to coding.

However, the Haskell project that I have been assigned to, the team prefers to transform the user requirements into predicate logic proposition/statements. I was aware of logic being used in safety critical systems and formal methods for software engineering, but not so much in day to day programming. Is this common practice in the FP realm? Where can I learn more about this?

It seems like a natural way to 'model' the requirements and derive the 'functions' from the predicates along with writing down the necessary type specifications for the functions to operate on. But is that how it is done/recommended in practice or is it something peculiar to my team?

(I've tried searching extensively prior to asking this question here. Searching for "requirements specification in functional programming" (and different keyword synonyms and combinations) doesn't lead to anything meaningful.)

答: That's one way to deal with functional programming. It tends to fall out from the flowcharts and data flow diagrams of the "old days." Instead of thinking in terms of objects, functional programming tends to focus on what actions need to be performed. The data becomes incidental, bits of fluff to carry along to hold on to what you're trying to do.</p>


问:
Why are regular expressions so morbidly attractive?
Exhibit 1, Exhibit 2, I guess you won't find it hard to recall other examples.

Thing is: if there is more than one way to solve a problem, the PHP programmer (I usually browse the PHP tag on StackOverflow) will ask for help on the solution involving regular expressions.

Even when it will be less economic, even when the php manual suggests (link) to use str_replace instead of any preg_* or ereg_* function when no fancy substitution rules are required.

Does somebody have a clue about why this happens?

Don't get me wrong, some of my best friends are regular expressions and I don't despise Perl. What I don't get is why there is no looking for alternatives whatsoever, even when the overkill is obvious (regex to switch strings) or the code complexity rises exponentially (regex for getting data from html in PHP)

答:
I think it's because:

They are fantastically concise (when used properly) compared to the equivalent code, and

They are widely supported across programming languages, so most developers are familiar with them.

ContentLicense: CC BY-SA 2.5


问:
Using an LGPL licensed library that may or may not include GPL licensed code from an MIT licensed library
I have read Interfacing with GPL applications from MIT licensed code - is a dual-license unavoidable? (now deleted) on Stack Overflow, but it doesn't appear to fully answer my question.

I maintain a library which is licensed under the MIT License. In my MIT licensed library, I dynamically link (Python ctypes to be specific) against another library which is licensed under the GNU Lesser General Public License 2.1 (LibRaw). This would be fine by itself, however, LibRaw is sometimes statically linked against a sort of "plugin" called the LibRaw Demosaic Pack which is licensed under GNU General Public License 2+ or GNU General Public License 3 depending on the version. I have no way of checking if LibRaw has been linked against these libraries. (LibRaw is just installed on the end users computer and when they download our library and use it it links against it, I am not redistributing or building LibRaw.)

Does linking against the LGPL library from my MIT library when the LGPL library has been linked against GPL code mean that I'm illegally using GPL code in my MIT Library?

If it is so, is there some way around this short of sub-licensing parts of my code under the GPL, or dual-licensing (which is just confusing for the end user)? Or can I still link against the LGPL library under the terms of the LGPL even though it then links against GPLed code?

答:
You designed your library to depend only on the LGPL version of LibRaw. That way you are following the license conditions of LibRaw. When the end-user links it against a version of that library which contains GPL code, that's their own business, not yours.

You can not prevent your end-users from doing this. And doing that is not even illegal for them: The (L)GPL only governs redistribution, it does not restrict what people may do with the software on their own machines.

However, other people are not allowed to distribute an application which depends on the GPL version of the library under MIT, because in that case they would be violating the GPL license of the demosaic pack. But what they can do is redistribute the whole application with your library all under GPL. Both the LGPL and the MIT license allow relicensing under the GPL, so anyone can turn a MIT-licensed work into a GPL work. But that's an issue between them and the authors of said plugin. You are out of it because your library only requires the LGPL version.

By the way: If you have any similar questions, then you might want to ask them on Open Source Stackexchange.


答:
I will say that it's not limited to functional programming, it's more related to the goal of the project. By using predicate logic (higher order logic) you can create prove for the logic used in the requirement. Translating the logic into functional languages is probably easier. It's also possible to then translate the proven functional language implementation into procedural languages to get some kind of proven way of implementing it.

If we can prove the program then we don't need to test it. Even if a program passed  1000 tests, it's still not proven. Obviously, it's not easy to create the proofs so we just create tests instead.

You might also want to search for theorem prover, isabelle/hol.

Title: Is it common practice to transform requirement specifications into predicate logic for functional programming?

Body:
I've recently been assigned to work on a small project which is being implemented in Haskell. Coming from an OO/imperative background, I'm used to converting requirements/user-stories into use-cases and sequence diagram prior to coding.

However, the Haskell project that I have been assigned to, the team prefers to transform the user requirements into predicate logic proposition/statements. I was aware of logic being used in safety critical systems and formal methods for software engineering, but not so much in day to day programming. Is this common practice in the FP realm? Where can I learn more about this?

It seems like a natural way to 'model' the requirements and derive the 'functions' from the predicates along with writing down the necessary type specifications for the functions to operate on. But is that how it is done/recommended in practice or is it something peculiar to my team?

(I've tried searching extensively prior to asking this question here. Searching for "requirements specification in functional programming" (and different keyword synonyms and combinations) doesn't lead to anything meaningful.)


问:
What is the "type" of data that pointers hold in the C language?
I know that pointers hold addresses. I know that pointers' types are "generally" known based on the "type" of data they point to. But, pointers are still variables and the addresses they hold must have a data "type". According to my info, the addresses are in hexadecimal format. But, I still do not know what "type" of data is this hexadecimal. (Note that I know what a hexadecimal is, but when you say 10CBA20, for example, is this string of characters? integers? what? When I want to access the address and manipulate it .. itself, I need to know its type. This is why I am asking.)

答:
Types combine.

In particular, certain types combine, almost as if they were parameterized with placeholders.  Array and pointer types are like this; they have one such placeholder, which is the type of the element of the array or the thing being pointed to, respectively.  Function types are also like this; they can have multiple placeholders for the parameters, and a placeholder for the return type.

A variable that is declared to hold a pointer to char has type "pointer to char".  A variable that is declared to hold a pointer to pointer to int has type "pointer to pointer to int".

A (value of) type "pointer to pointer to int" can be changed to "pointer to int" by a dereference operation.  So, the notion of type is not just words but a mathematically significant  construct, dictating what we can do with values of the type (such as dereference, or pass as parameter or assign to variable; it also determines the size (byte count) of indexing, arithmetic, and increment/decrement operations).

P.S. If you want to get way deep into types, try this blog:
http://www.goodmath.org/blog/2015/05/13/expressions-and-arity-part-1/


问:
std::vector Non-Array Implementation?
I've seen some posts on the StackExchange family of sites talking about std::vector implementations. They all seem to indicate that std::vector is implemented strictly as an array (in practice), and that C++ 2003 dictates contiguity of elements - pretty much closing non-array loopholes.

Now I thought that I had read once of a non-array implementation of std::vector - perhaps this predated the 2003 enforcement of contiguity? (Edit: Herb Sutter makes note of this here) I believe it was something like a series of linked arrays with decreasing or increasing sizes under the hood but I can't remember the details. Does anyone know of std::vector implementations (or perhaps, more broadly, non-STL vector implementations) that use a non-array approach like this?

Edit: I'd like to clarify here that the emphasis is less on strict std::vector implementation for C++ and rather more on 1) historical STL implementations prior to C++ 2003 contiguous elements constraints or possibly even 2) "vector" implementations in other languages - that do not use the usual array-like structure. A VList implementation of a vector might be a potential example and I'm looking for others.

答:
It took me a while to find something I thought to be authoritative and finally found this nugget from a Dr. Dobb's Journal 2001 article:

"Intuitively, the standard-library vector class is like a built-in array: we can think of it as holding its elements in a single block of contiguous memory. Indeed, although the C++ Standard does not explicitly require that the elements of a vector occupy contiguous memory, the standards committee decided in its October, 2000 meeting that this requirement was missing due to an oversight, and voted to include the requirement as part of its Technical Corrigendum. This delayed imposition was not a particular hardship, because every existing implementation already worked that way."

So from a strict perspective, I believe no STL implementation ever used something other than an array.

However, for the curious, I believe that VLists (the growing array variant) more or less meet all the runtime requirements of std::vector without contiguity and notably without extra copies during expansion. From a more theoretical point of view, stable_vector is an interesting approach for iterator management and fits the bill from a more "letter of the law" perspective.

Also, thanks @0fnt for your explanation of amortized growth!

Title: std::vector Non-Array Implementation?


答:
Comment was getting too long, and my previous answer was complex enough not to further muddy it, but based on your VList link, here's another answer:

Main data structure: List (no need to be linked) of arrays (I'll call them main_arrays), doubling in size whenever capacity is constrained. Start with 1 sized main_array, then add a 2-length main_array, then a 4-length.

Maximum such array size would depend on computer's bitness, so 2^64 for a 64 bit computer. 2^64 total capacity vector would require 63 such main_arrays in our data structure. So allocate a 63 (or 64) size auxilliary array (I will call it aux_array) to keep references to end points of each of these main_arrays. Allocation of space would be constant time if OS pleases. Adding entry to aux_array is constant time.

Now the trick here is that for all practical purposes, specially when one is talking about C++ stl, we can use RAM model for analysis, which means all bit operations would be constant time.

Say we've so far allocated n=5 main_arrays, total vector capacity so far is: 2^0 + 2^1 .. 2^4 = 2^n - 1 = 31.

Now to access (k = 3)th element, subtract k from 2^n - 2, (2^5-2)-3 = 27.

J = Bitwise OR the result such that 64-n initial bits of this result are 1.

Now find the first 0 bit from left in this integer.(This is constant time in RAM model)

Lets say the index is q. let p = 63 - q.

End address of main_array that stores this element is aux_array[ p ].
H = Create a new integer which is 0.left_shift( p bits, insert 1).

Value at address aux_array[ p ] - ( J & H ) should give you your array value.

O(1) time for every single acces. I might have made some off by one errors, but none so bad that it changes the complexity of the algorithm (I think! :-)).

Happy to know if there are mistakes in this algorithm..

EDIT: If we don't assume RAM model, then the expected complexity of an access would be O(1) under assumptions of all indices being access uniformly. The time bound step would be finding which main_array has the data and that would be computed by looking at the bits in the index. The probabilistic analysis here is same as that of VList.

Title: std::vector Non-Array Implementation?

Body:
I've seen some posts on the StackExchange family of sites talking about std::vector implementations. They all seem to indicate that std::vector is implemented strictly as an array (in practice), and that C++ 2003 dictates contiguity of elements - pretty much closing non-array loopholes.

Now I thought that I had read once of a non-array implementation of std::vector - perhaps this predated the 2003 enforcement of contiguity? (Edit: Herb Sutter makes note of this here) I believe it was something like a series of linked arrays with decreasing or increasing sizes under the hood but I can't remember the details. Does anyone know of std::vector implementations (or perhaps, more broadly, non-STL vector implementations) that use a non-array approach like this?

Edit: I'd like to clarify here that the emphasis is less on strict std::vector implementation for C++ and rather more on 1) historical STL implementations prior to C++ 2003 contiguous elements constraints or possibly even 2) "vector" implementations in other languages - that do not use the usual array-like structure. A VList implementation of a vector might be a potential example and I'm looking for others.


问:
Why is there a gap between JBoss EAP and the JBoss AS/Community edition?
Admittedly new to this but I wanted to understand why there is a gap between Red Hat's JBoss EAP project (their enterprise version) and JBoss AS/Wildfly/community project.

Looking at this post from Red Hat, it seems that they don't withhold the source/patches. Makes sense since withholding the source would be a GPL violation, which in spirit wants source distributions so end users can recreate/reuse the binaries.

So if the sources are identical, then why isn't the AS/community version exactly at par with the EAP version? Shouldn't they be bit-exact, like having the same SHA256 value? It appears that the AS/community version usually lags by several hundred patches (from here, "Intro" section)

Talking about the latest JBoss Application Server is always tricky.
  Red Hat simultaneously offers two versions of JBoss: community
  edition, the current release where is 7.1.1-Final, and Enterprise
  Application Platform, EAP, edition where JBoss AS component version is
  7.1.3-Final. The difference between these is actually a few hundred bug-fixes, which is enormous ...

Since EAP binary distribution is controlled by Red Hat, surely there is enough community interest that the community itself rebuilds and redistributes AS/Wildfly binaries that are at-par with the EAP binaries, right? (a single Maven server should suffice).

I mean look at the popularity of CentOS (the community version of Red Hat Enterprise Linux) - the community IS interested in using software in production without RedHat's blessings/support.

So, what am I missing here?

答:
When community is finished, that's the start point for JBoss EAP.   It goes through a much more harden software process than the community version.   https://docs.jboss.org/jbossas/docs/Server_Configuration_Guide/beta500/html/ch01s01s01.html

Since enterprise is the "enterprise version", new features get developed, features are backported, security is backported, etc etc.     In community, once it's done, it's done, no more enhancements. The developers move to the next version.

So there are a lot of differences.

As a Red Hatter, I would encourage you to contact Red Hat to get the real story.  Too much FUD on internet.

Updated: Here's a video from Red Hat on the differences. https://www.youtube.com/watch?v=ty328F9Li4w


答:
In earlier phases of my career (ie. pre-PHP), I was a Perl guru, and one major aspect of Perl gurudom is mastery of regular expressions.

On my current team, I'm literally the only one of us who reaches for regex before other (usually nastier) tools. Seems like to the rest of the team they're pure magic. They'll wheel over to my desk and ask for a regex that takes me literally ten seconds to put together, and then be blown away when it works. I don't know--I've worked with them so long, it's just natural at this point.

In the absence of regex-fluency, you're left with combinations of flow-control statements wrapping strstr and strpos statements, which gets ugly and hard to run in your head. I'd much rather craft one elegant regex than thirty lines of plodding string searching.

Title: Why are regular expressions so morbidly attractive?

Body:
Exhibit 1, Exhibit 2, I guess you won't find it hard to recall other examples.

Thing is: if there is more than one way to solve a problem, the PHP programmer (I usually browse the PHP tag on StackOverflow) will ask for help on the solution involving regular expressions.

Even when it will be less economic, even when the php manual suggests (link) to use str_replace instead of any preg_* or ereg_* function when no fancy substitution rules are required.

Does somebody have a clue about why this happens?

Don't get me wrong, some of my best friends are regular expressions and I don't despise Perl. What I don't get is why there is no looking for alternatives whatsoever, even when the overkill is obvious (regex to switch strings) or the code complexity rises exponentially (regex for getting data from html in PHP)


问:
What is the best way to go about storing application options: file system or db?
We are looking to find the best way to store user options (skills, degrees, industries, languages, etc.) for drop downs. The options are between a JSON file we can store on the server file system or in the db (MongoDB).

What are the pros and cons of each method and how will they affect server performance under heavy usage?

答:
Json Way

Pros:

Faster than DB

There is no weight for server/job

Cons:

Update/Edit content is difficult.

DB Way

Pros:

Can be develop for speed

Cons:

Sometimes its unnecessary if it isn't change.

If its grow, it will weight for server

My suggest is using DB. Because you can develop for speed. Generally, I'm using JSON for static weight contents.


问:
python code style for long lists
when coding a very long list in python, is it better to fit several items on each line or should I limit it to 1 per line? 99% of the time I would go with style2 below but I have 5 lists each about the same length as the one below and it seems like too many lines. any advice would be appreciated.

for example:

```<code>style1 = [
    'Email:', 'SSN:', 'Address:', 'Home Phone:',
    'Mobile Phone: ', 'DOB:', 'Date of Surgery:',
    'Date of Service:', 'Facility of Service:', 'Clinic Number:',
    'Employer:', 'Work Phone: ', 'Fax: ', 'Type:', 'IPA:',
    'Health Plan:', 'ID #:', 'Claims Address:', 'Group #:',
    'Claim # / PO #:', 'Phone:', 'Fax:', 'Contact',
    'Adjuster Email', 'Util Review Phone', 'Util Review Fax',
    'Doctor:', 'NPI #: ', 'Date of Injury: ', 'Body Parts:',
    'Body Part Side:', 'Gender:', 'Diagnosis:', 'Diagnosis 2:',
    'Procedure:'
    ]

style2 = [
    'Email:',
    'SSN:',
    'Address:',
    'Home Phone:',
    'Mobile Phone: ',
    'DOB:',
    'Date of Surgery:',
    'Date of Service:',
    'Facility of Service:',
    'Clinic Number:',
    'Employer:',
    'Work Phone: ',
    'Fax: ',
    'Type:',
    'IPA:',
    'Health Plan:',
    'ID #:',
    'Claims Address:',
    'Group #:',
    'Claim # / PO #:',
    'Phone:',
    'Fax:',
    'Contact',
    'Adjuster Email',
    'Util Review Phone',
    'Util Review Fax',
    'Doctor:',
    'NPI #: ',
    'Date of Injury: ',
    'Body Parts:',
    'Body Part Side:',
    'Gender:',
    'Diagnosis:',
    'Diagnosis 2:',
    'Procedure:'
    ]
</code>```

答: Personally, I'm using style2. Because its very easy for adding new item to list. Also with style2 you can easly delete item with deleting row. But its difficult on style1.

Title: python code style for long lists


问:
F# MailboxProcessor aka Agent as an API
Seeing how there's raise in actor-based solutions, I'm a bit confused about the lack of F# libs that use something like the stock MailboxProcessor as the API.

What's the downside?

Why deal with constrained capabilities and the overhead of wrappers?

Are there any F# APIs that use an agent as the first-class API instead of implementation detail?

I'm talking about non-blocking concurrency with desired side effects scenarios.
Especially the cases when a lib already uses something like MailboxProcessor under the hood, but defines wrappers around the communication protocol (which could be nicely defined with DUs).

I guess the message passing upsides are in the eye of beholder, but I think Erlang and Scala show that functional goes together with Actors rather nicely. There are even Haskell implementations, so it's not a question purity, but rather of style.

When I say the wrappers are constrained, I mean:

protocol duplication (wrapper + underlying messaging). It's ok if all you expose is one method, but often times it's not.

explicit capabilities duplication (fire-and-forget, async with result, sync, etc). Covering every possibility with a wrapper would result in unnecessarily bloated API, while not covering it - actually remove the capability.

non-standard set of verbs, reducing ability to compose.

Assuming you are not against actors on principle, what are the downsides of using MailboxProcessor as the standard API for implementations involving non-blocking concurrency?

答:
The F# MailboxProcessor is essentially an in-memory queue in front of a single-threaded loop. While this definitely makes it easier to program 'concurrent' systems that need to manipulate state, it has the following disadvantages:

Runs only on a single thread

Overhead from synchronisation

The Actor model is a sane approach to stateful programming. When you need it, it's much preferable to approaches involving threads and locks.

F#, though, is a Functional First programming language, and most of the F# libraries I've come across take that seriously. They emphasise side-effect queries over stateful programming, which often make their APIs embarrassingly parallel. When you have something that's embarrassingly parallel, there's no reason to put it on a single thread.

Title: F# MailboxProcessor aka Agent as an API


答:
People have made a big deal of whether pointers are integers or not.  There are actually answers to these questions.  However, you are going to have to take a step into the land of specifications, which is not for the faint of heart.  We're going to take a look at the C specification, ISO/IEC 9899:TC2

6.3.2.3 Pointers

An integer may be converted to any  pointer type.   Except as previously specified, the
result is implementation-defined, might not be correctly aligned, might not point to an
entity of the referenced type, and might be a trap representation.

Any pointer type may be converted to an integer type.  Except as previously specified, the
result is implementation-defined.  If the result cannot be represented in the integer type,
the behavior is undefined.  The result need not be in the range of values of any integer
type.

Now for this, you're going to need to know some common spec terms.  "implementation defined" means every single compiler is allowed to define it differently.  In fact, a compiler may even define it different ways depending on yours compiler settings.  Undefined behavior means the compiler is allowed to do absolutely anything at all, from giving a compile time error to unexplainable behaviors, to working just perfectly.

From this we can see that the underlying storage form is not specified, other than that there may be a conversion to an integer type.  Now truth be told, virtually every compiler under the sun represents pointers under the hood as integer addresses (with a handful of special cases where it might be represented as 2 integers instead of just 1), but the specification permits absolutely anything, such as representing addresses as a 10 character string!

If we fast forward out of C and look at the C++ spec, we get a little more clarity with reinterpret_cast, but this is a different language, so its value for you may vary:

ISO/IEC N337: C++11 draft specification (I only have the draft on hand)

5.2.10 Reinterpret cast

A pointer can be explicitly converted to any integral type large enough to hold it. The mapping function is implementation-defined. [Note: It is intended to be unsurprising to those who know the addressing structure of the underlying machine. —end note] A value of type std::nullptr_t can be converted to an integral type; the conversion has the same meaning and validity as a conversion of (void*)0 to the integral type. [Note: A reinterpret_cast cannot be used to convert a value of any type to the type std::nullptr_t
. —end note]

A value of integral type or enumeration type can be explicitly converted to a pointer. A pointer converted to an integer of sufficient size (if any such exists on the implementation) and back to the same pointer type will have its original value; mappings between pointers and integers are otherwise implementation-defined. [Note: Except as described in 3.7.4.3 , the result of such a conversion will not be a safely-derived pointer
value. —end note ]

As you can see here, with a few more years under its belt, C++ found that it was safe to assume that a mapping to integers existed, so there is no longer talk of undefined behavior (though there is an interesting contradiction between parts 4 and 5 with the phrasing "if any such exists on the implementation")

Now what should you take away from this?

The exact representation of pointers is implementation defined. (in fact, just to make it messier, some small embedded computers represent the null pointer, (void)0, as address 255 to support some address aliasing tricks they use)*

If you have to ask about the representation of pointers in memory, you are probably not at a point in your programming career where you want to be fiddling with them.

The best bet: casting to a (char*).  The C and C++ specifications are full of rules specifying the packing of arrays and structs, and both always allow the casting of any pointer to a char*.  char is always 1 byte (not guaranteed in C, but by C++11 it has become a mandated part of the language, so its relatively safe to assume it is 1 byte everywhere).  This allows you to do some pointer arithmetic at the byte-by-byte level without resorting to actually needing to know the implementation specific representations of pointers.

Title: What is the "type" of data that pointers hold in the C language?

Body: I know that pointers hold addresses. I know that pointers' types are "generally" known based on the "type" of data they point to. But, pointers are still variables and the addresses they hold must have a data "type". According to my info, the addresses are in hexadecimal format. But, I still do not know what "type" of data is this hexadecimal. (Note that I know what a hexadecimal is, but when you say 10CBA20, for example, is this string of characters? integers? what? When I want to access the address and manipulate it .. itself, I need to know its type. This is why I am asking.)


问:
Given an array of n bits, how to generate every permutation with i 1's and n-i 0's?
It's simple enough to brute force a collection of strings and then filter for every occurrence with the required count of 1's.

As n increases the number of possible permutations becomes very large, very quickly, however, and due to speed and space considerations, I'm trying to find a more sophisticated method -- ideally, one that doesn't involve excessive string processing.

答:
You can slice up the problem in subprocess (pseudocode):</p>

```<code>array[] GetArrays(j, n)
    if(n = 0)
        return one empty array
    if(j = 0)
        return one array of n zeroes
    array[] zero = map(prepend 0,  GetArrays(j, n-1))
    array[] one = map(prepend 1,  GetArrays(j - 1, n - 1))
    return concat(zero, one)
</code>```

Body:
You can slice up the problem in subprocess (pseudocode):

array[] GetArrays(j, n)
    if(n = 0)
        return one empty array
    if(j = 0)
        return one array of n zeroes
    array[] zero = map(prepend 0,  GetArrays(j, n-1))
    array[] one = map(prepend 1,  GetArrays(j - 1, n - 1))
    return concat(zero, one)


问:
Heuristic for consistiently ordering points in a a plane
I have rectangular regions in a plane. I want to consistently order them in a human-friendly way that a typical y-x sort won't work for. Basically I want (0,0), (1,0), and (0,1) to sort the same as (0,0), (1, -0.1), and (-0.1, 1).

Ideas?

From comments:

The obvious answers, y-x and x-y sort, result in different orders for the short example I posted. The things I'm coming up with, now, are clustering approaches where I cluster the y values, sort by cluster y means, then by x.

Question: What are you sorting your rectangles for? Searching? Displaying?

Numbering the regions, and I want two region sets a human would say are nearly identical to get numbered identically.

Question: Is the orientation of the rectangles really important (what is the difference between (0,1) and (-1,0) in the problem domain)? Would primarily sorting by area or diagonal be ok?

I can't tell the orientation of them beyond portrait or landscape, and size doesn't work because a lot might be practically the same.

答:
I realized there's a better way to approach the problem. What I was really trying to do was match (0,0), (1,0), and (0,1) to (0,0), (1, -0.1), and (-0.1, 1), respectively. Ordering them, then matching up sequences like Python's itertools.zip() seemed like an elegant solution.

But what's easier is to treat this as a clustering problem. Running K-means on the concatenated list of points where K = n/2 (3 in the case of my example above) would to the matching I needed.


答: Man is a tool-using creature, and regular expressions are powerful tools. A nice metaphor for regular expressions is a meat slicer from a deli. If you want paper-thin slices of turkey, corned beef, etc., it's just the thing. However, you need skilled hands to use it, because you can cut yourself really badly with it and you won't feel a thing until you see the blood. What I mean by this is that the big problem with regular expressions is getting them slightly off means that you match something you shouldn't, or vice versa, and you don't find out until it causes an issue further along in the process.</p>


问:
What's the best way to return an array as a response in a RESTful API?
Assume we have resources like this,

```<code>book:
    type: object
    properties:
        author: {type: string}
        isbn: {type: string}
        title: {type: string}

books:
    type: array
    items: book
</code>```

So, when someone makes a GET on the books resource, we would be returning the following

```<code>[{"author": "Dan Brown", "isbn": "123456", "title": "Digital Fortress"},
 {"author": "JK Rowling", "isbn": "234567", "title": "Harry Potter and the Chamber of Secrets"}]
</code>```

I heard from someone at work that the recommended REST practice is to always return responses as JSON objects, which would mean that our schema for books would look like this,

```<code>books:
    type: object
    properties:
        list:
            type: array
            items: book
</code>```

So, now, response would look like this,

```<code>{
    "list": [{"author": "Dan Brown", "isbn": "123456", "title": "Digital Fortress"},
             {"author": "JK Rowling", "isbn": "234567", "title": "Harry Potter and the Chamber of Secrets"}]
}
</code>```

Which of these is the best REST practice?

答:
Both

```<code>[{"author": "Dan Brown", "isbn": "123456", "title": "Digital Fortress"},{"author": "JK Rowling", "isbn": "234567", "title": "Harry Potter and the Chamber of Secrets"}]
</code>```

and

```<code>{
    "list": [{"author": "Dan Brown", "isbn": "123456", "title": "Digital Fortress"},
         {"author": "JK Rowling", "isbn": "234567", "title": "Harry Potter and the Chamber of Secrets"}]
}
</code>```

are valid Json. I don't think you should add "list" if it's not needed, it might even be confusing because what's following it is an array, instead of a list.

Best REST practice? The API should give proper response to whatever set in Accept header, and also good documentation.

Body:
Both

[{"author": "Dan Brown", "isbn": "123456", "title": "Digital Fortress"},{"author": "JK Rowling", "isbn": "234567", "title": "Harry Potter and the Chamber of Secrets"}]

and

{
    "list": [{"author": "Dan Brown", "isbn": "123456", "title": "Digital Fortress"},
         {"author": "JK Rowling", "isbn": "234567", "title": "Harry Potter and the Chamber of Secrets"}]
}

are valid Json. I don't think you should add "list" if it's not needed, it might even be confusing because what's following it is an array, instead of a list.

Best REST practice? The API should give proper response to whatever set in Accept header, and also good documentation.


答: Pick an arbitrary algorithm for generating all combinations of i elements from n. See this former SO post, for example, or the 75 examples in different programming languages at Rosetta Code. Then use it to generate all combinations of i elements from the set {0,1,2,...,n-1} and assign each result R=(r1,r2,...,r_i) a string of length n of zeros and ones where the positions of the ones are the values in R.

Title: Given an array of n bits, how to generate every permutation with i 1's and n-i 0's?

Body:
It's simple enough to brute force a collection of strings and then filter for every occurrence with the required count of 1's.

As n increases the number of possible permutations becomes very large, very quickly, however, and due to speed and space considerations, I'm trying to find a more sophisticated method -- ideally, one that doesn't involve excessive string processing.


答:
Integer.

Address space in a computer is numbered sequentially, starting at 0, and increments by 1. So a pointer will hold an integer number which corresponds to an address in address space.


问:
How can I reinforce that security questions answers should not be the same and how to encrypt?
When my users are creating an account they need to fill and set several security questions pertaining to their account. I am wondering, how can I make sure that the answer the user enters for each security question is not the same as an answer for a different question? What's the proper attribute for it?

Also, for the security question answers, should I encrypt the answers so that whoever is sniffing the network won't see the answers? How? What should I look into or lookup for this approach?

答: Security questions are useless. They do not add security but annoy the hell out of the users. Do what serious companies do and verify identity via cell phone or just send a password reset link to the associated email (case in point: Stack Exchange).</p>


问:
TDD in theory only
A little over a year ago I was fortunate enough to be able to take a 9 month break from work.  I decided that in that time time I would hone my C# skills.  I started working on a bunch of projects and forced myself to follow TDD.

It was a fairly enlightening process.

It was tough at first, but over time I learned how to write more testable code (which, as it turns out, tends to be more SOLID code) and in the process I also sharpened my OO design skill.

Now I'm back in the workforce and I'm noticing something odd.

I prefer not to follow TDD.

I find TDD slows me down and actually makes it harder to design a clean application.

Instead, I've adopted a slightly (massively) different approach:

Pick a vertical slice of work

Develop a functioning prototype

Refactor until everything is nice and tidy

Sit back an appreciate the beautifully SOLID and testable code I've written.

You may have noticed that step 1 wasn't "define the public surface of my test target" and step 2 wasn't "test the bejesus out of said public surface."  You may have also noticed that none of the steps involve testing.  I'm writing testable code, but I'm not testing it... just yet.

Now, I'd like to make it clear that I'm not actually foregoing any kind of testing.  The code I'm writing works.  It works because I'm testing it manually.

I'd also like to make it clear that I'm not foregoing all automated testing either.  This is where my process is different.  And this is why I'm asking this question.

TDD in theory.  Not in practice.

My process has evolved a bit and I've struck a balance between TDD and no tests that I find very productive and also reasonably safe.  It goes as follows:

Implement a working vertical slice of work with testing in mind, but don't write any tests.

If down the road (eg, a month later) that slice needs modification

Write Unit Tests, Integration Tests, Behaviour Tests, etc that guarantee the slice of work is correct

Modify the code

If that slice doesn't need modification,

Do nothing

By simply shifting the burden of writing tests from before writing the code to before modifying the code I've been able to produce much more working code.  And, when I do get around to writing tests I write far fewer of them but cover nearly as much ground (higher ROI).

I like this process, but I'm concerned it might not scale well.  Its success hinges on developers being diligent about writing tests before they change things.  And that seems like a pretty big risk.  But, TDD has the very same risk.

So, am I going to [BT]DD hell, or is this a common form of pragmatic coding and testing?

I'd like to keep working this way.  What can I do to make this process work in the long term?

Note:

I am the sole developer on my projects and I am responsible for everything:  Requirements gathering, design, architecture, testing, deployment, etc.  I suspect this is why my process is working.

答:
For me the key thing appears to be this:

I am the sole developer on my projects and I am responsible for
  everything: Requirements gathering, design, architecture, testing,
  deployment, etc. I suspect this is why my process is working.

This works for you and you're producing nice clean code (I assume!). The only thing I would say you need to do is create a test harness so as other developers can come in and be confident in making changes. Also the test harness ensures consistency in the code's behaviour.

I think your approach is is similar to mine. I am usually the sole developer on my projects. I've found that an appreciation of TDD has enabled me to write smaller functions and cleaner code but I add tests whilst writing the code as a test harness. That way as the code evolves and functionality changes I can be reasonably confident in making changes.

A secondary reason for writing tests is that I feel they are a form of documentation. They can explain my reasonings behind why a function was created. But here, I'm thinking more about Behaviour Driven Development.

Title: TDD in theory only


答:
To make the process work in the long term I would write the tests when the code is being written.

Which may seem to contradict your approach.  However you've posed the question so I'll give you my take:

You don't have to write the tests before the code.  forget that purity.  However you want to write the tests around that time.

Once you have got the code working, you've tweaked it a bit, got some bugs out (we're talking about a timescale of hours here), you are then at a point of maximum knowledge about what the code is doing.  This is a great time to write tests that capture your knowledge.

Leaving this until later means the knowledge will (naturally) diminish over time.

It also means that should you ever leave and should anyone else take over you will not have the immediate technical debt of not having documented (through tests) what does what.

Most of all, "some day" may not come.  You may either get hit by a bus or you might board the bus for new adventures.

Finally, manual testing doesn't scale and frequently doesn't cover all the devices used by the end user.

Title: TDD in theory only

Body:
A little over a year ago I was fortunate enough to be able to take a 9 month break from work.  I decided that in that time time I would hone my C# skills.  I started working on a bunch of projects and forced myself to follow TDD.

It was a fairly enlightening process.

It was tough at first, but over time I learned how to write more testable code (which, as it turns out, tends to be more SOLID code) and in the process I also sharpened my OO design skill.

Now I'm back in the workforce and I'm noticing something odd.

I prefer not to follow TDD.

I find TDD slows me down and actually makes it harder to design a clean application.

Instead, I've adopted a slightly (massively) different approach:

Pick a vertical slice of work

Develop a functioning prototype

Refactor until everything is nice and tidy

Sit back an appreciate the beautifully SOLID and testable code I've written.

You may have noticed that step 1 wasn't "define the public surface of my test target" and step 2 wasn't "test the bejesus out of said public surface."  You may have also noticed that none of the steps involve testing.  I'm writing testable code, but I'm not testing it... just yet.

Now, I'd like to make it clear that I'm not actually foregoing any kind of testing.  The code I'm writing works.  It works because I'm testing it manually.

I'd also like to make it clear that I'm not foregoing all automated testing either.  This is where my process is different.  And this is why I'm asking this question.

TDD in theory.  Not in practice.

My process has evolved a bit and I've struck a balance between TDD and no tests that I find very productive and also reasonably safe.  It goes as follows:

Implement a working vertical slice of work with testing in mind, but don't write any tests.

If down the road (eg, a month later) that slice needs modification

Write Unit Tests, Integration Tests, Behaviour Tests, etc that guarantee the slice of work is correct

Modify the code

If that slice doesn't need modification,

Do nothing

By simply shifting the burden of writing tests from before writing the code to before modifying the code I've been able to produce much more working code.  And, when I do get around to writing tests I write far fewer of them but cover nearly as much ground (higher ROI).

I like this process, but I'm concerned it might not scale well.  Its success hinges on developers being diligent about writing tests before they change things.  And that seems like a pretty big risk.  But, TDD has the very same risk.

So, am I going to [BT]DD hell, or is this a common form of pragmatic coding and testing?

I'd like to keep working this way.  What can I do to make this process work in the long term?

Note:

I am the sole developer on my projects and I am responsible for everything:  Requirements gathering, design, architecture, testing, deployment, etc.  I suspect this is why my process is working.


问:
How do you get complete manual testing by QA in a git/hg flow development process?
I have a question about working with independent testers doing manual testing (not about automated unit and regression testing.)

In a flow process I do my work on a feature branch until I'm confident that it works and I haven't introduced bugs.  I merge from the develop branch to my feature, late and often, to ensure I haven't broken anything in merges with other recent work.  Sometimes I'll even do it again during the testing phase, so that the tester can work with the most recent snapshot.  Still, there's always a small window of time after testing where new work can -- and in high traffic times does -- come in from other features.

This means that the merge back to the develop/release branch is sometimes not trivial, despite our treating it like it should be.  (Sometimes it's even iterative: by the time I'm done making sure I've correctly integrated one feature that's slipped in, running regression tests, checking the code, and doing some manual testing, yet another one has come in.)

My question is, is there a workflow for developers and testers where you don't lose out on the safety net of testers for that last step (but also hopefully don't need to ask again and again for re-testing tested work)?  What are industry best practices here?  If we could assure that branches won't interfere with one another, we'd be fine, but in practice we get conflicts sometimes.

I'll add that I'm sure we don't want to do our main testing on the develop/release branch.  It's been a huge win and stress-reducer since we switched to flow.  We can easily put off releasing work that's created a problem or raised a question during testing.  In our pre-flow practice, we wound up with emergencies near a release, where a problem was found that we had to deal with urgently before releasing because the work of a non-critical feature was already merged into the main branch for testing.

答:
So your problem is ultimately nothing to do with testing but the issue of difficult merges of your feature branch back to develop?

I'd say why do you not want to run your tests off the develop branch? Are you testing the individual feature you're developing, or the integration whole of yours and others features? I'd say the feature branch testing is a matter for the developer, only when you think its complete do you merge to develop and then build a package for the test team from there (personally I'd rename the 'develop' branch to 'integration'). This way, test team has a current version of the product, and can test completed features, feeding back bugs to the developer to fix and iterate the feature=merge-to-develop process again until test find no bugs in it, then the feature is closed. When the test team declares the product tested, can it be merged from develop to master.

Typically you'll want to perform QA tests on the releases as well, but if master is simply a snapshot copy of develop for release purposes then you can skip this.


问:
A practical use of "yield" keyword in C#
After almost 4 years of experience, I haven't seen a code where yield keyword is used. Can somebody show me a practical usage (along explanation) of this keyword, and if so, aren't there other ways easier to fullfill what it can do?

答:
Although the merging case has already been covered in the accepted answer, let me show you the yield-merge params extension method™:

```<code>public static IEnumerable<T> AppendParams<T>(this IEnumerable<T> a, params T[] b)
{
    foreach (var el in a) yield return el;
    foreach (var el in b) yield return el;
}
</code>```

I use this to build packets of a network protocol:

```<code>static byte[] MakeCommandPacket(string cmd)
{
    return
        header
        .AppendParams<byte>(0, 0, 1, 0, 0, 1, 0x92, 0, 0, 0, 0)
        .AppendAscii(cmd)
        .MarkLength()
        .MarkChecksum()
        .ToArray();
}
</code>```

The MarkChecksum method, for example, looks like this. And it has a yield, too:

```<code>public static IEnumerable<byte> MarkChecksum(this IEnumerable<byte> data, int pos = 6)
{
    foreach (byte b in data)
    {
        yield return pos-- == 0 ? (byte)data.Sum(z => z) : b;
    }
}
</code>```

But be careful when using aggregate methods like Sum() in an enumeration method as they trigger a separate enumeration process.

Body:
Although the merging case has already been covered in the accepted answer, let me show you the yield-merge params extension method™:

public static IEnumerable<T> AppendParams<T>(this IEnumerable<T> a, params T[] b)
{
    foreach (var el in a) yield return el;
    foreach (var el in b) yield return el;
}

I use this to build packets of a network protocol:

static byte[] MakeCommandPacket(string cmd)
{
    return
        header
        .AppendParams<byte>(0, 0, 1, 0, 0, 1, 0x92, 0, 0, 0, 0)
        .AppendAscii(cmd)
        .MarkLength()
        .MarkChecksum()
        .ToArray();
}

The MarkChecksum method, for example, looks like this. And it has a yield, too:

public static IEnumerable<byte> MarkChecksum(this IEnumerable<byte> data, int pos = 6)
{
    foreach (byte b in data)
    {
        yield return pos-- == 0 ? (byte)data.Sum(z => z) : b;
    }
}

But be careful when using aggregate methods like Sum() in an enumeration method as they trigger a separate enumeration process.


问:
What is an "assertion framework"?
I was reading about the js-test-driver unit-testing framework, when I found out that the guys behind the framework intend it to be integrated with an assertion framework. What is an assertion framework? Is it a kind of unit-testing framework? If it is the case what is specific to such frameworks?</p>

答:
JsTestDriver is primarily concerned with providing a test-runner, i.e. the way that you execute the tests.

It provides a built in assertion framework, which is xUnit in style. This is used to actually write the tests (e.g. assertTrue, assertEquals, etc). However, it also allows you to plugin in alternative assertion frameworks. There are currently plugins available for Unit and Jasmine, which offers BDD style assertions.

Title: What is an "assertion framework"?


问:
API call to login from a link in email
I am trying to make a something like a shopping cart. I want to add a feature, that if a person adds a product on website but does not purchase the item, i will send him an email with a link. If the person clicks on the link, then I want to login him automatically and take him directly to payment page. I don't want him to enter password in between. So can I somehow create some API call which can login him and then redirect him to concerned URL?</p>

答:
Sure you can. It's your application, you can handle access to it the way you want. But you should remember several important points.

Whoever gets access to that link gains access to the customer's payment page. That is a lot of access to be sent over something as blatantly insecure as email.

The link that you generate should not transparently include any user credentials. This is easy to get horribly wrong. You don't want to create something that allows an attacker to access every other customer's payment data just by incrementing a number somewhere in the URL.

The link should probably be usable only once, and only within a short time of its generation, to mitigate the risks that you can't avoid when generating such pre-approvied log-ins.

Title: API call to login from a link in email


答:
I agree with both Daniel Hollinrake and Ewan, that the first key point why your test-only-if-modify works well so far is:

```<code>I am the sole developer on my projects and I am responsible for everything
</code>```

and that a likely second key point is:

```<code>you're producing nice clean code
</code>```

I do not think TDD brings a huge productivity boost for sole programmers, and it may not hugely improve the quality of your code if you are already writing good clean code.

However, TDD will surely improve the quality of the code of poor / inexperienced / obsolete programmers, especially when the time comes to modify the code without breaking anything else. And even more so if the person modifying the code is not the same person that wrote the code originally or several months have passed in between.

In other words, I think TDD is both good practice to improve the quality of your code (as you acknowledge yourself) but also (and more important) a sort of hedge when you are working with average or mediocre programmers (say, from a different department or a different company) which is a far more common situation than working solo.

Title: TDD in theory only

Body:
I agree with both Daniel Hollinrake and Ewan, that the first key point why your test-only-if-modify works well so far is:

I am the sole developer on my projects and I am responsible for everything

and that a likely second key point is:

you're producing nice clean code

I do not think TDD brings a huge productivity boost for sole programmers, and it may not hugely improve the quality of your code if you are already writing good clean code.

However, TDD will surely improve the quality of the code of poor / inexperienced / obsolete programmers, especially when the time comes to modify the code without breaking anything else. And even more so if the person modifying the code is not the same person that wrote the code originally or several months have passed in between.

In other words, I think TDD is both good practice to improve the quality of your code (as you acknowledge yourself) but also (and more important) a sort of hedge when you are working with average or mediocre programmers (say, from a different department or a different company) which is a far more common situation than working solo.


问:
Can multiple synchronized methods in same object run concurrently
As far as i know when there are multiple synchronized methods(both static and instance) in a class, java allows only one such method to run at a time. But what if a thread acquires lock on an object instance(or class), then enters a synchrozed method inside that object and then makes a call to another synchronized method of the same object. I mean to say:

```<code>Class AA
{
 ..
 ..
synchronized void X()
{
  Y();
}

synchronized void Y()
{
 ..
 ..
}
</code>```

Is any thread execting the method X going to block forever? Since java wont allow to run both method X and Y at the same time?

答:
In Java, synchronized locks are re-entrant.

Or in other words if your thread already holds the lock on an object it doesn't have to wait on itself.


答:
If you read carefully the documentation of synchronized you will find that it is explicitly stated that once a thread has acquired a lock, it is allowed to re-acquire it as many times as it pleases.

According to the Java Language Specification:

Section 8.4.3.6. "synchronized Methods" says that the synchronized keyword acquires a monitor.  See: http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.3.6

Section "17.1 Synchronization" then says that A thread t may lock a particular monitor multiple times. See http://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.1

So, it is only other threads that have to wait if a thread has acquired a lock.  The same thread may reacquire the lock without ever having to wait.

Title: Can multiple synchronized methods in same object run concurrently

Body:
As far as i know when there are multiple synchronized methods(both static and instance) in a class, java allows only one such method to run at a time. But what if a thread acquires lock on an object instance(or class), then enters a synchrozed method inside that object and then makes a call to another synchronized method of the same object. I mean to say:

```<code>Class AA
{
 ..
 ..
synchronized void X()
{
  Y();
}

synchronized void Y()
{
 ..
 ..
}
</code>```

Is any thread execting the method X going to block forever? Since java wont allow to run both method X and Y at the same time?


问:
How to pick a random move/action/element non-probabilistically?
I am trying to create a simple AI that can play Go using Monte Carlo Tree Search.

This question, however, is valid for all games where players take turns doing some action that, on average, reduce the amount of possible actions to take in the future. (Other examples might be Tic Tac Toe, Connect 4 and a whole bunch of others.), or any situation in which we need to  "Pick a random possibility until it is within expected parameters".

In Go, Players take turns placing a stone of their color on the board. As the board fills up, some moves are no longer valid (For instance, because there might be a stone at that location already.*)

The algorithm should pick a move at random. However, how do we ensure that the move we picked is valid? I see the following options, each with their own drawbacks:

When the move is not valid, pick a new random one. Drawback: The program is now probabilistic; it is very possible that it picks only invalid moves repeatedly, and therefore never finishes executing.

When the move is not valid, move to the next square (wrapping around at the edges of the board). Drawback: When there is a large region of the board that is already occupied, the distribution of moves picked is no longer random: It is far more likely that the position right next to the filled area is picked, as when the random number falls in this range, this is the chosen square.

First obtain a list of all possibilities, and choose a random element from this list. This ensures an equal distribution of probabilities. Drawback: Because we need to iterate over the whole board and obtain a list of all possible moves, this is inefficient. As the algorithm should run as fast as possible (As we want to simulate as many games as possible), iterating over the whole board should best be avoided.

Now, I am wondering if there exist another method of picking a move at random that:

Does not significantly favour certain outcomes over others.

Will terminate.

Does not need to find out all possible moves from a certain position beforehand.

*(The rules of Go have more conditions for a move to be valid, but these do not change this question)

答:
How about using a hybrid approach?

First, estimate the number of available valid moves.  (Probably based on the percentage of the board that is covered with stones/pegs/pawns.)

If the number of available valid moves is large, then it is okay to follow the strategy of trying moves at random until a valid one is found, because it will soon yield a result.

If the number of available valid moves is small, then you know that iterating over the whole board and obtaining a list of all possible moves is not going to represent a terribly large overhead, so you can go ahead and construct this list and then randomly pick from the list a move which is already known to be valid.


答:
Maintain and update the list of possible moves to pick from.

Changes to this list will be small per move on average and often localized to where the piece was put.

Title: How to pick a random move/action/element non-probabilistically?

Body:
I am trying to create a simple AI that can play Go using Monte Carlo Tree Search.

This question, however, is valid for all games where players take turns doing some action that, on average, reduce the amount of possible actions to take in the future. (Other examples might be Tic Tac Toe, Connect 4 and a whole bunch of others.), or any situation in which we need to  "Pick a random possibility until it is within expected parameters".

In Go, Players take turns placing a stone of their color on the board. As the board fills up, some moves are no longer valid (For instance, because there might be a stone at that location already.*)

The algorithm should pick a move at random. However, how do we ensure that the move we picked is valid? I see the following options, each with their own drawbacks:

When the move is not valid, pick a new random one. Drawback: The program is now probabilistic; it is very possible that it picks only invalid moves repeatedly, and therefore never finishes executing.

When the move is not valid, move to the next square (wrapping around at the edges of the board). Drawback: When there is a large region of the board that is already occupied, the distribution of moves picked is no longer random: It is far more likely that the position right next to the filled area is picked, as when the random number falls in this range, this is the chosen square.

First obtain a list of all possibilities, and choose a random element from this list. This ensures an equal distribution of probabilities. Drawback: Because we need to iterate over the whole board and obtain a list of all possible moves, this is inefficient. As the algorithm should run as fast as possible (As we want to simulate as many games as possible), iterating over the whole board should best be avoided.

Now, I am wondering if there exist another method of picking a move at random that:

Does not significantly favour certain outcomes over others.

Will terminate.

Does not need to find out all possible moves from a certain position beforehand.

*(The rules of Go have more conditions for a move to be valid, but these do not change this question)


问:
What would you consider best practice workflow tools for web application (PHP) development?
I'm really hoping somebody with more experience can edit the question as per my examples of answers:

using version control

test driven development

debugging code (xdebug for php)

use of UML diagrams

use of OOP for maintainable, reusable code

use of frameworks (like Zend Framework for php) for rapid application development

Anything else or an elaboration of what I mentioned above?

Basically, I'm in the middle of forming a team of developers (I'm a developer myself) and I'd like some advice on how professional programmers/designers etc should work together and what standards/paradigms they should use.

Also, if anybody has any books or links on the subject I'd welcome that!

I did find this which I guess satisfies what I'm looking for, or at least part thereof:

http://www.ibm.com/developerworks/websphere/library/techarticles/0306_perks/perks2.html

答:
Framework: codeigniter, with no doubt. It has all the functionalities you might ever need, and does not force you to use any of them unless you do need them;

Version control, IDE: I'm pretty old-school, and I don't think my answer could really help you;

Wireframing, UML: old school in this too, but really: whiteboards win. They're flexible, extensible, and support any convention you might see fit;

Database administration: phpmyadmin;

Development server OS: I might be banal, but: Ubuntu. Install a LAMP server in seconds; don't panic about adding new libraries (the dreaded imagick: one command, done); if you like PHP you'll probably end up working on linux server in production so it's better to start practicing. (Disclaimer: Ubuntu is not my favorite distribution).

Misc: grep can be incredibly useful when debugging other poeople's code (wanna know how many controllers use a given model? Done!).

edit

I forgot the most important thing: specs. Write real specs for your project before touching any code. Have all the user interaction diagrams in mind. It will save you centuries.


答:
The PEP 8 Python style guide shows lists in the form:

```<code>my_list = [
    1, 2, 3,
    4, 5, 6,
    ]
</code>```

In the indentation section of the pep https://www.python.org/dev/peps/pep-0008/#indentation

For this reason I would say style 1 (ensuring not to violate the line length rules).

Title: python code style for long lists

Body:
when coding a very long list in python, is it better to fit several items on each line or should I limit it to 1 per line? 99% of the time I would go with style2 below but I have 5 lists each about the same length as the one below and it seems like too many lines. any advice would be appreciated.

for example:

```<code>style1 = [
    'Email:', 'SSN:', 'Address:', 'Home Phone:',
    'Mobile Phone: ', 'DOB:', 'Date of Surgery:',
    'Date of Service:', 'Facility of Service:', 'Clinic Number:',
    'Employer:', 'Work Phone: ', 'Fax: ', 'Type:', 'IPA:',
    'Health Plan:', 'ID #:', 'Claims Address:', 'Group #:',
    'Claim # / PO #:', 'Phone:', 'Fax:', 'Contact',
    'Adjuster Email', 'Util Review Phone', 'Util Review Fax',
    'Doctor:', 'NPI #: ', 'Date of Injury: ', 'Body Parts:',
    'Body Part Side:', 'Gender:', 'Diagnosis:', 'Diagnosis 2:',
    'Procedure:'
    ]

style2 = [
    'Email:',
    'SSN:',
    'Address:',
    'Home Phone:',
    'Mobile Phone: ',
    'DOB:',
    'Date of Surgery:',
    'Date of Service:',
    'Facility of Service:',
    'Clinic Number:',
    'Employer:',
    'Work Phone: ',
    'Fax: ',
    'Type:',
    'IPA:',
    'Health Plan:',
    'ID #:',
    'Claims Address:',
    'Group #:',
    'Claim # / PO #:',
    'Phone:',
    'Fax:',
    'Contact',
    'Adjuster Email',
    'Util Review Phone',
    'Util Review Fax',
    'Doctor:',
    'NPI #: ',
    'Date of Injury: ',
    'Body Parts:',
    'Body Part Side:',
    'Gender:',
    'Diagnosis:',
    'Diagnosis 2:',
    'Procedure:'
    ]
</code>```

Body:
The PEP 8 Python style guide shows lists in the form:

my_list = [
    1, 2, 3,
    4, 5, 6,
    ]

In the indentation section of the pep https://www.python.org/dev/peps/pep-0008/#indentation

For this reason I would say style 1 (ensuring not to violate the line length rules).


答:
In order to make this more on-topic, this is a way to go about determining which one is better for a particular situation. Note: you may find that the best solution could change over time as your application's requirements change.

Do Both: Sorry, if you want to really find out the best solution, I recomend doing both and comparing your results. This accomplishes a few things:

Performance comparison (Assuming you can simulate a load)

Learn how to implement both in case you need to change.

Design your code so swapping data sources is not that difficult.

Part of this process could be used to create a unit or integration test.

Again, this is all predicated on not know which one will work for your situation, so you build your app in order to change the data sources as needed. You may find a need for some sort of in-memory data caching for this sort of thing. You'll be ready to do this without a major change to your application.

Title: What is the best way to go about storing application options: file system or db?

Body:
We are looking to find the best way to store user options (skills, degrees, industries, languages, etc.) for drop downs. The options are between a JSON file we can store on the server file system or in the db (MongoDB).

What are the pros and cons of each method and how will they affect server performance under heavy usage?


答:
Java synchronisation uses a recursive lock for the instance of the synchronised method. It is as if each instance had a recursive lock, and @synchronized would lock that recursive lock (JVM uses a more clever method obviously). Therefore:

Any number of threads can use @synchronized for different objects.

One thread can use @synchronized for the same object multiple times.

One thread can use @synchronized for any number of objects that are not @synchronized by any other thread.

For @synchronized class methods, a recursive lock for the class itself is used. Same rules apply as above, since classes are first class objects.

java allows only one such method to run at a time

Well, that's absolutely not true. First, 10 threads can call ten synchronized methods of ten different instances, and they can all run at the first time. Each synchronized method can in turn call other synchronized methods of other instances, and as long as they are not used with @synchronized methods, that will also work. And each @synchronized method can recursively call @synchronized methods of the same instance, as much as it likes.

The restriction is: No two threads can run @synchronized methods of the same instance simultaneously, or run @synchronized class methods of the same class simultaneously.


答:
If you never make mistakes you don't really need tests. Most developers do make mistakes, but if you never do, and you are confident you will never make mistakes in the future (and you are the only one on the project), there is really no reason to waste time writing tests.

But your solution is kind of halfway because you are proposing to write tests when changing code, but at the same time your method assumes that you'll never make mistakes when you decide which parts of the code to write tests for. This only works if you always understand perfectly which areas a change may affect. I think many common developers (not you of course!) have experienced to make a change, and then a test somewhere unexpected fails, because you made a mistake.

Of course good architecture, SOLID principles etc. should prevent this happening, but most developers are not perfect, and this is why tests across the system are valuable.

Title: TDD in theory only


问:
Do you have any team guidelines regarding exceptions?
My team recently inherited a project from a team where the amount of developers dropped so low they had to offload some work. One of the projects we inherited was a project littered with nested code, and awful exception handling (Exceptions were in effect handled as goto statements and thus used as a part of the normal program flow.).

All in all it was a hairy code ball someone had been coughing up for a few years.

Now we've been having a few team guidelines in place for quite some time, but all of the regards to the structures of objects, coding styles and what not. But we haven't covered exception handling.

So I'm wondering if you have any guidelines in your teams regarding exception handling, and if so how you enforce them?

答: Although they aren't official guidelines on any team I've ever been on, I feel that exceptions should only be used for truly exceptional conditions, or when you absolutely (for some reason) have to throw up your hands and let your caller (or bubble up from your current point, potentially all the way to the user) know that there's absolutely no way that a particular component can function under the current conditions and it's not possible to recover without some kind of outside (other module or user) intervention.</p>


问:
How can Guard Statements and Small Functions coexist?
By Guard Statements I mean something similar to the first part of the function:

```<code>def doSomething(String something)
{
    // Guard Statement
    if(!something)
    {
        return false
    }

    // more stuff
}
</code>```

Say you might have several parameters, maybe you need to log that the method was called with a null parameter, or maybe throw a specific exception.

Clarification: I've read that both Guard Statements and smaller functions are good design choices, but it seems like if you include Guard Statements your functions won't be small.

By smaller functions I'm referencing Robert C. Martin's smaller function suggestions in Clean Code.

I guess what I'm asking is it worth it to include Guard Statements in a function even though it makes the function longer. I understand the answer could very based on if it's a public API or private function, for this purpose it's not a private function but a service in a MVC application, so I guess that makes it public?

答:
"Functions should be small" is not an absolute requirement. The time to read and understand a function could be modeled as a constant, plus some small constant times the number of lines of code squared. Many small functions are hard to understand. Few enormous functions are hard to understand. There is middle ground that you need to look for.

But then, you are not looking for the least complex code. You are looking for the least complex code that solves your problem reliably and in an acceptable time. If guard statements are needed to make your code reliable, then it doesn't matter how much they add to the size of a function.

It has been said "don't use guards". Determine what happens without guards and how bad that is. If you figure out "if I don't use a guard, then the code will crash in development" - don't use the guard. Wait for the crash in development, fix the reason for the crash. Define the interface for your function, document it, and if the caller doesn't respect it, feel free to crash (sometimes you may use a guard to invoke the crash). If you figure out "if that guard ever triggers, then I'm in a totally unexpected situation". Feel free to crash if that is better than running code without any idea what the result will be.

Where you should have guards is when you expect that things could be wrong. Typical: Processing JSON data from an unknown source. Anything could go wrong, and you want to use guards to tell the caller "your data was rubbish" instead of "I processed all your nice data".


问:
Functionality in ISO 9126 is Non-functional quality? Contradiction in ISTQB and many sources
I have been doing some research and realized that I missed the fact that in ISO 9126 and ISO 25010, all characteristics are quality characteristics and represent (according to various papers) just non-functional ones. It surprised me as I thought "Functionality" is clearly functional but now I can see that they probably mean "evaluation of functionality from the non-functional view, i.e. how is the system doing these things".

Then I found an interesting thing in an ISTQB book. They talk about functional tests and reference ISO 9126 Functionality. But in the non-functional testing section, they enumerate non-functional requirements according to this ISO and do state Functionality, referencing the section in Functional testing page!

ISO 25010 is said to present 8 non-functional categories, including Functional suitability. That does sound like a non functional one but again it is said it is just renamed Functionality from ISO 9126. And yet there are books saying that "Functional suitability" from ISO  25010 is functional and should be tested functionally (well, it does make sense more than saying it is non-functional)...

Most of the QA books typically lists ISO 9126 Functionality under Functional testing so I cannot understand how this can be listed as non-functional...

Similarly, I found for the ISO 9126 sources claiming that its Functionality is quality requirement, therefore non-functional requirement, while the other sources state that non-functional are those except for this one.

Does anyone know this ISO standard well enough to explain the problem?

答:
Look at the quality model listed here.  Every one of those qualities is non-functional.

Functionality that fulfills the business's needs is determined by your functional software requirements.  Each functional requirement should be accompanied by an acceptance test, and it is that acceptance test (and not some ISO standards document) that dictates whether or not that functional requirements is fulfilled.

Hypothetically, an ISO document might address the way the requirement and its acceptance test are written and executed, but not the nature of the functional requirements themselves.  Functional requirements are wholly dependent on the needs of the stakeholders.


答:
Encode your preconditions in the type system so that a program which violates your guard can't compile. For example (scala)

```<code>object PositiveInt {
  /** Returns a positiveInt wrapper or None */
  def apply(i: Int): Option[PositiveInt] = if (i >= 0) Some(PositiveInt(i)) else None
}
case class PositiveInt private (value: Int) extends AnyVal // Value class to avoid extra object creation

def squareRoot(i: PositiveInt): Double = math.sqrt(i.value)
</code>```

In this case I make it so that it's not possible to invoke squareRoot on an int which we haven't verified as being positive. The constructor is private so the only way to get one is to use method returning Option and handle the case where it returns None - failure to do this means the program doesn't compile.

Title: How can Guard Statements and Small Functions coexist?

Body:
By Guard Statements I mean something similar to the first part of the function:

```<code>def doSomething(String something)
{
    // Guard Statement
    if(!something)
    {
        return false
    }

    // more stuff
}
</code>```

Say you might have several parameters, maybe you need to log that the method was called with a null parameter, or maybe throw a specific exception.

Clarification: I've read that both Guard Statements and smaller functions are good design choices, but it seems like if you include Guard Statements your functions won't be small.

By smaller functions I'm referencing Robert C. Martin's smaller function suggestions in Clean Code.

I guess what I'm asking is it worth it to include Guard Statements in a function even though it makes the function longer. I understand the answer could very based on if it's a public API or private function, for this purpose it's not a private function but a service in a MVC application, so I guess that makes it public?

Body:
Encode your preconditions in the type system so that a program which violates your guard can't compile. For example (scala)

object PositiveInt {
  /** Returns a positiveInt wrapper or None */
  def apply(i: Int): Option[PositiveInt] = if (i >= 0) Some(PositiveInt(i)) else None
}
case class PositiveInt private (value: Int) extends AnyVal // Value class to avoid extra object creation

def squareRoot(i: PositiveInt): Double = math.sqrt(i.value)

In this case I make it so that it's not possible to invoke squareRoot on an int which we haven't verified as being positive. The constructor is private so the only way to get one is to use method returning Option and handle the case where it returns None - failure to do this means the program doesn't compile.


答:
Don't think of short functions in terms of absolute LOCs number. It is irrelevant, because:

void demo(int a)
{
    if (a < 0)
    {
        this.dealWithNegative();
    }

    for (int i = 0; i < a; i++)
    {
        yield this.doSomething(i);
    }
}
```

<p>and:</p>

<pre class="lang-java prettyprint-override"><code>void demo(int a) {
    if (a < 0) this.dealWithNegative();
    for (int i = 0; i < a; i++) yield this.doSomething(i);
}
</code>```

are the same in terms of complexity: the second variant is not three times better because of its LOC of 4 lines versus 12 lines in the first example. (Actually, the second example is much more error prone, and so worse, but this is a different subject.)

Think of short functions in terms of how long would it take you to understand them. When you start working with a method, you tell:

“Oh heck, it would take me two hours to figure out what is all this code about.”

and not:

“Well, there are 124 lines of code, so it should take me from 96 to 112 minutes to figure this code out.”

right?

While bigger LOC usually leads to methods which take more time to understand, there is no strict correlation between two factors. For example, how long would it take you to understand a method which maps a value to another, containing 50 values (and so 53 LOCs)? Would that change if the map contains only 10 values? What about 300 values?

Guard clauses don't necessarily make methods longer, because they are simple to understand and don't take too much of your time when you prepare to work with the code. They may not even increase the absolute number of LOCs, because most stuff they deal with is otherwise scattered in your code. For example, what is simpler:

The code with guard clauses:

void demo(int a, int b)
{
    if (a <= 0) throw new ArgumentOutOfRangeException(...);
    if (b < a) throw new ArgumentException(...);

    var c = b / a;
    this.doSomething(c);
}
```</li>
<li><p>or the contrived logic of the similar code without them:</p>

<pre class="lang-java prettyprint-override"><code>void demo(int a, int b)
{
    if (a != 0)
    {
        // The division is safe: we won't have division by zero here.
        var c = (double)b / a;
        if (c < 1.0)
        {
            // We shouldn't have `c` inferior to 1.
            throw new NotImplementedException();
        }

        this.doSomething((int)c);
    }
    else
    {
        throw new ArgumentOutOfRangeException();
    }
}
</code>```

Body:
Don't think of short functions in terms of absolute LOCs number. It is irrelevant, because:

void demo(int a)
{
    if (a < 0)
    {
        this.dealWithNegative();
    }

    for (int i = 0; i < a; i++)
    {
        yield this.doSomething(i);
    }
}

and:

void demo(int a) {
    if (a < 0) this.dealWithNegative();
    for (int i = 0; i < a; i++) yield this.doSomething(i);
}

are the same in terms of complexity: the second variant is not three times better because of its LOC of 4 lines versus 12 lines in the first example. (Actually, the second example is much more error prone, and so worse, but this is a different subject.)

Think of short functions in terms of how long would it take you to understand them. When you start working with a method, you tell:

“Oh heck, it would take me two hours to figure out what is all this code about.”

and not:

“Well, there are 124 lines of code, so it should take me from 96 to 112 minutes to figure this code out.”

right?

While bigger LOC usually leads to methods which take more time to understand, there is no strict correlation between two factors. For example, how long would it take you to understand a method which maps a value to another, containing 50 values (and so 53 LOCs)? Would that change if the map contains only 10 values? What about 300 values?

Guard clauses don't necessarily make methods longer, because they are simple to understand and don't take too much of your time when you prepare to work with the code. They may not even increase the absolute number of LOCs, because most stuff they deal with is otherwise scattered in your code. For example, what is simpler:

The code with guard clauses:

void demo(int a, int b)
{
    if (a <= 0) throw new ArgumentOutOfRangeException(...);
    if (b < a) throw new ArgumentException(...);

    var c = b / a;
    this.doSomething(c);
}

or the contrived logic of the similar code without them:

void demo(int a, int b)
{
    if (a != 0)
    {
        // The division is safe: we won't have division by zero here.
        var c = (double)b / a;
        if (c < 1.0)
        {
            // We shouldn't have `c` inferior to 1.
            throw new NotImplementedException();
        }

        this.doSomething((int)c);
    }
    else
    {
        throw new ArgumentOutOfRangeException();
    }
}