问:
How do I maintain a really poorly written code base?

Possible Duplicate:

  I’ve inherited 200K lines of spaghetti code — what now?

Recently I got hired to work on existing web application because of NDA I'm not at liberty to disclose any details but this application is working online in sort of a beta testing stage before official launch. We have a few hundred users right now but this number is supposed to significantly increase after official launch.

The application is written in PHP (but it is irrelevant to my question) and is running on a dual xeon processor standalone server with severe performance problems.  I have seen a lot of bad PHP code but this really sets new standards, especially knowing how much time and money was invested in developing it.

it is as badly coded as possible there is PHP, HTML, SQL mixed together and code is repeated whenever it is necessary (especially SQL queries). there are not any functions used, not mentioning any OOP

there are four versions of the app (desktop, iPhone, Android + other mobile) each version has pretty much the same functionality but was created by copying the whole code base, so now there are some differences between each version and it is really hard to maintain

the database is really badly designed, which is causing severe performance problems also for fixing some errors in PHP code there is a lot of database triggers used which are updating data on SELECT and on INSERT so any testing is a nightmare

Basically, any sin of a bad programming you can imagine is there for example it is not only possible to use SQL injections in literally every place but you can log into app if you use a login which doesn't exist and an empty password.

The team which created this app is not working on it any more and there is an outsourced team which suggested that there are some problems but was never willing to deal with the elephant in the room partially because they've got a very comfortable contract and partially due to lack of skills (just my opinion).

My job was supposed to be fixing some performance problems and extending existing functionality but first thing I was asked to do was a review of the existing code base. I've made my review and it was quite a shock for the management but my conclusions were after some time finally confirmed by other programmers.

Management made it clear that it is not possible to start rewriting this app from scratch (which in my opinion should be done). We have to maintain its operable state and at the same time fix performance errors and extend the functionality.

My question is, as I don't want just to patch the existing code, how to transform this into properly written app while keeping the existing code working at the same time?

My plan is:

Unify four existing versions into common code base (fixing only most obvious errors).

Redesign db and use triggers to populate it with data (so data will be maintained in two formats at the same time)

All new functionality will be written as separate project.

Step by step transfer existing functionality into the new project

After some time everything will be in the new project

Some explanation about #2, right now it is practically impossible to make any updates in existing db any change requires reviewing whole code and making changes in many places.

Is such plan feasible at all?

Another solution is to walk away and leave the headache to someone else.

答:
It's difficult to assess the best approach without understanding your environment and the relationship between management and engineering. It is also pretty difficult without knowing what kind of resources management is willing to give you to accomplish the task.

Before you get into fixing the code, you should have a strong understanding and vision of how you want to succesfully release this project. Usually bulleted points are the best way to communicate these things.

Preparation.

if management will let you, create a team of talented and diverse engineers

make sure the team is small (2-4 engineers) - nothing derails a team like administrative overhead

have management's buy in to let you (or your technical lead) run your team and have issues be fronted by you or your technical lead

pick an engineer with strong database skills, orm skills and data scientist skills (know your data/content)

pick an engineer with good php/web/development skills

pick an engineer that is a jack of all trades, master of none

pick an engineer who has a good tooling background

pick an engineer with release management experience

a quality engineer for me is one who can learn and adapt, rather than one who has memorized an api

one engineer can fulfill several roles mentioned above

create a strong team vibe (balance hard work with fun down time)

organize your team to be agile

do daily stand ups (scrums)

do weekly iteration planning meetings (at first, bi-weekly as you find your rhythm)

commit very frequently

commit very small changes, but quickly

identify your development life cycle and setup your continuous integration

pick a versatile SCM that your engineers are comfortable with (i recommend git, but if your engineers know SVN then git can have a high learning curve - the key here is that the majority of your engineers should agree and be comfortable with it)

pick a CI tool (hudson/jenkins/bamboo/many others) and get it going

pick a bug tracker that integrates with CI, SCM and get it going

enforce unit and integration testing

make sure unit and integration tests are run in CI - you get quite a bang for your buck in unit tests

unit tests/integration tests can be a source of documentation when code is not always good

unit tests/integration tests help you fail fast

you will need to refactor a ton of code ... unit tests will save your skin here

setup standards for the team: no more than 2 consecutive broken builds, etc, etc

figure out a deployment strategy to deploy to test and production

this will allow you to test your packaging and deployment

allows you to test upgrading scenarios

if you have a well defined deployment strategy, the cycle between new feature/bug fix development and production can be shortened quite a bit

Now the code.

in general, by your description, you have a client/server stack where the server stack is composed of a database, a middle tier (running the PHP/SQL framework) and then the client browser

note that in this scenario, small changes at the bottom of the stack (database) will ripple up through the stack and have a big impact on the presentation layer

given how brittle you have described the code as being, the ripple effect will be intensified

this will not be very manageable in discrete, small chunks if you start with the database layer

you will also have to have a strong understanding of all the code before you can make any changes

it'll be the deer in the headlights scenario

recommendation

you had a win with management (i think) - with your code base analysis

now you need a win with management to show your ability to execute

identify low hanging fruit - there should be quite a few based on your description

plan a way to fix and implement fixes to the low hanging fruit, even if they are hacks

this will bring a win and will encourage management to give you the resources you need

it will alleviate pressure from the customer base and hold them at bay, while you and your engineers work in parallel to refactor the code base

start identifying and dissecting the client and middle tier with the following goals:

it will make your understanding of the system much better

you will want to parse your understanding into small, discrete chunks of features that can be changed without a huge ripple effect

because you're not yet changing database code, there won't yet be large ripples and you can run fast

as you move through this, identify database changes that have to be fixed and create requirements/issues around and assign them a priority

identify dependencies / relationships between modules

Make sure you have the release management, SCM, CI, scrums and other tools in place as fast as you can. Once you have momentum, and trust me you'll get it, the most difficult thing is stopping because you are not sure how to proceed or you do not have enough bandwidth to take care of these all-important but none-the-less side issues.

Hope this helps.


问:
Best way to use GIT to maintain web application template
I am a sole developer and I have a web application template that I have created in Visual Studio. I am using GIT for source control, but only on my development machine. Presently I have a master and I create branches for new features, merging them back in to the master as I complete the features.

I am at a point now where I am ready to use the template for deployments, and of course I want to continue adding new features via branching/merging.

My question is: what would be the typical/recommended way for me to create application deployments based on the master? Should I clone the repository into a new directory that is for a particular web application? Or should I also use branching to do project development based on the main project?

The projects would never be merged back into the master. However, it would be nice if I could merge future features into the master and have the ability to incorporate them into previously completed projects if desired.

For more specific details of my environment: I am using TortoiseGIT in Windows 7, Visual Studio 2012, ASP.NET Web Pages. Obviously the main differences between deployments would simply be differing pages, CSS files and jQuery scripts.

I found this post as I was writing this one. In order to do this should I clone the master repository and checkout from it?

答:
I think your idea of cloning your template is best. But you can tweak that by using GitHub or similar site.

With GitHub you would fork for each new project based on your template.

The fork would create a brand new git repository but based on your template.

Now if one your projects has an update you would like picked up in your original template repository, you could submit a pull request to the original template. Others could too, if you wanted to share.

Then you would simply accept the pull requests you found that you want to incorporate into your original project.

ContentLicense: CC BY-SA 3.0


问:
As a programmer, are you required to do timesheets?
Timesheets are something that I've never been fond of, but none the less something that is a requirement within my company. They don't bother me so much, but they seem to really grind some other people's gears. I suppose I have a few questions, and feedback would be great.

Are you required to do timesheets, assuming you aren't a contractor? (That is understandable to me).

What is the granularity of timesheets that you would be comfortable with or that you use? (ex: all entries must be under two hours).

Would timesheets ever factor into your reasons for not accepting a job or leaving a current one?

How has management within your organization justified timesheets if you aren't billing to a client?

答:
I'm amazed at how much time is wasted on time sheets and how little the organization is getting out of it.

For most groups here, the manager sends out the number of hours budgeted for the time period; per project, per employee in order to match the project plan. All programmers then enter that time for each project they work on; regardless of what time they actually spent per project. Or how useful that work was.

For them, time sheets are totally useless.

On the other hand, I get the build record from Hudson and commit log from VCS. From that I get a good sense on what my team actually worked on without having to ask them to file out more form.

Its more accurate as it tracks what developers have done and not what people said they spent time doing.

ContentLicense: CC BY-SA 2.5


问:
Is thıs code efficient always for finding array[max]?
I am trying to find max value of an array, firstly i am shorting my array min to max after that i am using array[array.length-1] Is this logic efficient in large arrays?

public static int findMax(int[] array){

    Arrays.sort(array);

    int max = array[array.length-1];

    return max;
}//end method
```

答:
No it's not.

```<code>Arrays.sort(array);
</code>```

That line alone has an O(nlogn) running time. It can result in as many iterations as n, where n is the number of elements in the array, multiplied by log base 2 of n.

It would be much faster to just iterate through the array once.

```<code>public static int findMax(int[] array) {
    int indexOfMax = 0;
    for (i=1; i < array.length; i++) {
        if (array[i] > array[indexOfMax] {
            indexOfMax = i;
    }
    return indexOfMax
}
</code>```

That has a maximum running time as O(n).

Body:
No it's not.

Arrays.sort(array);

That line alone has an O(nlogn) running time. It can result in as many iterations as n, where n is the number of elements in the array, multiplied by log base 2 of n.

It would be much faster to just iterate through the array once.

public static int findMax(int[] array) {
    int indexOfMax = 0;
    for (i=1; i < array.length; i++) {
        if (array[i] > array[indexOfMax] {
            indexOfMax = i;
    }
    return indexOfMax
}

That has a maximum running time as O(n).


问:
Help with algorithmic complexity in custom merge sort implementation
I've got an implementation of the merge sort in C++ using a custom doubly linked list.  I'm coming up with a big O complexity of n^2, based on the merge_sort() > slice operation.  But, from what I've read, this algorithm should be n*log(n), where the log has a base of two.

Can someone help me determine if I'm just determining the complexity incorrectly, or if the implementation can/should be improved to achieve n*log(n) complexity?

If you would like some background on my goals for this project, see my blog.  I've added comments in the code outlining what I understand the complexity of each method to be.

Clarification - I'm focusing on the C++ implementation with this question.  I've got another implementation written in Python, but that was something that was added in addition to my original goal(s).

答:
You're determining the complexity incorrectly. The standard mergesort recurrence is

```<code>T(n) = 2 T(n/2) + O(n)
</code>```

Since your slice is indeed O(n), you're fine.

As a minor optimisation, though, you might want to consider having a single method to split the list in two which doesn't involve iterating down the first half of the list twice.

Body:
You're determining the complexity incorrectly. The standard mergesort recurrence is

T(n) = 2 T(n/2) + O(n)

Since your slice is indeed O(n), you're fine.

As a minor optimisation, though, you might want to consider having a single method to split the list in two which doesn't involve iterating down the first half of the list twice.


答:
Cleaner implementation of the accepted answer:</p>

```<code>public static int findMax(int[] array) {

    // TODO: Take appropriate action if the array is empty.

    int max_value = Integer.MIN_VALUE;

    for ( int value : array ) {
        if ( value > max_value ) {
            max_value = value;
        }
    }

    return max_value;
}
</code>```

Title: Is thıs code efficient always for finding array[max]?

Body:
I am trying to find max value of an array, firstly i am shorting my array min to max after that i am using array[array.length-1] Is this logic efficient in large arrays?

public static int findMax(int[] array){

    Arrays.sort(array);

    int max = array[array.length-1];

    return max;
}//end method
```

Body:
Cleaner implementation of the accepted answer:

public static int findMax(int[] array) {

    // TODO: Take appropriate action if the array is empty.

    int max_value = Integer.MIN_VALUE;

    for ( int value : array ) {
        if ( value > max_value ) {
            max_value = value;
        }
    }

    return max_value;
}


答:
Management made it clear that it is not possible to start rewriting this app from scratch

This is your main concern. You can only patch it as you go along. Your plan involves a rewrite, but not a live one so you're asking management to pay for this and also the maintenance of the old version.

I can only see you chasing your tail as changes are applied to the old system they'll probably be incompatible with your new one and so you'll just end up in an endless cycle of refactoring.

Title: How do I maintain a really poorly written code base?

Body:
Possible Duplicate:

  I’ve inherited 200K lines of spaghetti code — what now?

Recently I got hired to work on existing web application because of NDA I'm not at liberty to disclose any details but this application is working online in sort of a beta testing stage before official launch. We have a few hundred users right now but this number is supposed to significantly increase after official launch.

The application is written in PHP (but it is irrelevant to my question) and is running on a dual xeon processor standalone server with severe performance problems.  I have seen a lot of bad PHP code but this really sets new standards, especially knowing how much time and money was invested in developing it.

it is as badly coded as possible there is PHP, HTML, SQL mixed together and code is repeated whenever it is necessary (especially SQL queries). there are not any functions used, not mentioning any OOP

there are four versions of the app (desktop, iPhone, Android + other mobile) each version has pretty much the same functionality but was created by copying the whole code base, so now there are some differences between each version and it is really hard to maintain

the database is really badly designed, which is causing severe performance problems also for fixing some errors in PHP code there is a lot of database triggers used which are updating data on SELECT and on INSERT so any testing is a nightmare

Basically, any sin of a bad programming you can imagine is there for example it is not only possible to use SQL injections in literally every place but you can log into app if you use a login which doesn't exist and an empty password.

The team which created this app is not working on it any more and there is an outsourced team which suggested that there are some problems but was never willing to deal with the elephant in the room partially because they've got a very comfortable contract and partially due to lack of skills (just my opinion).

My job was supposed to be fixing some performance problems and extending existing functionality but first thing I was asked to do was a review of the existing code base. I've made my review and it was quite a shock for the management but my conclusions were after some time finally confirmed by other programmers.

Management made it clear that it is not possible to start rewriting this app from scratch (which in my opinion should be done). We have to maintain its operable state and at the same time fix performance errors and extend the functionality.

My question is, as I don't want just to patch the existing code, how to transform this into properly written app while keeping the existing code working at the same time?

My plan is:

Unify four existing versions into common code base (fixing only most obvious errors).

Redesign db and use triggers to populate it with data (so data will be maintained in two formats at the same time)

All new functionality will be written as separate project.

Step by step transfer existing functionality into the new project

After some time everything will be in the new project

Some explanation about #2, right now it is practically impossible to make any updates in existing db any change requires reviewing whole code and making changes in many places.

Is such plan feasible at all?

Another solution is to walk away and leave the headache to someone else.


答:
I faced the same situation with a Java app.

This is what I did:

I used the "fit a mountain in a tea cup" approach. This means you actually don't put the mountain in the tea cup, insteada you dig for the diamond, then put the diamond in the teacup.

I identified the core functionality of the app, the most frequently used feature, the functionality that is responsible for the most part of duplicate code. I'm talking business logic only. Then I reengineered that business logic using OOP and tested it thoroughly making sure it did the exact same thing the old code did ( minus errors, plus performance improvements). Then I painstakingly went into every part of the code where the old logic was used and bypassed it making sure the new OOP, reengineered logic was called instead of the old one. Obviously the new code ended up having considerably less code lines.

Then I went to find my second diamond.

After three of four diamonds more. The very core of the application, under the hood was fresh and better. With the old code only running the less used, unimportant functionalities.

I didn't re-wrote the whole app. That would have been trying to actually fill the whole mountain in a tea-cup.


答:
Management made it clear that it is not possible to start rewriting this app from scratch (which in my opinion should be done). We have to maintain its operable state and at the same time fix performance errors and extend the functionality.

Management can state their requirements, but if it won't work, it won't work.  If I was you I would make clear to management (in writing) what you think the risks are.  These might include:

risk of system collapse due to performance issues,

risk of major security problems,

risk that extensions of functionality will be severely delayed.

A "can do" attitude is not going to help if the reality says that you can't do it.  Management needs to be fully aware of the risks ... even if they choose to ignore them.

Apart from that ... good luck!

Another solution is to walk away and leave the headache to someone else.

I'd be considering that too.


问:
What software do you use to track time spent on a project?
What software do you use to track time spent on a project?</p>

答: I check the build log from our Build System and the commit log from version control and compare that to the project plans our PHBs send out. For my team, we use Excel to augment the build and commit logs. For everything on the Excel list, I expect to see at least one commit mentioning it and one successful build after that commit. This only works is you really need to track tasks that are very course grained. Daily or weekly and not hour-by-hour.</p>


问:
Methodology behind fetching large XML data sets in pieces
I am working on an HTTP Server in Delphi which simply sends back a custom XML dataset. I am not following any type of standard formatting, such as SOAP. I have the system working seamlessly, except one small flaw: When I have a very large dataset to send back to the client, it might take up to 2 minutes for all the data to be transferred. The HTTP Server I'm building is essentially an XML Data based API around a database, implementing the common business rule - therefore, the requests are specific to the data behind the system.

When, for example, I fetch a large set of product data, I would like to break this down and send it back piece by piece. However, a single HTTP request calls for a single response. I can't necessarily keep feeding the client with multiple different XML packets unless the client explicitly requests it.

I don't have any session management, but rather an API Key. I know if I had sessions, I could keep-alive a dataset temporarily for a client, and they could request bits and pieces of it. However, without session management, I would have to execute the SQL query multiple times (for each chunk of data), and in the mean-time, if that data changes, the "pages" might get messed up, therefore causing items to show on the wrong pages, after navigating to a different page.

So how is this commonly handled? What's the methodology behind breaking down a large XML dataset into chunks to save the load?

答:
The solution depends on where the problem really is.

If the problem is in the time taken to generate the XML server-side, then you could consider optimizing that.  In particular look for an alternative approach that doesn't involve creating a DOM in memory and serializing it.  (I'm not familiar with Delphi).

If the problem is in fetching the data from the database, then query optimization may help.

If the problem is in the time taken to transmit the data, then consider sending less; e.g. leave out stuff that isn't going to be displayed immediately.  You can do this by leaving out fields (that can be fetched later if required) or by "paging" the dataset.  Unfortunately, both of these entail client-side changes as well as server-side changes.

If you scale this up, then paging is the only solution that can potentially scale indefinitely.

An entirely different approach is process the large dataset on the server side and only send a summary ...

I'm going to implement session management, where I can keep a dataset open for a period of time until idle time expires. During that time, the client can fetch chunks of the results at a time.

You need to be careful with this.  There is a potential for accidental or deliberate denial of service issues if clients open lots of datasets and allow them to expire:

The timeout should be short, and based on the time since the last use of the dataset handle, rather than the time since it was opened.

Consider an implementation that doesn't require a long-running transaction for each dataset handle; e.g. use some schema-specific identifier that allows you to close one database result set and then issue a new query to resume the iteration.


答: While debating the concept of Session Management, I've decided that I will go ahead and implement it. Each session will have just one dataset, refreshed upon request, where the client can fetch chunks of it at a time. I'm confident that I won't have excessive sessions and therefore I understand how to implement this via sessions. The structure is quite more than explained in the question, and I've concluded an API Key should trigger another level of authentication: Sessions/Cookies. Each session has its own dataset.</p>

Title: Methodology behind fetching large XML data sets in pieces

Body:
I am working on an HTTP Server in Delphi which simply sends back a custom XML dataset. I am not following any type of standard formatting, such as SOAP. I have the system working seamlessly, except one small flaw: When I have a very large dataset to send back to the client, it might take up to 2 minutes for all the data to be transferred. The HTTP Server I'm building is essentially an XML Data based API around a database, implementing the common business rule - therefore, the requests are specific to the data behind the system.

When, for example, I fetch a large set of product data, I would like to break this down and send it back piece by piece. However, a single HTTP request calls for a single response. I can't necessarily keep feeding the client with multiple different XML packets unless the client explicitly requests it.

I don't have any session management, but rather an API Key. I know if I had sessions, I could keep-alive a dataset temporarily for a client, and they could request bits and pieces of it. However, without session management, I would have to execute the SQL query multiple times (for each chunk of data), and in the mean-time, if that data changes, the "pages" might get messed up, therefore causing items to show on the wrong pages, after navigating to a different page.

So how is this commonly handled? What's the methodology behind breaking down a large XML dataset into chunks to save the load?


问:
learning on the clock
Some might argue this question is too general, but because keeping up seems especially relevant to  programming, is anyone's experience that:

do employers expect you to stay current? what is the "industry standard" of expected time a programmer should spend keeping up-to-date?

is it generally acceptable that a programmer can spend some time during working hrs on meeting the expectation to keep skills current? If not, how do most programmers find the time?

 -

答:
Somewhat.  I'd think it unrealistic to expect being up to date on everything though if one is working within a specific area, there may be an expectation to stay up to date within that realm of knowledge.  This does set dangerous precedents since one could accumulate knowledge on various systems and be expected to keep track of all of it in their head.  I doubt there is an "industry standard" given the range of different demands from different developers.  If a developer is working in a Research & Development lab, then I'd suspect lots of time would be spent exploring technologies that is different than developers in an IT department that may work on customizing software either developed in-house or bought off-the-shelf.  I can remember getting training on some software or some time to experiment with new stuff that was down this route but I'm not sure how standard this would be.

No though there can be exceptions here.  My experience is that there will be some time spent developing skills though this is mostly on an "as needed" basis and thus it isn't something easy to plan.  If a bug comes up in a part of a code base I don't know, then I'll spend some time learning that code base.  Similarly, there may be slow times where developers could work on technical debt rather than new features as some companies may not want to do a release in December and thus the developers get that month to do the various housekeeping things that have been left until there was some bandwidth.

Title: learning on the clock


答:
There's no industry standard(s) at all as far as I'm aware. There are some practices that I've seen. Some good (G), some bad (B).

(G) Training courses when adopting a new technology. I've seen companies, on a number of occasions, bring in an educator to give training sessions to their developers (or a select few) for a couple of days on a new technology that the company is adopting for their product(s).

(G/B) Reimbursement for certifications. It's common that most companies will reimburse the cost of certifications, if you pass the test. That's great. The bad part is that they will often require that you stay with the company for x months to keep the reimbursement - even though the studying and learning resources were paid for by the student/employee and performed on employee time.

(B) "Hiring for passion" Lots of companies try to hire specifically "passionate" developers. I assert that their motives for doing so are that passionate developers research/study/learn on their own time, and the company doesn't have to contribute to it.

(G) Conferences: in rare cases, I've seen companies send employees (usually 1-3), as attendees, to conferences and then present the material when they return. I've only ever seen this in large companies. Upon returning, the employees generally always have to provide notes and sometimes present the topics that they covered/learned at the conference. This is often huge conferences (recently ther was build, for eg) or highly specialized conferences (paris game ai conference for eg).

(G) In house lectures: At one company I worked at, we had something that worked really well. Each week, at our team meeting (team of 14 or so) one person from the team would give a lecture/whatever about something they were really interested in. It didn't have to specifically have anything to do with the technology used in the company. It was capped at 20 minutes. I presented automated testing Azure applications for example.

All of that said, I have never heard of any company, even those that are known for being amazing employers, that permit employees time to specifically study/learn on the clock. There are scenarios where the project implies it (proofs of concepts for unknown technologies/etc.) and I've seen that, but not general learning. ("20% time" is different because those projects are generally focused on producing something and is a way for companies to incubate ideas instead of allowing developers to learn/grow)

Title: learning on the clock

Body:
Some might argue this question is too general, but because keeping up seems especially relevant to  programming, is anyone's experience that:

do employers expect you to stay current? what is the "industry standard" of expected time a programmer should spend keeping up-to-date?

is it generally acceptable that a programmer can spend some time during working hrs on meeting the expectation to keep skills current? If not, how do most programmers find the time?

 -


答:
Decide on the maximum number of pages your user is expected to browse in 1 session. Do a client fetch that gets set of primary keys that satisfy your maximum criteria and return this set to your client. This process is performed only 1 time. Each time the user requests next or previous page, use the cashed set of keys to get the desired rows based on the page size. This method always retrieves at most n rows where n is the number of rows in your page (after the initial cash retrieval). When the user is done, flush the keys cash. This method is specially useful when you have a complex query where a simple SQL such as "SELECT * FROM ... Where Key > lastKey" won't work. The drawbacks of this approach are:

1 - This method ignores new and removed records after the user has requested initial browse request, however, this is usually acceptable in many types of LOB applications.

2 - This method requires fetching the keys in advance, however, if your max. number of pages is reasonable, this should not be a problem, specially when the query is well-qualified.


问:
Will You Use an Online Technical Skills Test to Hire a Senior Developer?
There are online services such as IKM that offer skills tests in many areas, including programming.

Would you use these kind of tests when hiring for a senior developer position?

What about just for objectively benchmarking candidates before calling them for an interview? Would you use it as a step after short-listing candidates after interviews?

Is this approach more suitable in some situations compared to others? Have you personally used this kind of service or know someone who has?

答:
Are you hiring him to take tests or write code?

If you're having that much of an issue with the introductory screen, your recruiters and placement partners are doing a bad job and you should replace them.  If someone send me nothing but a stream of really bad candidates that can't pass a simple in person test, we change recruiters.


问:
Why is the concept of lazy evaluation useful?
It seems lazy evaluation of expressions can cause a programmer to lose control over the order in which their code is executed. I am having trouble understanding why this would be acceptable or desired by a programmer.

How can this paradigm be used to build predictable software that works as intended, when we have no guarantee when and where an expression will be evaluated?

答:
There are several arguments for lazy evaluation I think are compelling

Modularity With lazy evaluation you can break code up into parts.  For example, suppose you have the problem to "find the first ten reciprocals of elements in a list list such that the reciprocals are less than 1."  In something like Haskell you can write

```<code>take 10 . filter (<1) . map (1/)
</code>```

but this is just incorrect in a strict language, since if you give it [2,3,4,5,6,7,8,9,10,11,12,0] you will be dividing by zero.  See sacundim's answer for why this is awesome in practice

More things work Strictly (pun intended) more programs terminate with non strict evaluation than with strict evaluation.  If your program terminates with an "eager" evaluation strategy it will terminate with a "lazy" one, but the oposite is not true.  You get stuff like infinite data structures (which are really only kinda cool) as specific examples of this phenomenon.  More programs work in lazy languages.

Optimality  Call-by-need evaluation is asymptotically optimal with respect to time. Although the major lazy languages (that essentially being Haskell and Haskell) don't promise call-by-need, you can more or less expect an optimal cost model.  Strictness analysers (and speculative evaluation) keep the overhead down in practice.  Space is a more complicated matter.

Forces Purity using lazy evaluation makes dealing with side effects in an undisciplined way a total pain, because as you put it, the programmer loses control.  This is a good thing.  Referential transparency makes programming, refractoring, and reasoning about programs so much easier.  Strict languages just inevitably cave to the pressure of having impure bits--something Haskell and Clean have resisted beautifully.  This is not to say that side effects are always evil, but controlling them is so useful that this reason alone is enough to use lazy languages.

Body:
There are several arguments for lazy evaluation I think are compelling

Modularity With lazy evaluation you can break code up into parts.  For example, suppose you have the problem to "find the first ten reciprocals of elements in a list list such that the reciprocals are less than 1."  In something like Haskell you can write

take 10 . filter (<1) . map (1/)

but this is just incorrect in a strict language, since if you give it [2,3,4,5,6,7,8,9,10,11,12,0] you will be dividing by zero.  See sacundim's answer for why this is awesome in practice

More things work Strictly (pun intended) more programs terminate with non strict evaluation than with strict evaluation.  If your program terminates with an "eager" evaluation strategy it will terminate with a "lazy" one, but the oposite is not true.  You get stuff like infinite data structures (which are really only kinda cool) as specific examples of this phenomenon.  More programs work in lazy languages.

Optimality  Call-by-need evaluation is asymptotically optimal with respect to time. Although the major lazy languages (that essentially being Haskell and Haskell) don't promise call-by-need, you can more or less expect an optimal cost model.  Strictness analysers (and speculative evaluation) keep the overhead down in practice.  Space is a more complicated matter.

Forces Purity using lazy evaluation makes dealing with side effects in an undisciplined way a total pain, because as you put it, the programmer loses control.  This is a good thing.  Referential transparency makes programming, refractoring, and reasoning about programs so much easier.  Strict languages just inevitably cave to the pressure of having impure bits--something Haskell and Clean have resisted beautifully.  This is not to say that side effects are always evil, but controlling them is so useful that this reason alone is enough to use lazy languages.


问:
Are python's cryptographic modules good enough?
I mean, say you were writing professional grade software that would involve sensitive client information. (Take this in the context of me being an amateur programmer.)

Would you use hlib and hmac? Are they good enough to secure data? Or would you write something fancier by hand?

Edit: In context of those libraries containing more or less the best hashing algorithms in the world, I guess it's silly to ask if you'd "write something fancier."

What I'm really asking here is whether it's enough on its own.

答:
The pre-built library is almost certainly more secure than something you will write yourself. Writing security libraries like these is very difficult to do correctly without making any mistakes. The team of developers that made it probably have a lot more experience in this sort of thing than the average developer. Those libraries are also more "battle-tested" than something you'd write yourself. You should definitely use pre-build libraries instead of doing it yourself.

There's a lot to keep in mind when trying to do something securely though. It's possible to use the most secure tools and libraries, but combine them in a way that isn't secure. This is more likely than the core libraries themselves being insecure. This is why you want to keep everything as simple as possible, even when using secure libraries and tools.


问:
What's the most absurd myth about programming issues?
To put it another way... What is the most commonly held and frustrating misunderstanding about programming, you have encountered?

Which widespread and longstanding myths/misconceptions do you find hard for programmers to dispel/correct.

Please, explain why this is a myth.

答: If we use something other than Java, C# and C++ in our project, we won't find any programmers to support it.</p>


问:
At what point/range is a code file too big?
I'm finding lots of 2-3k line files, and it doesn't really feel like they should be that big.

What is a good criteria to objectively call a source code file "too big"?, is there such thing  as a maximum amount of lines a source code file should have?

答:
As an ideal model I use the following criteria (with a similar rationale to what Martin Beckett suggested, i.e. to think in terms of logical structure and not in terms of lines of code):

Rule 1

One class per file (in C++: one class -> one header and one implementation file).

Rule 2

Seven is considered the number of items that our brain can observe at the same time without getting confused. Above 7 we find it difficult to keep an overview of what we see. Therefore: each class should not have more than 7-10 methods. A class that has more than 10 method is probably too complex and you should try to split it. Splitting is a very effective method because every time you split a class you reduce the complexity of each individual class at least by a factor of 2.

Rule 3

A method body that does not fit in one or two screens is too big (I assume that a screen / editor window is about 50 lines). Ideally, you can see the whole method in one window. If this is not the case, you only need to scroll up and down a bit, without forgetting the part of the method that gets hidden. So, if you have to scroll more than one screen up or down to read the whole method body, your method is probably too big and you can easily lose the overview.

Again, splitting methods using private help methods can reduce method complexity very fast (at every split the complexity is at least halved). If you introduce too many private help methods you can consider creating a separate class to collect them (if you have more private methods than public ones, maybe a second class is hiding inside your main class).

Putting together these very rough estimates:

At most one class per source file.

At most 10 public method per class.

At most 10 private method per class.

At most 100 lines per method.

So a source file that is more than 2000 lines is probably too large and starting to be too messy.

This is really a very rough estimate and I do not follow these criteria systematically (especially because there is not always enough time to do proper refactoring). Also, as Martin Beckett suggested, there are situations in which a class is a large collection of methods and it does not make sense to split them in some artificial way just to make the class smaller.

Anyway, in my experience a file starts to get unreadable when one of the above parameters is not respected (e.g. a 300 line method body that spans six screens, or a source file with 5000 lines of code).


问:
Is Google Closure a true compiler?
This question is inspired by the debate in the comments on this Stack Overflow question. The Google Closure Compiler documentation states the following (emphasis added):

The Closure Compiler is a tool for making JavaScript download and run faster. It is a true compiler for JavaScript. Instead of compiling from a source language to machine code, it compiles from JavaScript to better JavaScript.

However, Wikipedia gives the following definition of a "compiler":

A compiler is a computer program (or set of programs) that transforms source code written in a programming language (the source language) into another computer language... A language rewriter is usually a program that translates the form of expressions without a change of language.

Based on that, I would say that Google Closure is not a compiler. But the fact that Google explicitly state that it is in fact a "true compiler" makes me wonder if there's more to it. Is Google Closure really a JavaScript compiler?

答:
First, lets get this out of the way source-to-source compiler exists. You cannot say something isn't a compiler because the end result isn't a code of lower level.

While it is correct that Closure Compiler generate AST and have code generation phrase, many Javascript minimizer out there already does that and I would probably not call them compilers neither.

What truly sets Closure Compiler apart is it's application of many well known compiler techniques in error detection and optimization. Here are some examples:

Type system:

Closure Compiler defines an annotated type system. It utilizes type inference techniques that many compiler uses to check your program for errors.

Interprocedural optimizations

Closure Compiler builds call graphs to rename and remove dead code in a whole program level.

Intraprocedural optimizations

Closure Compiler optimizes Javascript by apply different Control Flow Analysis as well as Data Flow analysis. Classic compiler techniques such as: Inlining, Register Allocation, Live Variable Analysis.. and many more are all utilized to squeeze that last byte out of the output Javascript.

Module System

A lesser known part of Closure Compiler that can be used to divide your code into seperate download for faster start-up time. It utilizes many graph algorithms as well. Something is also very common in "traditional" compilers.

All these compiler and static analysis techniques is what sets Closure Compiler apart from other Javascript minimizer. Taking away from the fact that the targeted input and output language is the same, I don't see why it isn't classified as a "true compiler".

Title: Is Google Closure a true compiler?


答:
Unfortunately, yes.

But not only one timesheet. We have to:

Check in and check out on arrival/departure

Fill in the timesheet for our parent company at the end of the month

Our idiotic government (Croatia) recently added another nuisance: filling in another daily timesheet. Why? So they can send an "inspection" to steal your money if every employee doesn't have it completely filled in.

Title: As a programmer, are you required to do timesheets?

Body:
Timesheets are something that I've never been fond of, but none the less something that is a requirement within my company. They don't bother me so much, but they seem to really grind some other people's gears. I suppose I have a few questions, and feedback would be great.

Are you required to do timesheets, assuming you aren't a contractor? (That is understandable to me).

What is the granularity of timesheets that you would be comfortable with or that you use? (ex: all entries must be under two hours).

Would timesheets ever factor into your reasons for not accepting a job or leaving a current one?

How has management within your organization justified timesheets if you aren't billing to a client?


答:
I'm not a proponent of re-write, be it a slow rewrite where you create a new project and slowly turn off functionality in the other app or a big bang rewrite.

I do like refactoring. Start reducing the number of interdependencies the app has (so that a page depends on say 24 instead of 56 external classes), fix the easy stuff like code formating, do the easy extractions like a data tier (move SQL executions to code external to what is calling it), find dead code and archive it.  In the process things will break, so as you go along you will want to look for opportunities to set up integration tests. I tend to find that beautiful unit tests don't become possible until fairly late in the maintenance cycle.

Another thing I've started doing recently for this type of code is extensive logging-- be careful that your logging doesn't interfer with production perf and behavior though. With code bases like this, a big challenge do moving it forward or rewriting it in any sense of the word is that it is hard to figure out what it is doing. With logging you can figure out what the true sequence of events is, what code is really dead, what code is the "root" that gets called over and over again, where the entry points are etc. Also, once you discover where the roots and hotspots are, you know what areas will cause the most pain should they break.


问:
Should I use the factory design pattern for every class?
I've been writing a website in PHP. As the code becomes more complex, I keep finding problems that can be solved using the factory design pattern. For example: I've a got a class Page which has subclasses HTMLPage, XMLPage, etc. Depending on some input I need to return an object of either one of these classes. I use the factory design pattern to do this.

But as I encounter this problem in more classes, I keep having to change code which still initiates an object using its constructor. So now I'm wondering: is it a good idea to change all code so that it uses the factory design pattern? Or are there big drawbacks?

I'm currently in a position to change this, so your answers would be really helpful.

答:
I don't know a lot of people using design patterns in PHP, but Joshua Bloch recommends the Factory pattern in his book, "Effective Java."  In fact, it is his first recommendation: Item 1.  Here are several of his points which are specific to Java, but most probably apply to PHP:

Advantages

As you mentioned, a factory method can return any sub-type of object

Unlike constructors, factory methods are not required to create a new object each time they are invoked - this allows you to manage the set of objects internally.  For example, a printable ASCII character class only ever needs 95 instances.  You don't need two objects to represent a lower-case 'k'.

Factory methods can be given meaningful names (in Java)

Disadvantages

In Java, you cannot create a subclass if the parent class lacks a public or protected constructor.

Static factory methods are not readily distinguishable from other static methods.  Bloch suggests a naming pattern to distinguish them.

The goal behind most of Bloch's suggestions is that if you send your class out into the world and many people use it, you want it to present an interface that allows you to adapt and change the implementation of your classes without breaking client code.  Bloch's perspective was formed by trying to fix bugs and design flaws in the Java API's without changing the interface that they present to the world.


问:
Securing credentials passed to web service
I'm attempting to design a single sign on system for use in a distributed architecture. Specifically, I must provide a way for a client website (that is, a website on a different domain/server/network) to allow users to register accounts on my central system.

So, when the user takes an action on a client website, and that action is deemed to require an account, the client will produce a page (on their site/domain) where the user can register for a new account by providing an email and password.

The client must then send this information to a web service, which will register the account and return some session token type value.

The client will need to hash the password before sending it across the wire, and the webservice will require https, but this doesn't feel like it's safe enough and I need some advice on how I can implement this in the most secure way possible.

A few other bits of relevant information:

Ideally we'd prefer not to share any code with the client

We've considered just redirecting the user to a secure page on the same server as the webservice, but this is likely to be rejected for non-technical reasons.

We almost certainaly need to salt the password before hashing and passing it over, but that requires the client to either a) generate the salt and communicate it to us, or b) come and ask us for the salt - both feel dirty.

Any help or advice is most appreciated.

答:
Client-Side SSL (public-key) Certificates are the only scheme that protects clients against man-in-the-middle attacks, thus making them the most secure.  Edit Last time I checked, Verisign was chaging $100-200 per client certificate End-Edit.  If clients are humans, you can install the certificate in their browser and move it to a different browser at any time.  It's a little like a more secure, universally accepted cookie.  If you read the OpenSSL manual, you can use OpenSSL to become your own Certificate Authority and generate and accept your own certificates, but you have to be very careful to do everything right (any mistake can undermine the security of the system as seen repeatedly in the news).  When I last checked, Chrome required the user to use the command line to set a client certificate, but all the other popular modern browsers could set certificates through JavaScript.

Client-side cookies.  Clients still log in the way they do now, but the server sends them an encrypted cookie (the server does all hashing and salting and chooses what data to hash and salt).  Most people go this route, probably because it is easy to implement.  When you see a "Keep me logged in" checkbox on the login page of a web site, this is usually what's happening.

OpenID has complete documentation and implementations available.  It allows you to leverage one account (which is OpenID enabled) to log in many places.  It has the advantage that the user only needs to "remember" one password (I hate the word "remember" with passwords - people should be using a password manager to store passwords that they cannot remember).  The big disadvantage of this is that if someone compromises the master account, all connected accounts will fall with it.

ActiveDirectory/LDAP This is the most popular and traditional form of single-sign-on for internal applications within enterprises.  I think it was created by Novel at a time when managing an address book of names and phone numbers (the "Directory" in LDAP) was considered a big deal.  This was a time before computer security was even much of a consideration.  Microsoft's Active Directory implementation has shipped with all their major operating systems for over a decade.  People can be automagically signed-in to AD/LDAP-enabled intranet sites just by being signed into their desktop.  It requires all clients to be on the same local network, or at least for the AD/LDAP server to be accessible to the web server checking credentials.  It provides no security, or really bad security in and of itself.  You absolutely must test that your authentication packets are encrypted by the transport layer (ssl over https) and test your server to be sure that it will NEVER accept any un-encrypted connections.  The idea of sending people's desktop login information freely in plain text over the network makes me really uncomfortable.  It almost cheapens the word "exploit" to say that this weakness has been exploited many times over the years.  If you go this route, I believe that LDAP clients are available for Linux and Mac as well as Windows.


问:
What is the career path for a software generalist?
A question on software specialties inspired this question.

How valuable is a software generalist compared to a specialist?

When I say generalist, I mean someone who can take a project from requirements to deployment, and is competent with all phases of the software development lifecycle. Someone who can put all the specialties together into a cohesive whole. An expert generalist knows his or her weaknesses and fills them by relying on specialists - example: Oracle specialists or UX specialists.

What do you see as the ultimate career path of the software generalist?

答:
Software/System/Enterprise Architect - Too many x Architect titles out there these days, but you get the idea :).

As long as you remain a relatively hands-on architect (and not a white paper writing ivory tower architect) then that's a fairly good career path for a generalist.


问:
Is there a clean separation of my layers with this attempt at Domain Driven Design in XAML and C#
I'm working on an application.  I'm using a mixture of TDD and DDD.  I'm working hard to separate the layers of my application and that is where my question comes in.

My solution is laid out as follows

```<code>Solution
    MyApp.Domain (WinRT class library)
        Entity (Folder)
            Interfaces(Folder)
                IPost.cs (Interface)
            BlogPosts.cs(Implementation of IPost)
        Service (Folder)
            Interfaces(Folder)
                IDataService.cs (Interface)
            BlogDataService.cs (Implementation of IDataService)
    MyApp.Presentation(Windows 8 XAML + C# application)
        ViewModels(Folder)
            BlogViewModel.cs
        App.xaml
        MainPage.xaml (Contains a property of BlogViewModel
    MyApp.Tests (WinRT Unit testing project used for my TDD)
</code>```

So I'm planning to use my ViewModel with the XAML UI

I'm writing a test and define my interfaces in my system and I have the following code thus far.

```<code>    [TestMethod]
    public void Get_Zero_Blog_Posts_From_Presentation_Layer_Returns_Empty_Collection()
    {
        IBlogViewModel viewModel = _container.Resolve<IBlogViewModel>();

        viewModel.LoadBlogPosts(0);

        Assert.AreEqual(0, viewModel.BlogPosts.Count, "There should be 0 blog posts.");

    }
</code>```

viewModel.BlogPosts is an ObservableCollection<IPost>

Now.. my first thought is that I'd like the LoadBlogPosts method on the ViewModel to call a static method on the BlogPost entity.

My problem is I feel like I need to inject the IDataService into the Entity object so that it promotes loose coupling.  Here are the two options that I'm struggling with:

Not use a static method and use a member method on the BlogPost entity.  Have the BlogPost take an IDataService in the constructor and use dependency injection to resolve the BlogPost instance and the IDataService implementation.

Don't use the entity to call the IDataService.  Put the IDataService in the constructor of the ViewModel and use my container to resolve the IDataService when the viewmodel is instantiated.

So with option one the layers will look like this

ViewModel(Presentation layer) -> Entity (Domain layer) -> IDataService (Service Layer)

or

ViewModel(Presentation layer) -> IDataService (Service Layer)

答:
I am not sure I understood eveything you wrote. I prefer my domain object not to know too much about persistence objects, but there is a huge debate on this in the ddd community. This is how I do things usually :

The viewModel takes a dependency on a application service (eg : BlogService).
The bogService takes a dependency on a repository service ( eg: RepositoryBlog).

blogService is used to fetch data through its repository, and start the action of the aggregate root. The dependency injector framework might take care of all your dependency injection.

When thinking about injection of dependence, you might think of the lifetime of your object. if the dependency equals or is greater than the object, think ctor, otherwise, you might prefer injection through the method.

pseudoCode with Article as the aggregateroot:

VIEWMODEL

```<code>ViewModel (IArticleService service)
{
    _service=service;
}

public PostNewArticle(string postText, Guid idUser)
{
    _service.PostNewArticle(postText, idUser)
}
</code>```

APPLICATION SERVICE

```<code>ArticleService(IRepositoryArticle repository )
{
    _repository = repository;
}

public PostNewArticle(string postText, Guid idUser)
{
    var user= _repository.GetUser(idUser);

    var article = user.CreateArticle(postText);

    _repository.SaveArticle(article);
}
</code>```

DOMAIN

```<code>User()
{}

public Article CreateArticle(string text)
{
    if(!user.Active)
       throw new Exception("user not active")

     return new Article(text);
}

------------------

Article(string text)
{
    _text= text;
}
</code>```

Hope it helped.

OwnerDisplayName: Buddy James

Body:
I am not sure I understood eveything you wrote. I prefer my domain object not to know too much about persistence objects, but there is a huge debate on this in the ddd community. This is how I do things usually :

The viewModel takes a dependency on a application service (eg : BlogService).
The bogService takes a dependency on a repository service ( eg: RepositoryBlog).

blogService is used to fetch data through its repository, and start the action of the aggregate root. The dependency injector framework might take care of all your dependency injection.

When thinking about injection of dependence, you might think of the lifetime of your object. if the dependency equals or is greater than the object, think ctor, otherwise, you might prefer injection through the method.

pseudoCode with Article as the aggregateroot:

VIEWMODEL

ViewModel (IArticleService service)
{
    _service=service;
}

public PostNewArticle(string postText, Guid idUser)
{
    _service.PostNewArticle(postText, idUser)
}

APPLICATION SERVICE

ArticleService(IRepositoryArticle repository )
{
    _repository = repository;
}

public PostNewArticle(string postText, Guid idUser)
{
    var user= _repository.GetUser(idUser);

    var article = user.CreateArticle(postText);

    _repository.SaveArticle(article);
}

DOMAIN

User()
{}

public Article CreateArticle(string text)
{
    if(!user.Active)
       throw new Exception("user not active")

     return new Article(text);
}

------------------

Article(string text)
{
    _text= text;
}

Hope it helped.

OwnerDisplayName: Arthis


答:
Look into OAuth which is designed for this permission-to-do-something role. You don't ask for a user identity, instead you ask the user to provide you with a token (that you trust) that you can use to determine the permissions you're willing to give that user.

All the security encryption gubbins is handled the the framework so you don't have to worry too much about just how to encrypt the communication using such a framework.

Title: Securing credentials passed to web service

Body:
I'm attempting to design a single sign on system for use in a distributed architecture. Specifically, I must provide a way for a client website (that is, a website on a different domain/server/network) to allow users to register accounts on my central system.

So, when the user takes an action on a client website, and that action is deemed to require an account, the client will produce a page (on their site/domain) where the user can register for a new account by providing an email and password.

The client must then send this information to a web service, which will register the account and return some session token type value.

The client will need to hash the password before sending it across the wire, and the webservice will require https, but this doesn't feel like it's safe enough and I need some advice on how I can implement this in the most secure way possible.

A few other bits of relevant information:

Ideally we'd prefer not to share any code with the client

We've considered just redirecting the user to a secure page on the same server as the webservice, but this is likely to be rejected for non-technical reasons.

We almost certainaly need to salt the password before hashing and passing it over, but that requires the client to either a) generate the salt and communicate it to us, or b) come and ask us for the salt - both feel dirty.

Any help or advice is most appreciated.


答:
Of course not.

The factory pattern is useful if you need to encapsulate create-time polymorphism from consumers, that is, you want to provide a transparent point from which new instances of a polymorphic type are created.

If the type in question is not polymorphic, the factory pattern is pointless.

If a single point of creation doesn't make sense, neither does the factory pattern.

If it is undesirable to hide the polymorphism details away, the factory pattern is probably inappropriate, too.

As with anything that adds complexity, you should default to not using it, but spot the point at which it is beneficial early on and apply it before it is too late.

Also, consider this: If you use a factory for everything, who creates the factory? Another factory? And who creates that?

Title: Should I use the factory design pattern for every class?

Body:
I've been writing a website in PHP. As the code becomes more complex, I keep finding problems that can be solved using the factory design pattern. For example: I've a got a class Page which has subclasses HTMLPage, XMLPage, etc. Depending on some input I need to return an object of either one of these classes. I use the factory design pattern to do this.

But as I encounter this problem in more classes, I keep having to change code which still initiates an object using its constructor. So now I'm wondering: is it a good idea to change all code so that it uses the factory design pattern? Or are there big drawbacks?

I'm currently in a position to change this, so your answers would be really helpful.


答:
What exactly do you need? To be sure that the password won't be read by a man in the middle? To be sure that the man in the middle wouldn't be able to log on?

If all you want is preventing the man in the middle from reading the passwords, just hash those passwords. It's as easy as that.

You may also want to avoid the man in the middle from getting the user name. Here, you wouldn't be able to transmit only the hash, but instead, you can encrypt the user name/password pair with a public key sent to the client, given that the server will have the private key for the decryption.

If you want to prevent the man in the middle from logging on, then the task is slightly more complicated. You can still use public/private keys, but:

either the public key should be communicated in advance to the consumer of the web service (which has a drawback of using the same key pair again and again, as well as the difficulty of transmitting the private key by some other channel where the man in the middle cannot catch it),

or the consumer of the web service can send a second public key which will serve for the server to encrypt its own public key in the response.


答:
Create an static Factory class.

That class will have static methods like this:

```<code>public static class Factory{

    public static Vehicle getCarInstance(){ ... }
    public static Vehicle getPlaneInstance(){ ... }
    public static Vehicle getVehicleInstance(int TYPE){ ... }

    public static Vehicle getVehicleWithPlaqueNumber(String plaqueNo){...}

    public static Account getAccountByID(int ID){..}

}
</code>```

You don't need a Factory for every class.

Body:
Create an static Factory class.

That class will have static methods like this:

public static class Factory{

    public static Vehicle getCarInstance(){ ... }
    public static Vehicle getPlaneInstance(){ ... }
    public static Vehicle getVehicleInstance(int TYPE){ ... }

    public static Vehicle getVehicleWithPlaqueNumber(String plaqueNo){...}

    public static Account getAccountByID(int ID){..}

}

You don't need a Factory for every class.


问:
Is there an appropriate coding style for implementing an algorithm during an interview?
I failed an interview question in C years ago about converting hex to decimal by not exploiting the ASCII table if (inputDigitByte > 9) hex = inputDigitByte - 'a'.  The rise of Unicode has made this question pretty silly, but the point was that the interviewer valued raw execution speed above readability and error handling.

They tell you to review algorithms textbooks to prepare for these interviews, yet these same textbooks tend to favor the implementation with the fewest lines of code, even if it has to rely on magic numbers (like "infinity") and a slower, more memory-intensive implementation (like a linked list instead of an array) to do that.  I don't know what is right.

Coding an algorithm within the space of an interview has at least 3 constraints: time to code, elegance/readability, and efficiency of execution.  What trade-offs are appropriate for interview code?

How much do you follow the textbook definition of an algorithm?  Is it better to eliminate recursion, unroll loops, and use arrays for efficiency?  Or is it better to use recursion and special values like "infinity" or Integer.MAX_VALUE to reduce the number of lines of code needed to write the algorithm?

Interface: Make a very self-contained, bullet-proof interface, or sloppy and fast?  On the one extreme, the array to be sorted might be a public static variable.  On the other extreme, it might need to be passed to each method, allowing methods to be called individually from different threads for different purposes.

Is it appropriate to use a linked-list data structure for items that are traversed in one direction vs. using arrays and doubling the size when the array is full?  Implementing a singly-linked list during the interview is often much faster to code and easier remember for recursive algorithms like MergeSort.

Thread safety - just document that it's unsafe, or say so verbally?  How much should the interviewee be looking for opportunities for parallel processing?

Is bit shifting appropriate? x / 2 or x >> 1

Polymorphism, type safety, and generics?

Comments?

Variable and method names: qs(a, p, q, r) vs: quickSort(theArray, minIdx, partIdx, maxIdx)

How much should you use existing APIs?  Obviously you can't use a java.util.HashMap to implement a hash-table, but what about using a java.util.List to accumulate your sorted results?

Are there any guiding principals that would answer these and other questions, or is the guiding principal to ask the interviewer?  Or maybe this should be the basis of a discussion while writing the code?

If an interviewer can't or won't answer one of these questions, are there any tips for coaxing the information out of them?

答:
There is an awful lot in your question above so I am not positive I am going to hit on all of your points but let me at least give you some feedback.

First I am a Director of Software Development at a medium sized enterprise mobility company and we have grown quite a bit in the last few years. As a result I do a lot of programming interviews and although I am in management (queue typical useless manager joke) I still code and architect quite heavily and am very hands on. Because of this I also over see one of the main programming challenges during the interview. So here are the things I check for and I think are appropriate as well as some answers to your above question.

I have a small handful of challenges that take between 40 minutes to 2 hours to complete and I allow all of that time. I also allow myself to be a resource to the interviewee as if I was Google and I allow them to do some searches online if required. I do test algorithms but I do so in such a way as they are hidden in the use case and problem statement.

Here is where I think you are looking for answers. I do use a whiteboard currently and so I coach the interviewee to use whatever coding style they are comfortable with in the language I am checking for. I give them a few options of language to pick from based on the job reqs. I expect that whatever coding style they use they can back it up and are consistent in using it. I wouldn't fail an interviewee on coding style alone unless it was obvious they were looking up answers and using several different styles in putting the answer on the board.

I can usually tell how long someone has been programming and in what languages primarily based on coding style. However I don't dock someone for it. I may ask questions about why they did this or that. An example is if someone was coding a conditional and they did:

```<code>if (1 == A) {}
</code>```

versus:

```<code>if (A == 1) {}
</code>```

then I know they have been developing for a while in a C based language and they have been bit by the assignment bug more than once and used style to protect themselves. Right or wrong it tells a lot about a developer.

Now, as for your algorithm questions I look at it this way. I never test for textbook style algorithms or whether someone memorized one way to do it from a certain programming interview book. I always look for whether someone knows algorithms in general and can code a few ways to do one or notice when one is required in a solution. I never straight out ask for someone to tell me how to code a doubly linked lists or tell me what the most efficient sort is. Sometimes I will ask someone to give me what the BigO notation is for an algorithm they put on the board or to explain it in more depth.

If time allows and say the interviewee has solved the problem in less time than is required I love for them to go back and refactor, comment, explain, unit test and what not the answer. It shows more concern and a greater depth of understanding and some pride in what they do. This versus someone just trying to get through the development interview. Time willing or not a passionate developer will sit there and go over what they did and refine it almost always. I have rarely been burned hiring a passionate developer like that. Saying that, I do think basic comments are good to use always. If they are lacking I will sometimes start asking a lot of questions and normally they get the clue and start putting comments down so I stop bugging them :).

I don't mind a developer using an API that is part of the language set if it makes sense to do it. If I am trying to dig out whether they understand a certain algorithm I might say go ahead and use that API call, but do explain to me what it does and give me some detail. Understanding more than rote algorithm memorization is always expected.

In the end I am looking for problem solvers. Whether they are coding craftsmen, developers, rote development people that memorized the entirety of the Java API or whatever they have a job with me. They just need to be able to solve the problems we have with a decent velocity while working with a team.

Saying all of that I have been on more than one development interview where I had to do basic algorithms and I have even failed an interview because the person expected one version of the algorithm that was straight out of a book and failed to understand that what I did was the exact same algorithm. It happens. You don't want to work there anyway. So in the end it pays to know bit shifting, sorting, basic data structure, linked lists, Big O Notation, recursion, good programming style and all of the normal things expected of a developer even if you don't use them daily. However know and understand them fully and you will be better prepared. If you failed because someone didn't like your style, either it was so bad that maybe you should do some soul searching, or more likely it is a place you wouldn't want to work anyway.

Body:
There is an awful lot in your question above so I am not positive I am going to hit on all of your points but let me at least give you some feedback.

First I am a Director of Software Development at a medium sized enterprise mobility company and we have grown quite a bit in the last few years. As a result I do a lot of programming interviews and although I am in management (queue typical useless manager joke) I still code and architect quite heavily and am very hands on. Because of this I also over see one of the main programming challenges during the interview. So here are the things I check for and I think are appropriate as well as some answers to your above question.

I have a small handful of challenges that take between 40 minutes to 2 hours to complete and I allow all of that time. I also allow myself to be a resource to the interviewee as if I was Google and I allow them to do some searches online if required. I do test algorithms but I do so in such a way as they are hidden in the use case and problem statement.

Here is where I think you are looking for answers. I do use a whiteboard currently and so I coach the interviewee to use whatever coding style they are comfortable with in the language I am checking for. I give them a few options of language to pick from based on the job reqs. I expect that whatever coding style they use they can back it up and are consistent in using it. I wouldn't fail an interviewee on coding style alone unless it was obvious they were looking up answers and using several different styles in putting the answer on the board.

I can usually tell how long someone has been programming and in what languages primarily based on coding style. However I don't dock someone for it. I may ask questions about why they did this or that. An example is if someone was coding a conditional and they did:

if (1 == A) {}

versus:

if (A == 1) {}

then I know they have been developing for a while in a C based language and they have been bit by the assignment bug more than once and used style to protect themselves. Right or wrong it tells a lot about a developer.

Now, as for your algorithm questions I look at it this way. I never test for textbook style algorithms or whether someone memorized one way to do it from a certain programming interview book. I always look for whether someone knows algorithms in general and can code a few ways to do one or notice when one is required in a solution. I never straight out ask for someone to tell me how to code a doubly linked lists or tell me what the most efficient sort is. Sometimes I will ask someone to give me what the BigO notation is for an algorithm they put on the board or to explain it in more depth.

If time allows and say the interviewee has solved the problem in less time than is required I love for them to go back and refactor, comment, explain, unit test and what not the answer. It shows more concern and a greater depth of understanding and some pride in what they do. This versus someone just trying to get through the development interview. Time willing or not a passionate developer will sit there and go over what they did and refine it almost always. I have rarely been burned hiring a passionate developer like that. Saying that, I do think basic comments are good to use always. If they are lacking I will sometimes start asking a lot of questions and normally they get the clue and start putting comments down so I stop bugging them :).

I don't mind a developer using an API that is part of the language set if it makes sense to do it. If I am trying to dig out whether they understand a certain algorithm I might say go ahead and use that API call, but do explain to me what it does and give me some detail. Understanding more than rote algorithm memorization is always expected.

In the end I am looking for problem solvers. Whether they are coding craftsmen, developers, rote development people that memorized the entirety of the Java API or whatever they have a job with me. They just need to be able to solve the problems we have with a decent velocity while working with a team.

Saying all of that I have been on more than one development interview where I had to do basic algorithms and I have even failed an interview because the person expected one version of the algorithm that was straight out of a book and failed to understand that what I did was the exact same algorithm. It happens. You don't want to work there anyway. So in the end it pays to know bit shifting, sorting, basic data structure, linked lists, Big O Notation, recursion, good programming style and all of the normal things expected of a developer even if you don't use them daily. However know and understand them fully and you will be better prepared. If you failed because someone didn't like your style, either it was so bad that maybe you should do some soul searching, or more likely it is a place you wouldn't want to work anyway.


答:
The ultimate career path of the software generalist is to become the one person IT army, able to take on any problem involving code of any kind as a self-employed mercenary.  I'd imagine such people would be extremely rare, but they may exist somewhere. ;)

The generalist may have the challenge of maintaining their skill set as I'd imagine most people in this role would end up specializing a bit in terms of what they experience as it isn't often that a company would give the same guy the opportunity to know every kind of system,e.g. CRM, ERP and CMS to name a few by acronym.  There are various points between the generalist and specialist though as something like web development could be seen as being rather general or rather specialized depending on one's view.

Title: What is the career path for a software generalist?

Body:
A question on software specialties inspired this question.

How valuable is a software generalist compared to a specialist?

When I say generalist, I mean someone who can take a project from requirements to deployment, and is competent with all phases of the software development lifecycle. Someone who can put all the specialties together into a cohesive whole. An expert generalist knows his or her weaknesses and fills them by relying on specialists - example: Oracle specialists or UX specialists.

What do you see as the ultimate career path of the software generalist?


问:
What should be allowed inside getters and setters?
I got into an interesting internet argument about getter and setter methods and encapsulation. Someone said that all they should do is an assignment (setters) or a variable access (getters) to keep them "pure" and ensure encapsulation.

Am I right that this would completely defeat the purpose of having getters and setters in the first place and validation and other logic (without strange side-effects of course) should be allowed?

When should validation happen?

When setting the value, inside the setter (to protect the object from ever entering an invalid state - my opinion)

Before setting the value, outside the setter

Inside the object, before each time the value is used

Is a setter allowed to change the value (maybe convert a valid value to some canonical internal representation)?

答:
If the getter/setter simply mirrors the value then there is no point in having them, or in making the value private. There is nothing wrong with making some member variables public if you have a good reason. If you are writing a 3d point class then having .x, .y ,.z public makes perfect sense.

As Ralph Waldo Emerson said, "A foolish consistency is the hobgoblin of little minds, adored by little statesmen and philosophers and the designers of Java."

Getters/setters are useful where there may be side effects, where you need to update other internal variables, recalculate cached values and protect the class from invalid inputs.

The usual justification for them, that they hide the internal structure, is generally the least useful. eg. I have these points stored as 3 floats, I might decide to store them as strings in a remote database so I'll make getters/setters to hide them, as if you could do that without having any other effect on the caller's code.


问:
Is the UX affected negatively by fully cacheable pages?
I want to have fully cacheable pages in my websites, but one cannot do that if they contain user-specific data, like the userbar or things in the UI that can change depending on the permissions the user has.

So I was thinking whether it was possible to pull everything that is user-specific via ajax, and update the UI accordingly.

But I'm worried that this might be annoying for the user, and also it might be difficult to develop.

What do you think? Is there a pattern or something I can follow to deal with this?

答: Yes, pulling dynamic data via AJAX is a totally viable solution. Not sure if that pattern has a name or not, but I've done it before. Another option that is supported by some edge cache platforms (both hosted and otherwise) is ESI which works like SSI, but allows you set a custom TTL for page fragments. One thing to consider is whether you will have content that is unique per visitor (like a welcome message) versus having a handful of permutations which might be managed with slightly different URLs (like a query param or hashbang).</p>


问:
Can a flow diagram have more than one start?
I'm drawing a flow diagram which should visualize the communication between 4 services I created.

Now I've got a question I'm not quite sure about. There are two ways the services could be started. Is it allowed to have multiple starting-points in a flow chart?

And: do I have to visualize error handling, like a service not being available? I think this doesn't belong in a flow chart, perhaps?

答:
If you are using flowcharts, then you can have 3 separate flowcharts. 1 to represent the overall view showing the decision that leads to initiating the service in the 2 different ways you say you have in your case. The other two diagrams will detail the process in each scenario. Flow charting is a loose technique with hardly any rules beyond what the shapes mean. This causes an inconsistency problem sometimes.

For documenting OO systems, I suggest you use UML 2.0+ and in particular Activity diagrams (similar to flow charts) and Sequence diagrams as well as use cases.


答:
It really depends on the job you're applying for, and even for the same job, different interviewers will have different opinions.  The best bet is to ask the interviewer.  If they can't or won't give you an answer, then your best bet is to use your best judgment, defend your choice, and explain how you would do it given different criteria.  "This is the simplest implementation, but if parallelization were a big concern, I would do it this way."

You might think ASCII is obsolete, for example, but there are a whole bunch of embedded C programmers who have never needed to use Unicode their entire career, for whom using the ASCII table in that manner is more readable and less error prone, not just a matter of "raw execution speed."  Asking such a question is a good way to assess how familiar you are with that particular programming subculture.  If you're not, that's not necessarily a deal breaker, especially if you defended your design decisions well, but you'd still need to show an ability to adapt to the coding style of the job you're applying for.

Title: Is there an appropriate coding style for implementing an algorithm during an interview?

Body:
I failed an interview question in C years ago about converting hex to decimal by not exploiting the ASCII table if (inputDigitByte > 9) hex = inputDigitByte - 'a'.  The rise of Unicode has made this question pretty silly, but the point was that the interviewer valued raw execution speed above readability and error handling.

They tell you to review algorithms textbooks to prepare for these interviews, yet these same textbooks tend to favor the implementation with the fewest lines of code, even if it has to rely on magic numbers (like "infinity") and a slower, more memory-intensive implementation (like a linked list instead of an array) to do that.  I don't know what is right.

Coding an algorithm within the space of an interview has at least 3 constraints: time to code, elegance/readability, and efficiency of execution.  What trade-offs are appropriate for interview code?

How much do you follow the textbook definition of an algorithm?  Is it better to eliminate recursion, unroll loops, and use arrays for efficiency?  Or is it better to use recursion and special values like "infinity" or Integer.MAX_VALUE to reduce the number of lines of code needed to write the algorithm?

Interface: Make a very self-contained, bullet-proof interface, or sloppy and fast?  On the one extreme, the array to be sorted might be a public static variable.  On the other extreme, it might need to be passed to each method, allowing methods to be called individually from different threads for different purposes.

Is it appropriate to use a linked-list data structure for items that are traversed in one direction vs. using arrays and doubling the size when the array is full?  Implementing a singly-linked list during the interview is often much faster to code and easier remember for recursive algorithms like MergeSort.

Thread safety - just document that it's unsafe, or say so verbally?  How much should the interviewee be looking for opportunities for parallel processing?

Is bit shifting appropriate? x / 2 or x >> 1

Polymorphism, type safety, and generics?

Comments?

Variable and method names: qs(a, p, q, r) vs: quickSort(theArray, minIdx, partIdx, maxIdx)

How much should you use existing APIs?  Obviously you can't use a java.util.HashMap to implement a hash-table, but what about using a java.util.List to accumulate your sorted results?

Are there any guiding principals that would answer these and other questions, or is the guiding principal to ask the interviewer?  Or maybe this should be the basis of a discussion while writing the code?

If an interviewer can't or won't answer one of these questions, are there any tips for coaxing the information out of them?