答:
The first thing to understand is that P and NP classify languages, not problems. To understand what this means, we need some other definitions first.

An alphabet is a non-empty finite set of symbols.

{0, 1} is an alphabet as is the ASCII character set. {} is not an alphabet because it is empty. N (the integers) is not an alphabet because it is not finite.

Let Σ be an alphabet. An ordered concatenation of a finite number of symbols from Σ is called a word over Σ.

The string 101 is a word over the alphabet {0, 1}. The empty word (often written as ε) is a word over any alphabet. The string penguin is a word over the alphabet containing the ASCII characters. The decimal notation of the number π is not a word over the alphabet {., 0, 1, 2, 3, 4, 5, 6, 7, 8, 9} because it is not finite.

The length of a word w, written as |w|, is the number of symbols in it.

For example, |hello| = 5 and |ε| = 0. For any word w, |w| ∈ N and therefore finite.

Let Σ be an alphabet. The set Σ＊ contains all words over Σ, including ε. The set Σ+ contains all words over Σ, excluding ε. For n ∈ N, Σn is the set of words of length n.

For every alphabet Σ, Σ＊ and Σ+ are infinite countable sets. For the ASCII character set ΣASCII, the regular expressions .* and .+ denote ΣASCII＊ and ΣASCII+ respectively.

{0, 1}7 is the set of 7-bit ASCII codes {0000000, 0000001, …, 1111111}. {0, 1}32 is the set of 32 bit integer values.

Let Σ be an alphabet and L ⊆ Σ＊. L is called a language over Σ.

For an alphabet Σ, the empty set and Σ＊ are trivial languages over Σ. The former is often referred to as the empty language. The empty language {} and the language containing only the empty word {ε} are different.

The subset of {0, 1}32 that corresponds to non-NaN IEEE 754 floating point values is a finite language.

Languages can have an infinite number of words but every language is countable. The set of strings {1, 2, …} denoting the integers in decimal notation is an infinite language over the alphabet {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}. The infinite set of strings {2, 3, 5, 7, 11, 13, …} denoting the prime numbers in decimal notation is a proper subset thereof. The language containing all words matching the regular expression [+-]?\d+\.\d*([eE][+-]?\d+)? is a language over the ASCII character set (denoting a subset of the valid floating-point expressions as defined by the C programming language).

There is no language containing all real numbers (in any notation) because the set of real numbers is not countable.

Let Σ be an alphabet and L ⊆ Σ＊. A machine D decides L if for every input w ∈ Σ＊ it computes the characteristic function χL(w) in finite time. The characteristic function is defined as

```<i>χ</i><sub><i>L</i></sub>: <i>Σ</i><sup>＊</sup> → {0, 1}
    <i>w</i>  ↦ 1,  <i>w</i> ∈ <i>L</i>
         0,  otherwise.```

Such a machine is called a decider for L. We write “D(w) = x” for “given w, D outputs x”.

There are many machine models. The most general one that is in practical use today is the model of a Turing machine. A Turing machine has unlimited linear storage clustered into cells. Each cell can hold exactly one symbol of an alphabet at any point in time. The Turing machine performs its computation as a sequence of computation steps. In each step, it can read one cell, possibly overwrite its value and move the read/write head by one position to the left or right cell. What action the machine will perform is controlled by a finite state automaton.

A random access machine with a finite set of instructions and unlimited storage is another machine model that is as powerful as the Turing machine model.

For the sake of this discussion, we shall not bother us with the precise machine model we use but rather suffice to say that the machine has a finite deterministic control unit, unlimited storage and performs a computation as a sequence of steps that can be counted.

Since you've used it in your question, I assume that you're already familiar with “big-O” notation so here is only a quick refresher.

Let f: N → be a function. The set O(f) contains all functions g: N → N for which there exist constants n0 ∈ N and c ∈ N such that for every n ∈ N with n > n0 it is true that g(n) ≤ c f(n).

Now we are prepared to approach the real question.

The class P contains all languages L for which there exists a Turing machine D that decides L and a constant k ∈ N such that for every input w, D halts after at most T(|w|) steps for a function T ∈ O(n ↦ nk).

Since O(n ↦ nk), while mathematically correct, is inconvenient to write and read, most people – to be honest, everybody except myself – usually writes simply O(nk).

Note that the bound depends on the length of w. Therefore, the argument you make for the language of the primes is only correct for numbers in unaray encodings, where for the encoding w of a number n, the length of the encoding |w| is proportional to n. Nobody would ever use such an encoding in practice. Using a more advanced algorithm than simply trying all possible factors, it can be shown, however, that the language of prime numbers remains in P if the inputs are encoded in binary (or to any other base). (Despite massive interest, this could only be proven by Manindra Agrawal, Neeraj Kayal, and Nitin Saxena in an award-winning paper in 2004 so you can guess that the algorithm is not very simple.)

The trivial languages {} and Σ＊ and the non-trivial language {ε} are obviously in P (for any alphabet Σ). Can you write functions in your favorite programming language that take a string as input and return a boolean telling whether the string is a word from the language for each of these and prove that your function has polynomial run-time complexity?

Every regular language (a language described by a regular expression) is in P.

Let Σ be an alphabet and L ⊆ Σ＊. A machine V that takes an encoded tuple of two words w, c ∈ Σ＊ and outputs 0 or 1 after a finite number of steps is a verifier for L if it has the following properties.

Given (w, c), V outputs 1 only if w ∈ L.

For every w ∈ L, there exists a c ∈ Σ＊ such that V(w, c) = 1.

The c in the above definition is called a witness (or certificate).

A verifier is allowed to give false negatives for the wrong witness even if w actually is in L. It is not, however, allowed to give false positives. It is also required that for each word in the language, there exists at least one witness.

For the language COMPOSITE, that contains the decimal encodings of all integers that are not prime, a witness could be a factorization. For example, (659, 709) is a witness for 467231 ∈ COMPOSITE. You can easily verify that on a sheet of paper while without the witness given, proving that 467231 is not prime would be difficult without using a computer.

We didn't say anything about how an appropriate witness can be found. This is the non-deterministic part.

The class NP contains all languages L for which there exists a Turing machine V that verifies L and a constant k ∈ N such that for every input (w, c), V halts after at most T(|w|) steps for a function T ∈ O(n ↦ nk).

Note that the above definition implies that for each w ∈ L there exists a witness c with |c| ≤ T(|w|). (The Turing machine cannot possibly look at more symbols of the witness.)

NP is a superset of P (why?). It is not known whether there exist languages that are in NP but not in P.

Integer factorization is not a language per se. However, we can construct a language that represents the decision problem associated with it. That is, a language that contains all tuples (n, m) such that n has a factor d with d ≤ m. Let us call this language FACTOR. If you have an algorithm to decide FACTOR, it can be used to compute a full factorization with only polynomial overhead by performing a recursive binary search for each prime factor.

It is easy to show that FACTOR is in NP. An appropriate witness would simply be the factor d itself and all the verifier would have to do is verify that d ≤ m and n mod d = 0. All of this can be done in polynomial time. (Remember, again, that it is the length of the encoding that counts and that is logarithmic in n.)

If you can show that FACTOR is also in P, you can be sure to get many cool awards. (And you have broken a significant portion of today's cryptography.)

For every language in NP, there is a brute-force algorithm that decides it deterministically. It simply performs an exhaustive search over all witnesses. (Note that the maximum length of a witness is bounded by a polynomial.) So, your algorithm to decide PRIMES was actually a brute-force algorithm to decide COMPOSITE.

To address your final question, we need to introduce reduction. Reductions are a very powerful concept of theoretical computer science. Reducing one problem to another basically means solving one problem by means of solving another problem.

Let Σ be an alphabet and A and B be languages over Σ. A is polynomial-time many-one reducible to B if there exists a function f: Σ＊ → Σ＊ with the following properties.

w ∈ A   ⇔   f(w) ∈ B   for all w ∈ Σ＊.

The function f can be computed by a Turing machine for every input w in a number of steps bounded by a polynomial in |w|.

In this case, we write A ≤p B.

For example, let A be the language that contains all graphs (encoded as adjacency matrix) that contain a triangle. (A triangle is a cycle of length 3.) Let further B be the language that contains all matrices with non-zero trace. (The trace of a matrix is the sum of its main diagonal elements.) Then A is polynomial-time many-one reducible to B. To prove this, we need to find an appropriate transformation function f. In this case, we can set f to compute the 3rd power of the adjacency matrix. This requires two matrix-matrix products, each of which has polynomial complexity.

It is trivially true that L ≤p L. (Can you prove it formally?)

We'll apply this to NP now.

A language L is NP-hard if and only if L' ≤p L for every language L' ∈ NP.

An NP-hard language may or may not be in NP itself.

A language L is NP-complete if and only if

L ∈ NP and

L is NP-hard.

The most famous NP-complete language is SAT. It contains all boolean formulas that can be satisfied. For example, (a ∨ b) ∧ (¬a ∨ ¬b) ∈ SAT. A valid witness is {a = 1, b = 0}. The formula (a ∨ b) ∧ (¬a ∨ b) ∧ ¬b ∉ SAT. (How would you prove that?)

It is not difficult to show that SAT ∈ NP. To show the NP-hardness of SAT is some work but it was done in 1971 by Stephen Cook.

Once that one NP-complete language was known, it was relatively simple to show the NP-completeness of other languages via reduction. If language A is known to be NP-hard, then showing that A ≤p B shows that B is NP-hard, too (via the transitivity of “≤p”). In 1972 Richard Karp published a list of 21 languages that he could show were NP-complete via (transitive) reduction of SAT. (This is the only paper in this answer that I actually recommend you should read. Unlike the others, it is not hard to understand and gives a very good idea of how proving NP-completeness via reduction works.)

Finally, a short summary. We'll use the symbols NPH and NPC to denote the classes of NP-hard and NP-complete languages respectively.

P ⊆ NP

NPC ⊂ NP and NPC ⊂ NPH, actually NPC = NP ∩ NPH by definition

(A ∈ NP) ∧ (B ∈ NPH)   ⇒   A ≤p B

Note that the inclusion NPC ⊂ NP is proper even in the case that P = NP. To see this, make yourself clear that no non-trivial language can be reduced to a trivial one and there are trivial languages in P as well as non-trivial languages in NP. This is a (not very interesting) corner-case, though.

Addendum

Your primary source of confusion seems to be that you were thinking of the “n” in “O(n ↦ f(n))” as the interpretation of an algorithm's input when it actually refers to the length of the input. This is an important distinction because it means that the asymptotic complexity of an algorithm depends on the encoding used for the input.

This week, a new record for the largest known Mersenne prime was achieved. The largest currently known prime number is 274 207 281 − 1. This number is so huge that it gives me a headache so I'll use a smaller one in the following example: 231 – 1 = 2 147 483 647. It can be encoded in different ways.

by its Mersenne exponent as decimal number: 31 (2 bytes)

as decimal number: 2147483647 (10 bytes)

as unary number: 11111…11 where the … is to be replaced by 2 147 483 640 more 1s (almost 2 GiB)

All these strings encode the same number and given any of these, we can easily construct any other encoding of the same number. (You can replace decimal encoding with binary, octal or hexadecimal if you want to. It only changes the length by a constant factor.)

The naive algorithm for testing primality is only polynomial for unary encodings. The AKS primality test is polynomial for decimal (or any other base b ≥ 2). The Lucas-Lehmer primality test is the best known algorithm for Mersenne primes Mp with p an odd prime but it is still exponential in the length of the binary encoding of the Mersenne exponent p (polynomial in p).

If we want to talk about the complexity of an algorithm, it is very important that we are very clear what representation we use. In general, one can assume that the most efficient encoding is used. That is, binary for integers. (Note that not every prime number is a Mersenne prime so using the Mersenne exponent is not a general encoding scheme.)

In theoretical cryptography, many algorithms are formally passed a completely useless string of k 1s as the first parameter. The algorithm never looks at this parameter but it allows it to formally be polynomial in k, which is the security parameter used to tune the security of the procedure.

For some problems for which the decision language in binary encoding is NP-complete, the decision language is no longer NP-complete if the encoding of embedded numbers is switched to unary. The decision languages for other problems remain NP-complete even then. The latter are called strongly NP-complete. The best known example is bin packing.

It is also (and perhaps more) interesting to see how the complexity of an algorithm changes if the input is compressed. For the example of Mersenne primes, we have seen three encodings, each of which is logarithmically more compressed than its predecessor.

In 1983, Hana Galperin and Avi Wigderson have written an interesting paper about the complexity of common graph algorithms when the input encoding of the graph is compressed logarithmically. For these inputs, the language of graphs containing a triangle from above (where it was clearly in P) suddenly becomes NP-complete.

And that's because language classes like P and NP are defined for languages, not for problems.

Body:
The first thing to understand is that P and NP classify languages, not problems. To understand what this means, we need some other definitions first.

An alphabet is a non-empty finite set of symbols.

{0, 1} is an alphabet as is the ASCII character set. {} is not an alphabet because it is empty. N (the integers) is not an alphabet because it is not finite.

Let Σ be an alphabet. An ordered concatenation of a finite number of symbols from Σ is called a word over Σ.

The string 101 is a word over the alphabet {0, 1}. The empty word (often written as ε) is a word over any alphabet. The string penguin is a word over the alphabet containing the ASCII characters. The decimal notation of the number π is not a word over the alphabet {., 0, 1, 2, 3, 4, 5, 6, 7, 8, 9} because it is not finite.

The length of a word w, written as |w|, is the number of symbols in it.

For example, |hello| = 5 and |ε| = 0. For any word w, |w| ∈ N and therefore finite.

Let Σ be an alphabet. The set Σ＊ contains all words over Σ, including ε. The set Σ+ contains all words over Σ, excluding ε. For n ∈ N, Σn is the set of words of length n.

For every alphabet Σ, Σ＊ and Σ+ are infinite countable sets. For the ASCII character set ΣASCII, the regular expressions .* and .+ denote ΣASCII＊ and ΣASCII+ respectively.

{0, 1}7 is the set of 7-bit ASCII codes {0000000, 0000001, …, 1111111}. {0, 1}32 is the set of 32 bit integer values.

Let Σ be an alphabet and L ⊆ Σ＊. L is called a language over Σ.

For an alphabet Σ, the empty set and Σ＊ are trivial languages over Σ. The former is often referred to as the empty language. The empty language {} and the language containing only the empty word {ε} are different.

The subset of {0, 1}32 that corresponds to non-NaN IEEE 754 floating point values is a finite language.

Languages can have an infinite number of words but every language is countable. The set of strings {1, 2, …} denoting the integers in decimal notation is an infinite language over the alphabet {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}. The infinite set of strings {2, 3, 5, 7, 11, 13, …} denoting the prime numbers in decimal notation is a proper subset thereof. The language containing all words matching the regular expression [+-]?\d+\.\d*([eE][+-]?\d+)? is a language over the ASCII character set (denoting a subset of the valid floating-point expressions as defined by the C programming language).

There is no language containing all real numbers (in any notation) because the set of real numbers is not countable.

Let Σ be an alphabet and L ⊆ Σ＊. A machine D decides L if for every input w ∈ Σ＊ it computes the characteristic function χL(w) in finite time. The characteristic function is defined as

χL: Σ＊ → {0, 1}
    w  ↦ 1,  w ∈ L
         0,  otherwise.

Such a machine is called a decider for L. We write “D(w) = x” for “given w, D outputs x”.

There are many machine models. The most general one that is in practical use today is the model of a Turing machine. A Turing machine has unlimited linear storage clustered into cells. Each cell can hold exactly one symbol of an alphabet at any point in time. The Turing machine performs its computation as a sequence of computation steps. In each step, it can read one cell, possibly overwrite its value and move the read/write head by one position to the left or right cell. What action the machine will perform is controlled by a finite state automaton.

A random access machine with a finite set of instructions and unlimited storage is another machine model that is as powerful as the Turing machine model.

For the sake of this discussion, we shall not bother us with the precise machine model we use but rather suffice to say that the machine has a finite deterministic control unit, unlimited storage and performs a computation as a sequence of steps that can be counted.

Since you've used it in your question, I assume that you're already familiar with “big-O” notation so here is only a quick refresher.

Let f: N → be a function. The set O(f) contains all functions g: N → N for which there exist constants n0 ∈ N and c ∈ N such that for every n ∈ N with n > n0 it is true that g(n) ≤ c f(n).

Now we are prepared to approach the real question.

The class P contains all languages L for which there exists a Turing machine D that decides L and a constant k ∈ N such that for every input w, D halts after at most T(|w|) steps for a function T ∈ O(n ↦ nk).

Since O(n ↦ nk), while mathematically correct, is inconvenient to write and read, most people – to be honest, everybody except myself – usually writes simply O(nk).

Note that the bound depends on the length of w. Therefore, the argument you make for the language of the primes is only correct for numbers in unaray encodings, where for the encoding w of a number n, the length of the encoding |w| is proportional to n. Nobody would ever use such an encoding in practice. Using a more advanced algorithm than simply trying all possible factors, it can be shown, however, that the language of prime numbers remains in P if the inputs are encoded in binary (or to any other base). (Despite massive interest, this could only be proven by Manindra Agrawal, Neeraj Kayal, and Nitin Saxena in an award-winning paper in 2004 so you can guess that the algorithm is not very simple.)

The trivial languages {} and Σ＊ and the non-trivial language {ε} are obviously in P (for any alphabet Σ). Can you write functions in your favorite programming language that take a string as input and return a boolean telling whether the string is a word from the language for each of these and prove that your function has polynomial run-time complexity?

Every regular language (a language described by a regular expression) is in P.

Let Σ be an alphabet and L ⊆ Σ＊. A machine V that takes an encoded tuple of two words w, c ∈ Σ＊ and outputs 0 or 1 after a finite number of steps is a verifier for L if it has the following properties.

Given (w, c), V outputs 1 only if w ∈ L.

For every w ∈ L, there exists a c ∈ Σ＊ such that V(w, c) = 1.

The c in the above definition is called a witness (or certificate).

A verifier is allowed to give false negatives for the wrong witness even if w actually is in L. It is not, however, allowed to give false positives. It is also required that for each word in the language, there exists at least one witness.

For the language COMPOSITE, that contains the decimal encodings of all integers that are not prime, a witness could be a factorization. For example, (659, 709) is a witness for 467231 ∈ COMPOSITE. You can easily verify that on a sheet of paper while without the witness given, proving that 467231 is not prime would be difficult without using a computer.

We didn't say anything about how an appropriate witness can be found. This is the non-deterministic part.

The class NP contains all languages L for which there exists a Turing machine V that verifies L and a constant k ∈ N such that for every input (w, c), V halts after at most T(|w|) steps for a function T ∈ O(n ↦ nk).

Note that the above definition implies that for each w ∈ L there exists a witness c with |c| ≤ T(|w|). (The Turing machine cannot possibly look at more symbols of the witness.)

NP is a superset of P (why?). It is not known whether there exist languages that are in NP but not in P.

Integer factorization is not a language per se. However, we can construct a language that represents the decision problem associated with it. That is, a language that contains all tuples (n, m) such that n has a factor d with d ≤ m. Let us call this language FACTOR. If you have an algorithm to decide FACTOR, it can be used to compute a full factorization with only polynomial overhead by performing a recursive binary search for each prime factor.

It is easy to show that FACTOR is in NP. An appropriate witness would simply be the factor d itself and all the verifier would have to do is verify that d ≤ m and n mod d = 0. All of this can be done in polynomial time. (Remember, again, that it is the length of the encoding that counts and that is logarithmic in n.)

If you can show that FACTOR is also in P, you can be sure to get many cool awards. (And you have broken a significant portion of today's cryptography.)

For every language in NP, there is a brute-force algorithm that decides it deterministically. It simply performs an exhaustive search over all witnesses. (Note that the maximum length of a witness is bounded by a polynomial.) So, your algorithm to decide PRIMES was actually a brute-force algorithm to decide COMPOSITE.

To address your final question, we need to introduce reduction. Reductions are a very powerful concept of theoretical computer science. Reducing one problem to another basically means solving one problem by means of solving another problem.

Let Σ be an alphabet and A and B be languages over Σ. A is polynomial-time many-one reducible to B if there exists a function f: Σ＊ → Σ＊ with the following properties.

w ∈ A   ⇔   f(w) ∈ B   for all w ∈ Σ＊.

The function f can be computed by a Turing machine for every input w in a number of steps bounded by a polynomial in |w|.

In this case, we write A ≤p B.

For example, let A be the language that contains all graphs (encoded as adjacency matrix) that contain a triangle. (A triangle is a cycle of length 3.) Let further B be the language that contains all matrices with non-zero trace. (The trace of a matrix is the sum of its main diagonal elements.) Then A is polynomial-time many-one reducible to B. To prove this, we need to find an appropriate transformation function f. In this case, we can set f to compute the 3rd power of the adjacency matrix. This requires two matrix-matrix products, each of which has polynomial complexity.

It is trivially true that L ≤p L. (Can you prove it formally?)

We'll apply this to NP now.

A language L is NP-hard if and only if L' ≤p L for every language L' ∈ NP.

An NP-hard language may or may not be in NP itself.

A language L is NP-complete if and only if

L ∈ NP and

L is NP-hard.

The most famous NP-complete language is SAT. It contains all boolean formulas that can be satisfied. For example, (a ∨ b) ∧ (¬a ∨ ¬b) ∈ SAT. A valid witness is {a = 1, b = 0}. The formula (a ∨ b) ∧ (¬a ∨ b) ∧ ¬b ∉ SAT. (How would you prove that?)

It is not difficult to show that SAT ∈ NP. To show the NP-hardness of SAT is some work but it was done in 1971 by Stephen Cook.

Once that one NP-complete language was known, it was relatively simple to show the NP-completeness of other languages via reduction. If language A is known to be NP-hard, then showing that A ≤p B shows that B is NP-hard, too (via the transitivity of “≤p”). In 1972 Richard Karp published a list of 21 languages that he could show were NP-complete via (transitive) reduction of SAT. (This is the only paper in this answer that I actually recommend you should read. Unlike the others, it is not hard to understand and gives a very good idea of how proving NP-completeness via reduction works.)

Finally, a short summary. We'll use the symbols NPH and NPC to denote the classes of NP-hard and NP-complete languages respectively.

P ⊆ NP

NPC ⊂ NP and NPC ⊂ NPH, actually NPC = NP ∩ NPH by definition

(A ∈ NP) ∧ (B ∈ NPH)   ⇒   A ≤p B

Note that the inclusion NPC ⊂ NP is proper even in the case that P = NP. To see this, make yourself clear that no non-trivial language can be reduced to a trivial one and there are trivial languages in P as well as non-trivial languages in NP. This is a (not very interesting) corner-case, though.

Addendum

Your primary source of confusion seems to be that you were thinking of the “n” in “O(n ↦ f(n))” as the interpretation of an algorithm's input when it actually refers to the length of the input. This is an important distinction because it means that the asymptotic complexity of an algorithm depends on the encoding used for the input.

This week, a new record for the largest known Mersenne prime was achieved. The largest currently known prime number is 274 207 281 − 1. This number is so huge that it gives me a headache so I'll use a smaller one in the following example: 231 – 1 = 2 147 483 647. It can be encoded in different ways.

by its Mersenne exponent as decimal number: 31 (2 bytes)

as decimal number: 2147483647 (10 bytes)

as unary number: 11111…11 where the … is to be replaced by 2 147 483 640 more 1s (almost 2 GiB)

All these strings encode the same number and given any of these, we can easily construct any other encoding of the same number. (You can replace decimal encoding with binary, octal or hexadecimal if you want to. It only changes the length by a constant factor.)

The naive algorithm for testing primality is only polynomial for unary encodings. The AKS primality test is polynomial for decimal (or any other base b ≥ 2). The Lucas-Lehmer primality test is the best known algorithm for Mersenne primes Mp with p an odd prime but it is still exponential in the length of the binary encoding of the Mersenne exponent p (polynomial in p).

If we want to talk about the complexity of an algorithm, it is very important that we are very clear what representation we use. In general, one can assume that the most efficient encoding is used. That is, binary for integers. (Note that not every prime number is a Mersenne prime so using the Mersenne exponent is not a general encoding scheme.)

In theoretical cryptography, many algorithms are formally passed a completely useless string of k 1s as the first parameter. The algorithm never looks at this parameter but it allows it to formally be polynomial in k, which is the security parameter used to tune the security of the procedure.

For some problems for which the decision language in binary encoding is NP-complete, the decision language is no longer NP-complete if the encoding of embedded numbers is switched to unary. The decision languages for other problems remain NP-complete even then. The latter are called strongly NP-complete. The best known example is bin packing.

It is also (and perhaps more) interesting to see how the complexity of an algorithm changes if the input is compressed. For the example of Mersenne primes, we have seen three encodings, each of which is logarithmically more compressed than its predecessor.

In 1983, Hana Galperin and Avi Wigderson have written an interesting paper about the complexity of common graph algorithms when the input encoding of the graph is compressed logarithmically. For these inputs, the language of graphs containing a triangle from above (where it was clearly in P) suddenly becomes NP-complete.

And that's because language classes like P and NP are defined for languages, not for problems.


问:
Why does the overriding rule of C++ not care about visibility changes?
In C++, it is possible to write an overriding for a base class's method even if the visibility declaration of the two don't match.
What are the possible design considerations under the decision of not considering the visibility in the overriding rule?

Consider this piece of code as an example:

```<code>class A{
    public: virtual void f() { cout << "A::f" << endl; }
};

class B : public A {
    private: void f() { cout << "B::f" << endl; }
};

int main() {
    A* a = new B;
    a->f();
}
</code>```

The above compiles in clang, and running it prints B::f, showing that it is possible to call a private function of B from outside the class, thus breaking encapsulation.

I don't really see why this type of behavior should be allowed. It is clearly not for performance/efficiency reasons, since checking statically that two visibility declarations match is trivial. Does anybody have an idea or hypothesis about what could possibly be the design decision behind this?

答:
For what it's worth, this actually has a semi-practical use. In the scenario you have set up, you can only use objects of type A or B via the interface defined by A. The function B::f is only callable via virtual dispatch, not directly.

For example:

```<code>B * pb = new B {};
A * pa = pb;
pa->f();       // fine, calls B::f via virtual dispatch
pa->A::f();    // fine, calls A::f directly
pa->B::f();    // error, B::f is private
pb->f();       // error, B::f is private
pb->A::f();    // fine, calls A::f directly
pb->B::f();    // error, B::f is private
</code>```

You could use this to discourage people from depending on your implementation and rather program against the abstraction as they ought to. In practice, however, I'd prefer to hide the existence of B altogether and only provide a factory function that gives clients a polymorphic A of unspecified dynamic type.

ContentLicense: CC BY-SA 3.0

Body:
For what it's worth, this actually has a semi-practical use. In the scenario you have set up, you can only use objects of type A or B via the interface defined by A. The function B::f is only callable via virtual dispatch, not directly.

For example:

B * pb = new B {};
A * pa = pb;
pa->f();       // fine, calls B::f via virtual dispatch
pa->A::f();    // fine, calls A::f directly
pa->B::f();    // error, B::f is private
pb->f();       // error, B::f is private
pb->A::f();    // fine, calls A::f directly
pb->B::f();    // error, B::f is private

You could use this to discourage people from depending on your implementation and rather program against the abstraction as they ought to. In practice, however, I'd prefer to hide the existence of B altogether and only provide a factory function that gives clients a polymorphic A of unspecified dynamic type.


问:
Where to inject dependency required by all implementors of an interface?
I have an interface whose job is to communicate with repository (that implements some interface). It doesn't seem to make sense to implement this interface without receiving a repository,so I'd like to inject it.

I then ask:where should I receive the repository? Since it is required in almost every method call it seems reasonable to inject the dependency in the constructor, and not in (practically) every method in the interface as this leads to a volition of the DRY (don't repeat yourself) principle.

On the other hand, there is no way of enforcing that every implementor would have this dependency in its constructor (moreover - how should an implementor even know this?)

I also thought about having an abstract class instead of an interface, but I soon ruled out that option as to not limit the option to derive another class.

What should I do in this situation, where should I receive the dependency?

答: Have both an interface and an abstract class which implements it so that only those implementations which need to derive from something else have to handle the dependency themselves, and they can look at the abstract class for guidance. Document it properly as well, of course.</p>


答:
Interfaces are used to define a contract: implementing an interface is a way for a class to indicate that a certain set of methods can be called on it, that these methods require well-defined arguments and that the result of the method will be of a certain type.

You need to think about the significance of the methods on the interface. If the methods on the interface explicitly have to deal with the repository, you should probably pass it in every method you have. Otherwise, the fact that your implementations use a repository is not relevant to the interface itself. It's very difficult to define an interface and require that implementors work a certain way with it. That's simply not what interfaces do. Forcing a class to work a certain way means deriving the class from an abstract class that imposes certain constraints on it.

A go-between solution would be to simply put a method on the interface that allows a class calling the interface to assign a repository to it. You can still inject it via constructor-based IoC (which I would recommend), but you also make the fact that this interface works on a repository explicit. The implementation of such a method is a very simple assigment to a local variable.

Title: Where to inject dependency required by all implementors of an interface?

Body:
I have an interface whose job is to communicate with repository (that implements some interface). It doesn't seem to make sense to implement this interface without receiving a repository,so I'd like to inject it.

I then ask:where should I receive the repository? Since it is required in almost every method call it seems reasonable to inject the dependency in the constructor, and not in (practically) every method in the interface as this leads to a volition of the DRY (don't repeat yourself) principle.

On the other hand, there is no way of enforcing that every implementor would have this dependency in its constructor (moreover - how should an implementor even know this?)

I also thought about having an abstract class instead of an interface, but I soon ruled out that option as to not limit the option to derive another class.

What should I do in this situation, where should I receive the dependency?


问:
Should I bother learning about small or niche languages?
If you browse the code golf questions on StackExchange, you notice a ton of non-standard but real world (Eg not brain-f*ck) languages like F#, Scala, R, J and Clojure. Visiting their websites, some of the languages look interesting solving problems in whatever language your already using.

However there is coding in spare time, and coding for money. The closest thing we have to the truth on who uses a language is the TIOBE Index, which lists none of the above languages in the top 10-15. Which makes me wonder if I'll ever use them.

Should I even bother learning some of the small niche languages? It doesn't seem I would be making money, and some will probably fail anyway.

答:
Agree with all of the points mentioned. Another motivation for learning a niche language is the possibility that the language will one day become very popular. In this situation, your early investment in the language could give you leads into work on influential frameworks, and elements of the language that could be in high demand in the future.

If the language does become popular, you will already be skilled in it, and therefore you will be in high demand.

Low probability, potentially high rewards.

ContentLicense: CC BY-SA 2.5


问:
"Who" should handle side tasks for events?
I'm currently on the process of creating a website/webapp.

My application is based on Node JS with the express framework.

My core backend concept consists of

routers: handle http request. Like  [POST] /api/team

controllers: business logic behind routers

model: interface between database and controller

I'm not sure if this follows any best practice patterns as MVC. It started as a very small personal project with business logic in routers. At some point I had to refractor my app (especially considering DRY) so I added controllers.

So let's say one can create an team with his account. The router will validate the request (user is authenticated, has permissions, ...) and forward the task to the controller. The controller will validate the form data, create a new database entry and return the new entry. The router will render the template and respond the request.

I think so far everything should be pretty straight forward.

Now the team is created and the user can invite other users to his team. Pretty much the same procedure as before.

Now we come to my actual question.

The invited user gets an notification. Currently I create notifications at the same place as I call the model to create a new entry for the invite.

I don't like that notifications after at the same place.  Notifications are a side effect and just decrease readability of the actual task.

So my idea was to use events. The team controller should emit an event when someone got invited.

The event handler will create the actual notification. But in my current concept there is no component which would fit the role of handling the event in my opinion.

The notification controller could listen for events on the team controller. But this could end in ring-dependencies (the current example is not the best example for this situation).

So my question is: WHO should listen for events and complete side tasks?

答:
This is typically the responsability of an event bus or command bus. You would raise events from somewhere within your application and hand these off to a command bus. The bus then resolves the appropriate event handlers or command handlers for the event that was raised and hands the event off for processing.

You can implement this in a number of different ways. Some application write events to an event store (which can be a simple database table) and have an asynchronously running component handle these events by polling the event store at an interval to check if new events are present and handle those. This can also be synchronous: the events are only kept in-memory and at the end of an operation or a number of operations the events are handled. For a web application, you could have a handler that runs as the very last operation in every request handle events.


问:
Consuming REST services: client or server
I am working on a new project in which we are currently deciding which technologies and frameworks we will be using. The application will eventually be cross platform. Therefore, for the server side, we will be using a REST api written in Java Spring.

We are now deciding on which technology we will be using for the front end web application.

The options are as following:

Using a front end javascript framework (we'd probably use ember js). Pages would be rendered purely in javascript, all REST requests would be sent from within Ember

Using a PHP server framework (Laravel). All REST calls would be made from within Laravel. Server side page rendering

My question: which approach is the best one? And why? If we would go for option 2 (using laravel to make the requests), wouldn't it be overkill to use Laravel as we would only be using it to generate views and make the calls to the REST api's? (all logic comes from the REST API) What bothers me in option 1 is that the rendering will be done client side, which will impact the initial loading time. The application will be widely used, also by users with low-end hardware.

Any input is welcome!If you have other suggestions or better options, please let me know!

答:
As is often the case, it depends

With a pure JS framework

you push a lot of processing to the clients. That means your webserver for the client application will only be serving static files that can be cached.

your clients have to be able to handle that processing and need some amount of computing power

your clients need to fully support all JS-features that your front-end framework uses and you are somewhat tied to the support that framework offers for older browsers. If your framework's newest version decides to drop support for some older IE version that your clients still rely on, you will be stuck with that.

your REST API's endpoints needs to be accessible by all the clients which might be an issue

Having an intermediate layer means

you put the processing power in your single server, which is something you can control and, if need be, add more resources to. For clients this is more difficult and sometimes impossible

you have the ability to control the calls to the REST API and, for example, cache data so you don't need to hit the API every time

you have more control over security as the endpoints for the REST API do not need to be public

you have more fine-grained control over the rendered HTML and are not tied to the components provided by your framework. You could create a component that initially uses JS to build part of a view and when performance becomes an issue replace that by HTML generated from the server

you need to run and maintain a server with some server-side programming language capability

The question is: which of these issues matter to you and which don't. If you have a requirement to support lower-end hardware I'd stay away from JS front-end frameworks. It's very hard to control performance that way and you are very limited in the optimisations you can perform.


问:
Javascript and HTML decoupling
Based on the following snippet

HTML

```<code><table id="example" class="display" cellspacing="0" width="100%">
<thead>
<tr>
  <th>Name</th>
  <th>Position</th>
  <th>Office</th>
  <th>Age</th>
  <th>Start date</th>
  <th>Salary</th>
</tr>
</code>```

Javascript

```<code>var tableNames = { "example": "#example" };

function main() {
    $(tableNames["example"]).DataTable();
}

$(document).ready(main());
</code>```

I just want to know which are some consistent ways to keep track of variable names in both HTML and JS.

Let's say that tomorrow I just rename example to foobar. Then the dataTables instance is not going to work as it works now. How may I manage that coupling between the variable name in the HTML code and the variable name in the javascript code?

I thought about the tableNames object, but I'm wondering if a more structured approach exists

Thanks

答:
Refer to the HTML-component in one single place: the selector.

```<code>var exampleTable = $("#example");
function main() {
    exampleTable.DataTable();
}
</code>```

This way, if the name changes, or if the way you select the table changes, you only need to make the change in one single place. This also means you can split up your code into components: initialize a component by passing it the selector and have the rest of the code work on the variable. This is the way jQuery components work too.

Title: Javascript and HTML decoupling

Body:
Refer to the HTML-component in one single place: the selector.

var exampleTable = $("#example");
function main() {
    exampleTable.DataTable();
}

This way, if the name changes, or if the way you select the table changes, you only need to make the change in one single place. This also means you can split up your code into components: initialize a component by passing it the selector and have the rest of the code work on the variable. This is the way jQuery components work too.


问:
Intelligent builder pattern - different parameters depending on type - generics?
Lets say we have the famous Joshua Bloch Nutrition Builder and we want to change it so it be a bit like dynamic builder which restricts visibility of setters and propably uses generics :

```<code> public class NutritionFacts {
private final int servingSize;
private final int servings;
private final int calories;
private final int fat;
private final int sodium;
private final int carbohydrate;

public static class Builder {
    // Required parameters
    private final int servingSize;
    private final int servings;

    // Optional parameters - initialized to default values
    private int calories      = 0;
    private int fat           = 0;
    private int carbohydrate  = 0;
    private int sodium        = 0;

    public Builder(int servingSize, int servings) {
        this.servingSize = servingSize;
        this.servings    = servings;
    }

    public Builder calories(int val)
        { calories = val;      return this; }
    public Builder fat(int val)
        { fat = val;           return this; }
    public Builder carbohydrate(int val)
        { carbohydrate = val;  return this; }
    public Builder sodium(int val)
        { sodium = val;        return this; }

    public NutritionFacts build() {
        return new NutritionFacts(this);
    }
}

private NutritionFacts(Builder builder) {
    servingSize  = builder.servingSize;
    servings     = builder.servings;
    calories     = builder.calories;
    fat          = builder.fat;
    sodium       = builder.sodium;
    carbohydrate = builder.carbohydrate;
}
</code>```

}

Now I would like this builder to build two types of NutritionFacts.
So lets say instead of:

```<code>NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).
  calories(100).sodium(35).carbohydrate(27).build();
</code>```

I would like to have something like that:

```<code>NutritionFactsA a = new NutritionFacts.Builder<NutritionFactsA>...(240, 8).
  calories(100).build(); //.sodium(35).carbohydrate(27) - these are not possible to be set, when I write NutritionFactsA I cannot see these parameters

NutritionFactsB b = new NutritionFacts.Builder<NutritionFactsB>(240, 8).
  .sodium(35).build(); //here I have set only sodium value, I cannot set anything else - I dont even see other setters...
</code>```

I don't know if I express myself clear and if I wrote generics in proper places...

Pleas advice, show some details, I am only beginning with generics and love it!

答:
I believe that generics are not the right solution to your problem. Interfaces should be enough.

In general, generics should be used on something that can be applied to different - generic - kinds of objects. Here, on the opposite, you want a different behaviour (i.e. interface) depending on the kind of object.

When you call new NutritionFacts.Builder<...>(240, 8) you're creating a Builder that has a well defined interface that nothing can change.

If you use a static method to get the builder you could "mask" its interface:

```<code>public class NutritionFacts {

    public interface IBuilder {
        NutritionFacts build();
    }

    public interface NutritionFactsABuilder extends IBuilder {
        NutritionFactsABuilder calories(int cal);
    }

    public interface NutritionFactsBBuilder extends IBuilder {
        NutritionFactsBBuilder sodium(int sodium);
    }

    // no more public
    static class Builder implements NutritionFactsABuilder, NutritionFactsBBuilder {
        // ...

        @Override
        public NutritionFactsABuilder calories(int val) { /*...*/ }

        @Override
        public NutritionFactsBBuilder sodium(int val) { /*...*/ }

        @Override
        public NutritionFacts build() { /*...*/ }
    }

    // this returns the builder for NutritionFactsA
    public static NutritionFactsABuilder buildA(int x, int y) {
        return new Builder(x,y);
    }

    // this returns the builder for NutritionFactsB
    public static NutritionFactsBBuilder buildB(int x, int y) {
        return new Builder(x,y);
    }
}
</code>```

This way you can do something like:

```<code>NutritionFacts.buildA(1,2) // now you can see only calories() and build()
        .calories(3)
        .build();
</code>```

This requires you to create a static method for every kind of builder you need.

Let's try generics

Now you can use generics if you really want, but it's going to be ugly because we're on the edge (or totally outside?) of what they are meant for:

```<code>static public <T extends IBuilder> T build(Class<T> clazz, int x, int y) {
    return (T) new Builder(x,y);
}

// used like this:
...
NutritionFacts
        .build(NutritionFactsABuilder.class, 1, 2)
        .calories(2)
        .build();
...
</code>```

Why is it bad?

This is ugly because of that unsafe cast. The generic build() signature only requires that you pass something that extends IBuilder. What if I make another implementation of IBuilder which has nothing to do with our old Builder?

```<code>public interface IPoisonBuilder extends IBuilder {
    IPoisonBuilder poison(int p);
}

public static class RogueBuilder implements IBuilder, IPoisonBuilder {

    @Override
    public IPoisonBuilder poison(int p) { /*...*/ }

    @Override
    public NutritionFacts build() { /*...*/ }
}

public static void main(String[] args) {
    NutritionFacts factsBad = NutritionFacts   // This compiles but...
            .build(IPoisonBuilder.class, 1, 3) // <-- ClassCastException at runtime!!!
            .poison(2)
            .build();
}
</code>```

Checking on this kind of problems gets tricky, so it's not worth it. With the simple static methods instead, you always have your types under control.

Body:
I believe that generics are not the right solution to your problem. Interfaces should be enough.

In general, generics should be used on something that can be applied to different - generic - kinds of objects. Here, on the opposite, you want a different behaviour (i.e. interface) depending on the kind of object.

When you call new NutritionFacts.Builder<...>(240, 8) you're creating a Builder that has a well defined interface that nothing can change.

If you use a static method to get the builder you could "mask" its interface:

public class NutritionFacts {

    public interface IBuilder {
        NutritionFacts build();
    }

    public interface NutritionFactsABuilder extends IBuilder {
        NutritionFactsABuilder calories(int cal);
    }

    public interface NutritionFactsBBuilder extends IBuilder {
        NutritionFactsBBuilder sodium(int sodium);
    }

    // no more public
    static class Builder implements NutritionFactsABuilder, NutritionFactsBBuilder {
        // ...

        @Override
        public NutritionFactsABuilder calories(int val) { /*...*/ }

        @Override
        public NutritionFactsBBuilder sodium(int val) { /*...*/ }

        @Override
        public NutritionFacts build() { /*...*/ }
    }

    // this returns the builder for NutritionFactsA
    public static NutritionFactsABuilder buildA(int x, int y) {
        return new Builder(x,y);
    }

    // this returns the builder for NutritionFactsB
    public static NutritionFactsBBuilder buildB(int x, int y) {
        return new Builder(x,y);
    }
}

This way you can do something like:

NutritionFacts.buildA(1,2) // now you can see only calories() and build()
        .calories(3)
        .build();

This requires you to create a static method for every kind of builder you need.

Let's try generics

Now you can use generics if you really want, but it's going to be ugly because we're on the edge (or totally outside?) of what they are meant for:

static public <T extends IBuilder> T build(Class<T> clazz, int x, int y) {
    return (T) new Builder(x,y);
}

// used like this:
...
NutritionFacts
        .build(NutritionFactsABuilder.class, 1, 2)
        .calories(2)
        .build();
...

Why is it bad?

This is ugly because of that unsafe cast. The generic build() signature only requires that you pass something that extends IBuilder. What if I make another implementation of IBuilder which has nothing to do with our old Builder?

public interface IPoisonBuilder extends IBuilder {
    IPoisonBuilder poison(int p);
}

public static class RogueBuilder implements IBuilder, IPoisonBuilder {

    @Override
    public IPoisonBuilder poison(int p) { /*...*/ }

    @Override
    public NutritionFacts build() { /*...*/ }
}

public static void main(String[] args) {
    NutritionFacts factsBad = NutritionFacts   // This compiles but...
            .build(IPoisonBuilder.class, 1, 3) // <-- ClassCastException at runtime!!!
            .poison(2)
            .build();
}

Checking on this kind of problems gets tricky, so it's not worth it. With the simple static methods instead, you always have your types under control.


问:
Is there a way to download Google's voice recognition API so it can be used offline?
I'm playing with Google's voice recognition for a personal project and I have a fun little Q&A program written in Python using it. The problem, as it were, is that it means I have to be connected to the internet to access the API or the program doesn't work. </p>

<p>I'm wondering if there is a way I can download the entire API so I can use it offline rather than being wifi dependent. </p>

答: You'll have to find out with Google themselves. My guest is that you cannnot, in the specific case of Google Voice recognition service. That's not because it is not technically feasible but because Google  simply hasn't designed it to be downloadabled and independant on the servers. As a counter-example, Apple's dictation services, that originally where dependant of an internet conection, now can be downloaded to be used off-line. </p>


问:
For what reasons Java and C# initialize static data on demand?
I am reading "The Go Programming Language" right now and I have read package initialization chapter which tells (or I read it wrong) that Go uses eagerly initialization.

So in time we saw say C++ eagerly initialization, then Java with on demand initialization, C# also on demand, and Go back with eager initialization (those languages are not strictly related, I am talking about time).

And I am curious about the reasons (in historical perspective) why on-demand model was chosen for Java and C#.

答:
My ideas on why lazy initialization may be preferrable in .NET:

Eager init can be quite hard to debug

I don't know about now, but earlier, when I had problems with static init in C++, it was a nightmare and I rather went away from using static in some cases.

Static init dependencies can be a headache even in C#, luckily they are much easier to debug and there are even limited testing posibilities. See this post by Jon Skeet for further information.

Avoiding unnecessary init

Unlike C++ constants, the .NET constants are not very powerful and so the static sees a very wide usage. With a vast amount of statically initialized memory, it might be wiser to initialize it on demand rather than further lengthen the program start-up which can already be a pain with a JIT-compiled language.

This feels similar to .NET's exclusive usage of .dlls and their dynamic loading during program run-time.


答:
C++ and Go are designed to compile to native machine code. Both have a phase during building where separate modules are linked together to produce a single combined module. Once this has been done, a complete list of all available objects is available. Therefore, the easiest way to initialise any object that requires initialisation is to scan that list, check for init code, and call it (there may be slightly more subtlety to it than that, but as a broad conceptual level it's close enough to how it works for the purposes of this discussion).

Java and C# were both designed to run in a virtual machine environment. Java specifically was designed to perform on-demand loading of code. Linkage is deferred until runtime in order to allow, for example, modules to reside on a remote server where they may be updated without changing the remaining program (this is important for Java's original designed purpose, which was for writing applications for smart tv systems). Furthermore, classes may be added to the system at runtime (using Class.forName). This means that it is impossible for a Java application to determine a complete list of all classes it may use at build time, or even when the application begins running. Therefore it is impossible for Java to perform initialisation at application start.

C#, AFAIK, had a design goal that it needed to be able to be used for any kind of application where Java could already be used. It therefore needed to follow Java's lead in using on-demand loading, even though it does have a separate link step, because not doing so would make it hard to support network-loaded applications.

Title: For what reasons Java and C# initialize static data on demand?

Body:
I am reading "The Go Programming Language" right now and I have read package initialization chapter which tells (or I read it wrong) that Go uses eagerly initialization.

So in time we saw say C++ eagerly initialization, then Java with on demand initialization, C# also on demand, and Go back with eager initialization (those languages are not strictly related, I am talking about time).

And I am curious about the reasons (in historical perspective) why on-demand model was chosen for Java and C#.


问:
Does it make sense to have a user specified thread limit?
I'm developing a C++14 application and would like to take advantage of the new multithreading features, in particular std::async. I have seen a number of applications which allow the user to specify the maximum number of software threads that can be used for the duration of the program run.  However, the recommend usage of std::async is default launch policy, which implies no control over the number of software threads that are actually created.

I assume the idea of explicit thread limits is to try control the number of cores used by the program, but I believe this to be misleading as the number of cores used will ultimately be determined by the OS. Is there any good reason to allow the program user to explicitly limit the number of software threads created by a program, or is it always preferable to let the implementation and OS handle threading?

Rather than allow the user to specify a thread limit, my intended solution was to just have a flag to allow enable threading, does this kind of user control even offer any advantage?

答:
It is not generally sensible to limit the number of threads, if these threads are used only for concurrency. I.e. aside from the extra resource use, spawning threads is fine to manage blocking operations, increase responsiveness, …. A good example is a web crawler that might want to download multiple small resources, and uses multiple threads to compensate the latency of the requests. However, using explicitly asynchronous approaches such as async IO or event loops will have the same advantages and should be preferred if possible.

If your application uses parallelism to speed up CPU-intensive computations, then limiting the number of threads is very useful. You will see no advantages over spawning as many threads as processors are available. However, your program is not the only one running, and other CPU-intensive programs might be running in parallel.

You could either be very clever and adapt the number of worker threads to the current load of the system (which would lead to unpredictable performance of your program). Or you could let the user select the number of threads, which is safer. In particular, you would at least want an option to only use a single worker thread, which makes debugging much easier. In such a case, do what make does: a single thread is a good default, but some users need the full power of make -j$(nproc).


问:
Could ANSI C standardized linkage syntax from early C wrong?
Recently I came up to something illogical, reading the latest ANSI C paper. It was talking about linkage but it never mentioned a way to declare internal identifiers inside block-scope (or at least in a useful way). Imagine something like this:

```<code>int main()
{

    //Here how to declare the identifier 'b'
    //with internal linkage

    b = 2;

    printf("%d", b);
}

static int b;
</code>```

If you try something like this:

```<code>{
    extern int b;
    //...
}
</code>```

Then the this would be UB because the identifier b is declared both internal and external in the same TU (according to the current standard).

However reading the K&B white paper ("The C Programming Language Edition 1") I came up to this (at page 137):

Imagine a fragment of a compiler that manipulates a symbol table. Each
  identifier in a program has certain information associated with it,
  for example, whether or not it is a keyword, whether or not it is
  external and/or static, and so on. The most compact way to encode such
  information is a set of one-bit flags in a single char or int.

See the important part is that in this example (which shows how a compiler could be written) it is considered the possibility for an identifier to have both static and extern storage specifier (remember in the current ANSI C standard we can only have a single storage specifier). Which actually make a lot of sense. This way we could specify in a declaration whatever we are referring to the identifier with internal or external linkage. This would be useful in certain situations. Imagine we have internal and external variable with the same identifier. This way we could distinguish between the both:

```<code>int main()
{
    extern static int b; //here internal variable should be declared (!)

    b = 2; //here internal variable should be modified

    {
        extern int b; //here external variable should be declared (!)

        b = 2; //here external variable should be modified
    }
}

static int b; //internal variable named 'b' defined here
</code>```

In the current ANSI C standard this is not supported and also there is some synthetic rule that if an identifier is declared with the extern specifier and there is already such identifier visible with some linkage — this linkage is inherit to the identifier currently declared.

This lead to code like this:

```<code>static int b;

int main()
{
    extern int b; //re-declaration of identifier 'b' with internal linkage

    b = 2;
}
</code>```

Which is rather confusing at least. Writing such code you'll suppose that the identifier with external linkages is modified.

Note that just putting static in a block-scope declarations only alters the storage-type of the variable.

Here are the original ANSI C statements about this:

$6.2.2.4:

For an identifier declared with the storage-class specifier extern in
  a scope in which a prior declaration of that identifier is visible,31)
  if the prior declaration specifies internal or external linkage, the
  linkage of the identifier at the later declaration is the same as the
  linkage specified at the prior declaration. If no prior declaration is
  visible, or if the prior declaration specifies no linkage, then the
  identifier has external linkage.

And at $6.2.2.7:

If, within a translation unit, the same identifier appears with both
  internal and external linkage, the behavior is undefined.

About storage-specifiers at $6.7.1.2:

At most, one storage-class specifier may be given in the declaration
  specifiers in a declaration, except that _Thread_local may appear with
  static or extern)

答:
First things first: The original K&R was written in 1978. Expecting that a book written in 1978 is authoritative now is a bad expectation.

The C language was an offshoot of B, which in turn was an offshoot of BCPL. In B, the auto keyword was essentially the opposite of the extrn keyword. That is perhaps the best way to think of the modern C extern keyword when used in block scope.

Per this most excellent answer at stackoverflow.com, the primary purpose of the auto keyword nowadays is to declare a vehicle:

```<code>auto vehicle_type my_car;
</code>```

A car that you just bought and that you need to register with the department of motor vehicles:

```<code>register vehicle_type my_brand_new_car;
</code>```

Your 1978 jalopy:

```<code>static vehicle_type my_very_old_car;
</code>```

A car that doesn't belong to you, that has been registered with the DMV, and that is somewhat modern:

```<code>extern vehicle_type taxicab;
</code>```

Finally, there are illegal declarations against which the compiler must issue a complaint:

```<code>extern static register auto vehicle_type car_flooded_by_a_hurricane;
</code>```

Tongue out of cheek, the extern keyword has different meanings in block scope versus file scope. That shouldn't be surprising; the static keyword also has different meanings in block scope versus file scope. In both cases, the context (block scope versus file scope) is clear, so the compiler knows how to interpret those keywords. (And presumably, so does the human author / reader of the code in question.)

At file scope, qualifying some declarations with the extern keyword means that the thing being declared is defined in some other compilation unit. Resolving that is a problem for the linker to solve, as opposed to the compiler. At block scope, the extern keyword instead refers to something declared at a higher level, or at program level if there is no higher level declaration. If the compiler can resolve the reference, it will. If it can't, it will defer the issue of resolving the reference to the linker.

Update: Language lawyer details

The keywords auto, extern, register, static, and typedef are storage-class-specifiers. A symbol can be qualified by at most one storage-class-specifier. The declaration extern static int foo makes no sense (let alone extern static register auto int foo), and that is not what K&R meant by an externally static variable.

K&R (Kernighan and Ritchie) is aimed at normal human readers. When they wrote about external static variable (non-code font), they meant a variable that is not automatic, not a register, and not visible to the linker. They did not mean extern static (code font), let alone my extern static register auto vehicle_type car_flooded_by_a_hurricane. That did not make sense even in 1978, let alone 2016.

What K&R meant by an "externally static variable" is a variable declared at block scope qualified with the extern keyword that was previous declared at file scope as static. There was no mistake in 1978, and there is no mistake almost 40 years later.

Body:
First things first: The original K&R was written in 1978. Expecting that a book written in 1978 is authoritative now is a bad expectation.

The C language was an offshoot of B, which in turn was an offshoot of BCPL. In B, the auto keyword was essentially the opposite of the extrn keyword. That is perhaps the best way to think of the modern C extern keyword when used in block scope.

Per this most excellent answer at stackoverflow.com, the primary purpose of the auto keyword nowadays is to declare a vehicle:

auto vehicle_type my_car;

A car that you just bought and that you need to register with the department of motor vehicles:

register vehicle_type my_brand_new_car;

Your 1978 jalopy:

static vehicle_type my_very_old_car;

A car that doesn't belong to you, that has been registered with the DMV, and that is somewhat modern:

extern vehicle_type taxicab;

Finally, there are illegal declarations against which the compiler must issue a complaint:

extern static register auto vehicle_type car_flooded_by_a_hurricane;

Tongue out of cheek, the extern keyword has different meanings in block scope versus file scope. That shouldn't be surprising; the static keyword also has different meanings in block scope versus file scope. In both cases, the context (block scope versus file scope) is clear, so the compiler knows how to interpret those keywords. (And presumably, so does the human author / reader of the code in question.)

At file scope, qualifying some declarations with the extern keyword means that the thing being declared is defined in some other compilation unit. Resolving that is a problem for the linker to solve, as opposed to the compiler. At block scope, the extern keyword instead refers to something declared at a higher level, or at program level if there is no higher level declaration. If the compiler can resolve the reference, it will. If it can't, it will defer the issue of resolving the reference to the linker.

Update: Language lawyer details

The keywords auto, extern, register, static, and typedef are storage-class-specifiers. A symbol can be qualified by at most one storage-class-specifier. The declaration extern static int foo makes no sense (let alone extern static register auto int foo), and that is not what K&R meant by an externally static variable.

K&R (Kernighan and Ritchie) is aimed at normal human readers. When they wrote about external static variable (non-code font), they meant a variable that is not automatic, not a register, and not visible to the linker. They did not mean extern static (code font), let alone my extern static register auto vehicle_type car_flooded_by_a_hurricane. That did not make sense even in 1978, let alone 2016.

What K&R meant by an "externally static variable" is a variable declared at block scope qualified with the extern keyword that was previous declared at file scope as static. There was no mistake in 1978, and there is no mistake almost 40 years later.


问:
When do I have to distribute the source code of GPLv2 licensed software?
I was wondering if there is a time line when I have to distribute source code for a binary that has been released under the GPLv2 license. To my understanding, I would need to release the source code along site it (ie. immediately). </p>

<p>I'm asking this question because I've heard that Apple does not update its open source page as soon as they make changes to the kernel and publish a patch. Thus would They be violating the license agreement. </p>

答:
You don't have to distribute the source code at all until someone asks for it. But if you choose not to distribute it along with the executable, you do have to provide a "written offer" for the source code, which I assume would have to include instructions on how to contact you and ask for it.

From the GPL v2 preamble:

You must make sure that they, too, receive or can get the source code.

So it's fine if they don't receive the source code right away, as long as you provide some way for them to get it later if they want it.

I'm assuming you're already distributing the program in executable form, so the relevant part the main body of the license is:

3 You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:

a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,

b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,

c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)

All emphasis mine.


问:
When is it appropriate to make a separate function when there will only ever be a single call to said function?
We are designing coding standards, and are having disagreements as to if it is ever appropriate to break code out into separate functions within a class, when those functions will only ever be called once.

For instance:

```<code>f1()
{
   f2();
   f4();
}

f2()
{
    f3()
    // Logic here
}

f3()
{
   // Logic here
}

f4()
{
   // Logic here
}
</code>```

versus:

```<code>f1()
{
   // Logic here
   // Logic here
   // Logic here
}
</code>```

Some argue that it is simpler to read when you break up a large function using separate single-use sub functions. However, when reading code for the first time, I find it tedious to follow the logic chains and optimize the system as a whole. Are there any rules typically applied to this sort of function layout?

Please note that unlike other questions, I am asking for the best set of conditions to differentiate allowable and non-allowable uses of single call functions, not just if they are allowed.

答:
It's all about separation of concerns. (ok, not all about it; this is a simplification).

This is fine:

```<code>function initializeUser(name, job, bye) {
    this.username = name;
    this.occupation = job;
    this.farewell = bye;
    this.gender = Gender.unspecified;
    this.species = Species.getSpeciesFromJob(this.occupation);
    ... etc in the same vein.
}
</code>```

That function is concerned with one single concern: it sets the initial properties of a user from the provided arguments, defaults, extrapolation, etc.

This is not fine:

```<code>function initializeUser(name, job, bye) {
    // Connect to internet if not already connected.
    modem.getInstance().ensureConnected();
    // Connect to user database
    userDb = connectToDb(USER_DB);
    // Validate that user does not yet exist.
    if (0 != userDb.db_exec("SELECT COUNT(*) FROM `users` where `name` = %d", name)) {
        throw new sadFace("User exists");
    }
    // Configure properties. Don't try to translate names.
    this.username = removeBadWords(name);
    this.occupation = removeBadWords(translate(job));
    this.farewell = removeBadWords(translate(bye));
    this.gender = Gender.unspecified;
    this.species = Species.getSpeciesFromJob(this.occupation);
    userDb.db_exec("INSERT INTO `users` set `name` = %s", this.username);
    // Disconnect from the DB.
    userDb.disconnect();
}
</code>```

Separation of concerns suggests this should be handled as multiple concerns; the DB handling, the user-existence validation, the setting of the properties. Each of these is very easily tested as a unit, but testing all of them in a single method makes for a very convoluted unit test set, which would be testing things as different as how it handled the DB going away, how it handles creation of empty and invalid job titles, and how it handles creating a user twice (answer: badly, there's a bug).

Part of the problem is that it goes all over the place in terms of how high-level it is: low level networking and DB stuff has no place here. That's part of the concern separation. The other part is that stuff that should be the concern of something else, is instead the concern of the init function. For example, whether to translate or apply bad language filters, might make more sense as a concern of the fields being set.

Later edit: this all means that in an ideal codebase there should be no methods or functions which are called only once. They should be called at the very least twice: once by the code they're intended for, and once by the unit tests.

Body:
It's all about separation of concerns. (ok, not all about it; this is a simplification).

This is fine:

function initializeUser(name, job, bye) {
    this.username = name;
    this.occupation = job;
    this.farewell = bye;
    this.gender = Gender.unspecified;
    this.species = Species.getSpeciesFromJob(this.occupation);
    ... etc in the same vein.
}

That function is concerned with one single concern: it sets the initial properties of a user from the provided arguments, defaults, extrapolation, etc.

This is not fine:

function initializeUser(name, job, bye) {
    // Connect to internet if not already connected.
    modem.getInstance().ensureConnected();
    // Connect to user database
    userDb = connectToDb(USER_DB);
    // Validate that user does not yet exist.
    if (0 != userDb.db_exec("SELECT COUNT(*) FROM `users` where `name` = %d", name)) {
        throw new sadFace("User exists");
    }
    // Configure properties. Don't try to translate names.
    this.username = removeBadWords(name);
    this.occupation = removeBadWords(translate(job));
    this.farewell = removeBadWords(translate(bye));
    this.gender = Gender.unspecified;
    this.species = Species.getSpeciesFromJob(this.occupation);
    userDb.db_exec("INSERT INTO `users` set `name` = %s", this.username);
    // Disconnect from the DB.
    userDb.disconnect();
}

Separation of concerns suggests this should be handled as multiple concerns; the DB handling, the user-existence validation, the setting of the properties. Each of these is very easily tested as a unit, but testing all of them in a single method makes for a very convoluted unit test set, which would be testing things as different as how it handled the DB going away, how it handles creation of empty and invalid job titles, and how it handles creating a user twice (answer: badly, there's a bug).

Part of the problem is that it goes all over the place in terms of how high-level it is: low level networking and DB stuff has no place here. That's part of the concern separation. The other part is that stuff that should be the concern of something else, is instead the concern of the init function. For example, whether to translate or apply bad language filters, might make more sense as a concern of the fields being set.

Later edit: this all means that in an ideal codebase there should be no methods or functions which are called only once. They should be called at the very least twice: once by the code they're intended for, and once by the unit tests.

ContentLicense: CC BY-SA 4.0


问:
Efficient Repeating Alarm Clock in Low Level Language like C
I was thinking about it and I was curious as to how one would code an efficient repeating alarm clock in C? Would you set an alarm time and then offset the time with the ms time equivalent of a day (or two days or a week depending on how often it needed to repeat)? And then poll periodically to see if the times are equal? That sounds like a very inefficient solution, to me at least. I was am interested in how an alarm clock would work programatically.</p>

答:
for a repeating timer.

Use setitimer()

here is info from the man page

```<code>    NAME
           getitimer, setitimer - get or set value of an interval timer

    SYNOPSIS
           #include <sys/time.h>

           int getitimer(int which, struct itimerval *curr_value);
           int setitimer(int which, const struct itimerval *new_value,
                         struct itimerval *old_value);

    DESCRIPTION
           The  system  provides  each  process  with  three interval timers, each
           decrementing in a distinct time domain.  *When any timer expires, a sig‐
           nal is sent to the process*, and the timer (potentially) restarts.

           ITIMER_REAL    decrements in real time, and delivers SIGALRM upon expi‐
                          ration.

           ITIMER_VIRTUAL decrements only  when  the  process  is  executing,  and
                          delivers SIGVTALRM upon expiration.

           ITIMER_PROF    decrements  both  when the process executes and when the
                          system is executing on behalf of the  process.   Coupled
                          with  ITIMER_VIRTUAL, this timer is usually used to pro‐
                          file the time spent by the application in user and  ker‐
                          nel space.  SIGPROF is delivered upon expiration.

           Timer values are defined by the following structures:

               struct itimerval {
                   struct timeval it_interval; /* next value */
                   struct timeval it_value;    /* current value */
               };

               struct timeval {
                   time_t      tv_sec;         /* seconds */
                   suseconds_t tv_usec;        /* microseconds */
               };

           The  function  getitimer() fills the structure pointed to by curr_value
           with the current setting for the  timer  specified  by  which  (one  of
           ITIMER_REAL,  ITIMER_VIRTUAL, or ITIMER_PROF).  The element it_value is
           set to the amount of time remaining on the timer, or zero if the  timer
           is disabled.  Similarly, it_interval is set to the reset value.

           The  function  setitimer()  sets  the  specified  timer to the value in
           new_value.  If old_value is non-NULL, the old value  of  the  timer  is
           stored there.

           Timers decrement from it_value to zero, generate a signal, and reset to
           it_interval.  A timer which is set to zero (it_value  is  zero  or  the
           timer expires and it_interval is zero) stops.

           Both  tv_sec and tv_usec are significant in determining the duration of
           a timer.

           Timers will never expire before the requested time, but may expire some
           (short)  time  afterward,  which depends on the system timer resolution
           and on the system load; see time(7).  (But see BUGS below.)  Upon expi‐
           ration,  a  signal will be generated and the timer reset.  If the timer
           expires while the process is active (always  true  for  ITIMER_VIRTUAL)
           the signal will be delivered immediately when generated.  Otherwise the
           delivery will be offset by a small time dependent on the  system  load‐
           ing.

    RETURN VALUE
           On  success,  zero is returned.  On error, -1 is returned, and errno is
           set appropriately.

    ERRORS
           EFAULT new_value, old_value, or curr_value is not valid a pointer.

           EINVAL which is not one of ITIMER_REAL, ITIMER_VIRTUAL, or ITIMER_PROF;
                  or  (since Linux 2.6.22) one of the tv_usec fields in the struc‐
                  ture pointed to by new_value contains a value outside the  range
                  0 to 999999.

    CONFORMING TO
           POSIX.1-2001,  SVr4,  4.4BSD  (this  call  first  appeared  in 4.2BSD).
           POSIX.1-2008 marks getitimer() and setitimer()  obsolete,  recommending
           the  use  of  the POSIX timers API (timer_gettime(2), timer_settime(2),
           etc.) instead.

    NOTES
           A child created via fork(2) does  not  inherit  its  parent's  interval
           timers.  Interval timers are preserved across an execve(2).

           POSIX.1 leaves the interaction between setitimer() and the three inter‐
           faces alarm(2), sleep(3), and usleep(3) unspecified.

           The standards are silent on the meaning of the call:

               setitimer(which, NULL, &old_value);

           Many systems (Solaris, the BSDs, and  perhaps  others)  treat  this  as
           equivalent to:

               getitimer(which, &old_value);

           In  Linux,  this  is treated as being equivalent to a call in which the
           new_value fields are zero; that is, the timer is disabled.   Don't  use
           this Linux misfeature: it is nonportable and unnecessary.
</code>```

Body:
for a repeating timer.

Use setitimer()

here is info from the man page

    NAME
           getitimer, setitimer - get or set value of an interval timer

    SYNOPSIS
           #include <sys/time.h>

           int getitimer(int which, struct itimerval *curr_value);
           int setitimer(int which, const struct itimerval *new_value,
                         struct itimerval *old_value);

    DESCRIPTION
           The  system  provides  each  process  with  three interval timers, each
           decrementing in a distinct time domain.  *When any timer expires, a sig‐
           nal is sent to the process*, and the timer (potentially) restarts.

           ITIMER_REAL    decrements in real time, and delivers SIGALRM upon expi‐
                          ration.

           ITIMER_VIRTUAL decrements only  when  the  process  is  executing,  and
                          delivers SIGVTALRM upon expiration.

           ITIMER_PROF    decrements  both  when the process executes and when the
                          system is executing on behalf of the  process.   Coupled
                          with  ITIMER_VIRTUAL, this timer is usually used to pro‐
                          file the time spent by the application in user and  ker‐
                          nel space.  SIGPROF is delivered upon expiration.

           Timer values are defined by the following structures:

               struct itimerval {
                   struct timeval it_interval; /* next value */
                   struct timeval it_value;    /* current value */
               };

               struct timeval {
                   time_t      tv_sec;         /* seconds */
                   suseconds_t tv_usec;        /* microseconds */
               };

           The  function  getitimer() fills the structure pointed to by curr_value
           with the current setting for the  timer  specified  by  which  (one  of
           ITIMER_REAL,  ITIMER_VIRTUAL, or ITIMER_PROF).  The element it_value is
           set to the amount of time remaining on the timer, or zero if the  timer
           is disabled.  Similarly, it_interval is set to the reset value.

           The  function  setitimer()  sets  the  specified  timer to the value in
           new_value.  If old_value is non-NULL, the old value  of  the  timer  is
           stored there.

           Timers decrement from it_value to zero, generate a signal, and reset to
           it_interval.  A timer which is set to zero (it_value  is  zero  or  the
           timer expires and it_interval is zero) stops.

           Both  tv_sec and tv_usec are significant in determining the duration of
           a timer.

           Timers will never expire before the requested time, but may expire some
           (short)  time  afterward,  which depends on the system timer resolution
           and on the system load; see time(7).  (But see BUGS below.)  Upon expi‐
           ration,  a  signal will be generated and the timer reset.  If the timer
           expires while the process is active (always  true  for  ITIMER_VIRTUAL)
           the signal will be delivered immediately when generated.  Otherwise the
           delivery will be offset by a small time dependent on the  system  load‐
           ing.

    RETURN VALUE
           On  success,  zero is returned.  On error, -1 is returned, and errno is
           set appropriately.

    ERRORS
           EFAULT new_value, old_value, or curr_value is not valid a pointer.

           EINVAL which is not one of ITIMER_REAL, ITIMER_VIRTUAL, or ITIMER_PROF;
                  or  (since Linux 2.6.22) one of the tv_usec fields in the struc‐
                  ture pointed to by new_value contains a value outside the  range
                  0 to 999999.

    CONFORMING TO
           POSIX.1-2001,  SVr4,  4.4BSD  (this  call  first  appeared  in 4.2BSD).
           POSIX.1-2008 marks getitimer() and setitimer()  obsolete,  recommending
           the  use  of  the POSIX timers API (timer_gettime(2), timer_settime(2),
           etc.) instead.

    NOTES
           A child created via fork(2) does  not  inherit  its  parent's  interval
           timers.  Interval timers are preserved across an execve(2).

           POSIX.1 leaves the interaction between setitimer() and the three inter‐
           faces alarm(2), sleep(3), and usleep(3) unspecified.

           The standards are silent on the meaning of the call:

               setitimer(which, NULL, &old_value);

           Many systems (Solaris, the BSDs, and  perhaps  others)  treat  this  as
           equivalent to:

               getitimer(which, &old_value);

           In  Linux,  this  is treated as being equivalent to a call in which the
           new_value fields are zero; that is, the timer is disabled.   Don't  use
           this Linux misfeature: it is nonportable and unnecessary.


问:
Should we avoid language features that C++ has but Java doesn't?
Suppose I am limited to use C++ by the environment in the project. Is it good to prevent the use of some language features that C++ has but Java doesn't have (e.g.: multiple inheritance, operator overloading)?

I think the reasons are:

As Java is newer than C++, if Java doesn't provide a feature that C++ has, it means that the feature is not good, so we should avoid using it.

C++ code with C++ specific features (e.g.: friend functions, multiple inheritance) can only be maintained or reviewed by C++ programmers, but if we just write C++ like Java (without C++ language specific feature), the code can be maintained or reviewed by both C++ and Java programmers.

You may be asked to convert the code to Java some day

Code without C++ specific features is usually more maintainable

Every C++ language specific feature (e.g.: multiple inheritance) should have alternatives to be implemented in Java. If it doesn't, that means the design pattern or code architecture is problematic.

Is that true?

答:
No. This is woefully and terribly misguided.

Java features are not somehow better than C++ features, especially in a vacuum.

If your programmers don't know how to use a feature, train or hire better developers; limiting your developers to the worst of your team is a quick and easy way to lose your good developers.

YAGNI. Solve your actual problem today, not the ghost of some future problem.


问:
Is it acceptable to copy and paste long but straightforward code instead of wrapping them into a class or function?
Suppose I have a segment of code to connect to internet and show connection results like it:

```<code>HttpRequest* httpRequest=new HttpRequest();
httpRequest->setUrl("(some domain .com)");
httpRequest->setRequestType(HttpRequest::Type::POST);
httpRequest->setRequestData("(something like name=?&age=30&...)");
httpRequest->setResponseCallback([=](HttpClient* client, HttpResponse* response){
    string responseString=response->getResponseDataString();
        if(response->getErrorCode()!=200){
            if(response->getErrorCode()==404){
                Alert* alert=new Alert();
                alert->setFontSize(30);
                alert->setFontColor(255,255,255);
                alert->setPosition(Screen.MIDDLE);
                alert->show("Connection Error","Not Found");
            }else if((some other different cases)){
                (some other alert)
            }else
                Alert* alert=new Alert();
                alert->setFontSize(30);
                alert->setPosition(Screen.MIDDLE);
                alert->setFontColor(255,255,255);
                alert->show("Connection Error","unknown error");
            }
        }else{
            (other handle methods depend on different URL)
        }
}
</code>```

the code is long, and it is commonly used, but the code above does not require any extra things such as custom function and class (HttpRequest and Alert are both provided by framework by default), and although the code segment is long, it is straightforward and not complex (it is long just because there are bundles of settings such as url, font size...), and the code segment has little variations among class (e.g.: url,request data, error code handle cases, normal handle cases...)

My question is, is it acceptable to copy and paste long but straightforward code instead of wrapping them in a function to reduce the dependency of code?

答:
You need to consider the cost of change.  What if you wanted to change how connections are made?  How easy would it be?  If you have a lot of duplicated code, then finding all the places that need changing could be quite time consuming and error prone.

You also need to consider clarity.  Most likely, having to look at 30 lines of code isn't going to be as easy to understand as a single call to a "connectToInternet" function.  How much time is going to be lost trying to understand the code when new functionality needs to be added?

There are certain rare cases where duplication isn't a problem.  For example, if you are doing an experiment and the code is going to be thrown away at the end of the day.  But in general, the cost of duplication outweighs the small time savings of not having to pull the code out into a separate function.

See also https://softwareengineering.stackexchange.com/a/103235/63172


问:
How to delete user data that is referenced by another user?
Lets say a user has a set of data. This data is stored in user_data table. This user_data table is referenced by other users in some way. In case the user wants to delete a row from the user_data table, referential integrity dictates that it cannot be done as long as there exist a reference to that data.

Let me explain further by giving you an example of the type of data that user can store and are referenced by other users - a simplified video streaming service. Some data to be stored:

user_videos

id

video_name

video_url

owner_id

video_playlist

id

name

owner_id

playlist_items

playlist_id

video_id

So from the above example, a user can have videos that can be referenced in playlists which can be created by other users. If referential integrity is enforced, then user won't be able to delete the video unless there are no further references (on delete cascade).

How should I implement the database to handle the deletion?

Option 1: Do not enforce referential integrity. Playlists may refer to videos that do not exist.

Option 2: Hide user video data by introducing a "deleted" field.

Option 3: Assign video to a special user that takes ownership of all orphaned videos.

Option 4: On delete cascade and delete all playlist that references the video.

I'm leaning to towards option 1, but I've always been told to enforce a foreign key constraint. But in the case of interlinking user data as per my example above, could a foreign key be counter intuitive?

答:
My suggestion is similar to #3 but with a difference.

While in #3 su suggest not deleting the video at all but moving it to another user who will be the owner of all orphaned videos, I suggest this:

A special video called "deleted video" should exist, which owner is "Deleted video owner". That special video's ID is, say, 1.

As PLAYLIST_ITEM is a many-to-many table between USER_VIDEO and VIDEO_PLAYLIST (entity names should be singular), when a user deletes a video the program first updates the rows in PLAYLIST_ITEM that reference that video and changes them to reference video ID 1 ("deleted video").

Insert into a table called DELETED_VIDEO_COMMENT a comment like "Happy Kitten video deleted by owner". That would be a one-to-one table with a foreign key to PLAYLIST_ITEM, that would only containt a row explaining the name of the deleted, previosly referenced video.

After all references to the video to be deleted are gone, then delete it.

Advantages:

Playlist owners don't see their playlists shortened without apparent reason.

Playlist owners see a "deleted video" among their playlist items or even better "Happy Kitten (deleted by owner)".

ADDENDUM.

When playlist owners purge deleted videos from their playlist, the row in DELETED_VIDEO_COMMENT goes with them.


答:
No.

In fact, even your "simple" code should be split into smaller parts.  At least two.

One to make the connection and  handle the normal 200 response.  For example, what if you change from a POST to a PUT in some cases?  What if you are making zillions of these connections and need some multi-threading or connection-pooling?  Having the code in one single place, with an argument for the method, will make this much easier

Similarly, another to handle errors.  For example, if you change the color or font size of the alert.  Or you are having issues with intermittent connections and want to log the errors.

Title: Is it acceptable to copy and paste long but straightforward code instead of wrapping them into a class or function?

Body:
Suppose I have a segment of code to connect to internet and show connection results like it:

```<code>HttpRequest* httpRequest=new HttpRequest();
httpRequest->setUrl("(some domain .com)");
httpRequest->setRequestType(HttpRequest::Type::POST);
httpRequest->setRequestData("(something like name=?&age=30&...)");
httpRequest->setResponseCallback([=](HttpClient* client, HttpResponse* response){
    string responseString=response->getResponseDataString();
        if(response->getErrorCode()!=200){
            if(response->getErrorCode()==404){
                Alert* alert=new Alert();
                alert->setFontSize(30);
                alert->setFontColor(255,255,255);
                alert->setPosition(Screen.MIDDLE);
                alert->show("Connection Error","Not Found");
            }else if((some other different cases)){
                (some other alert)
            }else
                Alert* alert=new Alert();
                alert->setFontSize(30);
                alert->setPosition(Screen.MIDDLE);
                alert->setFontColor(255,255,255);
                alert->show("Connection Error","unknown error");
            }
        }else{
            (other handle methods depend on different URL)
        }
}
</code>```

the code is long, and it is commonly used, but the code above does not require any extra things such as custom function and class (HttpRequest and Alert are both provided by framework by default), and although the code segment is long, it is straightforward and not complex (it is long just because there are bundles of settings such as url, font size...), and the code segment has little variations among class (e.g.: url,request data, error code handle cases, normal handle cases...)

My question is, is it acceptable to copy and paste long but straightforward code instead of wrapping them in a function to reduce the dependency of code?