Surviving the Technical Interview

 

Surviving the Technical Interview

Useful tips and sample problems

(Page 1 of 6)
Jay Sutaria
Interviews for technical jobs are perhaps the most intimidating and mysterious events that job hunters experience. Jay discusses ways in which you can better showcase your skills and experience.

Jay is a software engineer at LinkExchange. He can be contacted at jay@ linkexchange.com.

 


 

The technical interview is perhaps the most intimidating and mysterious event that job hunters experience in the quest for that "killer offer." The rigor and format of the technical interview varies from one company to the next, but there are some fundamental similarities. An interviewer presents you with a problem to be solved. The interviewer may leave the room and give you some time to work the solution out before returning. Or the interviewer may wait patiently while you study the problem and figure it out. The interviewer may even start quizzing you right away about aspects of the problem and approaches to solving it. Some of these problems can appear quite challenging, especially if you've never been through a technical interview before. To make matters worse, simply getting the answer to the problem may not be enough to land the job. On the other hand, getting the correct answer may not even be necessary.

 

What is an interviewer looking for in candidates during the technical interview? Interviewers recognize that this setting is, by its very nature, stressful. Otherwise competent candidates may be completely stumped by an interview problem only to discover an elegant, simple solution later that night. Interviewers may be interested in seeing how you work under stressful situations or how well you adapt. It is worth noting that interviewers are more interested in seeing how you work than seeing whether you can come up with the correct answer. In this article, I will deal with both how you can better showcase your skills and experience, and what kinds of problems you can expect to be asked.

 

The Basic Rules

 

These basic rules are often taught to programmers and are (or at any rate, should be) drilled into your head in computer-science classes. For some reason, however, they are easily forgotten during the technical interview. Being one of the few candidates careful and experienced enough to remember these important steps can make the difference between getting an offer and getting the cold shoulder.

 

Don't be afraid to ask for clarifications of the problem or the requirements for the solution. You should never assume that you have been given all the data necessary to solve the problem to the satisfaction of the interviewer. This is especially likely to be the case when interviewing with IT consulting companies. In this environment, the client may need some prodding in order to provide a complete specification. So, the reasoning goes, ideal candidates will be willing to talk to the client to figure out the expected inputs, the desired outputs, the data ranges and data types, and the special cases. The ideal candidate will ask these questions rather than spend all the allotted time coming up with a solution that doesn't meet the client's needs.

 

The first thing to do, then, is to make sure that you and the interviewer agree on what the problem is and what an acceptable solution would be. Make all of your assumptions explicit and up-front, so the interviewer can correct you if you are mistaken.

 

Think out loud. If the interviewer stays in the room after presenting the problem, he or she is interested in seeing how you analyze and approach a problem. Of interest are how possible solutions are considered and eliminated. And frankly, watching a candidate sit and stare at a problem isn't all that entertaining for the interviewer.

 

Always allow sufficient time for design. The worst thing that you can do while attempting to solve a technical problem is to dive right into coding a solution and get about half way through it before realizing that the approach is all wrong. This is where a little forethought can save a great deal of effort and embarrassment. Don't worry about running out of time to answer the question before finishing the code for the solution. The idea, the algorithm, and the approach are the most important elements here.

 

If you're having trouble writing the code, offer to explain the algorithm. Stress and anxiety can make the technical interview more difficult than it needs to be. If you find yourself having difficulty with programming syntax or constructs, you should make sure that the interviewer knows that you understand the problem and its solution. While it's best to get both the algorithm and the implementation correct, it's far better to get points for demonstrating facility with one than fail to demonstrate either.

 

Be prepared to identify bottlenecks, possible optimizations, and alternative algorithms. Just because you've found one solution that produces the correct output, doesn't mean the problem has been solved to the interviewer's satisfaction. Interviewers, hinting at possible improvements, may prod you at this point. Occasionally, you may take an approach that the interviewer didn't anticipate. At this point, an interviewer may ask you to take a more conventional approach. This doesn't mean that you've done anything wrong; very often, an interviewer may be leading you along a particular approach with a purpose in mind. The interviewer may be intending to ask follow-up questions or present new problems that build on a particular solution.

 

Initialize all variables, give variables descriptive names, and always use comments. Interviewers may be watching your solutions to determine whether you follow good programming practices. Good programming practices make it easy to understand other people's code. This means that there aren't cryptic variables, functions with undocumented side effects, obfuscated algorithms, and sloppy (read: buggy) code. Just because you are being interviewed (and therefore, coding on a whiteboard or on a piece of paper) doesn't give you an excuse to be sloppy or lazy. Commenting code for an interview may seem like a waste of time, but some interviewers do look to see that candidates write comments while coding or before coding, rather than adding them in as an afterthought.

 

Check all boundary conditions. Candidates forget to do this frighteningly often. In fact, practicing programmers sometimes forget to do this. That's how bugs get started. You should verify that your code properly handles cases where inputs are negative or zero, lists are empty, strings are empty, and pointers are NULL. This is also a good habit to have after you get the job.

 

Expect bad input from users. Users rarely do as they are expected. You should protect your code, and return a descriptive error back to the user.

 

Display enthusiasm. Don't underestimate the importance of your appearance and attitude during the interview. While your skills and experience may be the focus of the technical interview, looking bored or uninterested may do more to sabotage your chances than blowing an interview problem.

 

Work Things Into Your Conversations

 

In addition to these basic rules for the technical interview, there are some other things worth pointing out. Interviewers don't always have the chance to examine your résumé in advance. This means that the interviewer may not be aware of your past work experience. Don't hesitate to point out experiences working in teams (whether as a part of a past job, a class programming project, or a hobby), working on large projects (paying attention to time spent on design, implementation, and testing), dealing with customers to define requirements, and managing people and projects. Interviewers are interested in hearing about successes as well as failures. When these past experiences weren't successful, you should point out the lessons learned or wisdom gained as a result of these failures. Interviewers want to see that candidates who have had negative experiences are not going to repeat their mistakes.

 

Typical Technical Questions

 

When preparing for a technical interview, you should review basic structures (linked lists, binary trees, heaps) and algorithms (searching, sorting, hashing). Having a mastery of these topics will likely give you all the necessary knowledge to tackle the problems you will encounter during the technical interview.

 

Also, review the areas for which you're interviewing. If you're interviewing for a systems programming job, review the differences between threads and processes, OS scheduling algorithms, and memory allocation. If you're interviewing for a job that requires experience with an object-oriented language, spend some time brushing up on object-oriented methodology.

 

Fortunately, some of the same problems come up with surprising frequency. Even if a given interviewer doesn't use any of the problems I present here, studying them should give you insight into solving other problems.

 

Problem: Write a function that returns the factorial of a number.

 

Solution: This is a typical, can-you-program warm-up question. Example 1 shows the iterative and recursive solutions. Notice that in both solutions, I check the input values and boundary conditions. Factorials of negative numbers are undefined, and the factorial of both 0 and 1 are 1. The functions in Example 1 handle these cases correctly, and they initialize all variables.

 

Problem: Write a function that computes the nth number in the Fibonacci sequence.

 

Solution: Example 2 contains both the iterative and recursive solutions. The iterative version maintains variables to hold the last two values in the Fibonacci sequence, and uses them to compute the next value. Again, boundary conditions and inputs are checked. The 0th number in the Fibonacci sequence is defined as 0. The first number in the sequence is 1. Return -1 if a negative number is passed.

 

The recursive version of the Fibonacci function works correctly, but is considerably more expensive than the iterative version. There are, however, other ways to write this function recursively in C that are not as expensive. For instance, you could maintain static variables or create a struct to hold previously computed results.

 

Problem: Write an implementation of strlen().

 

Solution: Given a char pointer, strlen() determines the number of chars in a string. The first thing that your strlen() implementation ought to do is to check your boundary conditions. Don't forget the case where the pointer you are given is pointing to an empty string. What about the case where the pointer is equal to NULL? This is a case where you should state your assumptions. In many implementations, the real strlen() doesn't check to see if the pointer is NULL, so passing a NULL pointer to strlen() would result in a segmentation fault. Making it clear to your interviewer that you are aware of both of these boundary conditions shows that you understand the problem and that you have thought about its solution carefully. Example 3 shows the correct solution.

 

Problem: Switch the integer values stored in two registers without using any additional memory.

 

To swap the values, you can carry out the following instructions:

 

Reg_1 = Reg_1 + Reg_2;
Reg_2 = Reg_1 - Reg_2;
Reg_1 = Reg_1 - Reg_2;

 

Problem: You are given a list of n numbers from 1 to n-1, with one of the numbers repeated. Devise a method to determine which number is repeated.

 

Solution: The sum of the numbers 1 to n-1 is (n)(n-1)/2. Add the numbers on the list, and subtract (n)(n-1)/2. The result is the number that has been repeated.

 

 

 

Problem: You are presented with a linked list, which may have a "loop" in it. That is, an element of the linked list may incorrectly point to a previously encountered element, which can cause an infinite loop when traversing the list. Devise an algorithm to detect whether a loop exists in a linked list. How does your answer change if you cannot change the structure of the list elements?

 

Solution: One possible answer is to add a flag to each element of the list. You could then traverse the list, starting at the head and tagging each element as you encounter it. If you ever encountered an element that was already tagged, you would know that you had already visited it and that there existed a loop in the linked list.

 

What if you are not allowed to alter the structure of the elements of the linked list? The following algorithm will find the loop:

 

  1. Start with two pointers ptr1 and ptr2.

     

  2. Set ptr1 and ptr2 to the head of the linked list.

     

  3. Traverse the linked list with ptr1 moving twice as fast as ptr2 (for every two elements that ptr1 advances within the list, advance ptr2 by one element).

     

  4. Stop when ptr1 reaches the end of the list, or when ptr1 = ptr2.

     

  5. If ptr1 and ptr2 are ever equal, then there must be a loop in the linked list. If the linked list has no loops, ptr1 should reach the end of the linked list ahead of ptr2.

 

Problem: Given the time, devise an algorithm to calculate the angle between the hour and minute hands of an analog clock.

 

Solution: The important realization for this problem is that the hour hand is always moving. In other words, at 1:30, the hour hand is halfway between 1 and 2. Once you remember that, this problem is fairly straightforward. Assuming you don't care whether the function returns the shorter or larger angle, Example 4 shows a solution to this problem.

 

Problem: Devise an algorithm for detecting whether a given string is a palindrome (spelled the same way forwards and backwards). For example, "A man, a plan, a canal, Panama."

 

Solution: For the sake of this problem, assume that the string has been stripped of punctuation (including spaces), and has been converted to a single case.

 

The most efficient way to detect whether a string is a palindrome is to create two pointers. Set one at the beginning of the string, and one at the end. Compare the values at those locations. If the values don't match, the string isn't a palindrome. Otherwise, move each pointer inward and repeat the comparison. Stop when the pointers are pointing to the same position in the string (if its length is an odd-number) or when the pointers have "crossed" (if the string's length is an even-number). Example 5 shows the correct solution.

 

Problem: Given an eight-bit bitmap graphics file, devise an algorithm to convert the file into a two-bit ASCII approximation.

 

Solution: Assume that the file format is one byte for every pixel in the file, and that the approximation will produce one ASCII character of output for each pixel.

 

This problem is easier to solve than it sounds. This is one of the tricks used in technical interview questions. Problems may be obscured or made to sound difficult. Don't be fooled! Take the time to think about the core of the problem. In this case, all you want is an algorithm for reading the values in a file and outputting characters based upon those values.

 

Eight-bit numbers can be in the range from 0 to 255. Two-bit numbers are in the range from 0 to 3. Basically, we want to divide the 256 numbers specified by an eight-bit number into four ranges, which can be indicated by a two-bit number. So, divide the range of 0 to 255 uniformly into four separate ranges: 0 to 63, 64 to 127, 128 to 191, and 192 to 255.

 

You then have to assign an ASCII character to each of those four ranges of numbers. For example, you could use "_", "~", "+", and "#". Then, the algorithm is as follows:

 

  1. Open the file.

     

  2. For every byte in the file:
    1. Read in one byte.

       

    2. If the value is in the range 0..63, we'll print '_'.

       

    3. If the value is in the range 64..127, we'll print '~'.

       

    4. If the value is in the range 128..191, we'll print '+'.

       

    5. If the value is in the range 192..255, we'll print '#'.
  3. Close the file.

 

Conclusion

 

The specific details of your interview will, of course, depend on a number of factors -- the type of job you are applying for, the needs and expertise of the technical interviewer, and guidelines set forth by the organization seeking to hire you. Still, if you generalize and apply the tips I've presented here, you should be well on your way to getting the programming job that you want.

 

 
 
(a)
int  iterative_factorial ( int  number) {
     
int  rval  =   1 ;
     
/*  first check input values  */
     
if  (number  <   0 ) {
          
/*  we'll return -1 if there's an error  */
          
return  ( - 1 );
     }
     
for  ( int  i  =  number; i  >   1 ; i -- ) {
          rval 
=  rval  *  i;
     }
     
return  (rval);
}

(b)
int  recursive_factorial ( int  number) {
     
if  (number  <   0 ) {
          
/*  we'll return -1 if there's an error  */
          
return  ( - 1 );
     }
     
else   if  ((number  ==   0 ||  (number  ==   1 )) {
          
return  ( 1 );
     }
     
else  {
          
return  recursive_factorial (number - 1 *  number;
     }
}
Example 1: Function that returns the factorial of a number: (a) iterative; (b) recursive.

 

 
 
(a)
int  iterative_fibonacci ( int  number) {
     
int  fib_n  =   0 ;
     
int  fib_n_plus_1  =   1 ;
     
int  rval  =   1 ;
     
int  i;
     
if  (number  <   0 ) {
          
/*  we'll return -1 if there's an error  */
          
return  ( - 1 );
     }
     
else  {
          
for  (i  =   0 ; i  <  number;  i ++ ) {
               rval 
=  fib_n  +  fib_n_plus_1;
               fib_n 
=  fib_n_plus_1;
               fib_n_plus_1 
=  rval;
          }
          
return  (rval);
     }
}

(b)
int  recursive_fibonacci_one ( int  number) {
     
if  (number  <   0 ) {
          
/*  we'll return -1 if there's an error  */
          
return  ( - 1 );
     }
     
else   if  (number  ==   0 ) {
          
return  ( 0 );
     }
     
else   if  (number  ==   1 ) {
          
return  ( 1 );
     }
     
else  {
          
return  (recursive_fibonacci_one (number - 1 )
               
+  recursive_fibonacci_one (number - 2 ));
     }
}
Example 2: Computing the nth number in the Fibonacci sequence: (a) iterative; (b) recursive.

 

 

 
 
int  strlen ( char   * ptr) {
    
int  i  =   0 ;
    
if  (ptr  ==  NULL) {
       
/*  the real strlen doesn't handle this  */
       
/*  case, but I do! I return -1  */
       
return  ( - 1 );
    }
    
while  ( * ptr ++ !=   '
Example 3: Implementing strlen().

 

 
 
float  time_angle ( int  hour,  int  minute) {
    
float  result;
    
float  hour_angle, minute_angle;
    
/*  mod minutes by 60, hour by 12 in case user  */
    
/*  inputs high values  */
    hour_angle 
=   0.5   *  ( float )((minute  %   60 +   60   *  
                                     (hour 
%   12 ));
    minute_angle 
=   6   *  (minute  %   60 );
    result 
=  (hour_angle  -  minute_angle);
    
/*  make the result positive  */
    
if  (result  <   0 ) {
        result 
=  result  *   - 1 ;
    }
    
return  result;
}
Example 4: Calculating the angle between a clock's hour and minute hands.

 

 
 
int  IsPalindrome ( char   *  myStr) {
    
/*  we'll return -1 if this is not a palindrome  */
    
/*  else we'll return 1  */
    
int  ptr1, ptr2;
    
/*  point to first character in the string  */
    ptr1 
=  myStr;
    
/*  point to last character in the string  */
    ptr2 
=  myStr  +  strlen(myStr)  -   1  ;
    
while  (ptr1  <  ptr2) {
        
/*  if we find characters that don't match,
           then this isn't a palindrome 
*/
        
if  ( * ptr1  !=   * ptr2) {
            
return  ( - 1 );
        }
        ptr1
++ ;
        ptr2
-- ;
    }
    
return  ( 1 );
}
Example 5: Is a string a palindrome?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值