1. Willingness to work at any level required in a system. All the way from high-level languages and environments (HTML/JS, UI toolkits, SQL) down through middle-level languages (Java, C#, C/C++), down through assembly language (understanding machine architecture, compilers, assembly-level debugging). You don't have to *start* with those skills, but you need to be willing to *learn* them and be comfortable working at any level.
2. Willingness to learn any new problem. We usually look at your background, and ask you one programming question that is solidly in your "comfort zone," and then ask programming questions that are outside your comfort zone. The first question is designed to see how much you can talk about something that is comfortable and familiar to you (and also frankly to make you feel comfortable -- after all, hiring is *not* adversarial for us, we're trying to see if you can work with us to solve problems). Can you explain a solution well? Can you teach something to someone else? The programming problems that are outside of your comfort zone are all about seeing whether you are able and willing to apply yourself to something new. For example, if your background is in networking, I might ask you a graphics programming problem. Or vice-versa. The goal is not to be a jerk, the goal is to see whether you can apply yourself to something new.
3. Ability to identify the problem, its exceptional cases ("corner cases"), and to identify engineering trade-offs (memory vs. speed, etc.). Just being able to identify what an interviewer is asking, in a programming problem, is an important skill. Very often, candidates will focus on the wrong aspect of a problem. Or they will rush into a problem without understanding it, and will miss the forest for the trees. This is a really basic skill that anyone can develop, and it helps in all job interviews (and in all real-world problem-solving situations).
5. Ability to communicate your thought processes. If you're working on a programming problem during an interview, then at least half of the interview is about *how* you approach (and maybe solve) a problem. Are you breaking a complex problem into smaller problems? (divide and conquer) Are you making something more complex than it actually needs to be? Can you identify an algorithm that you don't understand, but you understand how to use it? For example, I don't think I could invent the fast Fourier transform, but I think I could identify when to use it, during an interview. If I say to an interviewer, "Here is where I would convert this data from the time domain to the frequency domain, using an FFT library, and then I would use the frequency domain data in such-and-such a way to solve this problem," then that's good. You don't need to invent the FFT in order to apply it.
Unfortunately I'm not allowed to give any info on pay ranges. (I could be fired for doing so.) I will say this, though. The salary is decent, but not overwhelming (as tech jobs go), because the bonuses are huge. The bonuses and stock are where the real money comes from. If you perform well, your bonus could be as much as one third of your base salary. Your stock grant could be worth as much as your entire yearly salary. It's structured so that you are compensated for performance, rather than seniority.
Now, someone is going to attack me for saying that. "OMG, you're paying people to attack each other!!1!1!!" Well, would you rather reward people for seniority, or for results? Also, keep in mind that rewards are spent on successful *teams*, not just successful individuals. Yes, high-performing individuals get more rewards than their under-performing peers. But, all of that comes out of a team's budget for rewards. If your team blows it, then even the high-performing people will get crap reviews. Conversely, if your team nails it, even the middle-of-the-road performers will get a pretty fat review.