Senior Software Engineer Interview Questions

Scott Hanselman has posted some new questions here that you can use to interview a senior level software engineer.  There’s a lot of good questions and several are ones I need to look up myself :).  I think I may try posting answers to as many of these questions as well as some of the questions he’s listed in an older post.

I also found a link in the comments for 5 essential phone screen questions.  Take a look here when you get a chance.

Advertisements

Using Lamda Expressions as Properties

Found a really cool article describing how lambda expressions can be used as properties.  Here’s a brief description:

The idea is pretty simple.  You define a property, which, instead of returning some scalar value, returns a lambda expression (or pretty much any form on anonymous function).  The property works just like a instance method, except we can assign and change it at run-time.

http://honestillusion.com/blogs/blog_0/archive/2010/06/07/lambda-expressions-as-properties.aspx

UPDATE:   Looks like that link is dead.  Here’s a copy of the original article:

 

Peter recently caused a bit of a stir with his article “Sometimes an enum is not the best idea”.  In it, he had a very specific problem: When an enum is passed to a method as an Object, and that method converts it to a usable value by calling ToString(), you get that enum’s name and not it’s value.  And he gave a gave very specific solution to that problem.  Peter wanted an simple ad hoc solution that he could just drop into his code.  Peter’s idea was basically a quick fix to replace a bad design with something slightly less bad.   The problem arose when readers inferred that it was intended as a far more general solution, and pointed out different, more architectural solutions.  Bickering started in the comments.

I think the main problem is that Peter just want a quick fix to his existing design, and viewed a proper design as overkill for his simple needs.  However, since those simple needs were out of scope of his original purpose for the  article, he never got into specifics.  However, knowing the specifics would be key to knowing how complex the design needs to be.  This was the essence of Peter’s follow-up article (which he posted as I was in the middle of writing this)

So, let’s try looking at this problem to see if we can come up with a better design that still meets the goal of being simple.

In Peter’s design, he has a Suppliers class (which he occasionally refers to as the Company class), which has several instances — one for each supplier.  There is also an enum, PublicIds with one entry for each supplier.  PublicIds was used in two places:  In switch statements, and as a parameter in an ADO.NET statement:

public void DoWithCompany(PublicIds company)
{
    switch (company)
    {
      case PublicIds.Company1:
      // Do something with Company 1
      break;
      case PublicIds.MyCompany:
      // Do something with My Company  
      break;
      case PublicIds.ThatOtherCompany:
      // Do something else
      break;
    }
}

cmdExists.Parameters.AddWithValue(“@idSupplier”, Supplier.PublicIds.MyCompany);

 

The second use was the real motivator of Peter’s article – The first was what caused all the hoopla on the blog.

Commenters proposed some general ideas, basically out of Object-Oriented Design 101 – Creating a new subclass for  each of the Suppliers, with overridden methods.  Peter fought back — the code in the “do something” blocks is not part of Supplier, but is in other classes.  Subclasses would requiring moving non-related code to where it doesn’t belong.

Since Peter still hasn’t provided any real-world examples of his problem (which is reasonable, as they might involve proprietary material or just have too many dependencies to post meaningful excerpts), lets try to imagine some scenarios that might fit his description (namely that DoWithCompany is an example of  a method that “is a member of several quite different other classes and comes in many flavors”).

Ok, so let’s say we have a Order class, with a ProcessOrderToSupplier(Supplier sup) method.   Let’s further say that most of Order processing is the same for all suppliers, but some suppliers offer a discount (or surcharge) under some conditions.  Hence we need custom processing per supplier to handle the discount, but moving order handling into the Supplier class would clearly be wrong.

So, let’s try three different discounting schemes, and come up with three means of handling them in ways that are scalable, maintainable & understandable.

#1 – A flat discount rate on all items.

That’s simple.  A discount rate property (getter only) in Supplier.  It could be an abstract property which is overridden in derived classes (one for each Supplier), or just set in Supplier’s constructor.  (Could be set to zero for those suppliers not offering a discount).

#2 –  Several suppliers offering (free shipping on orders over $100).

The “free shipping blah-blah-blah” part is handled entirely in the Order class.  The Supplier class just needs a way to say whether of not a particular supplier offers it.  This could be handled by a  Property as described above, or an attribute on the derived class, or by a marker interface (a marker interface has no members, and is just used in statements like:

if (sup is IOffersFreeShipping)
     ProcessFreeShipping();

#3 – One supplier offers 10% off total orders over $100. Another offers 15% off individual items over $25. And a third offers a $1 shipping surcharge on items over 20 lb.

Basically,  every supplier offers something different, and each is complex.  We’d think we’d need derived classes with overridden methods here to keep this object-oriented.  But that is exactly “the first step to multiple inheritance or an unmaintainable set of interfaces” which Peter was afraid of.

(My laptop has an interesting way of telling me that I haven’t saved in a while — the battery falls out.  I’ve now – too late — discovered Windows Live Writer’s auto-save feature.  Now let’s see if I can recreate what I just lost……).

And besides that, creating a subclass specifically for one instance of a class just feels wrong — particularly when we would be creating multiple subclass, one for each of several instances.  But how can be package instances of distinct functionality in individual instances of an object.

By using Lambda Expressions as Properties. 

The idea is pretty simple.  We define a property, which, instead of returning some scalar value, returns a lambda expression (or pretty much any form on anonymous function).  The property works just like a instance method, except we can assign and change it at run-time.   If you’ve done any work in JavaScript, you’ve probably seen very much the same thing.

Let’s look at some code.  We start by defining the Supplier class like this:

public class Supplier 
{
    public PublicIds Id {get; private set;}
    public int IdCode {get { return (int) Id;}}
    public Action PerItem {get; private set;}

    public Supplier(PublicIds id, Action perItem)
    {
        Id = id;
        PerItem = perItem;
    }

    public Supplier(PublicIds id) : this(id, oi=> oi=oi)
    {}
}

Note that the constructor takes a Action delegate, and stores it in the PerItem property.

Next, define our instances like this:

Supplier Company1 = new Supplier(PublicIds.Company1);
Supplier MyCompany = new Supplier(PublicIds.MyCompany, oi=> { if (oi.Price > 25m) oi.Discount = oi.Price * 0.15m;});
Supplier ThatOtherCompany = new Supplier(PublicIds.ThatOtherCompany, oi=> {if (oi.Weight >=20) oi.Shipping = 1m;});

And used them  like this:

List items = new List();    
void ProcessOrderToSupplier(Supplier sup)
{
    // :
    items.ForEach(sup.PerItem);
    //:
}

“Ok“, you say. “We’ve got the distinct behavior without subclasses – but we still have order processing code defined outside of the Order class, and to make matters worse, it moved to the instance definition in a really messy way.”

No Problem, we just go back to out (new) old friend: Lambda Expression as Properties:

This time, we’ll create static properties in the Order class:

public class Order
{
    List items = new List();    
    void ProcessOrderToSupplier(Supplier sup)
    {
        // :
        items.ForEach(sup.PerItem);
        //:
    }    

    public static  Action Discount15on25
    {
        get
        {
            return oi => 
                { 
                    if (oi.Price > 25m) 
                        oi.Discount = oi.Price * 0.15m;
                };
        }
    }

    public static  Action Shipping1Over20
    {
        get
        {
            return oi=> 
                {
                    if (oi.Weight >=20) 
                        oi.Shipping = 1m;
                };
        }
    }
}

And we can now define out Supplier instances like this:

 

Supplier Company1 = new Supplier(PublicIds.Company1);
Supplier MyCompany = new Supplier(PublicIds.MyCompany, Order.Discount15on25);
Supplier ThatOtherCompany = new Supplier(PublicIds.ThatOtherCompany, Order.Shipping1Over20);

So, what have we accomplished?

  • We’ve distinct behavior amongst the different suppliers, without resorting to subclasses or switch/case blocks
  • We’ve all the Order processing code in the Order class.
  • We’ve neat & tidy Supplier instance definitions, which nevertheless indicates the special features of that supplier.
  • And we have those special features as part of the Supplier object.

But, wait.  You’re probably saying that those properties we’ve defined on Order are rather specific to one particular trait.  Would it be nice to be able to have one general algorithm which is customizable?  That can be done too, by just extending the general principle, which involves using a method instead of a property, but the basic idea is still the same:  instead of returning a value, we return a function:

public static  Action ShippingByWeight(int pounds, decimal cost)
{
    return oi=> 
        {
            if (oi.Weight >=pounds) 
                oi.Shipping = cost;
        };
}

// :

Supplier ThatOtherCompany = new Supplier(PublicIds.ThatOtherCompany, Order.ShippingByWeight(20,1m);

Most Used Enumerable(T) Methods

Here’s the Enumerable methods I use the most.  All of these are available in the .NET 4.0 Framework.

Enumerable.Any() – Determines whether a sequence contains any elements.

Enumerable.Empty<T>() – Returns an empty IEnumerable<T> that has the specified type argument.

Enumerable.Distinct() – Returns distinct elements from a sequence by using the default equality comparer to compare values.

Enumerable.FirstOrDefault() – Returns the first element of a sequence, or a default value if the sequence contains no elements.

Enumerable.Count() – Returns the number of elements in a sequence.

Enumerabel.LastOrDefault() – Returns the last element of a sequence, or a default value if the sequence contains no elements.

Enumerable.Max() – Returns the maximum value in a generic sequence.

Enumerable.Min() – Returns the minimum value in a generic sequence.

Enumerable.Select() – Projects each element of a sequence into a new form.

Enumerable.ToArray() – Creates an array from a IEnumerable<T>.

Enumerable.Where() – Filters a sequence of values based on a predicate.

Here’s a link to the MSDN site that lists all the available methods

Tuple

Tuple is a new class in the .Net 4.0 framework which allows you to hold up to 8 components in a single class.  The alternative is creating a specific class with properties for each component.  This makes this class ideal for the following situations:

1.  Returning multiple values from a method without the use of out parameters

2.  Pass multiple values to a method using a single class.

3.  Collections of Tuples can be used to represent database information or array data.

4.  Easy access and manipulation of a data set.

Here’s an example using Tuple<T1, T2>

class Program
    {
        static void Main(string[] args)
        {
            int dividend, divisor;
            Tuple<int, int> result;

            dividend = 136945; divisor = 178;
            result = IntegerDivide(dividend, divisor);
            if (result != null)
                Console.WriteLine(@"{0} \ {1} = {2}, remainder {3}",
                                  dividend, divisor, result.Item1, result.Item2);
            else
                Console.WriteLine(@"{0} \ {1} = <Error>", dividend, divisor);

            dividend = Int32.MaxValue; divisor = -2073;
            result = IntegerDivide(dividend, divisor);
            if (result != null)
                Console.WriteLine(@"{0} \ {1} = {2}, remainder {3}",
                                  dividend, divisor, result.Item1, result.Item2);
            else
                Console.WriteLine(@"{0} \ {1} = <Error>", dividend, divisor);

            Console.ReadLine();

        }

        private static Tuple<int, int> IntegerDivide(int dividend, int divisor)
        {
            try
            {
                int remainder;
                int quotient = Math.DivRem(dividend, divisor, out remainder);
                return new Tuple<int, int>(quotient, remainder);
            }
            catch (DivideByZeroException)
            {
                return null;
            }
        }

    }

A Few Good Resources

These are some recent books I’ve read related to software.

Clean Code:  A Handbook of Agile Software Craftsmanship

I highly recommend this book.  Go to the Amazon link above to read more about.

The Design of Design – Essays from a Computer Scientist

An interesting book that discusses the various design approaches.

The Art of Unit Testing

The definitive book on how to properly unit test.

Head First Design Patterns

A straightforward reference to many design patterns with easy to understand examples and excellent descriptions.

Design Patterns:  Elements of Reusable Object-Oriented Software

Another excellent reference for many design patterns used in software today.

ThreadPool

I discovered this class the other day.  It’s actually been around for a while as part of the .NET 2.0 framework.  You can use it to run a method in a different thread.  Here’s a description from the MSDN site.

A thread pool is a collection of threads that can be used to perform a number of tasks in the background. (See Using Threading for background information.) This leaves the primary thread free to perform other tasks asynchronously.

Thread pools are often employed in server applications. Each incoming request is assigned to a thread from the thread pool, so the request can be processed asynchronously, without tying up the primary thread or delaying the processing of subsequent requests.

Once a thread in the pool completes its task, it is returned to a queue of waiting threads, where it can be reused. This reuse enables applications to avoid the cost of creating a new thread for each task.

Thread pools typically have a maximum number of threads. If all the threads are busy, additional tasks are placed in queue until they can be serviced as threads become available.

Here’s a very simple example that illustrates how the main execution thread continues without waiting for the “DoSomething” thread to complete.  ≈

    class ThreadPoolExample
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Start");
            ThreadPool.QueueUserWorkItem(new WaitCallback(DoSomething), args);

            Console.WriteLine("Finish");

            Console.ReadLine();
        }

        private static void DoSomething(object args)
        {
            for (int i = 0; i < 10; i++)
            {
                Thread.Sleep(100);
                Console.WriteLine(i);
            }
        }
    }

Here’s the output:

 

 

 

 

 

 

If we needed to know when the work was finished from Threadpool, then a ManualResetEvent could be passed into a WaitHandle like the example described here.

A Few .NET String Functions (Split, Join, IsNullOrEmpty, IsNullOrWhiteSpace)

Here’s some of my favorite String functions in .NET.

    class StringFunctions
    {
        static void Main(string[] args)
        {
            // Check for Null or Empty
            const string emptyString = "";
            if (String.IsNullOrEmpty(emptyString))
                Console.WriteLine("String is Empty or Null");

            // Join an array of integers together
            Collection array = new Collection() { 1, 2, 3 };
            Console.WriteLine(String.Join(",", array));

            // Split a string into an array
            ICollection fullStringArray = "The cat in the hat".Split(' ');
            foreach (var element in fullStringArray)
                Console.WriteLine(element);

            // Split ignoring emtpy spaces
            const string numberList = "1,2,3,4,,6";
            ICollection trimmedStringArray = numberList.Split(new[] { ',' }, numberList.Length, StringSplitOptions.RemoveEmptyEntries);
            foreach (var element in trimmedStringArray)
                Console.WriteLine(element);

            Console.ReadLine();
        }
    }

Output:

 

 

 

 

 

 

Here’s a link to an article with more examples for Split.

IsNullOrWhiteSpace is new in .NET 4.0. It’s similar to IsNullOrEmpty, but it also will catch strings that contain only empty spaces. In prior versions, you would have to trim the string prior to calling IsNullOrEmpty if you wanted to treat strings with only empty spaces as empty strings.