There are either too many possible answers, or good answers would be too long for this format. Please add details to narrow the answer set or to isolate an issue that can be answered in a few paragraphs.
If this question can be reworded to fit the rules in the help center, please edit the question.

5 Answers
5

I think attitude is the first thing. There have been a lot of decisions made already in the project that you didn't have a chance to give input to. Likely you will disagree with some or even most of them. The last stages of a project is not usually the best time to revisit decisions made months ago and that a lot of the code depends on, so pick your battles carefully. You don't want to make enemies from day one. This is similar to coming in on a legacy project, when you come in late in the game. You don't understand everything about why they made the choices they made, so wait a bit, get some credibility from your own competence and then start suggesting changes in order of importance. Don't do it days before a critical deadline either.

Document problems you found with the approach so you can prove the issue in the next project that you are on from the start. Often having details about what turned out to be a mistake makes it easier to sell a different way later on.

Next big problem is getting up to speed fast enough to be of use. Especially towards the end of a project, people just don't have time to help you get up to speed.

So spend the first couple of days building a list of questions as you look through the code and then talk to a senior developer (or team lead if the person is technical) about your questions in one swoop rather than bother them continually for several days. You will have to ask some things immdeiately of course, you can't look through the code if you don't know where to find it. But try to be somewhat independent in figuring things out.

They will likely assign you to a specific area to work in, make it your business to read the requirements (if you have a requirements document) and look at the code in that area first. Once you think you understand it or know you are stuck in understanding it, then go talk to someone about it. Confirm that your understanding is correct and ask your questions. But above all don't ask the questions in such a way that makes the person feel as if you regard their code as garbage even if (maybe even espeically if) you do. If something feels off to you, ask why they did something not "how could you have done that?" Try to understand their thinking and decision making processes not just their code.

If coming in at the end of a project is discouraging (and let's face it they wouldn't be hiring near the end if they didn't have problems) keep in mind that you will be there for the beginning of the next project and have a chance to have more input. Your job, career-wise, is to do a good enough job on what they assign you to gain credibility for the being a significant player in the decision making process on the next project. So do your best to be a team player, to meet deadlines and to provide working code that plays well with what has already been finished. Now is the time to impress them with your abilty to get things done. You can impress them with your brilliance later.

If you join a project at any point during development, make sure that you have a clear understanding of the task and your role in it. If you have realistic expectations of the project and the project has realistic expectations of you, you're more likely to remain happy with each other.

One major problem is organizational knowledge. People who have been involved with a project from the beginning are privy to the reasoning behind design decisions, politics that might be minefields, undocumented foibles of the software, and so on. It only takes stepping on one landmine that you had no way of knowing about to make you consider pulling up stakes and moving on, especially when there is no understanding from management that the organizational knowledge problem exists (thus resulting in the new guy feeling that he's being blamed for something in which he had no role).

Rigorous, consistent documentation practices can make this a smaller hurdle. For example, if a new hire is filling a support role, make sure that he has the resources needed to actually answer questions competently rather than simply expecting that he'll be able to deduce the solution from training materials. ("Joe Oldguy, Client X just called asking about problem Y. What the heck is going on?" "Oh, Client X has a kink in their process. They have to A, B, and C before they D. This is different from everyone else. A step must have gone wrong in {A, B, C}.")

My experience of engineers joining a software project during development is that the later you are in an iteration (or heaven forbid if you are near the end of the implementation phase of a waterfall model project) the harder it is for an engineer to integrate with the team and the project itself. When you start any work there will usually be a 'ramp-up' period. If you are familiar with the work because you have done it before, can draw parallels, or were instrumental in the requirements and design phase, you will 'ramp-up' quicker. Otherwise, it can take some time.

The later in an iteration/project you are, generally the higher the pressure. Your project might be overspent or late, or both. You might be under intense pressure to resolve defects, or implement features, and the project plan hasn't accounted for 'ramp-up'. This is common. While you should be loaded at 80% on a plan so that holidays, sickness, etc. can be accounted for - my experience is that this is naive at best.

It is common in industry for mid-project joins to be difficult. It generally means you just have to knuckle down and put the hours in to get up to speed. Leverage whatever help you can from existing members of the team and do your best. Throwing engineers at a project without planning it (i.e. having them join mid way through without any allocated 'ramp-up') is usually a sign that all is not well on that project.

Pairing can make getting up to speed on a new development project much easier. Personally, I believe it can make me get up to speed on the project 3 or 4 times faster than doing the work on my own. This is helped a lot because you can get a lot of history/decisions of the project at the same time you are getting familiar with the code.