问:
Is it better to start a Pull Request or perform a local merge commit on master?
I have been using GitHub for quite some time now and I usually used to push my feature-branches and then start a Pull Request which I myself merged. I found it helped me keep track of where I merged branches.

But recently I have been reading more and more about how Git works and I realised that I can use the merge-commits to refer to when I merged branches.

So, what should I do when merging a feature-branch into master:

Perform a merge-commit on master and then push it upstream OR Push the local branch and start a Pull Request?

I have read Introducing Pull Requests for a 2 person team - merge my own requests? and Whats the work flow with 2 people on a project and Should I open pull requests from a branch on the official repo or my fork? but none of them seem to answer what I am looking for.

答:
git-merge mechanism:

Using git merge feature while on master merges the branch feature to master and produces a merge-commit (if the branch cannot be fast-forwarded) in the git history. To force a merge-commit being made, use the --no-ff option with merge.

Merge Pull Request mechanism:

When we start a Pull Request on GitHub, it creates a GitHub Issue where people can talk and discuss the commits in the PR before merging it. When a PR is merged on GitHub it does the exact same thing as git merge feature.

What should I  do?

So, as far as history is concerned, there is no difference between the two.

And as far as contribution goes, your contributors will not have to do anything different for the two situations. They are the same (minus the nice little chat).

Best Practices:

And I was unable to find a best practices but logic says that PRs are not much helpful if there is only a single contributor to a repository.

@lxrec and @amon helped me reach this conclusion.


问:
Is the strong exception safety guarantee with a pass-by-value argument which can throw on destruction possible?
Suppose you have a type with a throwing destructor, and a function receiving it by value.

Can that operation ever provide anything better than the basic exception guarantee?

Or formulated differently, may one disregard the destruction of the argument which was passed by value when determining whether an operation has commmit-and-rollback-semantics?

```<code>#include <cstdlib>

struct X {
    ~X() noexcept(0) {
        if(rand()%6 == 0) throw 0;
    }
    // some state
};

void update(database db, X arg) noexcept;

X x;
update(db, x);
</code>```

Personally, based on the definition from wikipedia

Strong exception safety, also known as commit or rollback semantics: Operations can fail, but failed operations are guaranteed to have no side effects, so all data retain their original values

I don't think it's useful to describe update as being strongly exception-safe, even though the function itself cannot even throw.

I would appreciate either someone showing me the folly of my current understanding, or giving a better argument.

答:
I'm not really sure in retrospect, but if update was generic or if X was abstract (ex: cloned and destroyed) -- i.e., if update could not know anything concrete about X, then for all practical purposes I'd describe it as having a strong exception-safety guarantee. At the very least that's as close to a strong exception-safety guarantee you'll ever get in an abstract context without x-raying a data type.

However, X is concrete, so that makes this question a lot more fuzzy. I'm still tempted to say that update "has a strong exception safety guarantee" since it is doing everything it can possibly do to enforce it. Does that sound like crazy talk? It does to me, but I can't really put it much better.

Especially in the context of a team environment where one author implements update and the other implements X, nothing could ever provide a strong exception-safety guarantee since X could be modified in ways that breaks the guarantee in ways completely beyond the control of update. For practical purposes, I think if update does everything it possibly can and should to roll back its own side effects in exceptional paths, it practically provides a strong exception safety guarantee.

Otherwise the strong exception safety guarantee becomes something impractical to ever provide in so many scenarios. Things could change outside the function's control. Things could be abstract in ways beyond the function's knowledge. The whole guarantee would be almost impossible to provide anywhere. In that case might we say that the strong exception guarantee of update propagates a responsibility to X to comply, or is it update that is required to know how X will be implemented at all times? I don't know. This is all very impractical either way, and I don't like impracticalities.

So I'm gonna go with the crude, yeah, "update is exception-safe, but X gone fubar and messed up everything. It's not update's fault at least. Don't sue the author of update! Sue the author of X!". I'd like to describe X as simply being fubar here, and update as possibly providing a strong exception safety guarantee which is being screwed by the fact that X is fubar. That is, unless there is a very hard interface-level understanding that X's destructor is designed to throw, in which case I have no idea how to describe it except as a "big problem". I think we need some fine print and disclaimers to come with these guarantees. update provides a strong exception-safety guarantee provided that [...]. No refunds if this is not the case!

This is like a philosophical question to me, interesting to think about but maybe one with no perfect answer. And what are guarantees anyway? Can we guarantee anything? I might guarantee that drinking beer would make me drunk and that could seem true all the time, but what if an extraterrestrial intervenes and uses some kind of alien technology which makes me sober no matter how much I drink? I can't guarantee that this won't happen. I can only say that this is highly improbable and that if such event were to happen, I would be powerless against it. I did my part. I drank my beer. I'm supposed to get drunk. I strongly guarantee it. But it's not for certain. There's always some probability, however astronomically remote, that the guarantee might not hold true. How about thread safety? Well, what if the alien spaceship comes and zaps our hardware and rearranges instructions in memory such that a formely thread-safe function is now no longer thread-safe at runtime? I can't guarantee that this won't happen. But I will guarantee thread-safety regardless without even going into such fine print about alien space ships, because it makes people feel nice and reassured, and what I'm saying is that I'm doing everything within my power and knowledge to enforce that guarantee.

Descartes once said, "I think therefore, I am." How does he know? What if he isn't? He could be an "am not" but perhaps "nots" can "think". I don't even know if I exist. What does thinking even mean anyway? It's like a word people use to describe some process that appears to go on introspectively and appears as though we, who may not even exist, are making decisions.

What if we are all just bits and bytes on some machine? Like that blonde or brunette in the Matrix. By the way, how can a blonde or especially brunette be stored in such a small stream of characters? Are they like UTF2048? It was some kind of alien stream of characters but there didn't appear to be too many unique characters. Perhaps it's some kind of function call. Anyway, I'm not sure we can guarantee anything. It's all relative to what we believe to be true.

ContentLicense: CC BY-SA 3.0


问:
Is 4-5 years the “Midlife Crisis” for a programming career?
I’ve been programming C# professionally for a bit over 4 years now. For the past 4 years I’ve worked for a few small/medium companies ranging from “web/ads agencies”, small industry specific software shops to a small startup. I've been mainly doing "business apps" that involves using high-level programming languages (garbage collected) and my overall experience was that all of the works I’ve done could have been more professional. A lot of the things were done incorrectly (in a rush) mainly due to cost factor that people always wanted something “now” and with the smallest amount of spendable money. I kept on thinking maybe if I could work for a bigger companies or a company that’s better suited for programmers, or somewhere that's got the money and time to really build something longer term and more maintainable I may have enjoyed more in my career. I’ve never had a “mentor” that guided me through my 4 years career. I am pretty much blog / google / self taught programmer other than my bachelor IT degree.

I’ve also observed another issue that most so called “senior” programmer in “my working environment” are really not that senior skill wise. They are “senior” only because they’ve been a long time programmer, but the code they write or the decisions they make are absolutely rubbish! They don't want to learn, they don't want to be better they just want to get paid and do what they've told to do which make sense and most of us are like that. Maybe that’s why they are where they are now. But I don’t want to become like them I want to be better. I’ve run into a mental state that I no longer intend to be a programmer for my future career. I started to think maybe there are better things out there to work on. The more blogs I read, the more “best practices” I’ve tried the more I feel I am drifting away from “my reality”. But I am not a great programmer otherwise I don't think I am where I am now. I think 4-5 years is a stage that can be a step forward career wise or a step out of where you are.

I just wanted to hear what other have to say about what I’ve mentioned above and whether you’ve experienced similar situation in your past programming career and how you dealt with it. Thanks.

答:
I’ve also observed another issue that most so called “senior” programmer in “my working environment” are really not that senior skill wise. They are “senior” only because they’ve been a long time programmer, but the code they write or the decisions they make are absolutely rubbish! They don't want to learn, they don't want to be better they just want to get paid

... followed by ...

I’ve run into a mental state that I no longer intend to be a programmer for my future career. I started to think maybe there are better things out there to work on.

Then it's time to start looking, and to take action. Because if you remain a programmer with this attitude, you will end up just like those "senior" people that you so clearly despise. The operative word is "trapped": you'll make enough money that you can't justify moving to something else, and your skills will be so narrow that you can't move within the industry.

OwnerDisplayName: Jeff

ContentLicense: CC BY-SA 2.5

OwnerDisplayName: kdgregory


问:
All methods in one file/class versus multiple files/classes
This question is mainly talking about PHP, but I think it can be applicable to other languages as well. This is a question about code organization.

I have a friend who insists the best approach regarding organization to PHP programming is to have one file/class with all functions ever written inside it. He says it's simpler like this because he can just do a find on function myFunctionName in order to find a function. I've tried breaking off from this approach and using multiple code files/classes to organize related code like I was taught in school. But I find it takes longer to find functions I'm looking for doing it like this. Is there a point when a project becomes big enough that multiple files becomes better than one file? When is this point?

What's a good argument for separating functions into different files?

答:
Usually, what we split into separate files is classes, not functions.

If your code is not object-oriented, so it consists of a multitude of free-standing functions, (as opposed to a bunch of classes where each function belongs to a specific class,) then it might actually be better to leave all functions in a single source file.

This way, you are clearly indicating to the unsuspecting viewer that this is a terrible lengthy mess of sixties-style function-call-function code that they better steer clear from and not even try to read or comprehend.

Dividing the functions into separate files might create the illusion of a software design, while in fact there is none.


问:
Protect settings on rooted device
I have an app and it stores data in shared preferences which can be easily changed using something like root explorer. So, how can I keep settings and be sure that user won't be able to edit them even with root access? </p>

答:
Not at all. Anything that is stored, transmitted, or processed by a device under another entities control, can be read and modified by that party. This most disturbingly applies to anything done in “the cloud”, but also means any user of your app can technically (though not necessarily legally) disassemble your app, modify any stored data, …. The only way to stop this is to store any data on your servers, but this might have negative privacy implications for your users, as it exposes the user to the same trust problems in you that you have in your users.

One possible half-solution would be to digitally sign the configuration values using public-private cryptography. This allows you to check that data has not been tampered with:

your app changes configuration values. It calculates a secure hash of the config values.

the hash is submitted to your server through a secure channel. The server signs it with their private key and returns a signature.

the new config is stored with the signature on the user device.

when the config is loaded, the hash is calculated. It must match the stored signature when using the known public key of your service.

Failure scenario: an attacker changes the config and signs it with their own key. They also modify the app to use a public key provided by them, rather than the key of your server. Techniques such as certificate pinning won't work because the attacker can modify your app.

So, why shouldn't users modify the configuration? Clearly, that voids any warranty for proper functionality of the app, so most people don't do that. If the security of your service relies on the app not being tampered with, that is bad – for you and for all your users. Anything that must not fall into wrong hands must not leave your hands, so don't give everyone access by putting the secrets on an app store. This is one reason why online services have largely moved away from shared secrets (such as passwords), and instead favour transient secrets (session tokens, one-time use tokens for 2FA or CSRF-prevention) and protocols such as OAuth to allow a limited-trust 3rd party to access a resource on behalf of a resource owner, without the resource owner having to disclose their secrets.

Title: Protect settings on rooted device


答:
Very good question! It is very similar to asking "why use classes?" and the answer is encapsulation.

First I would like to negate the "it makes it easier to search" argument, an IDE makes a big difference!  Even VB6 offers a find in files option (for the project or a folder location).  All IDEs and most text editors have this functionality which is commonly bound to CTRL+SHIFT+F.  Take a look at PHPStorm.

Additional benefits are:

With large projects if you cannot remember the name of something: it's much easier to navigate an organized file system hierarchy than scroll a huge PHP file.

It is also way easier to merge changes with other developers if you were working on separate files! You'll notice other developers are using multiple files - trust me: it's not just because they were told to in school.

Some PHP frameworks require you to work in multiple files.

But probably the biggest benefit is that it encourages you to at least think about the SRP (Single Responsibility Principle).  This is where each class (or even a file in some languages) has a very specific job to do and does only that job.  When you get into a habit of this, your code becomes much easier to read -- especially when you return to it after a long hiatus.  When you name your file (and class) correctly, you immediately get a sense of purpose for the code and this helps you stay on track.

There's nothing wrong with learning in a single file or even starting a project there -- in fact, many languages (eg. Python, TypeScript) encourage fewer files. But once you feel like you're starting to outgrow this, start reading about Patterns and good naming conventions and you'll realize you can code-share between projects which is a lot easier with files than lines of code.

Title: All methods in one file/class versus multiple files/classes

Body:
This question is mainly talking about PHP, but I think it can be applicable to other languages as well. This is a question about code organization.

I have a friend who insists the best approach regarding organization to PHP programming is to have one file/class with all functions ever written inside it. He says it's simpler like this because he can just do a find on function myFunctionName in order to find a function. I've tried breaking off from this approach and using multiple code files/classes to organize related code like I was taught in school. But I find it takes longer to find functions I'm looking for doing it like this. Is there a point when a project becomes big enough that multiple files becomes better than one file? When is this point?

What's a good argument for separating functions into different files?


答: I have worked for large (enterprise) software companies for the past 4-5 years, and as described in the question, have seen a number of solutions just been thrown together without any real thought or design.  I have been fortunate enough to work with some great people, but it does get a bit depressing to see the same mistakes being made time after time. More often than not, the problems are not technical, but are the result of poor management.  </p>

Title: Is 4-5 years the “Midlife Crisis” for a programming career?

Body:
I’ve been programming C# professionally for a bit over 4 years now. For the past 4 years I’ve worked for a few small/medium companies ranging from “web/ads agencies”, small industry specific software shops to a small startup. I've been mainly doing "business apps" that involves using high-level programming languages (garbage collected) and my overall experience was that all of the works I’ve done could have been more professional. A lot of the things were done incorrectly (in a rush) mainly due to cost factor that people always wanted something “now” and with the smallest amount of spendable money. I kept on thinking maybe if I could work for a bigger companies or a company that’s better suited for programmers, or somewhere that's got the money and time to really build something longer term and more maintainable I may have enjoyed more in my career. I’ve never had a “mentor” that guided me through my 4 years career. I am pretty much blog / google / self taught programmer other than my bachelor IT degree.

I’ve also observed another issue that most so called “senior” programmer in “my working environment” are really not that senior skill wise. They are “senior” only because they’ve been a long time programmer, but the code they write or the decisions they make are absolutely rubbish! They don't want to learn, they don't want to be better they just want to get paid and do what they've told to do which make sense and most of us are like that. Maybe that’s why they are where they are now. But I don’t want to become like them I want to be better. I’ve run into a mental state that I no longer intend to be a programmer for my future career. I started to think maybe there are better things out there to work on. The more blogs I read, the more “best practices” I’ve tried the more I feel I am drifting away from “my reality”. But I am not a great programmer otherwise I don't think I am where I am now. I think 4-5 years is a stage that can be a step forward career wise or a step out of where you are.

I just wanted to hear what other have to say about what I’ve mentioned above and whether you’ve experienced similar situation in your past programming career and how you dealt with it. Thanks.

OwnerDisplayName: MagicAndi


问:
Clarification on dispose method
If I wrap in a class an object that has the dispose method I'll need to implement the dispose method in the class too?

For example I have a class which wraps an instance of SQLiteConnection, should I need to implement the dispose method to call the SQLiteConnection one?

答:
I have a class which wraps an instance of SQLiteConnection, should I need to implement the dispose method to call the SQLiteConnection one?

Nope.  Just wrap your SQLiteConnection instantiation in a using statement.

```<code>using (connection = new SQLiteConnection())
{
    // use `connection` here
    // ...
} // `connection` is disposed here.
</code>```

Because SQLiteConnection implements IDisposable, the connection object is automatically disposed when the using block goes out of scope (at the ending brace of the using statement).

If you are inheriting from SQLiteConnection, then inherit also from IDisposable and implement the Dispose() method, which will do any local cleanup that's needed in your descendant class and then call Dispose() on the parent SQLiteConnection class.

Further Reading

Using Statement (C# Reference)

Title: Clarification on dispose method

Body:
I have a class which wraps an instance of SQLiteConnection, should I need to implement the dispose method to call the SQLiteConnection one?

Nope.  Just wrap your SQLiteConnection instantiation in a using statement.

using (connection = new SQLiteConnection())
{
    // use `connection` here
    // ...
} // `connection` is disposed here.

Because SQLiteConnection implements IDisposable, the connection object is automatically disposed when the using block goes out of scope (at the ending brace of the using statement).

If you are inheriting from SQLiteConnection, then inherit also from IDisposable and implement the Dispose() method, which will do any local cleanup that's needed in your descendant class and then call Dispose() on the parent SQLiteConnection class.

Further Reading

Using Statement (C# Reference)


答:
For example I have a class which wraps an instance of SQLiteConnection, should I need to implement the dispose method to call the SQLiteConnection one?

Yes.

If you have MySQLiteConnection which makes/opens a SQLiteConnection it will not automatically dispose of that member on garbage collection. You need to explicitly mark your wrapper as IDisposable and call the member SQLiteConnection::Dispose.

If you're just using the SQLiteConnection in the class, or you have a reference to one (but don't open/own it), the Robert Harvey's answer is correct - just use it as you would anywhere else.

Title: Clarification on dispose method

Body:
If I wrap in a class an object that has the dispose method I'll need to implement the dispose method in the class too?

For example I have a class which wraps an instance of SQLiteConnection, should I need to implement the dispose method to call the SQLiteConnection one?


问:
Is it possible to not have a zero-indexed array with javascript?
I've been coming across some interview questions that mention within the question "... given an integer x and a zero-indexed array..." Is it necessary to mention zero-indexed array? What languages support non-zero-indexed arrays? Is it possible with javascript?</p>

答:
An array in Javascript can be sparse where only some elements exist and the first element that exists does not have to be at index 0.  But, the .length property is always measured from index 0.

```<code>var array = [];
array[3] = "Hello";
array[9] = "Goodbye";

console.log(array.length);    // 10
console.log(array);           // [3: "Hello", 9: "Goodbye"]
console.log(array[0]);        // undefined
</code>```

Is it necessary to mention zero-indexed array?

It's not really necessary in Javascript since that is the default expectation, but does confirm that whatever values you are expecting in the array will start at the 0 index.

Body:
An array in Javascript can be sparse where only some elements exist and the first element that exists does not have to be at index 0.  But, the .length property is always measured from index 0.

var array = [];
array[3] = "Hello";
array[9] = "Goodbye";

console.log(array.length);    // 10
console.log(array);           // [3: "Hello", 9: "Goodbye"]
console.log(array[0]);        // undefined

Is it necessary to mention zero-indexed array?

It's not really necessary in Javascript since that is the default expectation, but does confirm that whatever values you are expecting in the array will start at the 0 index.


答: looks like its time to start dealing drugs.</p>

OwnerDisplayName: gweg


问:
How can I decouple query and context in a "query object" scenario?
I'm using a query object pattern (similar to this) to manage disparate queries while avoiding bloaded facades/repositories.

A query object takes a number of constructor parameters, representing query arguments. The query is then passed to an IQueryHandler by the caller, into which is injected the IDataContext. The IDataContext is then passed into an Execute method of the IQuery.

The thing I don't like is this:

```<code>public interface IQuery<TResult>
{
    public TResult Execute(IDataContext context);
}
</code>```

Because the IDataContext is passed into the method and thus explicitly declared in the interface, there is no option to have a query that fetches things via a different mechanism - IQuery is coupled to whatever defines the IDataContext interface. Suppose, for example, I want to switch from an SQL DB store to a document DB.

I've tried a couple of alternatives, but neither quite gets me where I want to be.

The first is to inject the data context into the query's constructor and use a factory to generate the query objects. This successfully decouples the interfaces, but now working with the queries is more cumbersome. Instead of using the constructor/object initializer to set up the query, callers have to do something like this:

```<code>var query = _queryFactory.Create<PersonQuery, Person>(); // Second type argument can't be inferred from first due to limitations in generic type inference.
query.Name = "Bob";
query.Age = 32;

var result = query.Execute();
</code>```

The second is to abstract the execution of the query - and thus the dependency on IDataContext - to a handler class, then have another class that resolves a handler for each query, which again abstracts the dependency away from any interfaces:

```<code>public class ISomeQueryHandler : IQueryHandler<SomeQuery, SomeQueryResult>
{
    private readonly IDataContext _context = ...;

    public SomeQueryResult Execute(SomeQuery query) { ... }
}
</code>```

I don't like this option because it means every new query involves writing two classes, which, again, is cumbersome and increases the potential for a query to exist with no way of handling it (it also involves an empty marker interface for queries since the Execute method is moved to the handler, which always feels off). It also involves some rather funky convention-based dependency resolution to get the right handler for each query.

Creating an abstraction over IDataContext is not really feasible due to its complexity.

Is there a happy medium I haven't seen?

答:
Suppose, for example, I want to switch from an SQL DB store to a document DB.

No, you are not. Possibility of that happening is extremely slim and even if you account for this, you are going to change your model, because the relational modelling is probably leaking into it.

But if I had to do this, I would separate Execution from Initialization of the query.

First I would create interfaces :

```<code>public interface IQuery<TResult>
{
    TResult Execute();
}

public interface ISqlQuery
{
   void SetContext(IDataContext context);
}
</code>```

Then, query can implement both if it needs SQL context.

Then, in handler, duck-type check if query implements specific interface and if yes, execute it. This interface is query saying "I need this service, someone provide it". And handlers tries to provide it.

```<code>public class Handler
{
    public TResult Execute<TResult>(IQuery<TResult> query)
    {
        if (query is ISqlQuery)
        {
            (query as ISqlQuery).SetContext(_datacontext);
        }

        return query.Execute();
    }
}
</code>```

This has two advantages. First, different queries might go to different data stores. Second, queries can have multiple data sources simply by implementing multiple interfaces. So query can access DB, external service and maybe something else all the same time.

Body:
Suppose, for example, I want to switch from an SQL DB store to a document DB.

No, you are not. Possibility of that happening is extremely slim and even if you account for this, you are going to change your model, because the relational modelling is probably leaking into it.

But if I had to do this, I would separate Execution from Initialization of the query.

First I would create interfaces :

public interface IQuery<TResult>
{
    TResult Execute();
}

public interface ISqlQuery
{
   void SetContext(IDataContext context);
}

Then, query can implement both if it needs SQL context.

Then, in handler, duck-type check if query implements specific interface and if yes, execute it. This interface is query saying "I need this service, someone provide it". And handlers tries to provide it.

public class Handler
{
    public TResult Execute<TResult>(IQuery<TResult> query)
    {
        if (query is ISqlQuery)
        {
            (query as ISqlQuery).SetContext(_datacontext);
        }

        return query.Execute();
    }
}

This has two advantages. First, different queries might go to different data stores. Second, queries can have multiple data sources simply by implementing multiple interfaces. So query can access DB, external service and maybe something else all the same time.


答: There is a difference between 10 years experience and one years experience 10 times.</p>

OwnerDisplayName: PurplePilot


问:
Could there by any issues with transition from MIT to Apache License?
I've started my own open source project, which is still in an early phase of development. I chose to use the MIT license for it.

However, I've read that the Apache license is better for large projects, and it's going to become a large project later. So, I plan to study the Apache license later, and consider it for my project when the project becomes stable.

Could transitioning from the MIT to the Apache license create any legal issues? Does a late transition involve any more risks?

Disclaimer: I'm a programmer, not a lawyer.

答:
The owner, or copyright holder of the project is the one who gets to decide what license to use on each distribution of that project. The owner is completely free to use different licenses on different distributions.

The tricky points to keep in mind are:

1) If others contribute to the project, then you are no longer the sole owner, so changing the license would have to involve getting multiple people together to agree on it. If you're going the typical open source route of allowing pull requests from pretty much anyone, this can be a problem.

2) The copies of the project that you have already distributed cannot have their licenses retroactively changed. The change can only apply to new distributions. In particular, anyone who has received old copies of the project under MIT is perfectly free to distribute copies of their copy under any license they please (since the MIT license imposes no restrictions on this behavior).

3) Some people have strong opinions on licensing issues, and some people get understandably nervous when licenses change. So if you do have a non-trivial user base when you make this change, then you should post a very clear and specific explanation of why you want to make this change, solely for PR reasons. In particular, at the risk of taking your question too literally, you should have a more specific reason than "because Apache is better for big projects and we are big now".

Note that I am using the term "distribution" instead of "version" because it is fairly commonplace to release the same version of a program under multiple licenses, for various reasons. For instance, you may release a program for free under a copyleft license, while at the same time allowing corporations to purchase a version with a more permissive or closed source license. The version the corporations purchase would simply have different LICENSE, COPYRIGHT and/or README files.

But in all honesty, MIT to Apache is not a huge change. It should be a perfectly harmless transition as long as you're aware of these potential issues ahead of time.


问:
Include exceptions in activity diagrams?
Should I include exceptions, like a TimeOutException or just general Exceptions, to a activity diagram?

For example: A activity diagram describing a client-server connection. Several exceptions can be thrown and in my software I use the Enterprise Library to handle/log it. Should I include the exception handling and if so how?
I already documented the connection between excpetion handling and the rest using component diagrams.

答:
I would include them when the exception affects the users actions. Ie. If the timeout causes the user to have to re-login.

I think you have another underlying question though. "How detailed should my activity diagrams be?" Which is much harder to answer.

On one hand you can virtualy write the code in UML and cover all the edge cases. But on the other, the usefulness of these diagrams over the raw code is that they are supposed to be easy to read and understand. If you put too much on them that goal is degraded


问:
PHP framework advice needed
I started PHP programming around 2002, when there were not that many frameworks around. Over the years, I developed my own PHP framework, which seems to be entirely different from any standard I come across.

I'll try to describe the framework that I created:

Basically it's an engine that builds an entire web-application, by converting template-files into HTML-files. An application typically consists of template-files for each different page in the application and some custom CSS / JS-files for things that are not (yet) in the engine. User-interaction is done with standard PHP-scripts in the framework that can handle all kinds of operations (select, create, update, view, delete, sending e-mails, export as PDF or Excel, etc.). The engine automatically knows which scripts should be used and all variables needed for these scripts to work are sent by Javascript using Ajax, including the operation-type and all needed form values. JSON or an URL to the created PDF or Excel-file is then sent back to the client.

The templates can contain clientside HTML, CSS and Javascript and serverside SQL, but most important are custom xml-tags that are interpreted by PHP and, depending on the attributes, converted into (multiple) HTML-tags, CSS and Javascript-code. There are a lot of different standard PHP-classes for custom tags that can output visual things, like buttons, datagrids, forms, etc. but the tags and attributes are also used for database-stuff, sessions, clientside updates using Ajax/jQuery, producing PDFs, sending e-mails, etc. The engine can use all kinds of libraries, like jQuery UI, Cordova, Bootstrap, PHPExcel, mPDF, etc. and automatically knows which JS and CSS-files to include in the outputted file. It can also cache the HTML, build the application and minify the JS and CSS.

This way I have no specific classes for anything that is in the application or database (e.g. Accounts or Invoices). When my data-model changes I only have to update the templates, and no PHP-code at all.

Every framework I'm trying out (e.g. Phalcon, CakePHP and Laravel) seems to require to define the business-logic, data-model and all interactions in specific PHP-classes (e.g. Account or Invoice). So when a field is added to a database-table, you need to add a property to its corresponding class. But of course also change the view-templates and interaction-controllers. And for every table in the database different model and controller files are needed. I think this is quite complex and time consuming, compared to my solution (some of my applications use 100+ different database tables).

The downside of my approach is that maintaining the standard-classes in the framework takes a lot of work. Especially because in different applications the same classes need to be able to behave a bit different, so every class has lots of properties to control all this. This way the engine has become very powerful, but also quite slow, complex and difficult to maintain. I realize that my solution doesn't really separate the code and design, but since I build mostly database web-applications, this is not really necessary for me. The way things look can be manipulated enough using some custom CSS.

So, where to go from here now? I really love my framework, but would like to comply more with web-standards to be able to hire external developers a bit easier. But since my framework is quite different from anything else, I have no idea which framework to choose.

My questions are :

What do you think of my 'web-application-engine' that mostly uses
templates only? Does anybody else do this?

Which existing framework
could be used to complement my own framework, rather than entirely
change the way I work now?

答:
PHP is a simple language by nature. It has many useful libraries but no built-in web framework unlike others such as C# and ASP.NET framework.

Therefore you need to use frameworks:

If you decide to write your own framework you will need strong understanding of design and structural patterns. If not it will be a challenge to maintain or modify the code.

If you use a known framework like one of the ones you have cited, the framework will be already written and well tested by tons of developers.

Remember PHP was itself written by its author to help him solve his own problems. This is how most frameworks got started. If your framework solves a problem that other frameworks can't then it might be worth it, you will also learn from doing it, otherwise you are reinventing the wheel.

Personally, when I first started programming I was anti-framework, writing my own helper classes. With the customers' ever changing needs, my elegant code eventually turned into nasty spaghetti code. I remember one time my boss asked me to remove a check Box from a page and when I removed it, it caused my half-baked web framework to crash during a demo. I learned from this that the MVC pattern would have avoided this issue. I since then use well known and tested frameworks to save time spent by other developers that I cannot afford to waste.

From your post it sounds like you are already facing issues with writing your own framework, that is the trade off, it seems to make things easy at first but then it's hard to modify. On the other hand other frameworks would seem like an overhead but in the long run it makes your application tighter.

You can choose any of these popular frameworks to achieve your task. The advantage of using Models and properties is that your views will be strongly typed which is much safer.

Title: PHP framework advice needed


答: This question describes pretty well the sad state of our industry: programming is awesome but most programming jobs sucks.

OwnerDisplayName: Mr. Brownstone


问:
What is "recorded" relationship in a class diagram?

Composite aggregates Part, Container contains Content, and Recorder records. Recorded are all very common relationships between classes in a class diagram. Creator suggests that the enclosing container or recorder class is a good candidate for the responsibility of creating the thing contained or recorded. Of course, this is only a guideline.

From the book: http://authors.phptr.com/larman/uml_ooad/index.html

What is this recorder? Any example would be appreciated.

答:
I'm not well-versed in the GRASP object-oriented design methodology, but I read through the Wikipedia article as well a some slide decks (1, 2) about the approach. This is my understanding.

One of the "patterns" in GRASP is the Creator Pattern. This isn't a design pattern in the sense of the Gang of Four patterns or Fowler's Patterns of Enterprise Architecture and so on. It's more of a principle or pattern. GRASP focuses on how you determine the responsibilities of a particular class in your object-oriented system.

A class that is a Creator means that it builds instances of other classes. There are different contexts for creation. In a composition or aggregation relationship, the parent may be responsible for creating the parts. In classes that record data, the class that records the data (for example, reading data from files or from user input or from databases) may be responsible for creating domain elements.

What this quoted paragraph is saying is, to the best of my knowledge, if you have a class that contains elements or records data, than you can consider having that class create the objects that represent its elements or data that is recorded.

Note that this is just guidance, though. Something to consider when working through your design. It's not a rule that must always be applied.


问:
Does a C# event have to have an object type as its first parameter?
I have a TCPClient class. It has several ClientEvents. Originally it followed the standard pattern

public delegate void ClientEvent(object sender, ClientEventArgs e);

Only TCPCLient uses this event. But I am pretty determined to keep things as standard as possible (all event based things I've seen use object sender). However what I don't see the point of, is having to cast sender to TCPClient every time.

```<code> private static void Client_OnReconnect(object sender, ClientEventArgs e) {
            TCPClient client = (TCPClient)sender;
        }
</code>```

Is there any reason I shouldn't just use

public delegate void ClientEvent(TCPClient client, ClientEventArgs e);

as my event?

答: The sender parameter is so that the callback can recognize the object that's invoking it.  In some situations, that's useful to know.  If you don't need that, though, then you don't need it, and there's no technical, language-level or framework-level reason why you necessarily have to use it.


答:
As Ashhar said, technically and history-wise there's no difference. For projects with a small team I prefer merging directly instead of the extra step of creating a PR. However, when a feature needs review/feedback or when it's a WIP and more than one person will be working on it I tend to open a PR and add a list of tasks to the PR's description.

Note that git merge might use fast-forward if there are no changes to master, so you might want to use git merge --no-ff. I tend not to.

So in summary, only use PRs when you need discussion. Otherwise just merge directly.

Title: Is it better to start a Pull Request or perform a local merge commit on master?

Body:
I have been using GitHub for quite some time now and I usually used to push my feature-branches and then start a Pull Request which I myself merged. I found it helped me keep track of where I merged branches.

But recently I have been reading more and more about how Git works and I realised that I can use the merge-commits to refer to when I merged branches.

So, what should I do when merging a feature-branch into master:

Perform a merge-commit on master and then push it upstream OR Push the local branch and start a Pull Request?

I have read Introducing Pull Requests for a 2 person team - merge my own requests? and Whats the work flow with 2 people on a project and Should I open pull requests from a branch on the official repo or my fork? but none of them seem to answer what I am looking for.


答:
Speaking for myself, there is a cycle. When I started professionally developing I was excited, eager and had a great time working through every new problem.  After a few years, I wound up traveling for a company for several months.  I wasn't really prepared for the amount of travel required and wound up moving on.  The next company I worked for had a problem with being too big and not having a clear focus.  There was never a clear intent or business reason for the coding I was doing.  As a result, it was mostly filling time.

After that, I became a consultant and found things aren't really that much different from FTE work.  I've typically been on multi-year assignments where eventually it just becomes a job.  As others have said, you wind up doing lots of evil things to get the job done and get mired in the technology you're using, as opposed to new and interesting things.  I spent several years where I didn't really care about the technology. I've seen cycle enough times now that I know that if you ignore a round or two, you won't really doom yourself... but it does take quite a bit of effort to get back on the bandwagon and catch up with the important changes.  Last time I had an interview, Unit Testing and MVC didn't really exist in the .NET space and patterns were barely spoken of in the .NET community.

I find the best determinant of if I'm "doing it right" is if I'm coding on my own on the weekends and evenings. If so, then I'm passionate about the technology, interested and learning.  If not, my job probably has me on the road too much or has me doing the same thing over and over and I've lost interest... in which case, it's probably time to move on.

Remember: Your boss is in charge of your job, you are in charge of your career.  (Blatantly stolen from Brian Prince's great talk on being a better developer)

OwnerDisplayName: Ben Von Handorf


问:
Terminology: abstraction vs models
I'm building a model of the SQL query language.

It doesn't attempt to abstract SQL at all - instead, it tries to model it directly, so it has model objects named Query, Table, Column, Variable, Expression, Join, etc.

Contrast this with an object/relational mapper, which tries to abstract away SQL and the DBMS in favor of some new/different and (usually) higher-level abstractions.

My question is regarding the terminology to describe what I'm writing: generally, is a model always an abstraction? Is an abstraction always a model? Are they synonymous, more or less?

Specifically, is a model of SQL also an abstraction, or is it correct to describe it as just a model?

答:
This is highly philosophical, but:

A model is definitely an abstraction if it is trying to represent real-world entities, in which case, of course you cannot have cars, trees, houses etc. living inside the computer, so obviously, you are abstracting.

But if the model is not trying to represent a real-world entity, and instead it is a one-to-one mapping to already abstract entities, then I think it can safely be called a model, without the need to add the "abstraction" part.

However, the reasons to go one way or the other are trifling.

Title: Terminology: abstraction vs models


问:
Acceptable design to use public member objects in composition?
Say I have a large class called Root, which has a lot of members & functions:

```<code>class Root {
public:
    void func1(); // operates on a and b
    void func2();
    ...
private:
    A a;
    B b;
    C c;
    ...
};
</code>```

The class Root is getting a bit big so I decide to factor out a few of the member variables and a function into another class:

```<code>class AB {
public:
    void func1();
    ...
private:
    A a;
    B b;
};
</code>```

Then using composition I can make AB ab a member variable of Root. Root is now a bit smaller / cleaner / more manageable. The question is about the access level of ab after this composition refactor.

Is it OK in this case for ab to be a public member? Any downsides? Public members are generally considered bad design from what I've read. But here the overall encapsulation / exposure hasn't actually changed...the objects a and b are private within AB so are still hidden from the outside.

(Sidenote: the reason why I would like to make ab public is that it allows easier traversing of Root's composition hierarchy. For example in Root's member c I might want to call func1:

```<code>void C::foo(Root& root) {
    //do some stuff
    root.ab.func1();
}
</code>```

If ab was private then I'd have to define a pass-through function in root.)

答:
From both an academic and a technical point of view, it is not okay.

From an academic point of view, you are violating the principle of encapsulation.

From a technical point of view, if you need to do any further refactoring in the future, you will have a lot of work to do.

That having been said, there is also a practical point of view, which boils down to this: if your IDE gives you the ability to refactor ab from public to private, adding all necessary accessors and replacing all references to root.ab with invocations of these accessors all over your entire code base, and if it can do that with just a couple of clicks and keystrokes, you are fine.  If not, you are better off not doing it.

It is not clear to me what you mean by sub-object c, but if you mean a subclass, then consider making ab protected.  This way, c will be able to access it, but no outside code will.


答:
I've felt the same way for a while. I'm in a large, corporate IT shop, and I'm seeing the same sort of thing; the seniors are mostly stagnant and resistant to change, and that resistance is so ingrained that we can't even get away with streamlining the user interfaces for our software, instead ending up cloning the original almost exactly.

It doesn't help that the original software is mostly terrible; the designs overly complex, very inefficient, and equally error prone... yet the management forces us to make many of the same architectural decisions.

So I'm working on transitioning to freelance...

OwnerDisplayName: Rakesh Malik


问:
Does Time Complexity analysis factor for cache performance of an algorithm?
If I have an algorithm A. and it has fewer instructions than algorithm B. but performs worse on a CPU due to poor memory coalescing (and hence, poor CPU cache performance), does that factor into the Time Complexity analysis - given that, CPUs can have different wildly different cache implementations (or no cache) such that a algorithm's effectiveness can only be adequately judged on a single given CPU?

If you don't understand the issue in question, please watch Mike Acton's CPPCon speech on youtube ("Data Oriented Design").

答:
Time Complexity (Big-O notation) does not measure performance of an algorithm. Instead, it categorizes how an algorithm's resource use scales with input size. This allows us to compare two algorithms with a judgement such as “for some sufficiently big input, algorithm A will always be faster than algorithm B”. We can do this judgement without even considering concrete implementations of the algorithms. As such, Big-O is not concerned about implementation details such as caching.

However, we do assume certain implementation details when calculating Big-O. E.g. it is common to assume that each memory access has constant cost. This clearly does not hold in an environment where lookups are actually O(n) (e.g. when memory is represented as a linked list). If you want to be very precise when calculating Big-O, we must draw up a cost model that assigns a concrete cost for each operation, though this may be expressed in terms of some undetermined constants. E.g. we usually assume that a memory load has concrete running time T(n) = c for some constant c. This constant will be eliminated when simplifying to Big-O. Incidentally, caching does not change the constant-time guarantee – as long as there is some fixed upper bound for an operation, it can be considered constant. Here, this would be the cost of a read with cache miss.

This also means that Big-O is not suitable for comparing real-world performance of algorithms with known workloads. Two algorithms might be in the same complexity class, but one may outperform the other by a consistent factor of 1000. Or one algorithm might have spectacular linear complexity, but requires so much pre-processing that even an exponential algorithm is faster in practice (real example: many regex engines).


答:
Time complexity is a mathematical concept that applies to a model of computation. Normally, we apply it to Turing machines, which have nothing like a cache, so most normal time complexity results are effectively assuming there are no caches.

But you can use more complex models if you want. I'm not aware of any mathematical models in common use that go as far as mimicking CPU caches, but there are certainly "register machines" that have a mathematically precise definition but unlike Turing machines have registers separate from main memory. They've been proven mathematically equivalent to Turing machines in terms of decideability, i.e. what computations they can perform, but they differ in the time complexities with which they execute those computations.

I suspect that the time complexities of a register machine will be somewhat closer to the "real-world time complexities" you get when CPU caching is involved, as registers are arguably the most primitive form of CPU caching. But how true that is will depend highly on the details of the model you choose. Figuring out what mathematical model best simulates your real-world computations is the sort of thing academic researchers are still working on.

Title: Does Time Complexity analysis factor for cache performance of an algorithm?

Body:
If I have an algorithm A. and it has fewer instructions than algorithm B. but performs worse on a CPU due to poor memory coalescing (and hence, poor CPU cache performance), does that factor into the Time Complexity analysis - given that, CPUs can have different wildly different cache implementations (or no cache) such that a algorithm's effectiveness can only be adequately judged on a single given CPU?

If you don't understand the issue in question, please watch Mike Acton's CPPCon speech on youtube ("Data Oriented Design").


答:
:-) I assure you, the law of code to market go's as follows:

Larger the corporation the least time to market you have, project timelines keep getting smaller and competition to get your product out quickest makes for almost zero time to write the "perfect" solution if there ever was such a thing.

In my personal experience, some 8+ years development in large corporations, smaller businesses and then medium scale enterprises - the projects I was able to focus the most amount of time and polishing was the SMME (small guys) - Sure cost comes into play but don't sell yourself out either!

As a developer stand up for realistic timeframes, have a game plan that allows enough time for some polish which will make you feel better about what you've delivered. Failing to plan is like planning to fail, a term coined by many to date.

Best of luck with your future plans / career.

OwnerDisplayName: Microdot


问:
SDK/DB isDeleted vs Integration Testing
((Using "users" as an example to represent one of many record types))

An application with user tracking typically has a User table.  Many, if not all, companies mandate that a User record should never be actually deleted.  Instead, a discrimating field "isDeleted" should be added.  The other possibility is a shadow table that tracks deleted users and its own set of questions which shouldn't be addressed here.

So in general, to retrieve a list of users, I may have a method like so:

public ICollection<User> GetUsers() {
    return Users.Where(x => x.isDeleted == false);
}
```

<p>So I have an SDK which wraps a web service which call domain services which depend on data access which hits my database.  The eventuallity is something like so:</p>

<pre class="lang-cs prettyprint-override"><code>public void DeleteUser(int id) {
    var user = Users.Where(x => x.id == id).Single();
    user.isDeleted = true;
    user.SaveDatShiz();
}
</code>```

So what about my Integration Test?  I have an Integration Test something like so:

public void TestUserCreation() {
    Dependency.CreateUser(user);
    var integratedUser = Dependency.GetUserBySomething(user.Something);
    Assert.AreEqual(integratedUser, user, "wut?");
    Dependency.DeleteUser(integratedUser.id); //Clean up!
}
```

The key above is that my Integration Test thinks it is cleaning up, but in reality, my Production Database has three times more fake test users than actual users.  The table is SUPER bloated from running Integration Tests on Deployment in a Continuous Deployment environment.

So how do I let my Integration Tests ACTUALLY Delete a user?  I'm not asking for a code answer, I'm asking for a architecturally correct answer.

E.G.: Should I create an endpoint that actually does a delete, but require a key that only the Integration Test knows?  That seems messy...

E.G.2: Should I get access directly to the production database and run delete queries against it?  (Lol, totally lawl no.)

E.G.3: Nobody else worries about this, so I shouldn't (Non-Refundable!!! I mean.. Not Acceptable!!!!)

答:
In cases like described here, I usually set up (or use) a dedicated integration testing environment. In that environment, the test script / test code has full and direct database access, and can do whatever it likes to the database, including creating/deleting stuff as it pleases. Ideally, the DB is an embedded DB, which is spun up explicitly for the test. If that is not enough, you need some type of "real" DB, but with modern virtualization technologies like Docker even that is feasible.

Now, this may sound like "cheating" - a test that directly messes with the DB. However, to be able to test a system thoroughly, you must be able to reproduce arbitrary system state. This includes state that you cannot produce through regular API calls, such as:

massive amounts of data that would take forever using the API

invalid data, maybe to simulate some DB bug, or a bug in an older version of your software

old data - for example, testing expiration of records older than a year

and, last not least, an empty DB to have a clean slate for the next test - which is the problem from the question

For thorough testing, the test code needs direct, full DB access - anything else will bite you at some point.

Title: SDK/DB isDeleted vs Integration Testing


答:
If class C wants to call func1() then pass the ab object to C's foo function instead of passing the root object. This better describes what is going on to other programmers and future you. It tells you that C does't need all of Root to do its job, it only needs AB (and it could conceivably get an AB from some source other than Root.)

```<code>void C::foo(AB& ab) {
    //do some stuff
    ab.func1();
}
</code>```

If I were you, I would also go through and change any other class that is accessing Root merely to call AB's func1() (and whatever other functions you move into the AB class.

Do this with an eye toward breaking up Root in other ways as well. If it is very large like you say, then there are likely lots of little classes trying to get out...

Title: Acceptable design to use public member objects in composition?

Body:
Say I have a large class called Root, which has a lot of members & functions:

```<code>class Root {
public:
    void func1(); // operates on a and b
    void func2();
    ...
private:
    A a;
    B b;
    C c;
    ...
};
</code>```

The class Root is getting a bit big so I decide to factor out a few of the member variables and a function into another class:

```<code>class AB {
public:
    void func1();
    ...
private:
    A a;
    B b;
};
</code>```

Then using composition I can make AB ab a member variable of Root. Root is now a bit smaller / cleaner / more manageable. The question is about the access level of ab after this composition refactor.

Is it OK in this case for ab to be a public member? Any downsides? Public members are generally considered bad design from what I've read. But here the overall encapsulation / exposure hasn't actually changed...the objects a and b are private within AB so are still hidden from the outside.

(Sidenote: the reason why I would like to make ab public is that it allows easier traversing of Root's composition hierarchy. For example in Root's member c I might want to call func1:

```<code>void C::foo(Root& root) {
    //do some stuff
    root.ab.func1();
}
</code>```

If ab was private then I'd have to define a pass-through function in root.)

Body:
If class C wants to call func1() then pass the ab object to C's foo function instead of passing the root object. This better describes what is going on to other programmers and future you. It tells you that C does't need all of Root to do its job, it only needs AB (and it could conceivably get an AB from some source other than Root.)

void C::foo(AB& ab) {
    //do some stuff
    ab.func1();
}

If I were you, I would also go through and change any other class that is accessing Root merely to call AB's func1() (and whatever other functions you move into the AB class.

Do this with an eye toward breaking up Root in other ways as well. If it is very large like you say, then there are likely lots of little classes trying to get out...


问:
Isn't the use of pointer variables a memory overhead?
In languages like C and C++, while using pointers to variables we need one more memory location to store that address. So isn't this a memory overhead? How is this compensated? Are pointers used in time critical low memory applications? </p>

答:
So isn't this a memory overhead?

Sure, an extra address (generally 4/8 bytes depending on processor).

How is this compensated?

It is not. If you need the indirection necessary for pointers, then you get to pay for it.

Are pointers used in time critical low memory applications?

I haven't done much work there, but I would assume so. Pointer access is an elementary aspect of assembly programming. It takes trivial amounts of memory and pointer operations are speedy - even in the context of these sorts of applications.


答:
Interesting post.  I'm midway through my fourth year professionally doing .net development.  I'm really unhappy with my current job (I am looking but so far there hasn't been much to say on that front).

I had a teacher who once went absurdly out of his way to stress documenting everything.  I don't mean code, I mean "everything".  And he said it probably still wouldn't be enough.  Well, there's a difference between knowing a thing and understanding it and I've come to understand it, and he's right.  There's never enough.  I fail to documnt but bring up a recent conversation, I lose.  I document, I get told I misunderstood something.  I have taken a long, hard look at myself through all of this, and I think some of my own faults are definately at work.  But communication is a two way street, and I am not always the one who fucks up.  It's even worse when I suggest things or address problems, these get blown off at the time, and then come up later.  I sat dumbfounded in the VP's office recently as he and my boss asked why I hadn't done something on a particular page on our most recently released app.  And yet I'd asked about doing that thing during development and was shot down.  Stuff like this is happening far too often for my tastes.

Learning/keeping up on your skills/etc is dicussed sometimes, but we don't do it.  We have opportunitues to do this at work and we still don't do it.  Very disappointing.  I don't expect us to jump on the latest and newest tech/tool every time one appears.  But e.g. we should be doing .net 3.5 development.  There is no argument for not doing 3.5 development.  But we're still doing 2.0 development.  It's stupid.  It's mostly good that my boss is distrustful of new things, but it's gotten silly.  I tried explaining LINQ to him recently (when arguing for moving to 3.5) and his response was "it sounds like that english language query stuff". I realize part of the problem was me doing a poor job explaining LINQ.   But going back to the two way street of communication, that was someone on the other end who didn't want to listen.  I don't expect the company to make mentoring me it's top priority.  But my group (just 3 developers) could do more to foster learning.

My group's standing in the company has improved somewhat in the last year and a half.  But we still have some problems.  Our VP is largely responsible for this.  It's frustrating, but I could live with this if certain other aspects of the job were more fulfilling.

Ironspeed Designer - god I hate you.  And the thing is, I understand why a code generator can be helpful.  I have wanted code generators for certain tasks at times in my life.  We seem to be becoming an Ironspeed driven group, though. I do not like this, since it will severly hamper my ability to grow on the job.

I care about the craft of software development and programming, even though I'm deficient at both.  I do not work with people who care about the craft of software development/programming.  No code reviews.  I often can't get help testing things (and then can't get users to test though things have gotten better there in the last year. . . and then get yelled at if a bug makes its way into production on a release.  I'm one man.  I can only do so much).

So I try to learn on my own (I'd do better around someone who is interested in seeing me learn, though).  I go through phases where I like to program outside of work, and phases where I can't stand it.  We just recently got done with a particularly hectic project that saw me put in significant overtime, and so I haven't done any real learning off the job in about 6 weeks. But I'll slip back into it and re-read Skeet's C# in Depth, and do some more playing around with MVC. . .

I have battled a lot of doubts (self confidence has never been one of my strong points anyway) in the last year and a half.  I wouldn't call it a crisis.  I soldier on because I do like doing this.  Even working at a crappy job.

OwnerDisplayName: peacedog


问:
ng-model for status picklist
I am the beginner to AngularJs. Finding difficult to understand the concept of ng-model.

I have a controller with $scope.statusPickList=["Planning" "Execution" "Closed"];

How this has to be used in the template(html file) in the < Select> statement? Can anyone please help me to understand?

I am trying the below < Select> statement but not getting the picklist entries.

```<code>< Select type="text" class="form-control" ng-model="statusPickList"
        ng-options="val as val for val in statusPickList">
 < /select>
</code>```

答:
Your ng-model should not be the same as your select data source (statusPickList). It represents the selected value, not the source. Also, your select HTML and JavaScript is not valid as listed. Here's a minimal modified example using your code:

```<code><!-- HTML -->
<div ng-app="app">
  <div ng-controller="ctrl">
    <select ng-model="selectedItem" ng-options="val for val in statusPickList">
    </select>
    <div>
      selectedItem = {{selectedItem}}
    </div>
  </div>
</div>

// JavaScript
angular.module('app', [])
.controller('ctrl', function($scope) {
    $scope.statusPickList = ["Planning", "Execution", "Closed"];
    $scope.selectedItem = "[not selected]";
});
</code>```

Running live: https://jsfiddle.net/yg1tvxcf/5/

In my example, selectedItem is simply a string value on $scope that stores whatever is selected in your select.

More details at the Angular documentation: Using select with ngOptions and setting a default value.

Title: ng-model for status picklist

Body:
Your ng-model should not be the same as your select data source (statusPickList). It represents the selected value, not the source. Also, your select HTML and JavaScript is not valid as listed. Here's a minimal modified example using your code:

<!-- HTML -->
<div ng-app="app">
  <div ng-controller="ctrl">
    <select ng-model="selectedItem" ng-options="val for val in statusPickList">
    </select>
    <div>
      selectedItem = {{selectedItem}}
    </div>
  </div>
</div>

// JavaScript
angular.module('app', [])
.controller('ctrl', function($scope) {
    $scope.statusPickList = ["Planning", "Execution", "Closed"];
    $scope.selectedItem = "[not selected]";
});

Running live: https://jsfiddle.net/yg1tvxcf/5/

In my example, selectedItem is simply a string value on $scope that stores whatever is selected in your select.

More details at the Angular documentation: Using select with ngOptions and setting a default value.


答:
Actually, the overhead does not really lie in the extra 4 or 8 bytes needed to store the pointer.  Most times pointers are used for dynamic memory allocation, meaning that we invoke a function to allocate a block of memory, and this function returns to us a pointer which points to that block of memory.  This new block in and of itself represents a considerable overhead.

Now, you don't have to engage in memory allocation in order to use a pointer: You can have an array of int declared statically or on the stack, and you can use a pointer instead of an index to visit the ints, and it is all very nice and simple and efficient.  No memory allocation needed, and the pointer will usually occupy exactly as much space in memory as an integer index would.

Also, as Joshua Taylor reminds us in a comment, pointers are used to pass something by reference. E.g., struct foo f; init_foo(&f); would allocate f on the stack and then call init_foo() with a pointer to that struct. That's very common. (Just be careful not to pass those pointers "upward".) In C++ you might see this being done with a "reference" (foo&) instead of a pointer, but references are nothing but pointers that you may not alter, and they occupy the same amount of memory.

But the main reason why pointers are used is for dynamic memory allocation, and this is done in order to solve problems that could not be solved otherwise. Here is a simplistic example: Imagine you want to read the entire
   contents of a file.  Where are you going to store them?  If you try
   with a fixed-size buffer, then you will only be able to read files
   that are not longer than that buffer.  But by using memory
   allocation, you can allocate as much memory as necessary to read the
   file, and then proceed to read it.

Also, C++ is an object-oriented language, and there are certain
   aspects of OOP like abstraction that are only
   achievable using pointers.  Even languages like Java and C# make
   extensive use of pointers, they just don't allow you to directly manipulate the pointers, so as to prevent you from doing dangerous
   stuff with them, but still, these languages only begin to make sense
   once you have realized that behind
   the scenes everything is done using pointers.

So, pointers are not only used in time-critical, low-memory applications, they are used everywhere.

Title: Isn't the use of pointer variables a memory overhead?

Body: In languages like C and C++, while using pointers to variables we need one more memory location to store that address. So isn't this a memory overhead? How is this compensated? Are pointers used in time critical low memory applications? </p>


答:
I don't quite have the same spin on this as Telastyn.

System globals in an embedded processor might be addressed with specific, hard-coded addresses.

Globals in a program will be addressed as an offset from a special pointer that points to the place in memory where globals and statics are stored.

Local variables appear when a function is entered and are addressed as an offset from another special pointer, often called the "frame pointer".  This includes the arguments to the function.  If you are careful about the pushes and pops with the stack pointer, you can do away with the frame pointer and access local variables straight from the stack pointer.

So you pay for the indirection of pointers whether you're striding through an array or just grabbing some unremarkable local or global variable.  It's just based on a different pointer, depending on what kinda variable it is.  Code that is compiled well will keep that pointer in a CPU register, rather than reloading it each time it's used.


问:
Automatically verifying INSERTs when building a PHP(5.3.3) application
I am building a form in PHP. I would like to automatically verify that INSERT queries are successful, and populate data correctly, as opposed to running queries in Workbench or MySQL with every code change.

The only ways I can think of are to count the number of rows before and after, and see if they are equal, or write code to call posted data and compare it to the inserted data, query by query.

Is there some standardized way to go about this?

A Note, I am stuck on PHP 5.3.3

答: Whenever you use a DML statement (INSERT/UPDATE/DELETE), it always returns a integer number. Which can denote the number of rows updated while query execution, OR In case of insertion, it returns ROW ID(I am guessing you have a column named id with auto-increment, If yes this is the value created).


问:
Is 4-5 years the “Midlife Crisis” for a programming career?
I’ve been programming C# professionally for a bit over 4 years now. For the past 4 years I’ve worked for a few small/medium companies ranging from “web/ads agencies”, small industry specific software shops to a small startup. I've been mainly doing "business apps" that involves using high-level programming languages (garbage collected) and my overall experience was that all of the works I’ve done could have been more professional. A lot of the things were done incorrectly (in a rush) mainly due to cost factor that people always wanted something “now” and with the smallest amount of spendable money. I kept on thinking maybe if I could work for a bigger companies or a company that’s better suited for programmers, or somewhere that's got the money and time to really build something longer term and more maintainable I may have enjoyed more in my career. I’ve never had a “mentor” that guided me through my 4 years career. I am pretty much blog / google / self taught programmer other than my bachelor IT degree.

I’ve also observed another issue that most so called “senior” programmer in “my working environment” are really not that senior skill wise. They are “senior” only because they’ve been a long time programmer, but the code they write or the decisions they make are absolutely rubbish! They don't want to learn, they don't want to be better they just want to get paid and do what they've told to do which make sense and most of us are like that. Maybe that’s why they are where they are now. But I don’t want to become like them I want to be better. I’ve run into a mental state that I no longer intend to be a programmer for my future career. I started to think maybe there are better things out there to work on. The more blogs I read, the more “best practices” I’ve tried the more I feel I am drifting away from “my reality”. But I am not a great programmer otherwise I don't think I am where I am now. I think 4-5 years is a stage that can be a step forward career wise or a step out of where you are.

I just wanted to hear what other have to say about what I’ve mentioned above and whether you’ve experienced similar situation in your past programming career and how you dealt with it. Thanks.

答:
My personal experience is the same that you mention. Mostly all the projects i have been working on lately all are made in a rush and all could be better. I've been a program developer for roughly 7 years now and been in the same medium sized company. The management dont have a clue and are running all projects as "non-projects". There is very little order in the chaos. </p>

<p>The thing i fear the most is, that I fall into the pit you are talking about and start doing "crappy" programming and stupid decision just to get forward in my career. I hope there is someone there to hit me in the head if that happens. </p>

Body:
My personal experience is the same that you mention. Mostly all the projects i have been working on lately all are made in a rush and all could be better. I've been a program developer for roughly 7 years now and been in the same medium sized company. The management dont have a clue and are running all projects as "non-projects". There is very little order in the chaos.

The thing i fear the most is, that I fall into the pit you are talking about and start doing "crappy" programming and stupid decision just to get forward in my career. I hope there is someone there to hit me in the head if that happens.

OwnerDisplayName: Arto Uusikangas


问:
How to adjust workflow around longer build time?
I've stared to work on developing larger applications, and am struggling to adjust around non-instant builds. Before I would make a small change, then build and test that change. This doesn't work so well when building + unit tests take several minutes. Any suggestions?

Edit - The suggested duplicate is about how to decrease unit test time. My question is not about how to speed up builds, but how to work with long build times.

答:
Three possibilities:

Parallelize: find someting else that you can do while waiting for the build: answer some email, write documentation, whatever. But the mental context switching overhead makes this work pretty badly in many cases.

Improve your build or modularize the project to allow incremental deployments or partial test runs, so that you don't have to build the entire project to run some unit tests.

Work in larger increments and reduce the number of test cycles. Do more than just some small change before running the build/test step, be more mindful and conscientious to avoid wasting a test cycle on trivial mistakes.

And whenever you're annoyed about waiting 5 minutes for your build to complete, remember that not too long ago, developers wrote their programs on paper and it could take a whole day before they got any result, even if it was just a compiler error because of a typo...


问:
APIs and functional programming
From my (admittedly limited) exposure to functional programming languages, such as Clojure, it seems that encapsulation of data has a less important role. Usually various native types such as maps or sets are the preferred currency of representing data, over objects. Furthermore, that data is generally immutable.

For example, here's one of the more famous quotes from Rich Hickey of Clojure fame, in an interview about the matter:

Fogus: Following that idea—some people are surprised by the fact that Clojure does not engage in data-hiding encapsulation on its types. Why did you decide to forgo data-hiding?

Hickey: Let’s be clear that Clojure strongly emphasizes programming to abstractions. At some point though, someone is going to need to have access to the data. And if you have a notion of “private”, you need corresponding notions of privilege and trust. And that adds a whole ton of complexity and little value, creates rigidity in a system, and often forces things to live in places they shouldn’t. This is in addition to the other losing that occurs when simple information is put into classes. To the extent the data is immutable, there is little harm that can come of providing access, other than that someone could come to depend upon something that might change. Well, okay, people do that all the time in real life, and when things change, they adapt. And if they are rational, they know when they make a decision based upon something that can change that they might in the future need to adapt. So, it’s a risk management decision, one I think programmers should be free to make. If people don’t have the sensibilities to desire to program to abstractions and to be wary of marrying implementation details, then they are never going to be good programmers.

Coming from the OO world, this seems to complicate some of the enshrined principles I've learned over the years. These include Information Hiding, the Law of Demeter and Uniform Access Principle, to name a few. The common thread being that encapsulation allows us to define an API for others to know what they should and shouldn't touch. In essence, creating a contract that allows for the maintainer of some code to freely make changes and refactorings without worrying about how it might introduce bugs into the consumer's code (Open/Closed principle). It also provides a clean, curated interface for other programmers to know which tools they can use to get at or build upon that data.

When the data is allowed to be directly accessed, that API contract is broken and all those encapsulation benefits seem to go away. Also, strictly immutable data seems to make passing around domain-specific structures (objects, structs, records) much less useful in the sense of representing a state and the set of actions that can be performed on that state.

How do functional codebases address these issues that seem to come up when the size of a codebase grows enormous such that APIs need to be defined and lots of developers are involved on working with specific parts of the system? Are there examples of this situation available that demonstrate how this is handled in these type of codebases?

答:
Some functional languages give the ability to encapsulate or hide implementation details in abstract data types and modules.

For example, OCaml has modules defined by a collection of named abstract types and values (notably functions operating on these abstract types). So in a certain sense, Ocaml's modules are reifing APIs. Ocaml also has functors, which are transforming some modules into another one, thus providing generic programming. So modules are compositional.

Title: APIs and functional programming


问:
Why is dealing with multiple threads considered difficult?
You can say this is opinion based, but the problem is that everyone's opinion on this issue is same.

Even the lead developers say that creating the threads is easy, dealing with them together is difficult. It isn't a newbie's job.

All I know is that to deal with threads you have to lock all shared data till each thread finishes accessing it on its own (rather than getting interrupted by kernel), and then unlock it.

That will solve all deadlocks and race conditions. Won't it?

What point am I missing here?

答:
Concurrent programming is difficult, notably because you need to deal with synchronization issues.

All I know is that to deal with threads you have to lock all shared data till each thread finishes accessing it on its own (rather than getting interrupted by kernel), and then unlock it.

You don't know enough about threads. Read some POSIX thread tutorial. You not only need to use mutexes, but you should avoid deadlocks, and you probably need condition variables.

And in practice, finding good trade-offs is difficult (see the table here to grasp the typical timings of operations). Locking granularity matters a lot (you probably don't want to lock & unlock some mutex every two lines).

At the hardware level, cache coherence is important in multi-core processors, and memory models, memory ordering are difficult to understand. In practice, a multi-core system does not behave "intuitively" w.r.t. time (in other words, each core might have its own notion of time & clock).


答:
As usual, there is a trade-off involved. Doing everything in one thread is simple and risk-free. Doing things in multiple threads increases performance, but introduces risk of consistency errors. Using locks to guard against such errors can negate the entire performance advantage for which you introduced threads in the first place.

In other words, maintainability, performance and correctness form a triad of requirements, of which only two are easy to fulfill simultaneously. There is a reason why so many alternative concurrency models are being floated nowadays; the problem is only going to become more pressing in the future, because CPUs don't get faster anymore, just more parallel, and the average programmer isn't up to making productive use of them with our existing models.

Title: Why is dealing with multiple threads considered difficult?

Body:
You can say this is opinion based, but the problem is that everyone's opinion on this issue is same.

Even the lead developers say that creating the threads is easy, dealing with them together is difficult. It isn't a newbie's job.

All I know is that to deal with threads you have to lock all shared data till each thread finishes accessing it on its own (rather than getting interrupted by kernel), and then unlock it.

That will solve all deadlocks and race conditions. Won't it?

What point am I missing here?


答: I just started working about 2 months ago in a small company. Programming isn't boring at all if you really love it.  And I also rely on the internet to search for answers for my own questions but there is also our manager (who is also a developer/programmer) who I can ask from.  Well, it's not all about earning huge income but your passion to get things done.  Try to add some skills.  I'm not just programming but I'm also writing.  I'm also into database design.  When I'll have my spare time, I'll start doing my personal project.  As of now, I enjoy what I'm doing and I'll be still enjoying it after 5 years.</p>


答:
Locking objects can be the cause of deadlocks if you're not careful.  Suppose you have two data structures A and B that need to have data in them synchronised.  Thread 1 updates A with new information, then updates B to match.  Thread 2 updates B with new information, then updates A to match.

So the workflow for thread 1 might be:

```<code> 1. Receive new data.
 2. Lock A.
 3. Update A.
 4. Lock B.
 5. Update B to match.
 6. Unlock B.
 7. Unlock A.
 8. Goto 1.
</code>```

Note that we have A and B locked at the same time so somebody else doesn't modify B until we've got our changes synchronized across the two.

Suppose threads 1 and 2 both receive new information at the same time and need to update the data structures.  The order in which things could happen is totally unpredictable, but it could be:

```<code> 1. Thread 1 locks A
 2. Thread 1 updates A
 3. Thread 2 locks B
 4. Thread 2 updates B
 5. Thread 1 now needs to update B, so it tries to lock B.  B is already locked so it waits.
 6. Thread 2 now needs to update A, so it tries to lock A.  A is already locked so it waits.
 7. Oops - deadlock.  The whole program is now permanently stuck.
</code>```

Body:
Locking objects can be the cause of deadlocks if you're not careful.  Suppose you have two data structures A and B that need to have data in them synchronised.  Thread 1 updates A with new information, then updates B to match.  Thread 2 updates B with new information, then updates A to match.

So the workflow for thread 1 might be:

 1. Receive new data.
 2. Lock A.
 3. Update A.
 4. Lock B.
 5. Update B to match.
 6. Unlock B.
 7. Unlock A.
 8. Goto 1.

Note that we have A and B locked at the same time so somebody else doesn't modify B until we've got our changes synchronized across the two.

Suppose threads 1 and 2 both receive new information at the same time and need to update the data structures.  The order in which things could happen is totally unpredictable, but it could be:

 1. Thread 1 locks A
 2. Thread 1 updates A
 3. Thread 2 locks B
 4. Thread 2 updates B
 5. Thread 1 now needs to update B, so it tries to lock B.  B is already locked so it waits.
 6. Thread 2 now needs to update A, so it tries to lock A.  A is already locked so it waits.
 7. Oops - deadlock.  The whole program is now permanently stuck.


答:
Clojure's tendency to just use hashes and primitives is not, in my opinion, parts of its functional heritage, but part of its dynamic heritage. I've seen similar tendencies in Python and Ruby (both object-oriented, imperative and dynamic, even though both have pretty good support for higher-order functions), but not in, say, Haskell (which is statically typed, but purely functional, with special constructs needed to escape immutability).

So the question you need to ask is not, how do functional languages handle big APIs, but how do dynamic languages do it. The answer is: good documentation and lots and lots of unit tests. Luckily, modern dynamic languages usually come with very good support for both; for example, both Python and Clojure have a way of embedding documentation in the code itself, not just comments.

Title: APIs and functional programming

Body:
From my (admittedly limited) exposure to functional programming languages, such as Clojure, it seems that encapsulation of data has a less important role. Usually various native types such as maps or sets are the preferred currency of representing data, over objects. Furthermore, that data is generally immutable.

For example, here's one of the more famous quotes from Rich Hickey of Clojure fame, in an interview about the matter:

Fogus: Following that idea—some people are surprised by the fact that Clojure does not engage in data-hiding encapsulation on its types. Why did you decide to forgo data-hiding?

Hickey: Let’s be clear that Clojure strongly emphasizes programming to abstractions. At some point though, someone is going to need to have access to the data. And if you have a notion of “private”, you need corresponding notions of privilege and trust. And that adds a whole ton of complexity and little value, creates rigidity in a system, and often forces things to live in places they shouldn’t. This is in addition to the other losing that occurs when simple information is put into classes. To the extent the data is immutable, there is little harm that can come of providing access, other than that someone could come to depend upon something that might change. Well, okay, people do that all the time in real life, and when things change, they adapt. And if they are rational, they know when they make a decision based upon something that can change that they might in the future need to adapt. So, it’s a risk management decision, one I think programmers should be free to make. If people don’t have the sensibilities to desire to program to abstractions and to be wary of marrying implementation details, then they are never going to be good programmers.

Coming from the OO world, this seems to complicate some of the enshrined principles I've learned over the years. These include Information Hiding, the Law of Demeter and Uniform Access Principle, to name a few. The common thread being that encapsulation allows us to define an API for others to know what they should and shouldn't touch. In essence, creating a contract that allows for the maintainer of some code to freely make changes and refactorings without worrying about how it might introduce bugs into the consumer's code (Open/Closed principle). It also provides a clean, curated interface for other programmers to know which tools they can use to get at or build upon that data.

When the data is allowed to be directly accessed, that API contract is broken and all those encapsulation benefits seem to go away. Also, strictly immutable data seems to make passing around domain-specific structures (objects, structs, records) much less useful in the sense of representing a state and the set of actions that can be performed on that state.

How do functional codebases address these issues that seem to come up when the size of a codebase grows enormous such that APIs need to be defined and lots of developers are involved on working with specific parts of the system? Are there examples of this situation available that demonstrate how this is handled in these type of codebases?


答:
In languages like C and C++, while using pointers to variables we need one more memory location to store that address. So isn't this a memory overhead?

You assume that the pointer needs to be stored. That is not always the case. Every variable is stored at some memory address. Say you have a long declared as long n = 5L;. This allocates storage for n at some address. We can use that address to do fancy things like *((char *) &n) = (char) 0xFF; to manipulate parts of n. The address of n isn't stored anywhere as an extra overhead.

How is this compensated?

Even if pointers are explicitly stored (e.g. in data structures such as lists), the resulting data structure is often more elegant (simpler, easier to understand, easier to handle, etc) than an equivalent data structure without pointers.

Are pointers used in time critical low memory applications?

Yes. Devices that use micro-controllers often contain very little memory but the firmware might use pointers for handling interrupt vectors or buffer management, etc.


答:
Having a pointer definitely consumes some overhead, but you can see the upside too.Pointer is  like index. In C you can use complex data structures like string and structures due to pointers only.

In fact suppose you want to pass a variable by reference then its easy to maintain a pointer rather than replicating the whole structure and synchronizing changes between them(even for copying them you will need pointer ). How would you deal with non contiguous memory allocations and de-allocations without pointer ?

Even your normal variables have  an entry in symbol table that stores address where your variable is pointing towards. So, I don't think it creates much overhead in terms of memory(just 4 or 8 bytes) . Even languages like java use pointers internally(reference), they just don't let you to manipulate them as it will make JVM less secure.

You should use pointers only when you have no other choice like missing data-types, structures(in c) as using pointers may be lead to errors if not handled properly and are comparatively harder to debug.


答:
Changing your perspective is very important

I think we programmers complain and cry about lot of things. We want everything to be "perfect" ( = we want everything to be our way). I was (still trying to change) a lot like you. But reading Chad Fowler's "The Passionate Programmer" changed everything for me. I now consider myself lucky to be a programmer. I do my 52-55 hrs a week job (yes this is true). It isn't "perfect". But, I try to do my work passionately. I work for an outsourcing firm in India and the kind of work we get is far from being termed as challenging.
Programmer are lucky to have a wide variety of opportunities to satisfy their creative urges. We can work on our own projects. We can work on open source projects. We can do freelancing on weekends. I think most professionals in other fields don't have that luxury.


答:
Yes, of course. But it's a balancing act.

Low memory applications would typically be constructed bearing in mind the trade-off between the overhead of a few pointer variables compared to the overhead of what would be a massive program (that must be stored in memory, remember!) if pointers could not be used.

This consideration applies for all programs, because nobody wants to build a horrid, unmaintainable mess with duplicated code left right and centre, that's twenty times larger than it needs to be.


问:
Reusing array with static test data across test classes
I have a Map which takes in an a String key, and an array of custom objects as the value. the map usually contains two entries, and the arrays for both entries never change in terms of data; once they are populated(one, for example, is an array of 50 state objects) they do not change. I have been following the practice that all tests should be self contained, i.e. each test class should have its own data for testing to reduce dependencies and such, but i have repeated the initialisation and population of these arrays across two different test classes already, with the potential to have to do it again for another couple of test classes. </p>

<p>Can it be considered best practice to have this array creation moved to a separate utility class solely for testing? </p>

答:
Tests are code, and as such common best practices should be applied: repeated code should probably be extracted into a method. However, this has to be balanced:

Tests should be very, very obvious, more so than other code. A layer of abstraction that makes it difficult to understand what a test does and why exactly it is supposed to pass, might make it unnecessarily difficult to debug a test failure.

Changes to the extracted initialization method affect all tests using that method, even if this is not intended. Therefore, common initialization should only be used where it is your intention that all of these tests use the same test fixture, not where this is an accidental test implementation detail.

If you have shared state, this makes your tests more brittle. A method that creates a fresh fixture is preferable over shared state. In particular, I'm very critical of setUp()/tearDown() methods common in some frameworks. Instead, the test fixture should be separate from the class holding the test methods, and each test case should instantiate its own fixture.


答:
lock all shared data till each thread finishes accessing it on its own

This is the difficult bit. You have to correctly identify all places in the software where shared data is accessed. You then have to apply locks at the correct scope level: if you have too much locked, then only one thread will be able to proceed (e.g. Python's global interpreter lock, GIL). If you lock/unlock too frequently, that will slow down the program.

Often you will find some parts of the architecture that are highly contended. Then you end up redesigning large areas of the system to reduce that contention.


答:
I really cannot overstate the degree to which mutability causes problems in software.  Many of the practices that are drummed into our heads are in compensation for problems that mutability causes.  When you take mutability away, you don't need those practices as much.

When you have immutability, you know your data structure won't change out from under you unexpectedly during runtime, so you can make your own derivative data structures for your own use as you add features to your program.  The original data structure doesn't need to know anything about these derivative data structures.

This means your base data structures tend to be extremely stable.  New data structures sort of get derived from it around the edges as needed.  It's really hard to explain until you've done a significant functional program.  You just find yourself caring about privacy less and less, and thinking about creating durable generic public data structures more and more.

Title: APIs and functional programming