Tuesday, November 09, 2010

My Common Interview Questions… Technical and Introspective

With all this focus I’ve had on finding another job, I started to look at the questions, and standards I have when interviewing a candidate in my company.  My upper management doesn’t like my questions, because I tend to lean more towards the computer science/software engineering side of the candidates skill set. Where my management would rather me evaluate their ability to show up to work on time (not that I’m bitter or anything). You see, I work for a service based company. One that get’s paid for “warm bodies”. They don’t have a large amount of pride and discipline for the engineering craft. Which is one of the main reasons I am looking for another job.

Anyway, I digress, my focus on what I bring to an interview, has been improved by my own interview questions. I like to use these to determine if someone is as average a web geek as I am.  I've collected a bunch of questions that are technical, but also inquire about the candidate’s professional and technical personality.

General Questions:

  • What sort of websites, blogs, and/or user forums do you follow? This is an open question, and there is no right answer. But anyone who is claiming to be technical should have a decent list of online resources for which they can learn, and stay on top of topics. For example, on a daily basis, I browse Slashdot, darknet, coding horror, DZone, Ben Nadel's ColdFusion blog, OWASP.org, and javablogs.com, among others.
  • If you are developing an application, and you come across an error that you've never seen before, what would you do? The wrong answer in this case is to ask someone in the office right away. Even though I pride myself to being a good resource for my co-workers, many times, the answers to all problems could be as simple as a google search. There should be an amount of time spent in research before they ask others to take the time to supply help. The previous question is a good lead into this because, if a developer has a good set of online resources, then they can solve most of their problems fairly easily.
  • How many web vulnerabilities are you aware of? And what can you do to prevent them? There are plenty to choose from, such as Reflected Cross Site Scripting, Persistent Cross Site Scripting, SQL Injection, Code Injection, Invalid Session management, Using default configurations, weak  encryption, improper error handling, poor input validation, weak authorization and authentication, and cross site request forgery, to name a few. The solutions to these problems include education, proper design, code review, testing, and common sense. A Good experienced programmer would recognize most, or more, of these. A mid-level programmer should know at least 4 or 5. A low level programmer would probably only recognize SQL Injection and cross site scripting.
  • Follow up question, what is the difference between Reflected Cross Site Scripting and Persistent Cross Site Scripting? Reflected is a flaw in which the user's input is reflected back to the user, this can cause a problem by allowing JavaScript code to be run in the browser. Persistent is when a similar flaw is saved to some persistent storage. Being able to answer this shows that they are not just reading buzz words.
  • Are you familiar with JavaScript? If so, how do you debug JavaScript? There are many tools out on the internet to help with JavaScript and CSS debugging. For example, I use FireBug, a plug-in for the Firefox browser to determine how JavaScript is running.

Advanced Programming:

  • Explain the benefits of Object Oriented Programming, and describe some techniques that can be used with of OOP. The benefits include improved maintainability, design, portability, modularity, and extensibility. Some techniques include data abstraction, encapsulation, modularity, polymorphism, and inheritance. As a follow up, ask to explain examples of each.
  • What are the differences between using stored procedures in a database vs writing the logic in a language like Java, and then calling the data with normal SQL queries. The DB stored procedures are compiled on the DB, so you can get better performance, but there is added complexity, since you may have different code based on different database’s.  This question shows that the candidate knows databases, and not just how to run SQL queries.
  • How would you debug a performance problem?  For example, if you have a web page that takes a long time to load, how would you debug it? This is a pretty open question. The candidate should be wondering, is this a static or dynamic page? Is there a lot of data? Large Images? Media? Try to determine where the performance problem is. Is it the Database? Check the SQL queries, analyze the database connections when the page loads. Is it the Code? Review the code for intensive loops or data calculations, watch the resources on the server, when the page loads. Is it the Network? Run traceroute or a network sniffer to look at how the packets are being transferred. All of these are potential areas for a performance problem.
  • Can you explain the differences between SOAP based web services and RESTful web services? SOAP is a standard, created by the W3C, that defines a request and response message for web services. REST is an architectural design which relies on XML, and HTTP request types. A follow up question would be to ask where you would use each.
  • Are you familiar with Aspect Oriented Programming (AOP)? If so, what benefit does it provide? Most experience developers should at least understand the concept of AOP. AOP allows for separating redundant code from modules so the developer can focus on the task at hand of the module. This saves development time, and improves maintainability and modularity.

Mid-level Questions:

  • What are 4 different types of scope used in web based programming languages like Java? Application, request, session, and page.
  • How would you loop through the GET and/or POST request parameters, when you don't know the names of the request parameters? This can be different depending on the server side language the candidate is being interviewed about, but they should all recognize the name-value pair characteristic of the request. In Java they can easily use request.getParameterNames() for an array of names. A followup question is to ask what sort of information is passed in the request. The candidate should be able to talk about the header information.
  • How would you design a multi-tiered application to separate display from business logic? This can be answered in many ways, but using a framework, an object oriented design, and or a design pattern,  can accomplish this. The key focus it to try to try and keep the HTML from getting cluttered up with logic code.
  • What software frameworks are you familiar with? Each language has their own frameworks. In Java there are quite a few, including Struts, Spring, Seam, and JavaServer Faces. A mid level programmer should be able to understand frameworks, at least on a high level.
  • What are some of the differences between Oracle and SQL Server, in terms of how the SQL is written? Most of the differences are with the out of the box functions, like getting time stamps getDate() for SQL Server, and SYSDATE for Oracle. But the SQL queries themselves are slightly different, especially with joining tables. SQL Server uses LEFT and RIGHT OUTER/INNER Join Syntax and Oracle has a short hand notation of using (+) to represent an outer join.
  • What are the benefits and disadvantages of Normalized vs. Non-normalized database design? Normalized database tables are easier to use, understand, and cuts back on redundant data. However, non-normalized table perform better.  Typical web applications use a normalized design, but reporting applications sometimes uses a non-normalized design to be able to run queries with a lot of data)

Low level programmer:

If the interviewee only answer a few of the questions above, then chances are, they are a low level programmer. If they are claiming more then 5 years experience, and cannot answer any of the above questions, that should be a red flag. However, someone with 2-4 years experience is still learning, and you could ask them how they keep up on the new technologies.

Overall, different organizations have different requirements for who they hire. Some have a strict budget to follow, others have a reputation to uphold. Regardless, the interviewer should have the knowledge of who they want on their team. If the person performing the interview cannot answer the questions they are asking, then it can be very easy to hire the wrong person.

Friday, October 22, 2010

Software Engineer Job Interviews

About 2 months ago, I was notified by a friend, about some job openings for Software Engineers, at her company.  I am pretty comfortable in my current position, but this other company looks pretty cool. Things like flex time, no dress code, high tech environment, and free coffee, makes me think that it could be the perfect job.

After a couple hours of research, it also looks like this company has high standards and employs really talented people. Not just a “Web Development” company, they expect you to understand Big O notation, and different design patterns. I consider myself an “Average Web Geek”, but I did receive a Masters in Computer Science, and my interests have always leaned more towards the engineering of software, compared to the assembly line culture that some IT companies represent.

I talked to the recruiter of this company, pretty standard stuff. She tells me that there are 4 phases to the interview process. There is first contact, that is that talk with the recruiting officer. Then there is a “homework” assignment, so the engineers can evaluate my initial coding skills. Then there is a phone interview with an engineer. Finally, there is a face-to-face. With the exception of the “homework” it is pretty standard.

Now, I should explain, I enjoy my job. But I am frustrated by the lack of a technical track. My company is looking for people to build web sites, then spend the rest of their professional lives as non-technical managers. I am also realizing there is a significant amount of co-workers who do not take as much pride as I do in engineering, and innovation. I consider myself the “Average” web geek, because I don’t see myself as anything special. Though, when I look around my office, I see a lot of people who are comfortable with their position, and the fact that they have no need to advance their knowledge, or experience. So, as happy as I am, I need to expand, and continue to advance my technical experience. This other company looks to have the direction I want to focus on.

The recruiter sends me the assignment. There are a couple questions about object oriented programming, and a Java interface for which I am required to supply an implementation. Question 1 is “What is an abstract class? Describe a common pattern that requires the use of abstract classes?” This is interesting. Normally I would use this as a question in a phone interview. It is a pretty basic question to test someone's basic object oriented knowledge. The other questions are specific to Java.

Based on the Job description, I know that they want an engineer with a large amount of Java experience, along with Spring, Hibernate, and JUnit. So, even though it isn’t required, I make sure that the code I send with the implementation class, contains these these concepts.

After a couple weeks, I hear back from them. They want to to set up a phone interview with a Lead Engineer. At this point, I am pretty excited. They seem like a pretty high tech company, with some really smart employees. So, I agree with excitement. The call comes in a couple days later. I take the call in the parking lot of a Trader Joes. I was expecting the interviewer to ask about my Java experience, shoot me some questions about Spring and Hibernate. Maybe test my knowledge of Java core concepts. But no, he hits me with a question to evaluate how I think.

He says “Lets say you are designing a card game, and you need a method to shuffle the cards. Describe the algorithm to do it.”

This question is very familiar, since I had it as a test question in my algorithms class during my graduate studies.  Unfortunately, that was about 8 years ago.  Though it shouldn’t be too hard. So, my first answer is to use 2 arrays. 1 contains 52 Card objects, and the other is empty. Then, using a random number generator, I would grab cards at random, and store them in the other array. Now, my current job hardly requires me to consider algorithms which are really speedy. Our datasets are small, and the schedules are short. So, usually the first solution is fine.  So, I was expecting his next question… “What about the blank cells in the original array? Are you concerned about those?”

Yes, of course. So, without thinking about redesigning the algorithm, I tell him that each time we remove a Card object, we can recreate the array with the size decremented. As I am talking I am realizing how stupid, and inefficient this sounds.  So I say, “It will work, but it isn’t efficient.” He then asks me to describe the performance in Big O notation. So…. there are n Card objects in the array (n = 52) , looping through the array n times to remove the Card objects. Then I would recreate the array as n-1, for each card. That is n*(n-1). Making the performance O(n^2), aka quadratic. Not very good considering that there is a better way.

After a couple minutes, it comes to me. There is actually a much simpler solution. I don’t need 2 arrays. Using just the original array of Card objects, I can generate 2 random numbers, and swap the cards. The random number generator, and swap function, would run in constant time, O(1). That leave the number of iterations. Therefore, the performance is O(n), aka linear. Much better.

The following code represents this algorithm:

public static void shuffleCards(Card[] deck) {
  Random generator = new Random();
   // shuffle the cards
   for (int i = 0 ; i < deck.length ; i ++) {
       int x1 = generator.nextInt(n) + 1;
       int x2 = generator.nextInt(n) + 1;
       Card card1 = deck[x1];
       Card card2 = deck[x2];
       deck[x1] = card2;
       deck[x2] = card1;
   }
}

This was the answer he was looking for. At this point, I could have pointed out that the code could be simplified by using the java.util.Collections class, which has a shuffle(List<?> list) method, and runs in linear time.

The phone interview continues with me asking questions about companies, and him asking a couple more questions about my experience. I guess I made an impression, since the recruiter schedules a series of face-to-face interviews. That will happen in the next week. So we would see what happens.

The moral of the story is, that there is a difference between being a average web coder, and a software engineer. I want to see what else is out there, so I have to break out of my IT shell and focus on the foundations which I learned in those Computer Science courses. It is very easy to grow comfortable and content in a stable position. But time keeps moving, and if you don’t keep learning, you can find yourself stuck. I hope one day I’ll consider myself to be more then just an Average Web Geek.

Friday, May 23, 2008

AD Authentication and Java

Well, it was only a matter of time before my job would require our Java apps to authenticate against Active Directory. For those who don't know what Active Directory (AD) is (myself included up till last year), AD is a Microsoft Windows implementation of LDAP. It is typically used in Windows 2000 based networks to tie together the standard IT resources like mail, calendars, and desktop computers. Those of us who are on a network that uses AD typically have a desktop that authenticates against AD, as well as MS Outlook for email. The good thing about a central authentication source for network credentials is that is allows for a single username and password to be used for things. Which can eventually lead to "Single Sign-On" (which will be discussed later, when I learn how to do it).

Anyway, a central source for authentication credentials also helps with web applications on that network, because now we no longer need to worry about password management, or user registration. That can reduce the project schedule by a week or two, depending on how strict your organization's password and user registration requirements are.

So, how do we do it? Well, it is actually pretty simple. Like I said, AD is basically another version of LDAP, so in Java you can use the Java Naming and Directory Interface (JNDI). There are a bunch of LDAP classes in the javax.naming.ldap package that can help. And because the Java API is so robust, it gives you a ton of flexibility to customize your code as much as possible. At the same time, it can seem a bit intimidating. Sun has some pretty good information on their website about LDAP authentication, which can also be used for AD Authentication. Lets take a look at some code.
Hashtable env = null;
DirContext ctx = null;
boolean isAuthenticated = false;

try {
try {
String loginId = "yourdomain\\avgwebgeek";
env = new Hashtable();   // hash table for your LDAP properties

// set up the LDAP properties
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://myadserver.mydomain.com:389");

// Set the authentication mechanism to be simple
env.put(Context.SECURITY_AUTHENTICATION, "simple");

// login credentials
env.put(Context.SECURITY_PRINCIPAL, loginId);
env.put(Context.SECURITY_CREDENTIALS, password);

// the following is helpful in debugging errors from the
// AD server side of things
//env.put("com.sun.jndi.ldap.trace.ber", System.err);

// Create the initial directory context
ctx = new InitialDirContext(env);
isAuthenticated = true;
} catch (AuthenticationException e) {
// this exception is typically found with incorrect credentials
e.printStackTrace();
} catch (NamingException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
} finally {  
try {
ctx.close();
}catch (NamingException e) {
e.printStackTrace();
}
}

if (isAuthenticated) {
System.out.println("I am authenticated.");
} else {
System.out.println("I am not authenticated.");
}

This is a very simple application. It does the job, however, it is not very secure. The problem is that I am setting the Context.SECURITY_AUTHENTICATION to "simple". What this means is that your password is being sent over the network through clear text. If someone is running a network sniffer, they can read your password from your IP packets. One way around this is to make sure that your LDAP connection is handled over SSL. In other words, use "ldaps://" with port 636, and not "ldap://" on port 389.

If your server is not setup to handle SSL, or you just want a little extra security, you can change the Context.SECURITY_AUTHENTICATION to "DIGEST-MD5". However, as I found out, AD treats this a little differently. The concept of using "yourdomain\\yourusername" needs to be reduced to just "yourusername". It has something to do with how AD 2003 sets up the HASH for the MD5. This method will use a Hashing algorithm to be verified with the server, that you indeed know your password.

So, that's it for AD authentication. Like I said, the Java API can let you do a lot more. You can set up controls to do searches, find specific user information, and find groups assigned to users. AD groups can be used to help with the Authorization portion of your apps. Take a look at the javax.naming.ldap API, there is a lot there, but it isn't too hard to follow.