6 tips for better interviewing for Software Engineers

A few weeks ago a good friend of mine interviewed for a Software Engineering position on my team. We have a very high bar when it comes to interviewing — our interview sessions usually include a lot of whiteboarding and tough programming problems. We didn’t end up making my friend an offer, and a few days later he texted me asking for advice that I could give him that he could use to improve his interviewing skills. Here’s what I ended up sending him:

1. Pick 5 hard problems, and know them well. I would suggest starting with 5 good programming problems, maybe even problems you heard while interviewing here or others you’ve come across. Make sure you understand the problem very well. Spend time thinking about the problem.

2. Practice in an environment that simulates the interview setting. Grab a friend and have her/him ask you questions that you’ve prepared in advance, and allow them to ask their own questions. Practice in front of a whiteboard, if possible in a meeting room or office, to simulate a real interview. Envision in your mind being at an actual interview, at the company you plan on interviewing with.

3. Restate the problem to the interviewer, and make sure that they know that you understand the problem. Part of this may be repeating or restating the question back to the interviewer. Doing this shows that you can communicate well. It also helps make sure that you are sure of what they are asking. At this point you want to clarify any assumptions you are making before you move forward. Getting an assumption cleared up or removed will help you tremendously — if they aren’t cleared up you can end up in left field real fast, solving a problem that is either not the problem the interviewer had in mind or is considerably harder than what was originally asked. If you clear up assumptions, you make the problem set very clear in your mind, and more often than not the problem becomes easier than it might have been.

4. Don’t ‘sign off’ too early. What I mean by this is many times interviewees tell the interviewer that they are done with their solution, when they haven’t double checked their work. When you feel you are done, take a deep breath and run through your code a couple of times. Test your code (see point 5). Don’t be too eager to be done with your solution. You’ll appear much better if you relax and take a second to revise and thoroughly inspect your code. You most likely have a problem that you’re not seeing. Fix the problem and repeat this process.

5. Test your code. In particular, boundary conditions. For example, if the problem being asked involved operations on a list, I would make sure that test cases I run through included lists with the following properties: null list, empty list, list with 1 item, list with a many items (or maximum depending on implementation/structure), list with mixture of null and non-null items, etc.

6. Think about memory and big O. More often than not, I’ll ask the interviewee, “Is there any way you can make this algorithm more efficient?” What I’m looking for is an understanding from you that you know there are tradeoffs of time and space when designing an algorithm. Can you reduce the amount of memory your solution uses? Can you improve the time complexity. What is the time complexity of your algorithm? Be prepared to answer these questions. Bonus: take a look at Wirth’s law and understand its implications.

Conclusion

These are just a few of the observations I’ve made while interviewing Software Engineers. Do you have any to add? Leave your suggestions in the comments below.

How to send a message from your WatchKit app to your iOS app

Have you ever wondered how to communicate from your WatchKit app to its containing iOS app?

Enter openParentApplication.

openParentApplication is a method on WKInterfaceController. It allows you to pass in an object that contains the information you want to pass along to the WatchKit app’s containing iOS app.

Here is a simple example:

Here I am sending a dictionary with a key of ‘buttonClicked’ and value of type String that represents which button in my UI was clicked. If you look at the method signature on openParentApplication, you’ll see that it accepts an NSObject of AnyObject:


That’s simple enough. What about receiving this message on the containing iOS app end?

Introducing handleWatchKitExtensionRequest.

Add handleWatchKitExtensionRequest to your application’s AppDelegate.

For example:

handleWatchKitExtensionRequest allows you to receive the object you had sent from your WatchKit app. In this example, since I had sent a dictionary from the WatchKit app, I get a dictionary on the iOS containing app’s side. I then look inside the dictionary for the existence of the key I had set on the WatchKit side, checking for nil. If the key exists in the dictionary, I print it out.

What about that reply parameter?

openParentApplication allows you to pass a closure via the reply parameter. This allows you to send a message from the containing iOS app to the WatchKit app. I will modify my example to demonstrate this. Here, instead of passing in nil for reply, I pass in a closure:

The closure for the reply parameter expects a dictionary and an NSError to be passed to it. If I run this code, what happens? The closure is executed, but we get an error:


Fortunately, the error is very helpful: ‘The UIApplicationDelegate in the iPhone App never called reply()’. So let me fix that. For simplicity’s sake, let’s say that I wanted the iOS app to communicate back to the WatchKit app a count of the number of times a particular button had been clicked. I’ll simply invoke the reply closure, passing along a dictionary of the desired information:


Back on the WatchKit side, in the else block, the dictionary that we received from the containing iOS app gets printed out:


When I run the WatchKit app, I now get the dictionary printed out to the debugger:


UIApplicationState.Background

Something you should be aware of is that the containing iOS app launches in the background. This is fine except that the normal app lifecycle is triggered and executes. For example, your app’s viewWillAppear method will be called. The way I got around that in my app is by adding the following to the containing iOS app’s AppDelegate didFinishLaunchingWithOptions method:

Final Thoughts

openParentApplication and handleWatchKitExtensionRequest are a powerful combination. Use them when you want to send information between your WatchKit extension and its containing iOS app. Be aware that the iOS app’s lifecycle is triggered and executes, even with the app running in the background.

Do you have any feedback? What has your experience been with these two methods? Let me know in the comments section below.

Related Links

WatchKit Framework Reference openParentApplication

UIKit Framework Reference handleWatchKitExtensionRequest

ASP.NET MVC: Code Nuggets

<% %>, <%= %>, and <%: %> have special meaning:

Code enclosed within <% %> will be executed
Code enclosed within <%= %> will be executed, and the result will be outputted to the page
Code enclosed within <%: %> will be executed, and the result will be outputted to the page, as well as being HTML encoded

If you’re on ASP.NET 4 or later, you’ll want to use the <%: %> syntax vs. the <%= %> syntax, as the result gets HTML encoded.

C#: static constructors, static classes

If you want to dynamically set a static member (i.e. read it from a database or file), you can make use of a static constructor. Here are some interesting notes about static constructors:

  • The static constructor runs before any instance constructors run.
  • Static constructors don’t take an access modifier and can’t take parameters.
  • Static constructors execute only one time, no matter how many instances are created.
  • Static constructors get called when an instance of the class is created or before the first static member of the class is accessed.
  • A class or structure can define only 1 static constructor.

C#: static keyword

Use the static keyword for members of a type that are so common that there isn’t a need to create an instance of the type. A few notes on on static data:

  • Static members can only operate on other static members.
  • Static data is allocated once and shared among all instances of the same type.
  • A non-static method can make use of non-static and static data. Static data is available to all instances of the type.
  • If you assign a static member in a constructor, every time a new instance is created, the static member gets reset.

C#: Read-only fields

The C# keyword readonly is used when you don’t know a value at compile time, but you want that value to never change once it’s been assigned. Read-only fields aren’t static like constants are; if you’d like to make them static you must include the static keyword.

An interesting fact about readonly fields is that their value can be assigned from within a constructor. An example of this is when you need to read a value from the database.

C#: Constants

A few notes about constants in C#:

  1. Once a constant has been assigned a value, you can’t change it’s value or you’ll receive a compile error.
  2. Constants may not be used as return values.
  3. The value assigned to a constant must be known at compile time.
  4. Constant fields are static and thus need to be prefixed with the type name. However if referencing a constant within the current type or member, you don’t need to prefix it with the type name.

C#: Default Values for member variables

5 simple rules to remember for the default values that class member variables get:

  1. Numeric data is set to 0 or 0.0
  2. char types are set to ‘\0’
  3. bool types are set to false
  4. string types are set to null
  5. Reference types are set to null

This is at the class level. When within method scope, you must assign an initial value before using a variable as they don’t receive a default assignment. The only exception is when using a variable as an output parameter (out keyword).

If you’d like to override the default values, you can assign a type’s member variable at the time of declaration:

Be aware that members are assigned before the constructor gets called. That means that if you give a member a default value but then assign it in the constructor, it cancels out the initial assignment.

C#: access modifiers

Members default to private when no access modifier is present.

public: accessible from an object variable as well as derived classes
private: accessible only from the class that has defined the method. In C#, all members are private by default
protected: accessible by the defining class and derived classes. Protected methods are not accessible from an object variable.
internal: accessible by any type in the assembly, but not outside the assembly
protected internal: access is limited to the current assembly or types derived from the defining class in the current assembly

internal or internal protected members are really only useful when creating code libraries.

Types (classes, interfaces, structures, enumerations, delegates) are limited to public or internal; private may be used when the type is nested. internal is the default accessibility for types in C#.

.NET: String Format Characters

C or c: currency based on local cultural symbol, $1234.56
D or d: decimal, optional number (i.e. {0:D8}) used to pad value, 012345678
E or e: exponential notation, 1.234E+05
F or f: fixed point, 0:F3 1234.567
G or g: general, used to format to fixed or exponential
N or n: numerical format (with commas), 1,234.00
X or x: hexadecimal, 0:X 123F, 0:x 123f

You can use this with string.Format, like below: