答:
I think that this is a really hard problem with no direct solution.  Here are some ideas on what you might try doing:

Fear of Change
On the subject of changing things for the better I  get why management fears change.  People are used to things a certain way and if you change it the users will revolt (maybe).  Change is a scary things and usually requires a lot of thought and study before done.  What you need is data to show that this is better and that users want it.  Speaking of gmail you might look into doing something like "Google Labs" where you could enable/disable new features so that users can give them a try.  Then hook up some data collection around this to help back up your changes.

Changing the Software Development Process
Again change is hard people don't just change because you say there is a better way.  I think that in this scenario my best recomendation is to lead by example.  Do things that way that you want them to be done and show people how much better it is.  Also, and this is key, you need to find the others that share your thoughts.  If you can get a few people on board that will greatly help your cause.  Once you can show some results then you can approach management about making these changes wider.  I find that a top down and a grass roots effort really does help with making changes.

Also on the tools side companies fear upgrading/changing these because they cost money and the results of new tools are not always measurable.  My recomendation here is to make your own tools.  If you make your own you will save yourself time and do better work.  Hopefully people wills start to notice and then want to use them too.

Changing management
This is hard and I am not sure how do it aside from being someone who produces results and has their opinion valued.  Once your opinion is valued people may start to listen or they may not.

Lastly remember change is hard and takes time.  Hang in there and start small and build up.

Title: What to do as a Dev when for years their team has lacked product innovation, not used project mgmt methodologies, and kept bad Software Dev practices?

Body:
I am interested in knowing how to deal with a current software development process that has not been changed for years and will eventually lead to product and team failure. Yes, probably the easier way to solve this is changing jobs, but with this economy is easier said than done. However, if you have specific examples and have seen or been multiple times in same situation and think that the best solution to address these issues, is to leave the company, then please support your answer. The point is, this question really has an answer especially if multiple experts on the subject end up indicating that the best route to go is : route A.

I know tons of developers have been or are in similar situations. This is one of the main reasons why companies go from being # 1 in their market to becoming last or even off the market. Hopefully the answers in this post will help other developers facing similar obstacles. In a small or large development team this usually happens:

Some developers seem not to care and decide to go with the flow and prefer to leave code with lots of code smell the way it is and development process as is,

Others get tired of no change and resign and move to another company,

Others seem to be afraid to talk and prefer to stay quiet,

At times very few developers or just one tries to speak up for improvement of product, and tells the team how important is to follow best coding practices and benefits of doing so for clients, users and team. These type of developers usually decide to stay with the team due to reasons such as company offers benefits that very few software companies offer, or the product has lots of potential, etc.

The product in our team is just a fraction of where the company gets its revenue from as it has an umbrella of products (this company is not a software/hardware company; therefore, no constant patent litigation, at least for now, which creates job instability). What I have learned so far during these years from other developers’ experiences and my experience is that to really know a development team, it takes time, not days, nor weeks, but a few months. During the interview process if the team wants to hire you, or needs you; they make everything sound great, and they might tell you what you want to hear. However, the reality is different when you start working in that team and begin digging inside the code and moving towards the complete SDLC process.  This is when as a developer, you start seeing the reality of the job you got into. This reality makes it difficult to want to move from one company to another because it is hard to know if the company you move to will be better or worse. Yes, you can read Glassdoor reviews etc.., but how many of those online reviews are real, and not from HR?

What would be the best way to tackle the issues outlined below considering that manager from the beginning has always resisted to change, and previous developers have been doing the same for years?

Lack of product Innovation for years: Product has lots of potential and brings good revenue to the company, but product looks like it was made 20 years ago. Some users have complained that product is not user friendly nor intuitive, and others have mentioned that are used to apps like Gmail and get frustrated when using the product because of not having similar features. The main issue here is that when you try as a developer to make changes to the product and start to move main elements of product around just a couple pixels away (to make it more user friendly, or intuitive), manager panics, and tells you to put it back where it was. If you try to add a feature that will benefit productivity for users, manager asks you to  remove it because of "users are used to doing the process the way it is etc.." I think you got the point of the resistance to change, improvement and innovation (manager is not open to change, even when you as a developer provide strong arguments of benefits). Company has a few competitors in the field (the products of few of them are way more competitive), but somehow the company has maintained the current clients for years.

Lack of project management coordination: As a result of this, some projects are delivered late, with bugs and some clients complain (clients report the bugs too), or budget is used too fast prior to delivering project etc.. I've provide them a few project coordination tips and the ideas are now being used regularly to track progress of projects and tasks to be done.

Bad software Development Practices: Code smell is seen on most if not all files, no documentation, code redundancy, front end tier and back end mixed on same file, outdated development tools, no a real testing environment nor test tools (just copy and paste files from dev environment to production, and then test manually that things look good and release) . Most of the development tools I use for development and testing where unknown by team, as team only uses 2 IDEs for code development and source control is only available for development environment. Other developers have tried to use latest frameworks to improve current issues, but manager does not like it because of "what if you leave, then who is going to maintain that code?, let’s leave it the way it is" Some of those developers already left and moved to another companies.

In summary, I am sure similar situations happen to many developers in other companies but due to different circumstances, a developer might prefer to stay in the team than going to another company for reasons like (convenience of job, work flexibility, company benefits, or just because a better opportunity has not arrived). There is not perfect company that I know of, but how would you as a developer behave and approach all these issues in order to keep things positive and ultimately promote change for the improvement of product and betterment of the software development process (whether you have many years of development experience or just a few)? I know this is post is long, but I preferred to give extra details to increase chances of getting more useful feedback.

Thanks a lot for your all your feedback and time


问:
Advice needed - CMS vs. framework
I am going to make a website for a client that wants to be able to alter the site about every week (changing pictures and textual information mostly). It is for a restaurant and so the client wants to alter the menu and images on an almost weekly basis. I've always made my websites and web apps from a framework or from scratch and have never worked with a CMS, but would a situation like this warrant the use of a CMS? What are some other options?

Edit: I would really like a CMS to be a last resort option, but if it is most likely the best option I will use it.

答:
As DougM stated, what your customer is looking for is a CMS. Although the requirements are simple, it can be quite time consuming to build it all from scratch. Here's a list of some features you will need:

website front-end

session management (to log in to an admin interface)

file handling or database connection

security (in all of the above)

If you don't have your personal code base for these things and don't want to spend too much time with this website, consider using an existing CMS. It's a lot easier and faster to implement. Also, as TimG mentioned, it's an experience for itself.

On the other hand, if you invest some more time in this project, you can build your own CMS, which may save you time for future projects.

ContentLicense: CC BY-SA 3.0

Title: Advice needed - CMS vs. framework


问:
What to do as a Dev when for years their team has lacked product innovation, not used project mgmt methodologies, and kept bad Software Dev practices?
I am interested in knowing how to deal with a current software development process that has not been changed for years and will eventually lead to product and team failure. Yes, probably the easier way to solve this is changing jobs, but with this economy is easier said than done. However, if you have specific examples and have seen or been multiple times in same situation and think that the best solution to address these issues, is to leave the company, then please support your answer. The point is, this question really has an answer especially if multiple experts on the subject end up indicating that the best route to go is : route A.

I know tons of developers have been or are in similar situations. This is one of the main reasons why companies go from being # 1 in their market to becoming last or even off the market. Hopefully the answers in this post will help other developers facing similar obstacles. In a small or large development team this usually happens:

Some developers seem not to care and decide to go with the flow and prefer to leave code with lots of code smell the way it is and development process as is,

Others get tired of no change and resign and move to another company,

Others seem to be afraid to talk and prefer to stay quiet,

At times very few developers or just one tries to speak up for improvement of product, and tells the team how important is to follow best coding practices and benefits of doing so for clients, users and team. These type of developers usually decide to stay with the team due to reasons such as company offers benefits that very few software companies offer, or the product has lots of potential, etc.

The product in our team is just a fraction of where the company gets its revenue from as it has an umbrella of products (this company is not a software/hardware company; therefore, no constant patent litigation, at least for now, which creates job instability). What I have learned so far during these years from other developers’ experiences and my experience is that to really know a development team, it takes time, not days, nor weeks, but a few months. During the interview process if the team wants to hire you, or needs you; they make everything sound great, and they might tell you what you want to hear. However, the reality is different when you start working in that team and begin digging inside the code and moving towards the complete SDLC process.  This is when as a developer, you start seeing the reality of the job you got into. This reality makes it difficult to want to move from one company to another because it is hard to know if the company you move to will be better or worse. Yes, you can read Glassdoor reviews etc.., but how many of those online reviews are real, and not from HR?

What would be the best way to tackle the issues outlined below considering that manager from the beginning has always resisted to change, and previous developers have been doing the same for years?

Lack of product Innovation for years: Product has lots of potential and brings good revenue to the company, but product looks like it was made 20 years ago. Some users have complained that product is not user friendly nor intuitive, and others have mentioned that are used to apps like Gmail and get frustrated when using the product because of not having similar features. The main issue here is that when you try as a developer to make changes to the product and start to move main elements of product around just a couple pixels away (to make it more user friendly, or intuitive), manager panics, and tells you to put it back where it was. If you try to add a feature that will benefit productivity for users, manager asks you to  remove it because of "users are used to doing the process the way it is etc.." I think you got the point of the resistance to change, improvement and innovation (manager is not open to change, even when you as a developer provide strong arguments of benefits). Company has a few competitors in the field (the products of few of them are way more competitive), but somehow the company has maintained the current clients for years.

Lack of project management coordination: As a result of this, some projects are delivered late, with bugs and some clients complain (clients report the bugs too), or budget is used too fast prior to delivering project etc.. I've provide them a few project coordination tips and the ideas are now being used regularly to track progress of projects and tasks to be done.

Bad software Development Practices: Code smell is seen on most if not all files, no documentation, code redundancy, front end tier and back end mixed on same file, outdated development tools, no a real testing environment nor test tools (just copy and paste files from dev environment to production, and then test manually that things look good and release) . Most of the development tools I use for development and testing where unknown by team, as team only uses 2 IDEs for code development and source control is only available for development environment. Other developers have tried to use latest frameworks to improve current issues, but manager does not like it because of "what if you leave, then who is going to maintain that code?, let’s leave it the way it is" Some of those developers already left and moved to another companies.

In summary, I am sure similar situations happen to many developers in other companies but due to different circumstances, a developer might prefer to stay in the team than going to another company for reasons like (convenience of job, work flexibility, company benefits, or just because a better opportunity has not arrived). There is not perfect company that I know of, but how would you as a developer behave and approach all these issues in order to keep things positive and ultimately promote change for the improvement of product and betterment of the software development process (whether you have many years of development experience or just a few)? I know this is post is long, but I preferred to give extra details to increase chances of getting more useful feedback.

Thanks a lot for your all your feedback and time

答:
Sounds like it's time for you to learn about cash cows.  Go here and here.  And take a look at the Growth Share Matrix.  The GSM provides some additional information on why cash cow is a good state to be in.

Investopedia (second link) probably has the best quote in this case.

A cash cow requires little investment capital and perennially provides positive cash flows, which can be allocated to other divisions within the corporation. These cash generators may also use their money to buy back shares on the market or pay dividends to shareholders.

As you noted, there are some upsides to being on a cash-cow project.

It's stable

A modest degree of new development is guaranteed

There's always bug-fix work to tackling.

And as you also noted, there are some downsides to those projects.

It's stable and the code base doesn't turn over much

New technologies are generally ignored (too expensive to bolt on)

And things get ... stale.

I once worked on a project where I had many similar complaints as what you've raised.  I distinctly remember sharing my concerns about the code base with my boss at the time.  His insight wasn't particularly enlightening so I won't share it.  But I stuck out the project and truth be told, it was one of the better projects I've seen.  No, it wasn't flashy.  Yes, we missed deadlines.  Yes, I racked up a few death marches from there.  No, the code technology wasn't all that innovative but we did generate some amazing solutions.

The problem was me.  I didn't have enough perspective to understand what a code base really requires in order to survive.  I didn't have the experience to see where the innovation was truly occurring.  I didn't understand the market fundamentals that dictated what the appropriate level of funding was for that cash-cow project.

I would encourage you to see this as a learning opportunity to better understand how business works and how you can improve your skills in adapting a product to the business' needs.  While the work may not be flashy, the learning potential is high and those skills will stand you well later on in your career.  The majority of corporate level development revolves around all of the constraints you just mentioned.  The code stinks; things were slapped in place to contain deadlines that had already escaped; many developers are resistant to change.

At some point, you'll still move on from the project.  The lessons you can take away with you can be real career making lessons.


问:
Documenting reports for end-users
I have an application that has about a dozen reports that provide totals and summaries of data in the database based on date ranges given as parameters. The application is near the end of user testing. The end-users are saying that the numbers in the totals don't match what they expect based on test data they have entered.

It seems like the developers and users interpret the data differently.

How can I document the reports in a way that the users will be able to see which records are being counted,summed etc to get the totals, without overwhelming them with technical details?

So far I have tried to write out the queries used in the reports in pseduo-code, but it seems too technical and I'm worried I'll just get the same 'The report doesn't produce the correct data.'...

答: If there is a descrepancy in a report like this, you will benefit from having some kind of data browsing interface.  Queries and database tools can be pretty awkward and intimidating to some end-users.  I have had some postive results from making a few diagnostic reports that show the pre-aggregated data (for each report).  Then if you need to, you can review the raw data with the users or they can review it themselves at their convenience.  It is a big plus if you can make it easy to pull the data into Excel.  Then you/they can roll-up/summarize/aggregate and then compare results to your report.  </p>

Title: Documenting reports for end-users


问:
Is it completely impossible to have total separation without leakage of any kind in a design?
For the past week I have been attempting to write a proof-of-concept project using dependency injection, a service layer, unit of work pattern + repository.

I am looking to design something that can easily be consumed by any type of application - be it a Windows desktop application, a CLI application, an ASP.NET MVC application, even an iOS application running Mono. Please, bear in mind that this is just for a proof-of-concept.

Until now, I have written

A Unit of Work + Unit of Work Factory for NHibernate and Entity Framework (2 OR/M frameworks for .NET)

(Generic) repository. There is one repository per OR/M implementation, taking it's respective Unit of Work Factory as a constructor parameter. It needs this to grab the current unit of work (since it's implementation contains stuff necessary for each OR/M framework to function)

This has accomplished:

I can swap out implementations of the repository and Unit of Work factory with NHibernate and Entity Framework, and it will just work. This is good, except I haven't implemented a real application yet, only unit-tests.

These are the problems/challenges I am facing:

<s>Each application type (Desktop, CLI, ASP.NET MVC, iOS, Android, whatever) do not define a unit of work the same way. A desktop application (AFAIK) should have a Unit of Work per screen - a Web application should have a Unit of Work per request, etc. I don't know how I would share a single unit of work with all the repositories/services (see below) that needs it.</s> - Michael is right.

I want all my logic to reside in a service layer. The service layer decides when a Unit of Work should commit. The idea is that whoever calls the service, knows what to pass to it, and knows what to expect as a result. If something goes wrong, the service logs it. If I had to do this on a per-application basis, DRY would be violated (right?).

It seems that if I had to implement this totally separated design, the amount of code I got to reuse would not be as much as the amount of code I'd have to write in order to implement it in each application type, which would, in the end, most likely leak my IoC container into the application.

Am I totally crazy for even attempting this?

EDIT: The actual problem I am facing, is providing my service layer and repositories with the same instance of a Unit of Work, no matter what application type is being used.

答:
It sounds like you are either doing something extremely stateful in your services or something very odd in the client.

EF context or NHibernate equiv are not going to be an easy thing to maintain across requests, once you get to load balancing and such it becomes next to impossible to do correctly, so you end up passing a token or using session (which is really a token lookup anyway) and the instances do not matter as much because you end up with methods like:

```<code> AddItemToCart(CartID, ItemID)
</code>```

that are simple.  You IoC the providers and abstract with a manager/controller/service.  Even if you pass the whole object across the service it goes through a serializer or something on both ends and you have two or more instances anyway.

Body:
It sounds like you are either doing something extremely stateful in your services or something very odd in the client.

EF context or NHibernate equiv are not going to be an easy thing to maintain across requests, once you get to load balancing and such it becomes next to impossible to do correctly, so you end up passing a token or using session (which is really a token lookup anyway) and the instances do not matter as much because you end up with methods like:

 AddItemToCart(CartID, ItemID)

that are simple.  You IoC the providers and abstract with a manager/controller/service.  Even if you pass the whole object across the service it goes through a serializer or something on both ends and you have two or more instances anyway.


答:
Martin Fowler's quote is relevant:  "You can change your organization or change your organization."  Given that you've apparently decided to change your organization (make it better) instead of change your organization (work for a different organization), here are a few suggestions.

First, a lot of your course of action depends on details about the power structures and politics at work.  Is there one software development manager, or several?  If several, are there any of them who aren't change-averse?  How many software developers are there?  Are the developers interested in changing?  If so, there are some changes that you should be able to make even without management approval.  (As Fowler suggests in Refactoring, you may not even have to tell management.  You're presumably hired to develop software as best you can, so if there's a better way of doing it, then just do it.)

Second, keep in mind that management may have good reasons for what they're doing.  You're a software developer; your job is to develop good software and to know good techniques for doing so.  Management's job is to understand bigger picture issues and business considerations that may be beyond your purview.  Even if you're right and they're wrong about what the business considerations are (your concerns about lack of innovation, late delivery, customer complaints, etc.), understanding where management is coming from will help you communicate in their terms, alleviate their concerns, and so on.

Third (and related), make sure you can speak the language of business.  A business is (rightly) not directly concerned with good software development practices; a business is concerned with serving customers' needs and making a profit.  (And many businesses will obviously do the minimum needs-serving possible to make a profit.)  You'll be more effective at promoting change if you can explain how bad software development practices and lack of innovation will hurt the company's profit or long-term health.

Fourth, changing a company culture from the position of a rank-and-file worker is extremely hard.  James Shore (an agile consultant and author) wrote a Change Diary describing his own efforts at doing so.  I'd strongly recommend reading the whole thing.  A few relevant points:

Don't try to change everything at once.  Find the biggest pain points and start there.  Get everyone on board by helping them to see how your changes address those pain points.

Understand others' perspectives.  Shore talks about how the changes he was pushing from a software development perspective were resisted by the project manager because he (Shore) failed to consider how the changes would affect the project manager.

Eventually, you'll need some support from higher up, even if you're prompting most of the changes yourself.  Shore talks about his champion ("somebody I work with who has more clout than me and thinks along generally the same lines I do").


答:
I'm struggling to see why you need to reuse units of work across service calls. Loading a shopping cart is a unit of work. Saving changes to that shopping cart is a separate unit of work.

Perhaps the real problem is in your definition of what comprises a unit of work. Whenever you call a service method in the application API, that is, by definition, a unit of work. If your units of work are breaking across multiple calls, that suggests to me that you have a business logic leak into your UI code.

Title: Is it completely impossible to have total separation without leakage of any kind in a design?

Body:
For the past week I have been attempting to write a proof-of-concept project using dependency injection, a service layer, unit of work pattern + repository.

I am looking to design something that can easily be consumed by any type of application - be it a Windows desktop application, a CLI application, an ASP.NET MVC application, even an iOS application running Mono. Please, bear in mind that this is just for a proof-of-concept.

Until now, I have written

A Unit of Work + Unit of Work Factory for NHibernate and Entity Framework (2 OR/M frameworks for .NET)

(Generic) repository. There is one repository per OR/M implementation, taking it's respective Unit of Work Factory as a constructor parameter. It needs this to grab the current unit of work (since it's implementation contains stuff necessary for each OR/M framework to function)

This has accomplished:

I can swap out implementations of the repository and Unit of Work factory with NHibernate and Entity Framework, and it will just work. This is good, except I haven't implemented a real application yet, only unit-tests.

These are the problems/challenges I am facing:

<s>Each application type (Desktop, CLI, ASP.NET MVC, iOS, Android, whatever) do not define a unit of work the same way. A desktop application (AFAIK) should have a Unit of Work per screen - a Web application should have a Unit of Work per request, etc. I don't know how I would share a single unit of work with all the repositories/services (see below) that needs it.</s> - Michael is right.

I want all my logic to reside in a service layer. The service layer decides when a Unit of Work should commit. The idea is that whoever calls the service, knows what to pass to it, and knows what to expect as a result. If something goes wrong, the service logs it. If I had to do this on a per-application basis, DRY would be violated (right?).

It seems that if I had to implement this totally separated design, the amount of code I got to reuse would not be as much as the amount of code I'd have to write in order to implement it in each application type, which would, in the end, most likely leak my IoC container into the application.

Am I totally crazy for even attempting this?

EDIT: The actual problem I am facing, is providing my service layer and repositories with the same instance of a Unit of Work, no matter what application type is being used.


问:
How to handle conflicts between developers in your team?
This is happening in every team.

For some reasons, conflicts arise in the team and they affect the overall motivation and productivity.

What is your recommended approach to solve that common problem?

Examples:

one part of the team wants to implement dependency injection, the other part think it's a waste of time.

some developers think the rest of the team is slowing down development (which explains why they are late on the schedule)

personal incompatibilities between one or more developers

one developer refuse to talk to another one (without apparent reason)

答:
TKI identifies a handful of different techniques for resolving conflicts that may be an idea for how to resolve some issues.  There are some legitimate issues such as using a framework or not, though this may be handled either by a team voting on something as one way to resolve it or by going to higher power like a manager of some kind.  Some times there can be disputes in interpreting requirements which are best handled by going to a project manager or business analyst to get a specific ruling,e.g. does a blank search return nothing as nothing was entered or does it return everything as the wild card matching used says everything has nothing in it.

If it is more personality conflicts then the question becomes how well does each know of the issue and what will be done if this persists.  This isn't so much an idle threat as much as a, "If you guys can't work this out, I'll work it out by removing at least one of you," mentality.  Course this does carry the potential for passive-aggressive behavior and other childish crap but this is what happens when bright resourceful people enter a way that doesn't use traditional weapons to resolve hostility.  "Mean Girls" has several examples of this kind of behavior, just to give a reference of sorts.

ContentLicense: CC BY-SA 2.5


答:
Your manager probably is resistant to change because he sees no (business) value is changing practices. The business sees no real problem because whatever is asked of the development team eventually gets done and client complaints don't make it to the people that care and/or can do something to ensure a better result. Either that or the business has come to accept the current state of affairs as unavoidable.

If you are going to change development practices, you need to show them that the current state of affairs is not unavoidable. And the only way you are going to be heard is by building a business case showing how the current state of affairs is running up the cost of the product and holding back the revenue potential given another state of affairs.

To build that business case you need to be talking to the product manager of this piece of software. The product manager being the person who decides on the priority of items to be developed based on the business value they represent. The product manager is (should be) the one that can see the benefit and business value of being able to build better software more quickly. (And I do hope it is not the same one as is in charge of the development team.)

The business case needs to address what the effects are on business revenue of:

Features that are not (yet) implemented that would generate more customers or retain more customers had they been implemented.

Features that are inadequately implemented that generate customer dissatisfaction and lead to attrition in customers.

The business case also needs to show how current development practices are affecting the speed and cost of developing much needed features:

How long it takes to make even the simplest changes.

How many bugs are introduced as a result of developing new features, both in the new feature as well as collateral damage in other features.

How much time is taken up with fixing these bugs that can't be spent on implementing new features.

How many support calls are generated because of these bugs and how much support staff needs to spend on these calls.

And of course needs to show how adopting better development practices is going to affect these figures.

You are probably facing the need for a (major) rewrite of (major) parts of the software. Even if you don't, then How To Survive a Ground-Up Rewrite Without Losing Your Sanity is a must read in how to approach these kinds of projects.

Final note: if the product manager isn't interested in all this, you're lost: jump ship.


问:
Why is it a good idea for "lower" application layers not to be aware of "higher" ones?
In a typical (well-designed) MVC web app, the database is not aware of the model code, the model code is not aware of the controller code, and the controller code is not aware of the view code. (I imagine you could even start as far down as the hardware, or perhaps even further, and the pattern might be the same.)

Going the other direction, you can go just one layer down. The view can be aware of the controller but not the model; the controller can be aware of the model but not the database; the model can be aware of the database but not the OS. (Anything deeper is probably irrelevant.)

I can intuitively grasp why this is a good idea but I can't articulate it. Why is this unidirectional style of layering a good idea?

答:
Because the higher levels <s>may</s>will change.

When that happens, whether because of requirements changes, new users, different technology, a modular (i.e. unidirectionally layered) application should require less maintenance and be more easily adapted to fit the new needs.


答:
Layers, modules, indeed architecture itself, are means of making computer programs easier to understand by humans. The numerically optimal method of solving a problem is almost always an unholy tangled mess of non-modular, self-referencing or even self-modifying code - whether it's heavily optimized assembler code in embedded systems with crippling memory constraints or DNA sequences after millions of years of selection pressure. Such systems have no layers, no discernible direction of information flow, in fact no structure that we can discern at all. To everyone but their author, they seem to work by pure magic.

In software engineering, we want to avoid that. Good architecture is a deliberate decision to sacrifice some efficiency for the sake of making the system understandable by normal people. Understanding one thing at a time is easier than understanding two things that only make sense when used together. That is why modules and layers are a good idea.

But inevitably modules must call functions from each other, and layers must be created on top of each other. So in practice, it's always necessary to construct systems so that some parts require other parts. The preferred compromise is to build them in such a way that one part requires another, but that part doesn't require the first one back. And this is exactly what unidirectional layering gives us: it is possible to understand the database schema without knowing the business rules, and to understand the business rules without knowing about the user interface. It would be nice to have independence in both directions - allowing someone to program a new UI without knowing anything at all about the business rules - but in practice this is virtually never possible. Rules of thumb such as "No cyclical dependencies" or "Dependencies must only reach down one level" simply capture the practically achievable limit of the fundamental idea that one thing at a time is easier to understand than two things.

Title: Why is it a good idea for "lower" application layers not to be aware of "higher" ones?

Body:
In a typical (well-designed) MVC web app, the database is not aware of the model code, the model code is not aware of the controller code, and the controller code is not aware of the view code. (I imagine you could even start as far down as the hardware, or perhaps even further, and the pattern might be the same.)

Going the other direction, you can go just one layer down. The view can be aware of the controller but not the model; the controller can be aware of the model but not the database; the model can be aware of the database but not the OS. (Anything deeper is probably irrelevant.)

I can intuitively grasp why this is a good idea but I can't articulate it. Why is this unidirectional style of layering a good idea?


答:
The fundamental motivation is this: You want to be able to rip an entire layer out and substitute a completely different (rewritten) one, and NOBODY SHOULD (BE ABLE TO) NOTICE THE DIFFERENCE.

The most obvious example is ripping the bottom layer out and substituting a different one.  This is what you do when you develop the upper layer(s) against a simulation of the hardware, and then substitute in the real hardware.

The next example is when you rip a middle layer out and substitute a different middle layer.  Consider an application that uses a protocol that runs over RS-232.  One day, you have to change the encoding of the protocol completely, because "something else changed".  (Example: switching from straight ASCII encoding to Reed-Solomon encoding of ASCII streams, because you were working over a radio link from downtown L.A. to Marina Del Rey, and you are now working over a radio link from downtown L.A. to a probe orbiting Europa, one of the moons of Jupiter, and that link needs much better forward error correction.)

The only way to make this work is if each layer exports a known, defined interface to the layer above, and expects a known, defined interface to the layer below.

Now, it is not exactly the case that lower layers know NOTHING about upper layers.  Rather, what the lower layer knows is that the layer immediately above it will operate precisely in accordance with its defined interface.  It can know nothing more, because by definition anything that is not in the defined interface is subject to change WITHOUT NOTICE.

The RS-232 layer doesn't know whether it is running ASCII, Reed-Solomon, Unicode (Arabic code page, Japanese code page, Rigellian Beta code page), or what.  It just knows that it is getting a sequence of bytes and it is writing those bytes to a port.  Next week, he might be getting a completely different sequence of bytes from something completely different.  He doesn't care.  He just moves bytes.

The first (and best) explication of layered design is Dijkstra's classic paper "Structure of the T.H.E. Multiprogramming System".  It is required reading in this business.


问:
How is IntelliJ better than Eclipse?
I know there have been questions like What is your favorite editor/IDE?, but none of them have answered this question: Why spend the money  on IntelliJ when Eclipse is free?

I'm personally a big IntelliJ fan, but I haven't really tried Eclipse. I've used IntelliJ for projects that were Java, JSP, HTML/CSS, Javascript, PHP, and Actionscript, and the latest version, 9, has been excellent for all of them.

Many coworkers in the past have told me that they believe Eclipse to be "pretty much the same" as IntelliJ, but, to counter that point, I've occasionally sat behind a developer using Eclipse who's seemed  comparably inefficient (to accomplish roughly the same task), and I haven't experienced this with IntelliJ. They may be on par feature-by-feature but features can be ruined by a poor user experience, and I wonder if it's possible that IntelliJ is easier to pick up and discover time-saving features.

For users who are already familiar with Eclipse, on top of the real cost of IntelliJ, there is also the cost of time spent learning the new app. Eclipse gets a lot of users who simply don't want to spend $250 on an IDE.

If IntelliJ really could help my team be more productive, how could I sell it to them? For those users who've tried both, I'd be very interested in specific pros or cons either way.

答:
Google just recently announced that it is moving Android development to IntelliJ.

There is a reason for this. I have been using Eclipse as an environment to teach courses for the past few years in both C++ and Android/JAVA. I have watched the quality of Eclipse deteriorate to something approaching unusable. In Fall, 2012, I adopted Eclipse Juno for my course and it was an unmitigated disaster. Not only was the program incredibly sluggish and loaded with bugs, it had several user interface changes that were beyond stupid. I now use it as a case study in bad user interface design.

I cannot recommend Eclipse to anyone at this point in time. The bug database has gotten so large that there is no chance they will ever address even a small fraction of them.

Title: How is IntelliJ better than Eclipse?


问:
simple 'defrag' logic that minimizes changes?
edit:

so clearly I didn't explain this well, so let me try again with examples.  I have a 'pipe' of a given size with signals routed through it at given offsets.  The pipe can get fragmented with signals in different offsets making it impossible to fit a new signal.  I want an algorithm that will tell me how to arrange the signals to defragment the pipe; but with a minimal number of signals actually being moved!  So for the example..

Say I have a pipe of size 16.  It has the following signals with the sizes and offsets described.

```<code>offset 0: A (size of 4; fills slots 0-3)
offset 5: C (size of 2, fills slot 5-6)
offset 8: B (size of 4, fills 8-11)
offset 14: D (size 2, fills 14-15)

Pipe: AAAA_CC_BBBB__DD
</code>```

In this case I have 1 slot open at offsets 4 & 7, and two at offset 12-13.  Now lets say I want to add a size 4 signal to this pipe.  There is no continuous space for it now, but I know I have enough space for it if I defragment.  The 'obvious' solution is to group all the signals together at the 'top' like this:

```<code>offset 0:  A (size 4, fills 0-3)
offset 4:  B (size 4, fills 4-7)
offset 8:  C (size 2, fills 8-9)
offset 10: D (size 2, fills 10-11)

Pipe: AAAABBBBCCDD____
</code>```

this leaves slots 12-15 free for my new signal.  However, to do this I repositioned 3 signals(B-D).  For each signal I moved I have to send commands down to hardware and wait for a non-trivial amount of time.

If I was smarter I could realize there is another approch.  I could reposition like this:

```<code>offset 0:  A(size 4, fills 0-3)
offset 8:  B(size 4, fills 8-11)
offset 12: C(size 2, fills 12-13)
offset 14: D(size 2, fills 14-15).

Pipe: AAAA____BBBBCCDD
</code>```

I can now fit my new signal in offsets 4-7; AND I only had to reposition one signal(B).  Thus saving on hardware calls.

I'm wondering if there is a good algorithm to detect sitations like this; where I can 'fit' a signal onto a pipe with the minimum number of signals moved.  The aproch thta comes to mind is an N! algorithm; which basically amounst to "generate every possible distribution, calculate how many moves it resulted in".  I'm loking for a faster approch.

The approch does not have to be 100% perfect, I'm looking primarily to minimize the average case, so long as the worst case isn't made too horrendous.  I know that I will never have more then 255 signals on a given pipe; so I may be able to 'get away' with N! as bad as that sounds.  I also know each signal's size is a power of 2, as is the pipe size.

also, are there any briliant algorithms for placing of signals that minimize fragmentation?

Question answered; see below.

I wanted to expain on the answer slightly to better explain how defragmentation would occure for anyone reading; buddy does explan it I wanted to point out a simpler approch to conceptualize and explain the defraging part in more detail since that was the original question.

I'm explaining my approch, which is a slightly different/simpler approch but effectively keeps the 'buddy' concept.  I'm not precomputing blocks or labeling them, this is too much effort to implement and maintain.  For me the CPU cost of calculating where a signal will go is pretty trivial compared to actual placing/deletion of signals; so I can afford to lose a tiny, linear, amount of CPU by not pre-computing to simplfy my logic.   So the process is:

for insertion:

All signals are kept in signal boundaries equal to the signal size, so a signal will start on offset where offest % signalsize=0.  For actuall offset we walk through and figure out intervals that keep this boundry.  So if my signal is size 4 on a 16 size pipe I'll look at intervals 0-4, 5-7, 8-11, 12-15.

For each interval check if all space in that interval is free.  In the simple case we have a interval with no signals in it and we just put the signal at that interval.  Important, we look at the intervals in order and place our signal in the first free interval, this ensure we break the smallest possible 'block' (using buddy terms) when we add our signal.  This should be equivlent to the buddy approch described by im3l96; except without precomputation of blocks.

if no interval is completely free we have to defrag.  For this we find the the signal with the most unused slots.  If multuple intervals have the same number of slots unused select the first interval.  We then find the largest signal in this interval and recursively call same insert algorithm for the smaller signal (except mark the interval we selcted to insert our first signal as unavailable somehow).  This moves the signal to somewhere else that it will fit.  We then find the next smallest signal in our selected interval and do the same until we moved all signals.  Worst case of 2^n-1 signals moved; where N is the number of potential signal sizes <=our signal  (assuming signals are multuple of 2 then N=log2(signalSize)).

Here is an example.  * stands for a slot marked as unavailable when we recursively call this method (ie the interval that the calling method wanted to place it's signal in, and thus doesn't want the recursive call to try to place a signal into)

Here is an exaple, simplest case I could come up with that still demonstrates full complexity.  Note: the following structure would be hard to create, but could result from the buddy approch if someone tried very very hard.

```<code>FFFFFFFF__AA_B__EEEE_HGGCC_DII_J
</code>```

Someone passes in a signal Z of size 8

we select offset 8:

defragInsert(z, size 8)

```<code>effective structure: FFFFFFFF__AA_B__EEEE_HGGCC_DII_J

placing signal in interval: __AA_B__
</code>```

defragInput(A, size 2)

```<code>effective structure: FFFFFFFF********EEEE_HGGCC_DII_J
place signal in interval (offset 20)  _H
</code>```

defragInput(H, size1)

```<code>effective structure: FFFFFFFF********EEEE**GGCC_DII_J
place signal between C & D
</code>```

return defragInput(H, size1)

```<code>effective structure: FFFFFFFF********EEEE__GGCCHDII_J
place H at offset 20 now that it's open
</code>```

return defragInput(A, size 2)

effective structure: FFFFFFFF___B__EEEEAAGGCCHDII_J
   move B now...

defragInput(B, size1)

effective structure: FFFFFFFF****EEEEAAGGCCHDII_J
   place B between I & J

return defragInput(B, size1)

effective structure: FFFFFFFF____EEEEAAGGCCHDIIBJ
   add B

return defragInsert(z, size 8)

```<code>fianl structure: FFFFFFFFzzzzzzzzEEEEAAGGCCHDIIBJ
</code>```

答:
Well, before looking for an answer, you should first define clearly what you want to minimize, that is, what kind of signal repositioning is allowed.

to take one (and just one) signal out of the pipe and add this at another place with no overlappings (and repeat that step n times)?

or to take n signals simultaneously from your pipe and reinsert them then afterwards with no overlappings (counted as n moves)?

Obviously, this first alternative is much more restricted, giving you a much smaller search space. For example, to go from AAAA_CC_BBBB__DD to AAAA_CC___DDBBBB, one will need at least 4 moves if no simultanous repositionings are allowed, and 2 moves if they are allowed.

I assume you have the first problem in mind (please confirm that), so here is my suggestion for this:

make this a graph search problem. For a give pipe, each signal configuration defines a  vertices of your graph, and the edges between those vertices are the possible repositionings.

give each vertice a value: the length of the longest continuous slot sequence

Now it should be easy to use a standard graph search technique like breadth first search or  A* search to find the smallest number of steps until you reach a pipe configuration which has enough space for the new signal you want to add.


答:
I would like to add my two cents to what Matt Fenwick and Kilian Foth have already explained.

One principle of software architecture is that complex programs should be built by composing smaller, self-contained blocks (black boxes): this minimizes dependences thus reducing complexity. So, this unidirectional dependency is a good idea because it makes it easier to understand the software, and managing complexity is one the most important issues in software development.

So, in a layered architecture, the lower layers are black boxes that implement abstraction layers on top of which the upper layers are built. If a lower layer (say, layer B) can see details of an upper layer A, then B is no longer a black box: its implementation details depend on some details of its own user, but the idea of a black box is that its content (its implementation) is irrelevant for its user!


问:
Integration test instead of unit test involving personal data?
I am trying to develop a series of unit tests for a production system that are dependent on a person's social security number. While I am more than comfortable hard coding a clearly bad social security number to test for failure, I'm uneasy about including one that is good for proper (and passing) results. The following is a simplified test that I'm using:

```<code>[TestMethod]
    public void API_Hours_Get()
    {
        var controller = new HoursController();
        var employee = new EmployeeController();
        var badResult = controller.Get(123124569);
        var goodResult = controller.Get(employee.GetEmployeeByUserId("Username").First().SSNumber);
        Assert.IsFalse(badResult.Any());
        Assert.IsTrue(goodResult.Any());
    }
</code>```

This test passes just fine and gives me the results I want. But, from my understanding, it is an integration test. From a best practices perspective, is this substitute okay for my test suite and just ignore the fact that I don't have a 'pure' unit test for the SSN-dependent modules or is there a better approach for situations like this?

答:
A better approach for this sort of thing is to create fake/test data that is operationally real enough without getting into issues like using customers SSNs and email addresses. You can then write the entire test suite against fake data -- and do things like simulate various real operational bugs across the way.

Looking at the code I think you've got some way to go here -- it looks like you aren't even setup for dependency injection which is the gateway drug to this sort of thing.

ContentLicense: CC BY-SA 4.0


答:
I think that the main reason is that it makes things more tightly coupled.  The tighter the coupling the more likely to run into issues later.  See this article more info: Coupling

Here is an excerpt:

Disadvantages

Tightly coupled systems tend to exhibit the following developmental characteristics, which are often seen as disadvantages:
  A change in one module usually forces a ripple effect of changes in other modules.
  Assembly of modules might require more effort and/or time due to the increased inter-module dependency.
  A particular module might be harder to reuse and/or test because dependent modules must be included.

With that being said on reason to have a tigher coupled system is for performance reasons.  The article that I mentioned also has some information about this too.


问:
What to do when you are faced with programming task that you have never done?
I started my career as a .NET developer 3 months ago and after a long training plan on diverse technologies, patterns and concepts the developers who were supervising me have decided that I am ready to join one of the many projects the company handles.

I am very excited to finally be able to start coding. The team I have joined is rather small for now because were starting with a new project, which is great because I get to be involved in the entire life cycle of the project. It is a web based SPA project with a backed that uses ASP.NET MVC/ASP.NET Web API and in front-end the Durandal framework and related libraries.

My problem is that after having a meeting with my colleagues and establishing the tasks and estimations for the next month I find myself in a position that I do not know if I am capable of taking on any of the tasks.

I have never done any of the created tasks and I do not know how should I proceed.

For example one of tasks created is creating a generic error handling mechanism for the entire application.

How does one usually proceed when faced with tasks that he has never done?

答:
Rejoice in that you aren't doing something you've done a hundred times before. You've found the joy of software development (for me, anyway, YMMV) - learning how to drive while you hurtle down the freeway at extraordinary speeds. This is the kind of thing a great developer lives for and excels at.

My personal process is something like this:

Research. Find out if and how this problem, or a similar problem, has been solved before. Even if you can only find information on solutions for different languages or platforms, it can still be extremely informative.

Prototype. The absolute best way to do something right is to do it wrong first. Build a solution, making everything up as you go, based on your research. Try to make it conform to the major requirements, giving consideration to ancillary requirements. Don't bother making it pretty or perfect or extensible or flexible or performant, just make it work. Take notes of lessons learned - what worked, what didn't, potential roadblocks, etc. Then throw the code away. If you're worried about looking a fool for taking too long, do this on your own time. It benefits you personally, in terms of knowledge.

Design. Combine your outside knowledge (research) with personal knowledge (prototype lessons learned) and formulate a design of what you think would be the Right Way to do it.

Cooperate. Find a senior team member, show them your proposed design, get feedback. Show it to someone else, get their feedback. Refine your design.

Iterate. If you're still unsure of your solution, make sure peer reviews are part of your iteration cycle. Bring your implementation to a senior team member regularly for feedback.

Be happy - you've advanced your knowledge, and your career, and you got to do something new and interesting instead of something old and boring you've done a thousand times before. Try to make your next project an even greater challenge.

And lastly, don't worry too much about appearances. As a dev team manager, I'd rather have someone who can prove they can learn whatever they need to learn as they need it, than someone who can prove they already know the one thing we're trying to do right now. The former will be more useful for whatever we end up doing tomorrow, or next month, or next year.


问:
Worst coding standard you've ever had to follow?
Have you ever had to work to coding standards that:

Greatly decreased your productivity?

Were originally included for good reasons but were kept long after the original concern became irrelevant?

Were in a list so long that it was impossible to remember them all?

Made you think the author was just trying to leave their mark rather than encouraging good coding practice?

You had no idea why they were included?

If so, what is your least favorite rule and why?

Some examples here

答:
I currently work in a company where SQL queries are done through something called "Request Class". How ridiculous:

In "include/request.class.php"

```<code>class RequestClass
{
    // ... some code.

    public function getUser($where)
    {
        global $initrequest

        $sql = $initrequest['users']
        $sql.= $where;

        return execute($sql);
    }
}
</code>```

In initrequest.php:

```<code>$initrequest['users'] = 'SELECT * FROM users WHERE ';
</code>```

And it was called from the application in this way:

```<code>$request = new request();
$tmpquery = "username = $username AND password = $password";
$request->getUsers($tmpquery);
</code>```

And they have a similar template system based in "blocks", but after understanding what I show here, I kept pressing to trash our whole software and rewrite it in Symfony.

Body:
I currently work in a company where SQL queries are done through something called "Request Class". How ridiculous:

In "include/request.class.php"

class RequestClass
{
    // ... some code.

    public function getUser($where)
    {
        global $initrequest

        $sql = $initrequest['users']
        $sql.= $where;

        return execute($sql);
    }
}

In initrequest.php:

$initrequest['users'] = 'SELECT * FROM users WHERE ';

And it was called from the application in this way:

$request = new request();
$tmpquery = "username = $username AND password = $password";
$request->getUsers($tmpquery);

And they have a similar template system based in "blocks", but after understanding what I show here, I kept pressing to trash our whole software and rewrite it in Symfony.

OwnerDisplayName: Arie Deckelmann


问:
Best way to structure a Git repository for Maven
I need some advice on how to structure our projects in Git. We use Java and Maven is our build tool. Maven kinda assumes all of your projects have a common ancestor eventually. Maven can also be a real drama queen when things aren't setup exactly the way the Apache foundation sets up their projects (anyone using the release plugin probably knows what I'm talking about).

We want a top level parent pom that controls plugin versions and build configuration (repo config, what artifacts to build, naming conventions, plugin versions, etc). Maven would want all of our IT projects to be in subfolders of that main project. This implies one massive Git repo for the organization.

This will make for a very noisy environment. If there are two teams working on unrelated projects, they will constantly have to pull in merges from the other team. Ideally I'd like to have one repo per project.

But that sort of clashes with the extremely hierarchal model of Maven, which demands sub-projects be sub-folders.

I need some advice on how people have reconciled these two models... thank you!

答:
You have 2 options:

by git way: use submodules. Here is a documentation how git manage submodules [git submodules][1]. I personally didn't use it but it looks to  fit your problem.

by maven way: in maven it is not mandatory that your root project (configuration) to be hierarchically the parent directory of all your projects. You can have a structure like that:

```<code>configuration
 +-- pom.xml (configuration:XXX)
project1
 +-- pom.xml (project1:1.0-SNAPSHOT)
 !
 +-- module11
 !     +-- pom.xml (1.0-SNAPSHOT)
 +-- module12
       +-- pom.xml (1.0-SNAPSHOT)
project2
 +-- pom.xml (project2:2.0-SNAPSHOT)
 !
 +-- module21
 !     +-- pom.xml (2.0-SNAPSHOT)
 +-- module22
       +-- pom.xml (2.0-SNAPSHOT)
</code>```

configuration, project1 and project2 are on the same directory level and each one could be a git repository. When build project1 or project2 you run the maven command from project1 or project2 level and maven will try to fetch the parent (configuration) from maven repository not from parent directory. You should pay attention to versions. I would recommend in project1 or project2 to keep a reference to a parent (configuration) with a release version.

To make a release you have to do it in 2 steps: release configuration first and release project second. Project1 and project2 can evolve independently and doesn't have to have the same configuration version as a parent.

Just for special cases when you want to have both configuration and projects as SNAPSHOT versions, in project1 or project2 you can use the <relativePath> tag inside <parent> tag to point to your local path of configuration. I don't recommend this because will create problems on development environment (at least for me in Eclipse)

I apologize for my English.
[1]: http://git-scm.com/book/en/Git-Tools-Submodules

Body:
You have 2 options:

by git way: use submodules. Here is a documentation how git manage submodules [git submodules][1]. I personally didn't use it but it looks to  fit your problem.

by maven way: in maven it is not mandatory that your root project (configuration) to be hierarchically the parent directory of all your projects. You can have a structure like that:

configuration
 +-- pom.xml (configuration:XXX)
project1
 +-- pom.xml (project1:1.0-SNAPSHOT)
 !
 +-- module11
 !     +-- pom.xml (1.0-SNAPSHOT)
 +-- module12
       +-- pom.xml (1.0-SNAPSHOT)
project2
 +-- pom.xml (project2:2.0-SNAPSHOT)
 !
 +-- module21
 !     +-- pom.xml (2.0-SNAPSHOT)
 +-- module22
       +-- pom.xml (2.0-SNAPSHOT)

configuration, project1 and project2 are on the same directory level and each one could be a git repository. When build project1 or project2 you run the maven command from project1 or project2 level and maven will try to fetch the parent (configuration) from maven repository not from parent directory. You should pay attention to versions. I would recommend in project1 or project2 to keep a reference to a parent (configuration) with a release version.

To make a release you have to do it in 2 steps: release configuration first and release project second. Project1 and project2 can evolve independently and doesn't have to have the same configuration version as a parent.

Just for special cases when you want to have both configuration and projects as SNAPSHOT versions, in project1 or project2 you can use the <relativePath> tag inside <parent> tag to point to your local path of configuration. I don't recommend this because will create problems on development environment (at least for me in Eclipse)

I apologize for my English.
[1]: http://git-scm.com/book/en/Git-Tools-Submodules


答:
Of course you have no idea how to write a "generic error mechanism".  No one knows how to write a "generic error mechanism" until some requirements are defined.  It sounds like all you have is someone's notion that a "generic error mechanism" is somehow required to start this project.

Personally, I would push back on this notion.  Writing "generic" anything before implementing actual user requirements is almost always a waste of time.  And since it's generic, by definition it is not specific to your company or application, so there is probably something already available that will meet about 95% of your needs.

But since you are the junior member, pushing back may not be a great idea.  So you need to talk to the people who think they need a "generic error mechanism" and find out what services they are expecting this mechanism to provide.  Then search the net to see if something already written will suffice.  If you find something, propose simply using it.  They probably won't agree, because anyone who asks for a "generic error mechanism" is likely suffering from a bad case of not-invented-here.

If that fails, he next step is to define an interface for the error mechanism and get it approved by the stakeholders.  After that, implementation will probably be trivial.

=================

P.S. There are some programmers who think that the way to start any project is by writing a "platform" to provide all the common services that will be needed by the application modules.  This usually devolves into months of trivial work reinventing stuff already readily available for free.  Until you hit the performance limits of the available solutions, there is no reason to write "platform" services.  Nor is there any reason to write wrappers around existing APIs.  If you refactor continuously, the exact wrapper required by your application will magically appear.

Title: What to do when you are faced with programming task that you have never done?

Body:
I started my career as a .NET developer 3 months ago and after a long training plan on diverse technologies, patterns and concepts the developers who were supervising me have decided that I am ready to join one of the many projects the company handles.

I am very excited to finally be able to start coding. The team I have joined is rather small for now because were starting with a new project, which is great because I get to be involved in the entire life cycle of the project. It is a web based SPA project with a backed that uses ASP.NET MVC/ASP.NET Web API and in front-end the Durandal framework and related libraries.

My problem is that after having a meeting with my colleagues and establishing the tasks and estimations for the next month I find myself in a position that I do not know if I am capable of taking on any of the tasks.

I have never done any of the created tasks and I do not know how should I proceed.

For example one of tasks created is creating a generic error handling mechanism for the entire application.

How does one usually proceed when faced with tasks that he has never done?


问:
Why there is much more support for closed xls format in rails (and ruby) than to an open ods format?
It is little depressive, but it seems to me that there is much more support for manipulating ugly proprietary closed format like xls in rails (and ruby) in general that to documented open Open Document format. Why it is so? (I know it is kind of philosiophical, but I just do not get the fact, that the opensource is not more inclined to write SW for open formats).

For example for ruby there is a spreadsheet gem.

答:
Your question is tied to "Why do corporations/people use commercial suites/applications when equally good open source versions are available?"

Answer that and you'll have a good idea why there is less ODS support than XLS. For now, here's a hint: People do what their management asks.


问:
caching on multiple servers
Because we need to keep response times low, we get tons of requests, and we need to basically process ALMOST the same data (which I'll refer to as X) each request (the inputs are different though, so we can't cache responses), we are using a technique where we grab a new copy of X every 90 seconds from the database and store it locally in memory as a python list of dictionaries, on our application servers (we are using uwsgi).

The kink in the machine: There are temporary analytics that we need to keep track of in those 90 seconds to adjust our data each iteration, and each iteration is dependent on what we calculate from the last iteration.

The trouble with this is, we have multiple application servers that are storing the same data, X, in memory and each of those servers need to refresh X at the same time to keep calculations consistent for the next interval.  I've tried some techniques, like broadcasting a message after each calculation to reload each server's X, but it hasn't been as effective as I would hope, and it just makes things more complicated.

I should say, the reason we haven't used memcached or something similar is because we don't want to sacrifice any speed if we can.  Maybe I am ignorant on how fast we can retrieve and load the list into python objects from memcached.

I understand my explanation isn't the greatest, and will answer any questions to give a better picture of the situation.

Edit:
we are at about 5000 request/second, the size of the data we process is about 2MB at the moment but will continue to grow, so we'd like to avoid sending it over the wire for each request.

答:
I think a good approach would be to split checking for data and actually getting it. Why? Memcache is really fast... But as you explained, there is some latency due to the big chunk of data you need to recover. So let's just adjust your design around this topic.

That is, try to mimic the HEAD + GET methods of HTTP...

Each of your servers gets a little value from memcache. This tiny value acts a HEAD, just returning the date+time when the big 2MB data was last calculated.

If the server sees it's the same as its own copy, just goes on with the local cached version of the 2MB blob.

When the data is recalculated, both 2MB data and tiny semaphore are updated on memcache. So, next time a server gets the tiny date, it knows the data has to be reloaded into its local cache.

Title: caching on multiple servers


问:
Describe the best deployment environment you've worked with
The Joel Test includes the question:

Can you make a build in one step?

Which is important, but I'm wondering, how streamlined have some of the deployment processes been?

All software from shrink-wrap to web applies: what's the best deployment environment you've worked with, and what steps were involved?

答:
My current workflow is like this.

Develop on local VM

Test, Commit changes, push to github

ssh into EC2 and pull changes

This can all be scripted into one step.


问:
How is a "Software Developer" different from a "Software Consultant"? What makes a consultant?
I have seen a lot of people claiming themselves to be a "software consultant". These consultants do what a normal software developer does, write code, estimate tasks, fix bugs and attend meetings etc. The only difference being the financials, consultants end up earning more. Then how is a software developer different from a "consultant"?

In addition to the main question, I would like to know how can a software developer become a consultant? Are there any specific guidelines for a consultant? Do they need to amass certifications and write up research papers? Please do not confuse the software consultant with a management consultant. Software consultants I have seen are not managers.

答:
Developer or Contractor - You go looking for open software development positions (no end date) or contracts (defined end date).

Consultant - You make yourself known, and companies request your software development services, normally under a contract.

Everything else is ancillary based on the mechanics of the above.


答: You need to take a representative sample of your real data and simulate different repacking algorithms. At the moment, I don't have enough information to simulate the system  so could not check how any algorithm worked.</p>

Title: simple 'defrag' logic that minimizes changes?

Body:
edit:

so clearly I didn't explain this well, so let me try again with examples.  I have a 'pipe' of a given size with signals routed through it at given offsets.  The pipe can get fragmented with signals in different offsets making it impossible to fit a new signal.  I want an algorithm that will tell me how to arrange the signals to defragment the pipe; but with a minimal number of signals actually being moved!  So for the example..

Say I have a pipe of size 16.  It has the following signals with the sizes and offsets described.

```<code>offset 0: A (size of 4; fills slots 0-3)
offset 5: C (size of 2, fills slot 5-6)
offset 8: B (size of 4, fills 8-11)
offset 14: D (size 2, fills 14-15)

Pipe: AAAA_CC_BBBB__DD
</code>```

In this case I have 1 slot open at offsets 4 & 7, and two at offset 12-13.  Now lets say I want to add a size 4 signal to this pipe.  There is no continuous space for it now, but I know I have enough space for it if I defragment.  The 'obvious' solution is to group all the signals together at the 'top' like this:

```<code>offset 0:  A (size 4, fills 0-3)
offset 4:  B (size 4, fills 4-7)
offset 8:  C (size 2, fills 8-9)
offset 10: D (size 2, fills 10-11)

Pipe: AAAABBBBCCDD____
</code>```

this leaves slots 12-15 free for my new signal.  However, to do this I repositioned 3 signals(B-D).  For each signal I moved I have to send commands down to hardware and wait for a non-trivial amount of time.

If I was smarter I could realize there is another approch.  I could reposition like this:

```<code>offset 0:  A(size 4, fills 0-3)
offset 8:  B(size 4, fills 8-11)
offset 12: C(size 2, fills 12-13)
offset 14: D(size 2, fills 14-15).

Pipe: AAAA____BBBBCCDD
</code>```

I can now fit my new signal in offsets 4-7; AND I only had to reposition one signal(B).  Thus saving on hardware calls.

I'm wondering if there is a good algorithm to detect sitations like this; where I can 'fit' a signal onto a pipe with the minimum number of signals moved.  The aproch thta comes to mind is an N! algorithm; which basically amounst to "generate every possible distribution, calculate how many moves it resulted in".  I'm loking for a faster approch.

The approch does not have to be 100% perfect, I'm looking primarily to minimize the average case, so long as the worst case isn't made too horrendous.  I know that I will never have more then 255 signals on a given pipe; so I may be able to 'get away' with N! as bad as that sounds.  I also know each signal's size is a power of 2, as is the pipe size.

also, are there any briliant algorithms for placing of signals that minimize fragmentation?

Question answered; see below.

I wanted to expain on the answer slightly to better explain how defragmentation would occure for anyone reading; buddy does explan it I wanted to point out a simpler approch to conceptualize and explain the defraging part in more detail since that was the original question.

I'm explaining my approch, which is a slightly different/simpler approch but effectively keeps the 'buddy' concept.  I'm not precomputing blocks or labeling them, this is too much effort to implement and maintain.  For me the CPU cost of calculating where a signal will go is pretty trivial compared to actual placing/deletion of signals; so I can afford to lose a tiny, linear, amount of CPU by not pre-computing to simplfy my logic.   So the process is:

for insertion:

All signals are kept in signal boundaries equal to the signal size, so a signal will start on offset where offest % signalsize=0.  For actuall offset we walk through and figure out intervals that keep this boundry.  So if my signal is size 4 on a 16 size pipe I'll look at intervals 0-4, 5-7, 8-11, 12-15.

For each interval check if all space in that interval is free.  In the simple case we have a interval with no signals in it and we just put the signal at that interval.  Important, we look at the intervals in order and place our signal in the first free interval, this ensure we break the smallest possible 'block' (using buddy terms) when we add our signal.  This should be equivlent to the buddy approch described by im3l96; except without precomputation of blocks.

if no interval is completely free we have to defrag.  For this we find the the signal with the most unused slots.  If multuple intervals have the same number of slots unused select the first interval.  We then find the largest signal in this interval and recursively call same insert algorithm for the smaller signal (except mark the interval we selcted to insert our first signal as unavailable somehow).  This moves the signal to somewhere else that it will fit.  We then find the next smallest signal in our selected interval and do the same until we moved all signals.  Worst case of 2^n-1 signals moved; where N is the number of potential signal sizes <=our signal  (assuming signals are multuple of 2 then N=log2(signalSize)).

Here is an example.  * stands for a slot marked as unavailable when we recursively call this method (ie the interval that the calling method wanted to place it's signal in, and thus doesn't want the recursive call to try to place a signal into)

Here is an exaple, simplest case I could come up with that still demonstrates full complexity.  Note: the following structure would be hard to create, but could result from the buddy approch if someone tried very very hard.

```<code>FFFFFFFF__AA_B__EEEE_HGGCC_DII_J
</code>```

Someone passes in a signal Z of size 8

we select offset 8:

defragInsert(z, size 8)

```<code>effective structure: FFFFFFFF__AA_B__EEEE_HGGCC_DII_J

placing signal in interval: __AA_B__
</code>```

defragInput(A, size 2)

```<code>effective structure: FFFFFFFF********EEEE_HGGCC_DII_J
place signal in interval (offset 20)  _H
</code>```

defragInput(H, size1)

```<code>effective structure: FFFFFFFF********EEEE**GGCC_DII_J
place signal between C & D
</code>```

return defragInput(H, size1)

```<code>effective structure: FFFFFFFF********EEEE__GGCCHDII_J
place H at offset 20 now that it's open
</code>```

return defragInput(A, size 2)

effective structure: FFFFFFFF___B__EEEEAAGGCCHDII_J
   move B now...

defragInput(B, size1)

effective structure: FFFFFFFF****EEEEAAGGCCHDII_J
   place B between I & J

return defragInput(B, size1)

effective structure: FFFFFFFF____EEEEAAGGCCHDIIBJ
   add B

return defragInsert(z, size 8)

```<code>fianl structure: FFFFFFFFzzzzzzzzEEEEAAGGCCHDIIBJ
</code>```


答:
I have had a team of 10 people for two years without a conflict(touch wood) I could be lucky or may be doing something right. The best way to handle conflict is never to let one exist for a longer time. There are several core values that you can preach.

Team Spirit

Fairness in everything (compensation/rewards)

Being appreciative

Give recognition, responsibility

Give freedom

Let people know they are not greater than the team

Personal success means nothing if the team fails

attach personally to people

never show a carrot you dont intend to give

never hire(no matter how good) who could ruin the team

communicate more often etc etc.

Appreciate whenever someone goes beyond the job

Give regular feedback on performance and set expectations preferrably monthly.

Let people know when they behave like children.

All these take guarded effort from some one.

Software is pretty much a team game individual brilliance is generally short lived. If I go by your examples :

We have decided decided to go with dependency injection. Period. We will see if it is the best way or not. If it is not, you get a chocolate :-) till than cooperate and let's make this thing happen

If the rest of the team is slowing you down you help them to make it faster they are your teammates you are the elder guy, help them. I know you are good.

Talk to both of them tell them they are spoiling the environment. If nothing works get rid of one of them or both of them.

One thing I find very effective is to repeat "we are a good team" and repeat "we are a team to the lonely one's".

Title: How to handle conflicts between developers in your team?

Body:
This is happening in every team.

For some reasons, conflicts arise in the team and they affect the overall motivation and productivity.

What is your recommended approach to solve that common problem?

Examples:

one part of the team wants to implement dependency injection, the other part think it's a waste of time.

some developers think the rest of the team is slowing down development (which explains why they are late on the schedule)

personal incompatibilities between one or more developers

one developer refuse to talk to another one (without apparent reason)


问:
Are there any Clojure libraries for p2p?
I'm a web developer, but lately I have been learning Clojure and now I'm interested in creating a p2p application. And since Clojure is a general purpose language, I guess I can just use that.

Any suggestions?

答:
Assuming your running Clojure on the JVM, something like Pastry?

We can't help you much since you haven't given us much to work with, so have you done a general search for "Java p2p"? What have you tried already?

Note that p2p is quite complex with lots of non-trivial problems like bypassing firewall's and NATs. I would start with a client-server architecture first and only go to p2p when its impossible to scale the server further


问:
Multiple orders in a single list
I have a problem with a ranking system I am using.

Scenario:

An online game with around 10k players calculates a real time ranking of points when a certain event occurs. Events don't occur that often, around 1 time per minute. This ranking is kept in the cache for quick calculations, sorting and access.

Now players can form groups and play against each other, but the scoring system is the same, only the ranking is based for the players in that group.

At first I created for every group a separate ranking, effectively having the same scores as the complete ranking, but with different positions in the ranking.

This is trivial because there are over 1.000 groups and every time an event occurs all the groups would have to be updated.

So what I did now is when the group ranking is requested take only the players that are in that group from the complete ranking and show them. The positions would have to be re-counted.

That re-counting is where the problem is. Because the sub-list is by-reference from the complete ranking list I cannot change the position of the player in the sub-ranking without updating it in the complete ranking, because it's just a reference.

I came up with two solutions:

Create a copy from the record every time it is requested and do some output caching (not very desirable because the rankings are live)

Create a copy and store this in a cache which is reset when an event occurs.

Create a sub-list with just the positions which is updated when an event occurs.

And the last solution: do the position counting in the output instead in the business side. This would be the best solution, only problem is that on some pages this text appears: "You are on position # in the ranking" where # is your ranking position. This number would be tedious to get then.

Does anybody have any suggestions to this problem?

答:
There may be minor performance considerations involved with it, but this sounds like the sort of thing LINQ is very useful for. The basic idea is this:

```<code>var enormousList = new List<record>();

//var enormousList = ... (over 5 million records)
var subList = enormousList.Where(onerecord => onerecord.clanName == "RAGIN CAJUN");

// At this point in the program, NO filtration has occurred just yet and little processing
// power has been used.

// This enumerates the list once for the "ragin cajun" filter, so this may take a while.
var sublistCount = subList.Count(); //take note that Count is a function here, not a property.
var pageSize = 50;
var hudDisplayPage = enormousList.Take(pageSize).Select((record, idx) =>
{
    return new HudPage(idx, record.clanName, record.playerName);
});
// for those who couldn't keep track; hudDisplayPage is now an IEnumerable (which you can use for-each on) containing
// 50 records of the list fitting the description. These are dynamic constructs; even now, hudDisplayPage hasn't
// yet been evaluated. If you want to cache one of these values so you're not doing the processing again later...
var saved = hudDisplayPage.ToArray();
</code>```

This sort of system should make it relatively easy to take slices out of your data, and precache whichever ones are likely to be needed many times.
Also, take note of this handy tip (but ONLY for queries that end up being a performance hit)

```<code>var saved = hudDisplayPage.AsParallel().ToArray();
</code>```

That line should essentially multithread your filtration process, so that all cores of your processor are on it.

I can't say I know enough about your problem to write out its solution in code; but it seems like your issue is mainly in figuring out the list processing, against a single list you don't want to modify or copy. Hope I haven't misunderstood your issue!

Title: Multiple orders in a single list

Body:
There may be minor performance considerations involved with it, but this sounds like the sort of thing LINQ is very useful for. The basic idea is this:

var enormousList = new List<record>();

//var enormousList = ... (over 5 million records)
var subList = enormousList.Where(onerecord => onerecord.clanName == "RAGIN CAJUN");

// At this point in the program, NO filtration has occurred just yet and little processing
// power has been used.

// This enumerates the list once for the "ragin cajun" filter, so this may take a while.
var sublistCount = subList.Count(); //take note that Count is a function here, not a property.
var pageSize = 50;
var hudDisplayPage = enormousList.Take(pageSize).Select((record, idx) =>
{
    return new HudPage(idx, record.clanName, record.playerName);
});
// for those who couldn't keep track; hudDisplayPage is now an IEnumerable (which you can use for-each on) containing
// 50 records of the list fitting the description. These are dynamic constructs; even now, hudDisplayPage hasn't
// yet been evaluated. If you want to cache one of these values so you're not doing the processing again later...
var saved = hudDisplayPage.ToArray();

This sort of system should make it relatively easy to take slices out of your data, and precache whichever ones are likely to be needed many times.
Also, take note of this handy tip (but ONLY for queries that end up being a performance hit)

var saved = hudDisplayPage.AsParallel().ToArray();

That line should essentially multithread your filtration process, so that all cores of your processor are on it.

I can't say I know enough about your problem to write out its solution in code; but it seems like your issue is mainly in figuring out the list processing, against a single list you don't want to modify or copy. Hope I haven't misunderstood your issue!


问:
How to explain OOP concepts to a non technical person?
I often try to avoid telling people I'm a programmer because most of the time I end up explaining to them what that really means. When I tell them I'm programming in Java they often ask general questions about the language and how it differs from x and y. I'm also not good at explaining things because 1) I don't have that much experience in the field and 2) I really hate explaining things to non-technical people.  </p>

<p>They say that you truly understand things once you explain them to someone else, in this case how would you explain OOP terminology and concepts to a non technical person? </p>

答:
OOP is a gross simplification if anything - an abstraction - of human thought process and understanding of the world to project functionality into a digital "void" to mimic familiar processes and classifications digitally. It is, in many regards, more about our primitive language state than us "thinking more like computers".

If programming mimicked reality or human thought it would be far more organic, chaotic and haphazard in nature - lateral even. Instead we simplify reality into baby steps, "2+2 logic", crude categories, re-usable little tools and prehistoric reasoning.

We're still trying to work out how to download our thoughts and desires into a protocol and common language and I for one think historians will be fascinated with its sophisticated crudeness one day - like we now see hieroglyphs.  It's not "clever" at all - it simply highlights how we can't easily explain how we decide or understand even the simplest of things. Computing is still at the "a dog is a dog because it's not a cat" level of thought evolution - it's millennia behind even basic spoken language.

OwnerDisplayName: John


问:
Is physical Agile board "always" better than electronic tool?
Whenever the question comes up on which Agile tool to use use there always some people that answer "don't use an electronic tool because you will lose the big-visible-board advantage which better generate team conversation".

Is this always the case or are there any contexts where an electronic tool is a better choice?  What are some of the pros and cons of each approach?

答:
Just as an addition to the other answers:

There's no need to make this an either-or situation -- you can have an electronic board and a physical one.

Our team uses an electronic board as the main working tool (we use Kanban) and as the authoritative source of information. The electronic board has all tasks, is updated as tasks are worked on etc.

In addition to that there is a physical board, which only has major stories. It is mainly meant to create visibility, especially to outsiders, such as PMs and stakeholders.

This does mean that changes to the electronic board need to be manually replicated on the physical board, but this is doable, as only major stories are tracked there, which usually take at leas a day.

We find this a good combination: The electronic board is useful for small stuff, for day-to-day work and for metrics, and allows comments, links to specs etc. The physical board gives a quick overview of project state and makes it easier to see the "big picture".


答:
The problem is similar to memory allocation, so my propose solution is to use http://en.wikipedia.org/wiki/Buddy_memory_allocation. Using buddy allocator minimise fragmentation from happening in the first place by choosing the smallest contiguous free space in the pipe for a signal.

Using the example, here's how the space will be allocated for size 8 pipe:

```<code>Initial state
Pipe: ----------------

A (size 4), smallest available is 16, so split that into 2x4 and 1x8
Pipe: AAAA ---- --------

C (size of 2), smallest available is 4, split that into 2x2
Pipe: AAAA CC -- --------

B (size of 4), smallest available is 8, split that into 2x4
Pipe: AAAA CC -- BBBB ----

D (size 2), smallest available is 2
Pipe: AAAA CC DD BBBB ----
</code>```

Freeing space is a matter of checking the "buddy" of space being freed; if buddy's also free, then they can be merged to form bigger contiguous space. So, if the space are being freed in the order of the signals coming in, then it'll look like this:

```<code>Free A (buddy of space being freed is not free)
Pipe: ---- CC DD BBBB ----

Free C (buddy is not free)
Pipe: ---- -- DD BBBB ----

Free B (buddy is free, merge)
Pipe: ---- -- DD --------

Free D (buddy is free, merge)
Pipe: ----------------
</code>```

It's quite simple and fast too because there's only little fragmentation, especially because the size of the signals are power of 2.

If it's really needed then defragmenting/compaction can be done easily too, it's just a matter of finding allocated blocks of same size with free buddies and merge them (moving one allocated block will create a larger free block).

Body:
The problem is similar to memory allocation, so my propose solution is to use http://en.wikipedia.org/wiki/Buddy_memory_allocation. Using buddy allocator minimise fragmentation from happening in the first place by choosing the smallest contiguous free space in the pipe for a signal.

Using the example, here's how the space will be allocated for size 8 pipe:

Initial state
Pipe: ----------------

A (size 4), smallest available is 16, so split that into 2x4 and 1x8
Pipe: AAAA ---- --------

C (size of 2), smallest available is 4, split that into 2x2
Pipe: AAAA CC -- --------

B (size of 4), smallest available is 8, split that into 2x4
Pipe: AAAA CC -- BBBB ----

D (size 2), smallest available is 2
Pipe: AAAA CC DD BBBB ----

Freeing space is a matter of checking the "buddy" of space being freed; if buddy's also free, then they can be merged to form bigger contiguous space. So, if the space are being freed in the order of the signals coming in, then it'll look like this:

Free A (buddy of space being freed is not free)
Pipe: ---- CC DD BBBB ----

Free C (buddy is not free)
Pipe: ---- -- DD BBBB ----

Free B (buddy is free, merge)
Pipe: ---- -- DD --------

Free D (buddy is free, merge)
Pipe: ----------------

It's quite simple and fast too because there's only little fragmentation, especially because the size of the signals are power of 2.

If it's really needed then defragmenting/compaction can be done easily too, it's just a matter of finding allocated blocks of same size with free buddies and merge them (moving one allocated block will create a larger free block).


答:
There's two kinds of wizards. There's the guy who makes specific things happen with magic words. He's got a word for summoning fire. He's got a word for making a frozen chicken appear out of thin air. And another word for creating a pot of force (I prefer my force green, glowy, and translucent) full of friolating goodness. With the right application of his words he can produce a fried chicken.

And then there's the OOP wizard. Who just summons an imp who knows how to go the grocery store, buy a chicken (or ingredients for any other food you want him to prepare), cook it, and serve you dinner. OOP Wizard doesn't have to tell his imp how to do it. He just needs to let him know what he wants which in this case is fried chicken. Not only that, the OOP wizard can summon other minions to tell his imp-chef what to do.

So, the incantation guy impresses at parties but the OOP wizard is the one you want when you're going to start a magic restaurant with a bunch of characters (like say, a pissed off unicorn waiter, and a troll floor manager) who all have to work together. If you try to invoke every step of the problem of solving "restaurant" you can easily get tangled up in the details and it's really easy to make mistakes. The OOP wizard pre-trains his minions to sort out the details for him so he can just focus on solving the bigger problem by having his people interact.

Not to mention it's easier to re-use your chef-imp for your grade school cafeteria problem then it is to separate all the junk you might or might not re-use when you're doing it all one step at a time by calling words and words that call other sets of words (which will get more an more numerous as you have to handle a greater variety of problems).

To be fair, with very, very careful application, the incantation wizard can get it all done as fast as the OOP wizard. He can break things down in the right way such that calling the right spells requires no more work on his part than the OOP wizard. But the work is much harder to understand or duplicate and much harder to re-use large portions of because it's all tied together for one specific complex problem.

Title: How to explain OOP concepts to a non technical person?

Body:
I often try to avoid telling people I'm a programmer because most of the time I end up explaining to them what that really means. When I tell them I'm programming in Java they often ask general questions about the language and how it differs from x and y. I'm also not good at explaining things because 1) I don't have that much experience in the field and 2) I really hate explaining things to non-technical people.  </p>

<p>They say that you truly understand things once you explain them to someone else, in this case how would you explain OOP terminology and concepts to a non technical person? </p>


答: IMO, it's very simple. You can't re-use something that keeps referencing the context it's used in.</p>