问:
How to add permissions checks 'after the fact'
I have a great number of PHP classes which perform the business logic of my application, e.g.

```<code>class FileMaker{
  public function makeFile(){
    //some code here to make a file
  }
}
</code>```

Now I need to add permissions checks to them. I want to avoid having to copy/paste $this->checkPermissions() or similar into every method in every class. What's the best way of achieving this?

I was thinking some kind of decorator pattern which could add permissions checks, e.g:

```<code>//decorator that can be used to check permissions
class PermissionsDecorator{
    private $ob;

    public function __construct($ob){
        $this->ob = $ob;
    }

    //magic method which is called when any function is called
    public function __call($name,$arguments){
        if($this->hasPermission(get_class($this->ob), $name)){
            call_user_func_array(array($this->ob,$name),$arguments);
        }else{
            throw new Exception('You do not have permission to perform this action.');
        }
    }

    public function hasPermission($class,$method){
        echo 'does the user have permission on '.$class.'->'.$method.'?<br/>';

        //do some logic here to work out whether the user has permission
        return true;
    }
}
</code>```

The decorator above could apply to all classes because it uses the __call magic method, rather than specifying the exact methods to call. Then I could use code such as:

```<code>$fm = new PermissionsDecorator(new FileMaker());
</code>```

This feels a bit 'hacky' to me though. Is there a standard way of doing this? Or will I just have to copy/paste permissions checks everywhere?

答:
If the amount of work you would need to expend to refactor towards a transparent implementation of authentication in your controllers is indeed absolutely prohibitive, a decorator will work.

The reason it ought feel somewhat 'hacky' is because relying on magic methods makes functionality somewhat opaque (magic methods, as well as call_user_func also have some performance penalties, but they are usually negligable), and because decorators aren't best practice when what they add is something that is necessary for the decoratee to work as intended.

The most transparent, secure and flexible way to do this (if it's really the individual objects/methods that need to check the authentication, which I doubt - see below) would be to implement a strategy pattern. In the constructor of classes whose instances need to do authentication, you would require an object (e.g. DefaultUserAuthenticator) that meets the interface designed for the strategy (e.g. IUserAuthenticator). A reference to the concrete authenticator would be stored in each class (PHP automatically assigns objects by reference), and then, yes, you would have to call the authenticate method of the locally referenced authenticator everywhere you really need to authenticate.

But if you always immediately turn a request for execution of a certain function to the object and method that performs the function, and then have to check user permission in every single such method / object - it seems that this might be the actual problem.

When you handle the request and decide what to do with it, you ought to check permission as 'high up' in the decision-tree as possible, to avoid precisely the situation you find yourself in now. So you might have a front-controller / page-controller / helper-service which delegates to the specific objects only once the user has been authenticated.

If you are considering using a decorator-pattern, that means the method of authentication doesn't vary with each object/method. As such, you should be able to check permission once, then delegate either to an exception-handler or the object whose responsibility it is to actually perform the requested function.... the individual objects and methods shouldn't need to do this.


问:
What do polynomial algorithms entail?
From here, I know it is that an algorithm that...

...is said to be solvable in polynomial time if the number of steps required to complete the algorithm for a given input is O(n^k) for some nonnegative integer k, where n is the complexity of the input.

Can some of you offer examples involving common data structures to explain polynomial time? I've looked it up but the available information is scarce.

答: Consider finding the smallest element in an unsorted collection. While you could use an array or linked list to hold the data, the time complexity will be O(n) as each element has to be examined as that could be the smallest that hasn't been known yet.</p>

OwnerDisplayName: eltigre

ContentLicense: CC BY-SA 3.0

Title: What do polynomial algorithms entail?


问:
Communicating between browser and a native application securely
I am working on web application that needs data it can only get from its locally installed native application browser.

How can you get around the browser sandbox so that you can communicate (securely, since the data is potentially sensitive), with a native application.

In the only example that I found, the user manually move some tokens and files between the two, which is a horrible user experience that i would like to avoid.

答:
There's a couple ways you can mingle a native app and a browser app.

You can embed the browser inside the native app, much like PhoneGap apps do on mobile.  That will allow you to extend the browser's javascript engine, and let you make calls between the two.

Alternatively, rethink your architecture.  Have both the native application and the browser based application use the server as a go-between.  So both the browser and native application only talk to the web server, which forwards information between the two as necessary.

Or if you need native functionality... just make a single native application.

I do not recommend the 'local web server' approach for anything other than applications run in controlled environments.  If your software is intended to install and run on end user machines with minimal support requirements, you'll find yourself dealing with a whole host of firewall and anti-virus software related problems.


答:
A classic example of an O(n³) algorithm is matrix multiplication. Multiplying two 10x10 matrices together will require 10^3 multiplications.

In practice, however, modern algorithms such as the Coppersmith–Winograd algorithm can bring the order down to about 2.37.

Title: What do polynomial algorithms entail?

Body:
From here, I know it is that an algorithm that...

...is said to be solvable in polynomial time if the number of steps required to complete the algorithm for a given input is O(n^k) for some nonnegative integer k, where n is the complexity of the input.

Can some of you offer examples involving common data structures to explain polynomial time? I've looked it up but the available information is scarce.


答:
What "polynomial time" means is that if you calculate a formula describing how long the algorithm will take to complete on a data set with n elements, the largest-magnitude term in the formula will be in the form of n^x.

Here are a few examples of runtime classes:

O(1): the runtime does not get larger as the data set increases in size.  Example: Array access.  Retrieving an arbitrary element in an array happens just as fast no matter how big the array is.  (Theoretically. In practice, if the array overflows physical memory and has to be paged to disc, that can change, but the complexity theory doesn't concern itself with details like that.)

O(log n): the runtime increases as the log of the size of the data set, a number which grows more slowly than the data set itself.  Example: A binary search through an array or balanced tree.  Since each check cuts the remaining number of elements under consideration in half, it will take 2 checks to search through 3 elements, 3 checks to search 7 elements, 4 checks to search 15 elements... and so on.  With 32 checks, you can search over 4 billion elements by a binary search.

O(n): The runtime increases at a rate directly proportionate to the size of the dataset. Example: A linear search through an array.  It will take 10 checks to iterate over 10 elements, or 4 billion checks to iterate over 4 billion elements.

O(n log n): The runtime increases faster than the size of the dataset, at a rate proportionate to the size times the log of the size. Example: divide-and-conquer sorting algorithms such as Quicksort and Mergesort, where the values to be searched get divided into smaller and smaller groups, much like the binary search above.

O(n^2): This is polynomial time, where the runtime increases proportionate to the square of the data set.  Any class where the runtime increases based on n^x, for any value of x, is considered polynomial time.  Example: Linear sorting algorithms where the values to be searched do not get divided into smaller groups, such as Bubble Sort and Insertion Sort.  In order to find where each element belongs, the algorithm must search the entire array, so the general runtime is n (the number of elements) times n (the number of elements to search through for each element).  The actual runtime will be lower, as you won't have to search the entire array for every single element, but complexity theory deals with generalizations, and in practice the amount of searching you end up not doing won't be enough to compensate for the increased complexity that comes with increasing size.

Polynomial time is important, because it's considered the highest class that is still "fast" by complexity theory.  There are higher complexity classes where complexity becomes very unmanageable very quickly, and they comprise some of the more interesting questions in computer science and information theory.

For example, the Travelling Salesman Problem, which can determine the most efficient order in which to perform a series of tasks, takes exponential time to solve: O(2^n).  This is very different from O(n^2); 32^2 = 1024, but 2^32 is over 4 billion, which explains why the complexity of NP algorithms (Non-deterministic Polynomial-time, or algorithms not known to have a solution that runs in polynomial-time or better) explodes once you get past trivial data sets!

Title: What do polynomial algorithms entail?


问:
Repository Pattern and custom queries/REST API. Is it the right approach?
I'm in the early stages of working on an application that is using the Repository Pattern to provide a data access abstraction. This application will have some form of a simple REST API but I'm not sure how to approach this using repositories. To illustrate this, a typical (very simplified) example of a repository is something like this:

<?php
$repo = new PostRepository(); // this would be resolved from an IoC container
$post = $repo->getByEmail('foo@wherever.com');
```

<p>or maybe a little less rigid, like this:</p>

<pre class="lang-php prettyprint-override"><code>$post = $repo->getBy('first_name', 'Bob');
</code>```

But the pattern doesn't seem suited to anything more complicated like, say, the query from this url:

api.example.com/posts?firstName=Bob&lastName=Doe&email=foo@example.com&with=comments
```

It seems like to handle stuff like that (let alone any much more complicated queries that many APIs support) you would pretty much end up having to reimplement the underlying ORM, or create a very leaky abstraction, neither of which seems ideal. Am I going about this wrong?

答:
A way to find instances by variable criteria, as suggested by scriptin's anwer is the right way. However, you don't necessarily need the full weight of the frameworks mentioned.

I have recently programmed exactly what you described. The repository needs meta-information about the fields ob the object you are requesting - a config class is a good option, and a way to check whether a request is valid for an object (a way to validate criteria - based on the meta-information).

In my implementation, I unified the repository pattern with the identity-map pattern. The repository holds a collection of entities, initially empty. An incoming selectByCriteria-request will first check the collection, and, if no entity is found, will have the criteria passed to a method for transformation into a db-query and executed. Returned rows are stored as entities in the repository-collection and then returned to the caller of the method as their own 'sub-collection'. Potential future requests to those resources in the lifetime of the application will then be fulfilled from the collection held in memory.

You need a way to normalize selection-criteria. The kind of requests a REST API has to fulfill can usually easily be normalized to Disjunctive Normal Form (DNF) or Conjunctive Normal Form (CNF). For simplicity of code and logic, I chose DNF for my implementation - lightweight, as a simple depth-3 array.

A set of selection criteria would then look like this:

```<code>array(
    array(
        array('fieldName','comparator','fieldValue'),
        **AND**
        array('fieldName','comparator','fieldValue')
        ...
    ),
    **OR**
    array(
        array('fieldName','comparator','fieldValue'),
        **AND**
        array('fieldName','comparator','fieldValue')
        ...
    )
    ...
)
</code>```

(The comparators don't have to be strings, they can be class-constants - the values don't have to be strings either - indeed it's more transparent to use the types they are being compared to - especially if we need to construct a DB-Query later on)

A service-object first validates a set of criteria against a config-object for a data-class, by checking the structure of the array, if field-names exist, if the comparators are allowed and if the field-types can be meaningfully compared with the given values and comparators. If the criteria-array is valid, it is checked with foreach-loops against the collection. The advantage of DNF here is that a loop can terminate checking each disjunct once the first conjunct in it is found to be invalid, and it can terminate the entire outer loop (over the disjuncts) once the first disjunct is found to be valid - simplifying the code.

Selecting from a collection is implemented like this:

```<code>    $resultCollection  = $this->getEmptyCollection;

    if(!$this->criteriaValidationService->validateCriteria($dataObjectConfig,$criteria)) {
        return $resultCollection;
    }

    foreach ($this->elements as $instance) {
        foreach ($criteria as $disjunctCriteria) {
            $isValidDisjunct = TRUE;
            foreach ($disjunctCriteria as $conjunctCriterion) {
                $fieldName    = $conjunctCriterion[0];
                $comparator   = $conjunctCriterion[1];
                if(isset($conjunctCriterion[2])) {
                    $compareValue = $conjunctCriterion[2];
                }

                if ($comparator == 'IS NULL') {
                    if(!(is_null($instance->$fieldName))) {
                        $isValidDisjunct = FALSE;
                        break;
                    }
                } elseif ($comparator == 'IS NOT NULL') {
                    if(is_null($instance->$fieldName)) {
                        $isValidDisjunct = FALSE;
                        break;
                    }
                } elseif ($comparator == '=') {
                    if (!(isset($instance->$fieldName) && $instance->$fieldName == $compareValue)) {
                        $isValidDisjunct = FALSE;
                        break;
                    }
                } elseif ($comparator == '!=') {
                    if (!($instance->$fieldName != $compareValue)) {
                        $isValidDisjunct = FALSE;
                        break;
                    }
                } elseif ($comparator == '>') {
                    if (!(isset($instance->$fieldName) && ($instance->$fieldName > $compareValue))) {
                        $isValidDisjunct = FALSE;
                        break;
                    }
                } elseif ($comparator == '<') {
                    if (!(isset($instance->$fieldName) && ($instance->$fieldName < $compareValue))) {
                        $isValidDisjunct = FALSE;
                        break;
                    }
                } elseif ($comparator == '<=') {
                    if (!(isset($instance->$fieldName) && !($instance->$fieldName <= $compareValue))) {
                        $isValidDisjunct = FALSE;
                        break;
                    }
                } elseif ($comparator == '>=') {
                    if (!(isset($instance->$fieldName) || ($instance->$fieldName >= $compareValue))) {
                        $isValidDisjunct = FALSE;
                        break;
                    }
                } elseif ($comparator == 'IN') {
                    if (!(in_array($instance->$fieldName, $compareValue))) {
                        $isValidDisjunct = FALSE;
                        break;
                    }
                } elseif ($comparator == 'LIKE') {
                    //Replace SQL-Wildcard with fnmatch-wildcard
                    $compareValue = preg_replace('/(?<!\\\\)%/', '*', $compareValue);
                    if (!(fnmatch($compareValue, $instance->$fieldName))) {
                        $isValidDisjunct = FALSE;
                        break;
                    }
                }
            }
            if ($isValidDisjunct) {
                $resultCollection->add($instance, TRUE);
                break;
            }
        }
    }
    return $resultCollection;
</code>```

Body:
A way to find instances by variable criteria, as suggested by scriptin's anwer is the right way. However, you don't necessarily need the full weight of the frameworks mentioned.

I have recently programmed exactly what you described. The repository needs meta-information about the fields ob the object you are requesting - a config class is a good option, and a way to check whether a request is valid for an object (a way to validate criteria - based on the meta-information).

In my implementation, I unified the repository pattern with the identity-map pattern. The repository holds a collection of entities, initially empty. An incoming selectByCriteria-request will first check the collection, and, if no entity is found, will have the criteria passed to a method for transformation into a db-query and executed. Returned rows are stored as entities in the repository-collection and then returned to the caller of the method as their own 'sub-collection'. Potential future requests to those resources in the lifetime of the application will then be fulfilled from the collection held in memory.

You need a way to normalize selection-criteria. The kind of requests a REST API has to fulfill can usually easily be normalized to Disjunctive Normal Form (DNF) or Conjunctive Normal Form (CNF). For simplicity of code and logic, I chose DNF for my implementation - lightweight, as a simple depth-3 array.

A set of selection criteria would then look like this:

array(
    array(
        array('fieldName','comparator','fieldValue'),
        **AND**
        array('fieldName','comparator','fieldValue')
        ...
    ),
    **OR**
    array(
        array('fieldName','comparator','fieldValue'),
        **AND**
        array('fieldName','comparator','fieldValue')
        ...
    )
    ...
)

(The comparators don't have to be strings, they can be class-constants - the values don't have to be strings either - indeed it's more transparent to use the types they are being compared to - especially if we need to construct a DB-Query later on)

A service-object first validates a set of criteria against a config-object for a data-class, by checking the structure of the array, if field-names exist, if the comparators are allowed and if the field-types can be meaningfully compared with the given values and comparators. If the criteria-array is valid, it is checked with foreach-loops against the collection. The advantage of DNF here is that a loop can terminate checking each disjunct once the first conjunct in it is found to be invalid, and it can terminate the entire outer loop (over the disjuncts) once the first disjunct is found to be valid - simplifying the code.

Selecting from a collection is implemented like this:

    $resultCollection  = $this->getEmptyCollection;

    if(!$this->criteriaValidationService->validateCriteria($dataObjectConfig,$criteria)) {
        return $resultCollection;
    }

    foreach ($this->elements as $instance) {
        foreach ($criteria as $disjunctCriteria) {
            $isValidDisjunct = TRUE;
            foreach ($disjunctCriteria as $conjunctCriterion) {
                $fieldName    = $conjunctCriterion[0];
                $comparator   = $conjunctCriterion[1];
                if(isset($conjunctCriterion[2])) {
                    $compareValue = $conjunctCriterion[2];
                }

                if ($comparator == 'IS NULL') {
                    if(!(is_null($instance->$fieldName))) {
                        $isValidDisjunct = FALSE;
                        break;
                    }
                } elseif ($comparator == 'IS NOT NULL') {
                    if(is_null($instance->$fieldName)) {
                        $isValidDisjunct = FALSE;
                        break;
                    }
                } elseif ($comparator == '=') {
                    if (!(isset($instance->$fieldName) && $instance->$fieldName == $compareValue)) {
                        $isValidDisjunct = FALSE;
                        break;
                    }
                } elseif ($comparator == '!=') {
                    if (!($instance->$fieldName != $compareValue)) {
                        $isValidDisjunct = FALSE;
                        break;
                    }
                } elseif ($comparator == '>') {
                    if (!(isset($instance->$fieldName) && ($instance->$fieldName > $compareValue))) {
                        $isValidDisjunct = FALSE;
                        break;
                    }
                } elseif ($comparator == '<') {
                    if (!(isset($instance->$fieldName) && ($instance->$fieldName < $compareValue))) {
                        $isValidDisjunct = FALSE;
                        break;
                    }
                } elseif ($comparator == '<=') {
                    if (!(isset($instance->$fieldName) && !($instance->$fieldName <= $compareValue))) {
                        $isValidDisjunct = FALSE;
                        break;
                    }
                } elseif ($comparator == '>=') {
                    if (!(isset($instance->$fieldName) || ($instance->$fieldName >= $compareValue))) {
                        $isValidDisjunct = FALSE;
                        break;
                    }
                } elseif ($comparator == 'IN') {
                    if (!(in_array($instance->$fieldName, $compareValue))) {
                        $isValidDisjunct = FALSE;
                        break;
                    }
                } elseif ($comparator == 'LIKE') {
                    //Replace SQL-Wildcard with fnmatch-wildcard
                    $compareValue = preg_replace('/(?<!\\\\)%/', '*', $compareValue);
                    if (!(fnmatch($compareValue, $instance->$fieldName))) {
                        $isValidDisjunct = FALSE;
                        break;
                    }
                }
            }
            if ($isValidDisjunct) {
                $resultCollection->add($instance, TRUE);
                break;
            }
        }
    }
    return $resultCollection;


问:
What pattern do I use and how do I implement it for one method that will be handled multiple ways
My scenario: I am creating an application that will allow me to create a mapping of redirect url's that will point from the request url (the url in the old ecommerce solution) to the target url. There will be multiple implementations as we have multiple ecommerce solutions that were moving to our new one.

I am working in Laravel and have created a controller action that currently returns in JSON the redirect url's for ONE of our current ecommerce solutions. The implementation of this method is going to differ greatly from one solution to the next.

I could be "dirty" and create an abstract class like storeAbstract and each store extends it and I just look at the store_type sent in to the controller and use the correct class.

This is how I have always done it but I am looking to expand my horizons and have deigned to find a design pattern that fits this situation. If anyone has any suggestions on which design pattern I should use and how I would implement it in laravel it would be greatly appreciated.

Example of how i would do it now:

```<code>Abstract class AbstractStore {
    public function getRedirectUrls() {}
}

class StorefrontStore extends AbstractStore {
    public function getRedirectUrls(){
        // code to get the redirect urls
    }
}

class <ecommstore>Store extends AbstractStore {
    public function getRedirectUrls(){
        // code to get the redirect urls
    }
}
</code>```

This just seems very basic and there has to be a better way.

答:
This is a classic use case for an abstract factory.

You'd have a single interface and then separate concrete factories for each individual implementation. You'd then use factory methods to control the initialization of each set of factories.


问:
Product backlog- when do task hours get estimated?
I am wondering if when developing a product backlog do tasks have hours estimated for them. To confirm, i can talking about a product backlog here not a sprint backlog as I know it does have. </p>

答:
Usually it is too time-consuming to estimate hours for items in the backlog. Your team can spend time for hour estimation while this backlog item may never make it to the top.
Thus usually only those items that make it into a sprint- are estimated in hours while being split into smaller pieces for sprint tasks.</p>


答:
You can use the strategy pattern to switch essential functionality. This seems to be more about behavior than about creating different kinds of subtypes of one supertype - so the behavioral strategy pattern seems more appropriate to me than the creational Abstract Factory pattern, though they can be combined: Strategy pattern for switching behavior, Abstract Factory pattern for creating the strategies... though you should consider whether such complexity is actually needed.

Using 'Strategy' You would have an abstract URLMappingStrategy and concrete strategies assigned to the various e-commerce solutions under a common IURLMappingStrategy-interface. The router then requires the interface and is composed with a concrete implementation (for the respective e-commerce platform), and dispatches calls to a mapURL-method to the concrete strategy it was constructed with (stored by reference in a field of the Router)

Title: What pattern do I use and how do I implement it for one method that will be handled multiple ways

Body:
My scenario: I am creating an application that will allow me to create a mapping of redirect url's that will point from the request url (the url in the old ecommerce solution) to the target url. There will be multiple implementations as we have multiple ecommerce solutions that were moving to our new one.

I am working in Laravel and have created a controller action that currently returns in JSON the redirect url's for ONE of our current ecommerce solutions. The implementation of this method is going to differ greatly from one solution to the next.

I could be "dirty" and create an abstract class like storeAbstract and each store extends it and I just look at the store_type sent in to the controller and use the correct class.

This is how I have always done it but I am looking to expand my horizons and have deigned to find a design pattern that fits this situation. If anyone has any suggestions on which design pattern I should use and how I would implement it in laravel it would be greatly appreciated.

Example of how i would do it now:

```<code>Abstract class AbstractStore {
    public function getRedirectUrls() {}
}

class StorefrontStore extends AbstractStore {
    public function getRedirectUrls(){
        // code to get the redirect urls
    }
}

class <ecommstore>Store extends AbstractStore {
    public function getRedirectUrls(){
        // code to get the redirect urls
    }
}
</code>```

This just seems very basic and there has to be a better way.


问:
Is a 1 < 10 comparison less expensive than 1 < 1000000?
I just used ~1 billion as the count for a z-index in CSS, and was thinking about the comparisons that must go on. Is there a difference in performance on the ALU level in comparisons between very large numbers vs very small ones?

For example, would one of these two snippets be more expensive than the other?

snippet 1

```<code>for (int i = 0; i < 10000000; i++){
    if (i < 10000000000000) {
        //do nothing
    }
}
</code>```

snippet 2

```<code>for (int i = 0; i < 10000000; i++){
    if (i < 1000) {
        //do nothing
    }
}
</code>```

答: If this code was being interpreted each time it ran, there'd be a difference as it takes longer to tokenise and interpret 10000000000000 compared to 1000. However, this is the obvious first optimisation of interpreters in this case: tokenise once and interpret the tokens.


问:
Who should be allowed to add stories to the product backlog?
What is the best practice for that prevents the backlog from becoming a mess, but also maintaining developer productivity

Who should we allow to add stories to the product backlog? And how do you make sure these stories meet certain requirements?

For example I find a few small css bugs during the development of Feature X. Should I then as a developer be allowed to add a story describing the bugs to the bottom of the backlog? Or should I discuss it with the product owner?

Having all ideas/bugs go through the product owner sounds like possible bottleneck.

答:
Whereever I have worked in software development, there was always an equivalent of a backlog, always a list of bug reports, and always someone responsible for the priorities (an equivalent of a PO), so your question, though it uses Scrum terms, is IMHO far from beeing restricted to Scrum.

A quick google search for "scrum backlog bugs" revealed that some teams separate bugs / issues from "new feature" stories, other's don't. Sometimes issue trackers are used, sometimes a Wiki, sometimes everything goes directly into the backlog, etc., and there is no consensus "which is better". So the first thing you should clarify in your team how you want to handle this, what does your team want to see in the backlog and what not, and what does your team think will work best for your case.

If you made the experience that if everyone is allowed to add anything to the backlog messes its up, it will probably better to separate user stories from bugs. The requirements how a good bug report should look like are probably different from the requirements how a good user story for a new feature should look like, which might be another reason, too. Nevertheless both will end up in tasks for the developers, which might be a reason to keep them in one place.

However, for most products it makes sense when bug reports can be given by anyone (users, testers, developers, marketing people, whoever notices a potential problem). "New features" should probably be discussed with the PO as part of the process when adding them to the backlog. Your PO should decide if he wants to put the stories into there by himself to do some editorial work beforehand, or if anyone can put the stories to the backlog and he does the editorial work afterwards. But for bugs, especially the ones which look severe to the reporter, there should be no discussion needed to add them to the issue tracker, or backlog or buglist document, or whereever you keep them. "No discussion" does not mean to put the bug report anywhere silently, quite the opposite. When a bug report is added, and the reporter thinks it is probably not a minor one, the PO (or whoever is responsible) must get informed.

As a final note: to make the right decision for your team how to manage this, it makes quite a difference what size your product has, how many people are going to report bugs and new stories, and if you get one but report per week, a dozen or several hundred.


问:
How to earn team members respect as team lead
If you were hired into a new company as a team lead (say a team of 10) one of the important things to do is to earn the respect of the members of the team. In the early days the new team lead may know nothing of the team culture, code base and business domain: in other words, is a complete neophyte. </p>

<p>How does one go about this? What are the do's and don'ts? </p>

答:
Know what your team's tasks actually involve and react accordingly.

You probably lead a team of developers with diverse skills — two PHP developers, a database designer, a UI designer, some HTML developers. Get to know what's involved in their day-to-day tasks and build expectations based on what they are able to reasonably accomplish.

Perhaps your database developer reasonably needs X time to complete what amounts to 20 lines of code because the design phase scales differently than it does for your PHP developers, who can pump out 500 lines in the same time.

ContentLicense: CC BY-SA 2.5


答:
It depends on the implementation, but it would be very, very unlikely.

I admit that I have not read through the implementation details of the various browser engines, and CSS does not specify any particular type of storage for numbers. But I believe that it is safe to assume that all of the major browsers are using 64-bit double-precision floating-point numbers ("doubles", to borrow a term from C/C++) to handle most of their numeric needs in CSS, because this is what JavaScript uses for numbers, and so using the same type makes integration easier.

From the computer's standpoint, all doubles carry the same amount of data: 64 bits, whether the value is 1 or -3.14 or 1000000 or 1e100. The amount of time it takes to do an operation on these numbers doesn't depend on the actual value of those numbers, because it's always working on the same amount of data. There's a tradeoff in doing things this way, in that doubles can't accurately represent all numbers (or even all numbers within their range), but they can get close enough for most matters, and the kinds of things CSS does aren't numerically-demanding enough to need more precision than that. Combine this with the benefits of straight-across compatibility with JavaScript, and you've got a pretty strong case for doubles.

It's not impossible that someone might implement CSS using a variable-length encoding for numbers. If someone used a variable-length encoding, then comparing against small numbers would be less expensive than comparing against large numbers, because large numbers have more data to crunch. These kinds of encodings can be more precise than binary, but they are also much slower, and for CSS in particular, the precision gains are probably not enough to be worth the performance hit. I would be very surprised to learn that any browser did things this way.

Now, in theory, there is one possible exception to everything I've said above: comparing against zero is often faster than comparing against other numbers. This isn't because zero is short (if that were the reason, then 1 should be just as fast, but it's not). It's because zero lets you cheat. It's the only number where all the bits are off, so if you know that one of the values is zero, you don't even have to look at the other value as a number: if any of the bits on then it's not equal to zero, and then you only have to look at one bit to see if it's greater than or less than zero.

Title: Is a 1 < 10 comparison less expensive than 1 < 1000000?

Body:
I just used ~1 billion as the count for a z-index in CSS, and was thinking about the comparisons that must go on. Is there a difference in performance on the ALU level in comparisons between very large numbers vs very small ones?

For example, would one of these two snippets be more expensive than the other?

snippet 1

```<code>for (int i = 0; i < 10000000; i++){
    if (i < 10000000000000) {
        //do nothing
    }
}
</code>```

snippet 2

```<code>for (int i = 0; i < 10000000; i++){
    if (i < 1000) {
        //do nothing
    }
}
</code>```


问:
Using Visual Studio with a screen reader without paying for an expensive edition
I'm a totally blind programmer who would like to learn .net.

It appears that the Visual Studio express editions are not accessible since the scripts that come with Jaws for Windows, the screen reading software I use, requires the VS object model to make Visual Studio accessible. This is not available in the express editions, so the scripts may partially work or not work at all.

None of the options mentioned in this question apply to me and I don't want to spend $500 or more to buy Visual Studio professional when I may never use it for a job.

If I take the time to try out the express versions and run into issues is there any way to contact Microsoft without my questions/feedback being lost in a black hole?

答: Visual Studio community edition appears to provide access to the VS object model. I was able to create a project and do basic code editing with no issues. I've just started but it looks like this solves my issue.</p>


问:
Python: Faster to use global variable or pass as arguments to a function?
Hey so i was wondering which is the more efficient way, or better practice to do in this situation.

1,

```<code>def function():
    global number
    number += 2
</code>```

Or 2,

```<code>def function(number):
    return number += 2
</code>```

Thanks.

答: Performance is irrelevant. Globals are evil (as gnat mentioned); you are best off forgetting the global keyword exists. There is always a better way.


问:
Best practice for uploading large file, previewing, and editing before saving to database?
I am allowing users to upload a relatively large .csv file (about 1MB) - it will contain thousands of records that each represent one of my business objects. I want the users to upload the file and then be displayed paged results (after I serverside parse it, add validation messages, etc). They can review/edit the results page by page until they are satisfied. At this point, they'd click a Save button and all of the data would be saved to my database. Alternatively, they could click a Cancel button - this would release all of the uploaded data and none of it would touch my database.

I would prefer to not use "staging" tables in my database. And by that I mean store the uploaded data in my db when it is uploaded and subsequently delete it if the user chooses to cancel the whole operation. Also, my situation is such that I would have to delete it from the "staging" table even if the user chose to save the data (working with legacy systems).

My initial reasoning for NOT using staging tables is primary the following:
 this feature could only be a small subset of my needs. I could realistically have several extremely similar features of my site that could necessitate the need for "staging" tables. I would prefer not to have my database littered (for lack of a better word) with such tables.

I would also prefer to avoid saving the file to disk as that type of solution is IMHO not as scalable as storing the file within the database.

Also, it should be noted that all data validation and parsing must (in my circumstances) be done serverside.

My question is this: In order to prevent seemingly excessive/unnecessary "staging" tables in my database, is it a bad practice to store ALL of the uploaded file's data (i.e in a byte array or base64 encoded string) in a property on my view model? The intent being to keep this large-ish value on my view model while the user pages through and reviews/edits it.

Although I think this question is fairly technology independent, if it helps, I am using ASP.Net MVC/Web API and an MSSQL database.

答:
For simplicity,  let you have 3 files
upload.aspx preview.aspx and store.aspx

You could place your upload button and all HTML things in upload.aspx and make a post request to preview.aspx with the uploaded contents.
The file, preview.aspx, would simply parse the users' file and output it as a value of HTML form and would present a submit/Cancel button for the HTML form.
When the form is submitted it would send all the data to store.aspx which would check if the submit button was clicked and would do all the server side tasks (validation & all) and would store it to your db.


问:
Is it bad form to break out of Range-based for
I have a range-based for that operates over a std::vector of objects (items), like so:

```<code>for(auto item : itemCollection)
{
   if(!item.some_check(...))
   {
      // do 5% stuff
      break;
   }

   // do the 95% stuff
}
</code>```

Most of the time (>95%) the loop operates on the entire container, however, if some_check() returns a false (about 5% of the time), it'll break out of the loop early.

Is it considered bad form to break out of a range-based for? Should I instead use a while or a C++03-style for(...;...;...) here?

答:
No, it is never bad form to break out of any loop early unless you are aware of an invariant that will always break early. I have seen loops process the first element only:

```<code>for (auto item : itemCollection) {
  // do the 95% stuff
  break;
}
</code>```

This code should never be used, unfortunately I have seen it in production code several times in the past. Of course this prompted a code review.

Anyway, this does not appear to be your case. I would still reconsider the design of your algorithm though. Why break out of the loop just because one element somewhere in the container fails a check? Why not skip that element? Maybe looking at the big picture will reveal a better way of doing whatever you are trying to do. It is difficult for me to give more guidance without more of the code and the overall design.

Body:
No, it is never bad form to break out of any loop early unless you are aware of an invariant that will always break early. I have seen loops process the first element only:

for (auto item : itemCollection) {
  // do the 95% stuff
  break;
}

This code should never be used, unfortunately I have seen it in production code several times in the past. Of course this prompted a code review.

Anyway, this does not appear to be your case. I would still reconsider the design of your algorithm though. Why break out of the loop just because one element somewhere in the container fails a check? Why not skip that element? Maybe looking at the big picture will reveal a better way of doing whatever you are trying to do. It is difficult for me to give more guidance without more of the code and the overall design.


答:
Storing files in memory doesn't seem such a bad idea if there are only a few of them. 1Mb of data isn't very much on modern servers so it's all down to the level of simultaneous users you have and what happens when you 'run out' of memory.

In my experience I try to reduce the memory footprint size of each web service request because the server is usually a better judge of caching and allocating memory between processes and it's sometimes difficult to judge or even test how an application scales when the number of users increase and the memory pool is reducing rapidly as a result. If you go down this route then I'd recommend very careful load testing if memory is even slightly under stress.

Also, if you keep the pre-checked file in memory only then debugging/auditing the upload/edit/save cycle becomes harder because you have no record of what the file looked like before it was reviewed and saved so if you have any issue with the editing code long term (or a user even disputes what your editing code does) you can't trace back and look at the code's effect, even for a short period of hours or days. In memory processing needs more effort with debug/audit tools creation.

Alternatively, two possible suggestions:

Have you considered running a second database instance with staging/temporary working tables in that database only? This would keep your main database 'clean' and (possibly expensive) deletion and post-deletion optimisation functions off your main database too. You could also store a 'purge' time on the table so a scheduled job then deletes old tables in case of a no-show in terms of a user never clicking the 'save' button. (They'd be prompted to re-upload their file if they left the gap between upload and save beyond a sensible threshold).

If you're not expecting too many concurrent users of this functionality then you could also consider using an in memory cache (such as memcached) to store the file whilst it is being reviewed etc. A 1Gb memcached would store up to a thousand of your files simultaneously so unless you were under very heavy load, this would save you having to prompt for a re-upload from the user because the cache had flushed out your file. Note that this solution doesn't necessary preclude a good audit trail, if you choose to audit then you can turn on a simple script that reads memcached entries and writes them to disk for later audit without affecting live code.

Title: Best practice for uploading large file, previewing, and editing before saving to database?

Body:
I am allowing users to upload a relatively large .csv file (about 1MB) - it will contain thousands of records that each represent one of my business objects. I want the users to upload the file and then be displayed paged results (after I serverside parse it, add validation messages, etc). They can review/edit the results page by page until they are satisfied. At this point, they'd click a Save button and all of the data would be saved to my database. Alternatively, they could click a Cancel button - this would release all of the uploaded data and none of it would touch my database.

I would prefer to not use "staging" tables in my database. And by that I mean store the uploaded data in my db when it is uploaded and subsequently delete it if the user chooses to cancel the whole operation. Also, my situation is such that I would have to delete it from the "staging" table even if the user chose to save the data (working with legacy systems).

My initial reasoning for NOT using staging tables is primary the following:
 this feature could only be a small subset of my needs. I could realistically have several extremely similar features of my site that could necessitate the need for "staging" tables. I would prefer not to have my database littered (for lack of a better word) with such tables.

I would also prefer to avoid saving the file to disk as that type of solution is IMHO not as scalable as storing the file within the database.

Also, it should be noted that all data validation and parsing must (in my circumstances) be done serverside.

My question is this: In order to prevent seemingly excessive/unnecessary "staging" tables in my database, is it a bad practice to store ALL of the uploaded file's data (i.e in a byte array or base64 encoded string) in a property on my view model? The intent being to keep this large-ish value on my view model while the user pages through and reviews/edits it.

Although I think this question is fairly technology independent, if it helps, I am using ASP.Net MVC/Web API and an MSSQL database.


问:
Hard Coded File Paths - Solution?
Say you have an application that saves image(.jpg, .png etc) and text(.txt, .xml) files, and the application has all of the files paths hard coded throughout code, per the example below.

Assuming the following file path structure exists:

jpg - \\MyFileServer\Media\jpg\

png - \\MyFileServer\Media\png\

txt - \\MyFileServer\Text\txt\

xml - \\MyFileServer\Text\xml\

The files in the destination file paths are referenced inside of a table, so in a VBA example the file path would be hard coded as:

```<code>Dim myFilePath as String
Dim myFileName as String
myFileName = "puppies.jpg" 'This would be the result of a query in a real scenario
myFilePath = "\\MyFileServer\Media\jpeg\" & myFileName
</code>```

Now say I have to split \\MyFileServer into \\MyMediaFileServer and \\MyTextFileServer

What would have been ideal is if I had a central location that I could have just changed a table value or variable, rather than trudging through every single function in the application to update the hard coded path. Just to change it again in the future if the situation arises again. So, my goal is to make sure my puppies image can be shown with minimal effort.

Concerning industry standard, I was wondering what is the best option, be it my two options below or another separate option.

Option 1:

Single Self Referential Table:

Defined in Mike's answer at hierarchical/tree database for directories in filesystem
by a hierarchical structure like the following:

```<code>        (ROOT)
      /        \
    Dir2        Dir3
    /    \           \
  Dir4   Dir5        Dir6
  /
Dir7
</code>```

You simply have a table like the following:

```<code>ID  ParentID     FilePath
______________________________________________
1   NULL         \\MyFileServer
2   1            \Images
3   2            \jpg
4   3            \10 MB Files
</code>```

OR Option 2:
Self Referential Table With Master Roots:

A slight deviation on option 1.

Perhaps a master file path would be clearer. Where there is a separate table.

```<code>ID    Name               FilePath
______________________________________________
1     Image Root         \\MyMediaFileServer\Images
2     Text Root          \\MyTextFileServer\Text
</code>```

Then in the structure mentioned in option 1.

```<code>ID  ParentID    RootID   FilePath
______________________________________________
1   NULL        1        \jpg
2   1           NULL     \10 MB Files
</code>```

I feel that option 1 is overall more simple to change, but will become more confusing as a tree expands, and option 2 allows for an easier absolute file path change. IS Option 1 the best solution to storing file paths or is there another industry standard I am not aware of?

答:
Option 1 is definitely overkill.

Mike's answer is awesome, if you want to store data about directories and their structure.
But that is not what you need here. You don't really care about folder hierarchy and the relations between them. You just want to know what the paths ARE.

You can get these parameters from either from a config/ini file or from a table (as you describe in Option 2). I find that config files are more popular, but there are advantages to both methods.
You can find a good discussion of these in Scriptin's answer to Should I use a config file or database for storing business rules?

Title: Hard Coded File Paths - Solution?


答:
Both options are over-engineered, involving the database is inappropriate here, and the directory structure is too deep.

Instead, for administrator-friendly software, I see the following patterns emerging:

Paths are configured in config files, not database.

Usually, you want to be able to copy
the database dump to another system.
Often, the database server is on another system.
You simply don't expect the database content to be entangled
with file system details,
the only exception being strictly relative paths.
Finally, having to make configuration changes in a database is a pain.

There's just one data directory to configure, if any.

This depends on the application, of course,
but you almost always want to have everything in a single directory.
Then the application, not the config file,
takes care of its inner structure.
In your case, all I want to configure is:

\\MyFileServer

Another common approach is not to configure it at all,
but to a well defined sub directory.
This is either within the user's HOME directory
or within some generic application data directory
(different conventions on different operating systems,
but that's another topic).

If you want another place,
you simply replace that directory with a symbolic link, such as:

{...}\Data  ->  \\MyFileServer

The inner structure of the data directory is managed by source.

Good applications have internal functions or property table for
all common directories,
usually all combined in a single class or module.

The base is something like getRootPath()
which reads the config file and returns something like \\MyFileServer.

Then, there functions like getMediaPath() or getTextPath()
which internally just call getRootPath()
(or each other) and append their relative path.

A common variation from the theme is to let those functions
take a filename (or relative file path) as argument,
and to return the full path to that file.
For example, getMediaPath("great.jpg") would return \\MyFileServer\Media\great.jpg.

Ideally, these functions also create the directory if it doesn't exist yet.
Another approach is to create each directory only when the first file
is written to it.
Either way, the point is not to expect a fully populated directory structure,
which is one less thing the admin (or installer) might get wrong.

If a future version of the application needs some more subdirectories,
it usually just creates those,
without bothering the administrator to creative those,
or to force them to add those paths to a config file,
or any another stupid hassles.
(see 2: There's just one data directory)

Directories structures are not deeper than necessary.

Your directory structure is essentially split by file extention.

{YourRoot}\Media\jpg\great.jpg

{YourRoot}\Media\png\great.png

{YourRoot}\Text\txt\great.txt

{YourRoot}\Text\xml\great.xml

Is that really necessary?
The files are already uniquely determined by their extension,
so why not skip those intermediate paths?

{YourRoot}\great.jpg

{YourRoot}\great.png

{YourRoot}\great.txt

{YourRoot}\great.xml

Of course, applications have good reasons for structuring
the data directory.
But that's usually a separation by usage (or purpose),
not merely by file extension.

If you must, split uniformly.

The only reasons for further splitting the directories
is if they get too large.
In that case, you still don't split by file extension,
but by something that provides a uniform partition.

Often, this is time based, e.g. daily or monthly:

{YourRoot}\2015-01\great.jpg

{YourRoot}\2015-01\stuff.png

...

{YourRoot}\2015-02\others.jpg

...

If you have uniform file names (e.g. hashes),
their prefix is often chosen as subdirectory name
(and cut from the original file name), such as:

{YourRoot}\12\34567.jpg

...

{YourRoot}\13\43577.png

...

Title: Hard Coded File Paths - Solution?

Body:
Say you have an application that saves image(.jpg, .png etc) and text(.txt, .xml) files, and the application has all of the files paths hard coded throughout code, per the example below.

Assuming the following file path structure exists:

jpg - \\MyFileServer\Media\jpg\

png - \\MyFileServer\Media\png\

txt - \\MyFileServer\Text\txt\

xml - \\MyFileServer\Text\xml\

The files in the destination file paths are referenced inside of a table, so in a VBA example the file path would be hard coded as:

```<code>Dim myFilePath as String
Dim myFileName as String
myFileName = "puppies.jpg" 'This would be the result of a query in a real scenario
myFilePath = "\\MyFileServer\Media\jpeg\" & myFileName
</code>```

Now say I have to split \\MyFileServer into \\MyMediaFileServer and \\MyTextFileServer

What would have been ideal is if I had a central location that I could have just changed a table value or variable, rather than trudging through every single function in the application to update the hard coded path. Just to change it again in the future if the situation arises again. So, my goal is to make sure my puppies image can be shown with minimal effort.

Concerning industry standard, I was wondering what is the best option, be it my two options below or another separate option.

Option 1:

Single Self Referential Table:

Defined in Mike's answer at hierarchical/tree database for directories in filesystem
by a hierarchical structure like the following:

```<code>        (ROOT)
      /        \
    Dir2        Dir3
    /    \           \
  Dir4   Dir5        Dir6
  /
Dir7
</code>```

You simply have a table like the following:

```<code>ID  ParentID     FilePath
______________________________________________
1   NULL         \\MyFileServer
2   1            \Images
3   2            \jpg
4   3            \10 MB Files
</code>```

OR Option 2:
Self Referential Table With Master Roots:

A slight deviation on option 1.

Perhaps a master file path would be clearer. Where there is a separate table.

```<code>ID    Name               FilePath
______________________________________________
1     Image Root         \\MyMediaFileServer\Images
2     Text Root          \\MyTextFileServer\Text
</code>```

Then in the structure mentioned in option 1.

```<code>ID  ParentID    RootID   FilePath
______________________________________________
1   NULL        1        \jpg
2   1           NULL     \10 MB Files
</code>```

I feel that option 1 is overall more simple to change, but will become more confusing as a tree expands, and option 2 allows for an easier absolute file path change. IS Option 1 the best solution to storing file paths or is there another industry standard I am not aware of?


问:
Overriding equals() method in Java
Short question: Why does Java allow overriding equals(), why is it not final?

I am reading Effective Java 2nd edition by Joshua Bloch.
I am a bit baffled by the conclusion that

There is no way to extend an instantiable class and add a value component while preserving the equals contract

Is not it saying the same as equals() should be a final method?

The book gives an example of a class A with equals() method and then a class AX extending A having its own equals() method which is different from the equals() method in A.

I will not go into details of equals() in A and equals() in AX, but it suffices to say that they are different. Therefore we have inter-operatability problem which guarantees violation of transitivity and/or symmetry (maybe even something else) of equals() when we mix different implementations of A in some contexts (especially HashSet, HashMap type).

Thinking further, I don't think I can agree with with the conclusion that having something like

```<code>public boolean equals(Object o) {
    if (o == null || o.getClass() != getClass())
      return false;
    ...
}
</code>```

is wrong. I think this is precisely the proper way to deal with overriding equals().

Java makes it possible so Java allows overriding equals() for a reason. If it had taken into account Liskov substitution principle in the strict sense, then it would not have allowed overriding equals() and implicitly makes any implementation of equals() final at the compiler level. What are your thoughts?

I can think of a case where composition is simply not suitable, and overriding equals() is the best option. This is the case where the class A is to be made persistent in a database and the context implies that there is no collection having both an implementation of A and subclasses of A such as AX.

答:
equals() is a byproduct of an attempt to improve C++ when it was created.  C++ has operator overloading which allows you to perform custom operations when called with otherwise valid operators such as <, >, !=, ==, and even =.

The team made the decision (wisely so) to make equality be class method rather than having external static methods as it was done in C++.  However, this also meant that equals() coupled with hashCode() defined how such classes were handled in collection classes.

Since any class could in theory override equals() or hashCode(), it means that just because you have a collection of a certain type does not guarantee that behavior is uniform.

For instance, suppose class A has two members x and y used to determine equality.  Along comes class B which has x, y, and z.  If an instance of B had the same values x and y, how would you go about inserting this instance in a Set?  If you call the equals of an instance of A, it will determine the two to be equal and if you call the equals of an instance of B, it will return false since it is not an instance of B.

To be perfectly correct, class B would have to treat member z as an additional condition only in the case in which it is an instance of B, otherwise it lends itself to the equals() method of class A, and, if such a thing is not possible, class B should not allow itself to override equals() or hashCode().  This creates a sticky situation since in theory you should not concern yourself with how the parent class works from an implementation standpoint (if done right anyway), but yet here we are.

You could make class A final to prevent such things from happening, but then of course you can never extend class A.  Java makes a point of making certain standard classes like String final to prevent complications of this nature (very smart decision on their part).  I think at the end of the day, what matters is that you are very careful in your usage of equals() and hashCode().  I try to use it sparingly, and I am always mindful of which classes I mean to be available in a library and which classes are for internal use as to not to create conditions where things could go horribly wrong.

The Liskov substitution principle is fine in theory, but in practice you can never quite manage it.  Take Collection as an example.  Collection is implemented by ArrayList, Set, or LinkedList among others.  While it is true that you could achieve the same ultimate goal by replacing a Collection with say a HashSet, it is not an ideal implementation for performing operations on all objects contained within (better LinkedHashSet at that point).  It wouldn't break existing code, but you may potentially render it grossly inefficient depending on how that Collection is used.  Consider that this is a rather clean example too.

If you're lucky, only the implementation details change, but many behave radically different, with some methods throwing a NotImplementedException.

Thus requiring that classes implementing equals() must respect the Liskov substitution principle is asking a lot, and I suspect that they didn't want to alienate the majority of C++ programmers getting familiar with Java.

Title: Overriding equals() method in Java


问:
Execute python code without showing the code
I want to use exec to execute python code (using the byte code, instead of the raw text that python will interpret). It's all for a competition where you can see the code of the other competitors, I want to be able to hide my code well enough so people won't bother messing with my code.

How do I do that?

答:
That's most likely not going to work. Even if you provide them with byte code only, it's usually possible to simply deassemble the code.

You'll lose comments, formatting and possibly variable names that way though. Code obfuscation might be an option, but at the same time you're not really hiding anything (which in the end is impossible, even if someone has to interpret machine code instructions in the end).


答:
Simple argument against your logic is, what is the use of the equals method if it's modified to be a final. Then it would execute same logic against any given objects. If you want to compare A and AX in the object class what would be the logic?

Overriding of final method is allowed to be able to verify if two different objects (living in 2 different memory locations) are actually equals (== method is there to check if two references are of the same object) based on defined logic. For example if you have a user object like this,

```<code>User
{
    string name;
    string email;
    string phone;
}
</code>```

For one system, it would be the email you might interest to uniquely identifying a user. So you may compare based on email value. But some other system might use phone as the unique identifier. So they may decide to implement different equals methods.

When it comes to logic of A,AX and Liksov substitution principle which is,

Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.

So if you do,

```<code>AX ax1 = new AX();
AX ax2 = new AX();
ax1.equals(ax2);
</code>```

and

```<code>A a = new AX();
AX ax = new AX();
a.equals(ax);
</code>```

should give you the same output, and it will.

Title: Overriding equals() method in Java

Body:
Short question: Why does Java allow overriding equals(), why is it not final?

I am reading Effective Java 2nd edition by Joshua Bloch.
I am a bit baffled by the conclusion that

There is no way to extend an instantiable class and add a value component while preserving the equals contract

Is not it saying the same as equals() should be a final method?

The book gives an example of a class A with equals() method and then a class AX extending A having its own equals() method which is different from the equals() method in A.

I will not go into details of equals() in A and equals() in AX, but it suffices to say that they are different. Therefore we have inter-operatability problem which guarantees violation of transitivity and/or symmetry (maybe even something else) of equals() when we mix different implementations of A in some contexts (especially HashSet, HashMap type).

Thinking further, I don't think I can agree with with the conclusion that having something like

```<code>public boolean equals(Object o) {
    if (o == null || o.getClass() != getClass())
      return false;
    ...
}
</code>```

is wrong. I think this is precisely the proper way to deal with overriding equals().

Java makes it possible so Java allows overriding equals() for a reason. If it had taken into account Liskov substitution principle in the strict sense, then it would not have allowed overriding equals() and implicitly makes any implementation of equals() final at the compiler level. What are your thoughts?

I can think of a case where composition is simply not suitable, and overriding equals() is the best option. This is the case where the class A is to be made persistent in a database and the context implies that there is no collection having both an implementation of A and subclasses of A such as AX.

Body:
Simple argument against your logic is, what is the use of the equals method if it's modified to be a final. Then it would execute same logic against any given objects. If you want to compare A and AX in the object class what would be the logic?

Overriding of final method is allowed to be able to verify if two different objects (living in 2 different memory locations) are actually equals (== method is there to check if two references are of the same object) based on defined logic. For example if you have a user object like this,

User
{
    string name;
    string email;
    string phone;
}

For one system, it would be the email you might interest to uniquely identifying a user. So you may compare based on email value. But some other system might use phone as the unique identifier. So they may decide to implement different equals methods.

When it comes to logic of A,AX and Liksov substitution principle which is,

Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.

So if you do,

AX ax1 = new AX();
AX ax2 = new AX();
ax1.equals(ax2);

and

A a = new AX();
AX ax = new AX();
a.equals(ax);

should give you the same output, and it will.


问:
Repository strategy for multiple interconnected components with small differences
At my work we have multiple products.. productA, productB, ... these products reference multiple components. componentA, componentB.. there are also shared components sharedA, sharedB... etc.. which are either shared by multiple components, multiple products or by a product and a component.

We are currently moving all these things to separate Git repositories however, we have a hard time find a way to set up repositories in such a way that everything stays manageable.

We have two problems that make setting up repositories hard.

There are a lot of hard dependencies. When I want to work on ProductA I need to have the source code for ProductA, componentA, componentB, and sharedComponentC on my computer, since I might be changing code in all of them. For ProductB I need componentA, sharedComponentC and... this makes it hard to choose what to store in what repository.

Say componentA is an interface library, this interface library is used by ProductA and ProductB. For ProductA it needs to work normally but in ProductB it needs to show an extra button. We have a lot of these very small differences in components should we make a branch per product and sometimes integrate the branches to make sure they have the same new features? Maybe develop on a 'general' branch and push changes to each 'small difference' branch? Is it bad to have a lot of active branches in a project?

Are there any rules of thumb that help to decide how to split software over multiple repositories? What are good ways to work on software that is in multiple repositories, or tooling that helps in this regard? What is proper repository set-up for components with a lot of small differences? In the end these are all the same question. What is a good repository strategy for multiple interconnected components with small differences?

Some more information that  might help. We develop solely on Windows, 99% of the code we write is C#, the other 1% is C++/CLI. All our developers have access to Visual Studio 2013 Pro. We are willing to buy software to help us with this problem but we are a small company so we do not have infinite budget :).

Of course a part of the problems we are having are due to (bad) design decisions in the past. (No design decision can completely safeguard against the future development of your software/company ;) ) We are working on changing that. But for the time being we would like to decide on a modern repository strategy that makes things a bit more manageable.

答:
With git you can use git submodule.

ProductA can have specific commit_ids (which can be a branch) of some submodules (for example ComponentA, ComponentB, SharedComponentC).

To add a component to ProductA, from the ProductA directory on your development machine do:

```<code>C:\projects\ProductA.git\> git submodule add --branch master --name ComponentA http://reposerver.ourcompany.com/ComponentA components/ComponentA
C:\projects\ProductA.git\> git submodule add --branch master --name ComponentB http://reposerver.ourcompany.com/ComponentB components/ComponentB
C:\projects\ProductA.git\> git submodule add --branch ProjectA --name sharedComponentC http://reposerver.ourcompany.com/ComponentC components/sharedComponentC
</code>```

Other developers can use:

```<code>C:\projects\ProductA.git\> git submodule init
C:\projects\ProductA.git\> git submodule update
</code>```

to receive the correct versions of the submodules in their working directory.

When you make some changes to a submodule, you commit the changes of the submodule and you commit the new version of the submodule in the project, i.e.:

```<code>C:\projects\ProductA.git\components\sharedComponentC\> git add ...
C:\projects\ProductA.git\components\sharedComponentC\> git commit
C:\projects\ProductA.git\components\sharedComponentC\> cd ..\..
C:\projects\ProductA.git\> git add components/sharedComponent
C:\projects\ProductA.git\> git commit
</code>```

Remarks

I used command-line syntax to explain how to use git; you are free to use any graphical tool or visual studio plugin that you like.

I checked the syntax and parameters under Linux and translated the examples to Windows command prompt, so there might some mistakes (e.g. slashes instead of dashes); refer to the git reference manual for the exact syntax.

The project directory (C:\projects\ProductA.git), branch name (ComponentA), repository location (http://reposerver.ourcompany.com/ComponentA), and submodule directory (components/ComponentA) can vary independently.

Body:
With git you can use git submodule.

ProductA can have specific commit_ids (which can be a branch) of some submodules (for example ComponentA, ComponentB, SharedComponentC).

To add a component to ProductA, from the ProductA directory on your development machine do:

C:\projects\ProductA.git\> git submodule add --branch master --name ComponentA http://reposerver.ourcompany.com/ComponentA components/ComponentA
C:\projects\ProductA.git\> git submodule add --branch master --name ComponentB http://reposerver.ourcompany.com/ComponentB components/ComponentB
C:\projects\ProductA.git\> git submodule add --branch ProjectA --name sharedComponentC http://reposerver.ourcompany.com/ComponentC components/sharedComponentC

Other developers can use:

C:\projects\ProductA.git\> git submodule init
C:\projects\ProductA.git\> git submodule update

to receive the correct versions of the submodules in their working directory.

When you make some changes to a submodule, you commit the changes of the submodule and you commit the new version of the submodule in the project, i.e.:

C:\projects\ProductA.git\components\sharedComponentC\> git add ...
C:\projects\ProductA.git\components\sharedComponentC\> git commit
C:\projects\ProductA.git\components\sharedComponentC\> cd ..\..
C:\projects\ProductA.git\> git add components/sharedComponent
C:\projects\ProductA.git\> git commit

Remarks

I used command-line syntax to explain how to use git; you are free to use any graphical tool or visual studio plugin that you like.

I checked the syntax and parameters under Linux and translated the examples to Windows command prompt, so there might some mistakes (e.g. slashes instead of dashes); refer to the git reference manual for the exact syntax.

The project directory (C:\projects\ProductA.git), branch name (ComponentA), repository location (http://reposerver.ourcompany.com/ComponentA), and submodule directory (components/ComponentA) can vary independently.


答:
To give a short answer to your short question - it's because the equals() function defined for java.lang.Object is largely useless.  It's just equivalent to "==" in that it returns true if the two references refer to the same object, and doesn't really test if they are "equal" in the normal sense of the word.

Thus, if you actually want to compare two objects to see if they hold equal data, you need to override the default implementation of equals().  You normally should override hashCode() as well.

Title: Overriding equals() method in Java


问:
Leaving intentional bugs in code for testers to find
We don't do this at our firm, but one of my friends says that his project manager asked every developer to add intentional bugs just before the product goes to QA. This is how it works:

Just before the product goes to QA, the development team adds some intentional bugs at random places in the code. They properly back up the original, working code to make sure that those bugs aren't shipped with the end product.

Testers are also informed about this. So they will test hard,
because they know there are bugs present and that not finding them might
be considered as a sign of incompetence.

If a bug (intentional or otherwise) has been found, they will be reported for the development team to fix. The development team then adds another intentional bug in a related section of the code just before the product goes to the second-level QA. The project manager says a tester should think like a developer and he/she should expect new bugs in sections where changes were made.

Well, this is how it goes. They say that this approach has following advantages.

Testers will be always on their toes and they will test like crazy.
That helps them to also find hidden (unintentional) bugs so developers
can fix them.

Testers feed on bugs. Not finding any bugs will affect their morale.
So giving them an easy one to find will help their morale.

If you ignore the scenario where one of these intentional bugs gets shipped with the final product, what are the other drawbacks we should consider before even thinking of adopting this approach?

Some clarifications:

They properly backup the original code in source control.

When a tester finds the intentional bug, the development team just ignores it. If tester finds out an unintentional (original) bug, the development team first checks whether it is caused by any of the intentional bugs. That is, the development team first tries to reproduce that on the original working code and tries to fix it if they can.

Just ignore the relationship issues between QA and development team. I specifically asked this question on Programmers, not on The Workplace. Consider that there is good rapport between QA and the development team, and they party together after working hours. The project manager is a nice, old gentleman who is always ready to support both teams (Godsend).

答:
A tester who is not taking the code-to-be-tested directly from the repository is doing it wrong. (1)

A developer who is checking in known-faulty code into the repository is doing it wrong. (2)

So at this stage, there is already no way for this scheme to work without one or both sides violating very basic premises of how development and testing ought to be done.

(1) Because you need to document which version you tested. A version tagged by a Git hash or a SVN revision number is something you can test, "the code Joe gave me" isn't.

(2) Because you just don't, outside of a test driver that is expecting failure.

This is an attempt at a shortest-possible, "elevator pitch" reason that should make immediate sense to devs, testers, and management alike.


答:
Lots of good answers already. I tried to do all these when I was a team lead.

Treat team with respect

Delegate to strengths, but also give tasks that may help team members improve on weaknesses

Protect the team from interruptions or distractions

Be willing to educate

Be willing to listen

Remove roadblocks and stay out of the team's way, but also be approachable when people need help

Be tactfully honest in assessing work. Some people do not respond well to even constructive criticism, but serious developers (or workers in any profession really) will want to know what to do to get better

Respect the team's personal time and allow for work/life balance (telecommuting, getting out an hour early to pick up kids or make a doctor's appointment), and when times dictate overtime, be prepared to reward the team for the sacrifice. Sometimes my company would authorize me buying lunch to celebrate a milestone, but when it didn't (cheap bastards!) I did something for the team on my dollar. If the team gave extra to help make a project successful, then it was the least I could do. It doesn't have to be extravagant or expensive, but a little appreciation helps; and lack of it can sap morale.

Work to be both a technical and subject matter expert. You don't have to do this, but in my experience a leader is more respected when the team members could both appreciate his/her knowledge and depend on him/her to help out when needed.

Do what it takes to make the team members more successful. That means educating and removing roadblocks, mentioned above, but also pitching in with documentation that the team can use when your brain isn't around for them to use, and writing some of the specs. Great specs will make developers more efficient and self sufficient, fill in knowledge gaps, and  help them meet requirements with a minimum of later rework. Do this in conjunction with getting them to work directly with the client.

Build relationships between the team and the clients. It will help with filling in the gaps on missed requirements and open doors for other feedback you might not normally get.

Accept that mistakes are a part of learning

Be ready to act to remove a team member that is a detriment to the team's cohesion or productivity. This is sometimes hard to do, but you will encounter people that lack the work ethic, productivity, or competence of the other team members. You can be patient to a point, but there comes a time when you may have to work with management to make a change. Truly poor team members will cost the team more time and effort. Trying too hard to be Mr. Fair and Nice can work against you if the better team members feel the underperformer is getting special treatment or is being compensated the same for lesser work.

Be transparent. Communicate regularly. If you get information about the company or a recent layoff, or a merger, share it with them. People do respect honesty even though sometimes in this nutty world the opposite seems true. If you can't be honest with your subordinates, then you don't want to be a team lead, you want to be an executive.

Be quick to share credit when good things happen

Be prepared to take responsibility when bad things happen

Title: How to earn team members respect as team lead

Body:
If you were hired into a new company as a team lead (say a team of 10) one of the important things to do is to earn the respect of the members of the team. In the early days the new team lead may know nothing of the team culture, code base and business domain: in other words, is a complete neophyte. </p>

<p>How does one go about this? What are the do's and don'ts? </p>


问:
What open source library licenses can I use in closed-source?
I like to create a closed-source program and sell it.  I would like to make use of various open source libraries to make it easier to write this program.

So how I will choose the libraries that I could use. Which licenses for libraries could I use? I only will use the library - I will not edit the libraries.

Which licenses allowed me to use it for closed-source program?

答:
If you want to remain free in which license to choose for your own parts of the application, you can use libraries with any license that doesn't try to extend its scope to the entire program, but is limited to the library in question.

So, the licenses that you must avoid are strong copyleft licenses, such as GPL and AGPL.

If you want to use a library with LGPL license, then you must ensure that your users are given the means to replace that library with a version of their own. The users that do this are assumed to have enough programming knowledge to use a compiler.


问:
Why doesn't Java have optimization for tail-recursion at all?
From what I have read: The reason is because it is not easy to determine which method will actually be called as we have inheritance.

However, why doesn't Java at least have tail-recursion optimization for static methods and enforce proper way to call static methods with the compiler?

Why doesn't Java have any support at all for tail-recursion?

I am not sure if there is any difficulty here at all.

Regarding the suggested duplicate, as explained by Jörg W Mittag1:

The other question asks about TCO, this one about TRE. TRE is much simpler than TCO.

Also, the other question asks about what limitations the JVM imposes on language implementations that wish to compile to the JVM, this question asks about Java, which is the one language that is not restricted by the JVM, since the JVM spec can be changed by the same people who design Java.

And lastly, there isn't even a restriction in the JVM about TRE, because the JVM does have intra-method GOTO, which is all that's needed for TRE

1Formatting added to call out points made.

答:
Java doesn't have tail call optimization for the same reason most imperative languages don't have it.  Imperative loops are the preferred style of the language, and the programmer can replace tail recursion with imperative loops.  The complexity isn't worth it for a feature whose use is discouraged as a matter of style.

This thing where programmers want to sometimes write in a FP-style in otherwise imperative languages only came into vogue in the last 10 years or so, after computers started scaling in cores instead of GHz.  Even now, it's not that popular.  If I suggested replacing an imperative loop with tail recursion at work, half the code reviewers would laugh and the other half would give a confused look.  Even in functional programming, you generally avoid tail recursion unless other constructs like higher-order functions don't fit cleanly.


答:
Java don't have tall call optimization because the JVM does not have a bytecode for tail calls (to some statically unknown function pointer, e.g. a method in some vtable).

It looks like for social (and perhaps technical) reasons, adding a new bytecode operation in the JVM (which would make it incompatible with earlier versions of that JVM) is terribly difficult to the owner of the JVM spec.

Technical reasons for not adding a new bytecode in the JVM spec include the fact that real-life JVM implementations are terribly complex software pieces (e.g. because of the many JIT optimizations it is doing).

Tail calls to some unknown function requires replacing the current stack frame with a new one, and that operation should sit in the JVM  (it is not only a matter of changing the bytecode generating compiler).

Title: Why doesn't Java have optimization for tail-recursion at all?

Body:
From what I have read: The reason is because it is not easy to determine which method will actually be called as we have inheritance.

However, why doesn't Java at least have tail-recursion optimization for static methods and enforce proper way to call static methods with the compiler?

Why doesn't Java have any support at all for tail-recursion?

I am not sure if there is any difficulty here at all.

Regarding the suggested duplicate, as explained by Jörg W Mittag1:

The other question asks about TCO, this one about TRE. TRE is much simpler than TCO.

Also, the other question asks about what limitations the JVM imposes on language implementations that wish to compile to the JVM, this question asks about Java, which is the one language that is not restricted by the JVM, since the JVM spec can be changed by the same people who design Java.

And lastly, there isn't even a restriction in the JVM about TRE, because the JVM does have intra-method GOTO, which is all that's needed for TRE

1Formatting added to call out points made.


答:
As explained by Brian Goetz (Java Language Architect at Oracle) in this video:

in jdk classes [...] there are a number of security sensitive methods that rely on counting stack frames between jdk library code and calling code to figure out who's calling them.

Anything that changed the number of frames on the stack would break this and would cause an error.  He admits this was a stupid reason, and so the JDK developers have since replaced this mechanism.

He further then mentions that it's not a priority, but that tail recursion

will eventually get done.

N.B. This applies to HotSpot and the OpenJDK, other VMs may vary.


问:
Is reading javadoc preferable to reading source code to familiarise yourself with a library?
I just came across the following in a lab manual at university:

You do need to study the interfaces of the classes by generating the javadoc for them so you know what operations are provided (feel free to look at the code, but
  when using somebody else’s code, as here, you should work from the javadoc rather than the code whenever possible).

I don't understand why this is the case; since the javadoc could be out of date, or could describe the function of the code badly. Surely looking at the source code, and reading the javadoc comments is best?

Is there a reason why, or a case when reading only the javadoc is the best thing to do?

答:
The recommendation is probably about programming to an interface rather than the implementation.

Sure, if you have access to the code then there's nothing stopping you from looking at the implementation to understand how it works.  But you should always make sure that the how doesn't influence your consumption of the API.

When you're consuming an API you're working against an abstraction.  Try to concern yourself only with what the API offers (the contract) and not the how (the implementation).

This is because there is no guarantee that an API's implementation won't change drastically from one version to the next, even if the contract has remained unchanged.


问:
Well defined mathematical operations for bearing (angle) class
I have written a class to represent bearings (angles with a nautical theme, and a specific normalisation range). In the program, it is necessary to perform some mathematical operations on them, so I've overloaded the +, -, * and / operators (this is in C++).

My question is: what operators are mathematically well defined for such a class?
Or more specifically, in the following code, are there any operators defined that I shouldn't have defined, and are there any operators undefined that I should have defined?

```<code>constexpr inline Bearing operator+(Bearing lhs, Bearing rhs) noexcept
{
    return Bearing::deg(lhs.getInDegrees() + rhs.getInDegrees());
}

constexpr inline Bearing operator-(Bearing lhs, Bearing rhs) noexcept
{
    return Bearing::deg(lhs.getInDegrees() - rhs.getInDegrees());
}

template <
    typename T,
    typename = EnableIfNumeric<T>
> constexpr inline Bearing operator*(Bearing lhs, T rhs) noexcept
{
    return Bearing::deg(lhs.getInDegrees() * static_cast<Bearing::ValueType>(rhs));
}

template <
    typename T,
    typename = EnableIfNumeric<T>
> constexpr inline Bearing operator*(T lhs, Bearing rhs) noexcept
{
    return Bearing::deg(static_cast<Bearing::ValueType>(lhs) * rhs.getInDegrees());
}

template <
    typename T,
    typename = EnableIfNumeric<T>
> constexpr inline Bearing operator/(Bearing lhs, T rhs) noexcept
{
    return Bearing::deg(lhs.getInDegrees() / static_cast<Bearing::ValueType>(rhs));
}

template <
    typename T,
    typename = EnableIfNumeric<T>
> constexpr inline Bearing operator/(T lhs, Bearing rhs) noexcept; // Intentionally not defined

constexpr inline Bearing::ValueType operator/(Bearing lhs, Bearing rhs) noexcept
{
    return lhs.getInDegrees() / rhs.getInDegrees();
}

// Bearing has value semantics
constexpr inline Bearing operator+=(Bearing lhs, Bearing rhs) noexcept; // Intentionally not defined
constexpr inline Bearing operator-=(Bearing lhs, Bearing rhs) noexcept; // Intentionally not defined
constexpr inline Bearing operator*=(Bearing lhs, Bearing rhs) noexcept; // Intentionally not defined
constexpr inline Bearing operator/=(Bearing lhs, Bearing rhs) noexcept; // Intentionally not defined

constexpr inline bool operator==(Bearing lhs, Bearing rhs) noexcept
{
    return lhs.getInDegrees() == rhs.getInDegrees();
}

constexpr inline bool operator!=(Bearing lhs, Bearing rhs) noexcept
{
    return !(lhs == rhs);
}
</code>```

In words:

(not shown in above code) Bearing instances must be created from static methods Bearing::deg or Bearing::rad, so the units are explicit at initialisation

Bearings may be added to or subtracted from other Bearings only

Bearings may be multiplied only by numeric types (not other Bearings)

Bearings may be divided only numeric types

Numeric types may not be divided by Bearings

Bearings may be divided by other Bearings, yielding a floating point value

Bearings have equality comparison operators, but no inequality comparison operators (because angles wrap around, both a < b and b < a are true if a and b are Bearings)

(note that there are member functions to determine the absolute and clockwise/anticlockwise distances between one bearing and another, so whatever you might want to do with inequality comparison operators should be possible)

Note that, by "normalisation", I mean wrapping the angles around so that they are always in the range [0, 360), or [-180, 180), and that this operation is only performed at the client's request, not after every operation.

P.S. I think this question is a good fit for Programmers, but if several people think it is a better fit for Code Review, then I will consider moving it there.

答:
This depends on what "mathematically well defined" means. All of your functions are well defined in the sense of having a unique definition. However, multiplication and division are problematic, since they are not guaranteeing

```<code>(b * n) * m == b * (n * m)
</code>```

nor

```<code>(b * n) / m == b * (n / m)
</code>```

where b is a bearing and n is a numeric value, and that is what you might expect. For example, if b = 45° and n = m = 8, you get

```<code>(b * n) / m == 360° / 8 == 0° / 8 == 0°
</code>```

but
    b * (n / m) == 45° * 1 == 45°

(or with multiplication, set m = 1/8, which shows you essentially the same).

So if you want to make this really foolproof, I suggest you add a conversion operator from a Bearing to a float by an interval given by the caller (for example, 0° to 360°or with multiplication, or set -180° to 180°). Multiplication and division should be done only by converting a bearing to a number using this range, then applying the operation, and afterwards converting back to a bearing. That would eliminate every disambiguties.

Body:
This depends on what "mathematically well defined" means. All of your functions are well defined in the sense of having a unique definition. However, multiplication and division are problematic, since they are not guaranteeing

(b * n) * m == b * (n * m)

nor

(b * n) / m == b * (n / m)

where b is a bearing and n is a numeric value, and that is what you might expect. For example, if b = 45° and n = m = 8, you get

(b * n) / m == 360° / 8 == 0° / 8 == 0°

but
    b * (n / m) == 45° * 1 == 45°

(or with multiplication, set m = 1/8, which shows you essentially the same).

So if you want to make this really foolproof, I suggest you add a conversion operator from a Bearing to a float by an interval given by the caller (for example, 0° to 360°or with multiplication, or set -180° to 180°). Multiplication and division should be done only by converting a bearing to a number using this range, then applying the operation, and afterwards converting back to a bearing. That would eliminate every disambiguties.


答:
Books on leadership tend to point to a single overarching quality of leaders:

They do what they say they're going to do.

There's more to it than that, but basically it means people consider someone a leader when that person says, "we're going to do X", and X is a challenge, and then the team or organization, or whatever, ends up pulling it off.  If you do this repeatedly, people will consider you a leader.


答:
Aside from the difference between the interface and the implementation, already explained in the previous answer, there is another important aspect: complexity.

Real-life systems are usually complex. If you start reading through the code of a class, you'll find that you should also go and read the code of another class, then another one, etc. A few hours later, you'll be simply lost in all the complexity and won't remember who calls what and in what cases.

When you use only the comments of the interface, you mitigate all this complexity. It might be that under the hood, everything is simple. Or it might be that under the hood, dozens or hundreds of classes interact each other, making it practically impossible to keep the whole image in your head.

You can do an experiment.

Find a part in OpenCV which interests you. Read through the interface documentation. How long does it take to be able to grasp the basics and effectively use the library?

Now look at the implementation. How many classes are called directly by the interface? How many classes are called by each of those classes? How many lines of code are there? How many methods? How long it would take you to explore all this source code before having a stack overflow in your brain?

Title: Is reading javadoc preferable to reading source code to familiarise yourself with a library?

Body:
I just came across the following in a lab manual at university:

You do need to study the interfaces of the classes by generating the javadoc for them so you know what operations are provided (feel free to look at the code, but
  when using somebody else’s code, as here, you should work from the javadoc rather than the code whenever possible).

I don't understand why this is the case; since the javadoc could be out of date, or could describe the function of the code badly. Surely looking at the source code, and reading the javadoc comments is best?

Is there a reason why, or a case when reading only the javadoc is the best thing to do?


问:
How does a user program access a device?
In Linux, from http://www.mulix.org/lectures/intro_to_linux_device_drivers/intro_linux_device_drivers.pdf

user programs talk with device drivers through device files

But if I understand correctly,

if the device driver is inside the OS kernel, a user program accesses the device, by making system calls to request the OS kernel to act on its behalf. How do the device file and system calls work together then, since they both help the user program to access the device? (Does the device file act both as an id to the device and also as the interface to the device driver?)

If the device driver is outside the OS kernel, does the user program only use the device file to access the device, without system calls?

Thanks.

答:
The user mode program always uses system calls to communicate with the hardware. The device file exists solely so that the program can use well-known, simple, standard system calls to get the job done rather than complicated device-specific ones.

Basically, reading and writing a device file involves exactly the same system calls open(), read(), write()` etc. as reading from a vanilla text file. Since many programmers already know how to do this, this makes controlling a device relatively easy - you only have to know the device node name and the protocol for talking to it, rather than the special verbs for programming your snazzy TV tune card.

With a user-space driver you can in principle allow the user space program to use a more complicated way of talking to the driver, but why would you want to? Device files bring a great reduction in complexity for a moderate loss in expressivity, so they are usually preferred. That way only driver programmers have to delve into the intricacies of the specific card.