I think Microsoft has one of the best interview processes of any major corporation around. There are other companies that use a similar approach; others, I know, use a very different approach. Despite the fact that I like our interview process, a colleague asked me a few days ago, what I’d change in our interview process. I think it’d be interesting to blog my answer, so, let me share my thoughts.
I’d like to see a few changes that may make a positive difference, and I think there are companies out there doing that. I’m not pretending to be like the great Mini-Microsoft blog; it’s just food for thought.
Gretchen Ledgard and Zoe Goldring here know everything about the interview process; they are from HR. In my case, my suggestions below are based on my personal experience and reflect just *my* perceptions.
A few facts before starting:
- Last year I badly wanted a position in another team. I was so nervous during the interview that I ended up having my worst interview ever. I couldn’t answer things that I’m used to blogging about, and I lost my concentration from the very beginning. I didn’t get the position that I really wanted.
- A quick calculation shows me my “approval rate” during my career before joining Microsoft was much better, actually, very high. In other words, it was easier for me to change companies in the past than changing teams at Microsoft nowadays.
- At the same time, my internal “approval rate” when trying to change teams is something close to 50%. Therefore, I may end up getting the position I was approved for but not the position I really wanted in the first place. Bottom line is: even if there were better candidates for the positions I applied for in the past, it may explain part of my failures to get approved. Another part, I believe, is the interview process itself, since you tend to be better in interviews for positions that you consider to be not ideal positions for you and, of course, you tend to be nervous and make mistakes when you really want a specific position. It’s psychological. Just out of curiosity, my friends have about the same “approval rate.” Since I’m already a full time employee and have gone through the interview process before, it should be easier for me to change positions and avoid losing the position I want, based on how well I was prepared for the interview. There’s a strong psychological factor affecting the performance during the interview, mainly when you’re being interviewed for THE position you want.
- It’s very easy to reject someone during the interview process even if the candidate rocks. However, it’s very difficult to select the right candidate. Even worse, the right candidate may not be approved based on the traditional interview process.
That said, what I’d like to see as part of the interview process is:
- Software matters! If the candidate has a cool utility (tool) or any other kind of software he created (maybe as a hobby), it should be considered more important than the ability to answer technical questions. For me it shows passion, and it’s the real proof the candidate created something. Questions about the software (tool, demo, utility…) should be part of the interview process. If the candidate really created the software, he/she will be able to talk about it.
- Have the candidate do your work for a few hours or something close to your daily work and monitor how he or she performs. Of course, don’t be at his/her side all the time; otherwise, it’ll affect the candidate’s performance. Give him/her a break and from time to time talk with him/her to see how things are going. Easy! The candidate should feel comfortable and have space for creativity here. This is what I’d really love seeing! Supposing the candidate has a good performance, isn’t it enough to have a good idea about his/her potential?
- Use technical questions during the first part of the interview, just to make sure you’re not going to interview the wrong candidate, but don’t use them to judge the candidate’s potential. Also, the questions shouldn’t be difficult. It’s easy to memorize things and be prepared for the interview and look good when answering questions. However, the real goal here is not to hire someone technically able to explain all C++ language constructs or all .NET Framework classes or yet someone that spent weeks studying for the interview process. We want someone who thinks outside of the box and has the ability to create and innovate. In my opinion, creativity is way more powerful than knowledge. I guess it’s difficult to accurately measure creativity, but it’s easy to recognize the lack of creativity. J
- Be flexible, your interviewee may be under stress and afraid of losing his/her dream job opportunity (I’ve been through it two or three times before): A nervous candidate may not be able to solve a logic problem or to create an algorithm under pressure during the interview. It doesn’t mean the person doesn’t have potential.
- I like puzzles. But I’ve learned they might not be an effective tool to hire people, so it’s better not to judge someone based on his ability to solve one specific puzzle.
Considering the time pressure and psychological factors, it’s better to analyze the approach the candidate takes to solve the problem, to look at the way the candidate thinks, not the solution. Besides, there’s the possibility the candidate has been studying puzzles to be able to solve them during the interview process.
- Blogs and utilities. There’re tons of blogs scattered in the internet. Some of them are pretty cool (I’m talking about content)! Again, it should be something to be considered during the interview process and not ignored. Last year I contacted two blog authors to see if they were interested to try an interview in my previous team. Needless to say, I was impressed by the content of their blogs. I’m also impressed when I see some cool free tools in the internet. In my opinion one cool tool is worth a thousand of words.
- I also think that internal candidates moving to other internal positions should have a conversation with the new manager and the team. I see no reason to go through the entire interview process over and over again. One more thing: no more permission to interview.
I believe this approach is more efficient for identifying talent, since it’s less “binary,” gives more space for creativity, and should help reduce the stress level during the interview process.
For internal candidates moving to other teams, the process should be easy and direct. It’d increase the probability of choosing the right person for a specific position at the right time, boosting the employee morale and productivity. It’s a win-win situation for the employee and for the company.
Not so long ago I had an interesting Messenger conversation with a great friend of mine that is a developer lead for one of the three top game companies. All started when he was telling me about the skills he was looking for to hire new developers. We both agreed that all software areas demand a lot of creativity, but the perception of creativity can be very different depending on the software area you work.
Let me explain my point. During the old times of VB 6/Visual C++ 4.0 (if I’m not wrong), I used to be a C developer that created DLLs for Visual Basic 6 developers, and my friend used to be the same. We reminded the perception our managers had at that time: those who were considered creative were the Visual Basic 6 developers working on the user interface, dragging and dropping buttons, resizing them, etc.—even those who didn’t know anything about user interface guidelines! Please, don’t get me wrong. I’m not saying there weren’t creative VB 6.0 developers. What I’m saying is that for people with basic computer skills or no computer skills at all, a great user interface sounded like pure creative work when compared to a C DLL that took a lot of creative effort to create, but didn’t have any “visual” interaction.
I remember the frustration it caused us and other folks in the same position.
When I was younger, I used to think the same about maintenance developers. For me it was like they weren’t creating anything new. Since I couldn’t see new features as the product of their work, it was easy to believe their work didn’t require creativity. Big mistake! The day I ended up doing some urgent coding maintenance I learned how wrong I was!
Now, let’s suppose, for instance, there’s a game developer in a room showing a game demo with a cool animation that he/she did and a database developer demonstrating a fancy and revolutionary algorithm to search information in a database, using a simple console window to demonstrate the algorithm executing. Let’s say there are ten people watching the game demo and the database algorithm. Assume the ten people don’t have any programming knowledge. Guess who is going to be considered the creative developer?
It’s easy to escalate the discussion out of proportion and cross the software boundaries. As a software developer myself, I’m biased to think that software developers are the most creative guys out there. J However, I bet the marketing folks think the same about themselves. Other professionals—like artists, actors, chess players—might also think the same about themselves. So, if it’s difficult for a software developer to “measure” the creativity of other software developers from another domain, it’s even more difficult when professionals from different areas do that.
To summarize, it’s easy to create a misconception about how creative someone is, over evaluating or under evaluating the “creativity level” if we don’t really understand the kind of work a person does and the kind of challenges a person has to face when doing her/his work. Also, it’s easy to create a misconception when you trust only what you see, like the user interface, when talking about software, to judge someone by his/her creativity. I don’t know about you, but for some managers I had in the past, when working for other companies, a beautiful user interface used to test a basic algorithm had more chances of being seen as cool (the algorithm) and creative than a poor interface used to test a very fancy algorithm with innovative ideas embedded.
Like those who don’t work with computers, we tend to see creativity only in terms of software features or graphical user interface, but most of the time there’s creative work done just under the hood.
Let me share with you some public tools I’ve been using when working with SharePoint cases. Please consider that I’m learning SharePoint; likewise, if you’ve been using other tools and want to share with us (me and my readers J) feel free to do so.
These are the tools I use before trying a hardcore approach like attaching the debugger to the application or collecting dumps to do a post-mortem debugging. Of course, there’re situations where debugging is the only option, but based on the SharePoint cases I’ve been working with, it should be more of an exception than a rule.
The tools below are used for troubleshooting purposes and should give you information through formatted reports and graphics, so it’s easy to visualize the information and send the information to your customer or team.
For IIS log analysis and other log analysis:
LogParser
For SQL Server analysis:
SQL Nexus (uses LogParser under the hood)
For SQL Server Profiler analysis:
RML ReadTrace
For Performance Monitor analysis:
PAL (uses LogParser under the hood)
Anti-panic warning: I’ve seen customers in panic because the red flags from the PAL report.
In some cases they were false positives. To avoid misinterpretation follow these guidelines:
a) When analyzing a counter, analyze it within the context of other counters. Do not consider one single counter alone. Context is very important when analyzing PerfMon logs.
b) Don’t worry about a few spikes. A few spikes doesn’t mean there’s a problem.
c) Always look at the graphic. The graphic means more than the numbers alone.
For gathering detailed information about SharePoint and the server:
SPSReport
For troubleshooting authentication and authorization failures in IIS:
AuthDiag (DebugDiag 1.1 has a newer version included)
I intend to update this article whenever I use a new tool that proves to be helpful.
Fiddler
Fiddler is a HTTP Debugging Proxy which logs all HTTP traffic between your computer and the Internet. Fiddler allows you to inspect all HTTP Traffic, set breakpoints, and "fiddle" with incoming or outgoing data.
WinDiff
Great to compare files, like logs from different machines.
Process Monitor
For monitoring registry and file access.
CLR Profiler
Using this tool you can have a graphical view of all objects stored in the managed heap and their corresponding root objects.
If you have been using different tools and want to share it with us, do it.
Years ago, when working for an Escalation Team, we decided to create a documentation to formalize the approach we use to isolate software problems. Actually, it’s the same approach other people use in other fields. It reminds me of when I first started using a structured approach to solve software problems, based on a great book called The McKinsey Way. This book has nothing to do with computers, but everything to do with problem solving.
The most common scenario we find when isolating software problems is to have different problems causing one specific symptom. It’s important to mention because 90% of the time I’m working with my customers they expect me to show them the smoking gun.
However, during the investigation the most common or most visible problems are the first problems to be found. After fixing them we should expect:
a) The symptom does not happen anymore because all problems causing or contributing to the symptom were fixed.
b) The symptom still happens, but less often or with less intensity. It may be an indication of:
- Some of the diagnosed problems are not fixed yet.
- All identified problems were fixed, but other problems that occur less often or are less visible are causing the symptom. At this point, it should be easier to identify this kind of problem since the number of problems decreased.
c) The symptom persists like before. It means we fixed a problem that was not causing the symptom we are investigating.
Other scenarios may happen, too. However, they should be more of an exception than a rule. For example, you fixed the problem, and the symptom changed.
Just keep in mind that usually there are different software problems causing a single symptom. I’m lucky when I’m working in a support incident and, after monitoring the fix for a problem, it proves to be the only problem. This is uncommon.
With this blog post I’m not saying anything new if you already use this approach; however, if people in your organization or your customers can share a “framework” to solve problems, the communication becomes easier.
In my reports for my customers, I always describe the structured approach used to isolate problems, so they can understand why I did the things I’ve done.
That said, the “Problem Resolution Framework” presented in this post is not the result of an individual effort, but the result of a team effort.













WinDbg for 32 bits and 64 bits has a set of internal pseudo-registers that you can use as variables or as a means to get specific information.
The pseudo-registers are, according to WinDbg documentation:
|
Pseudo-register |
Description |
|
$ea |
The effective address of the last instruction that was executed. If this instruction does not have an effective address, the debugger displays "Bad register error.” If this instruction has two effective addresses, the debugger displays the first address. |
|
$ea2 |
The second effective address of the last instruction that was executed. If this instruction does not have two effective addresses, the debugger displays "Bad register error.” |
|
$exp |
The last expression that was evaluated. |
|
$ra |
The return address that is currently on the stack.
This address is especially useful in execution commands. For example, g @$ra continues until the return address is found (although gu (Go Up) is a more precise effective way of "stepping out" of the current function). |
|
$ip |
The instruction pointer register.
x86-based processors: The same as eip. Itanium-based processors: Related to iip. (For more information, see the note following this table.) x64-based processors: The same as rip. |
|
$eventip |
The instruction pointer at the time of the current event. This pointer typically matches $ip, unless you switched threads or manually changed the value of the instruction pointer. |
|
$previp |
The instruction pointer at the time of the previous event. (Breaking into the debugger counts as an event.) |
|
$relip |
An instruction pointer that is related to the current event. When you are branch tracing, this pointer is the pointer to the branch source. |
|
$scopeip |
The instruction pointer for the current local context (also known as the scope). |
|
$exentry |
The address of the entry point of the first executable of the current process. |
|
$retreg |
The primary return value register.
x86-based processors: The same as eax. Itanium-based processors: The same as ret0. x64-based processors: The same as rax. |
|
$retreg64 |
The primary return value register, in 64-bit format.
x86 processor: same as the edx:eax pair. |
|
$csp |
The current call stack pointer. This pointer is the register that is most representative of call stack depth.
x86-based processors: The same as esp. Itanium-based processors: The same as bsp. x64-based processors: The same as rsp. |
|
$p |
The value that the last d* (Display Memory) command printed. |
|
$proc |
The address of the current process (that is, the address of the EPROCESS block). |
|
$thread |
The address of the current thread (that is, the address of the ETHREAD block). |
|
$peb |
The address of the process environment block (PEB) of the current process. |
|
$teb |
The address of the thread environment block (TEB) of the current thread. |
|
$tpid |
The process ID (PID) for the process that owns the current thread. |
|
$tid |
The thread ID for the current thread. |
|
$bpNumber |
The address of the corresponding breakpoint. For example, $bp3 (or $bp03) refers to the breakpoint which has a breakpoint ID of 3. Number is always a decimal number. If no breakpoint has an ID of Number, $bpNumber evaluates to zero. |
|
$frame |
The current frame index. This index is the same frame number that the .frame (Set Local Context) command uses. |
|
$dbgtime |
The current time, according to the computer that the debugger is running on. |
|
$callret |
The return value of the last function that .call (Call Function) called or that is used in an .fnret /s command. The data type of $callret is the data type of this return value. |
|
$ptrsize |
The size of a pointer. In kernel mode, this size is the pointer size on the target computer. |
|
$pagesize |
The number of bytes in one page of memory. In kernel mode, this size is the page size on the target computer |
Besides we have User-Defined Pseudo-Registers:
There are 20 user-defined pseudo-registers ($t0, $t1, ..., $t19). These pseudo-registers are variables that you can read and write through the debugger. You can store any integer value in these pseudo-registers. They can be especially useful as loop variables.
To write to one of these pseudo-registers, use the r (Registers) command, as the following example shows:
r @$t0 = 7
r @$t1 = 128 * poi(@$t0)
Like all pseudo-registers, you can use the user-defined pseudo-register in any expression, as the following example shows:
bp @$t3
bp @$t4
?? @$t1 + 4 * @$t2
Tip: