Tuesday, July 30, 2013

Interview War Stories : Thread Safety; I know everything!


Interview War Stories: Thread Safety; I know everything!



Note: I will use new names not to disclose the original name.

Interview War Stories; I'll borrow this title from (Cracking The Coding Interview - 4th edition).

Sara (the candidate) was a teaching assistant at one of top Computer Science schools at Egypt and worked for about 4 years at a famous multinational telecom and internet organization.
She applied to our company and since the position she applied for targets candidates with zero or one year experience, I decided to ask her harder questions. Someone may say this not fair! I'll reply No, it's very fair :). I decided to test her learning rate. If she stayed for 4 years in a company, She should get much experience than someone with zero or one year experience.

If I asked someone a question and he said explicitly that he didn't know or he didn't use this technique for a long time ago, I'll take it easy and proceed in asking questions or I'll try to help him in some way to answer this question.
Actually, no one knows everything or remember everything.
I'm always asking for thread safety and how to reach thread safety in different scenarios. If the candidate didn't hear about thread safety, It's Ok and I'll proceed in the questions.

I asked Sara a question: How to apply thread safety in Java?
I wanted to discuss with her the different techniques and why she used this technique not the other one and so on.
Sara said with a smile: we will use the synchronized keyword above the method with the troubles and her we got a synchronized method!
Me: good! But, What about if there is only one line inside the method that is not thread safe?
For example: this line will call a function from a library that is not thread safe (i.e. OpenNLP library).
Sara: Thinking ....... then, First solution : I'll enclose this line in a synchronized block.

<code>
void func1()
{
.
.
.
synchronized
{
          // function call to a function that is not thread safe 
}
.
.
.
}
</code>

Sara: Second Solution: I'll define a synchronized function that includes the call of the function that is not thread safe.
Me: Ok, you suggest two solutions! Do you see that the two solutions will apply the thread safety?
Sara: yes!
Me: Think again :)
Sara: yes, surely the two solutions will apply thread safety!
Me: I see that the first solution may cause some problems.
Sara: No, It will not.
Me: Are you sure?
Sara: yes, I'm very sure.
Me: but, I'm saying that it may cause some problems :). Think again!
Sara: Thinking ....... It'll not cause any problems :)
Me: Ok! Consider this case: I'll call the same function that is not a thread safe from another function func2(). How can you solve this?
Sara: Smiling ... the same solution in func1().
Me: Are you sure that this solution will not cause any problems?
Sara: yes. 
Me: but there will be a problem :)
Sara: No, It'll not be any problem! (Replied as she wanted to say "Enough is enough")
Me: Ok, here is the problem. I'll try to discuss.
synchronized keyword in func1() will block the code (or synchronize it) inside func1() and
synchronized keyword in func2() will block the code (or synchronize it) inside func2()
If in my threads I call both func1() and func2(), there will be a probability to call the function that is not thread safe in different contexts! Got it?
Sara: I still didn't see any problem!
Me: discussing more and more and more ... finally she began to relate.
Me: She didn't receive my discussion in a good manner. Actually, she was annoyed because I have the right solution!


Here is the problem with here in the interview:

I see this like that she want to say "I know everything", which is not true for anyone :)

My advice:

Don't be like Sara. I'll not work with someone who sees that his solution is always the right solution and take a long time in arguing about the solution and refuses to be wrong!
Be open for the solutions from your interviewer. Try to get a good ideas and knowledge from any interview. You are not always right.


The solution:

1 - The second solution is the best from my point of view. Always make a wrapper to the library you will use and include a thread safe functions that you will use in your application.
OR
2 - The first solution wants a small edit to work well.
define a static final object in the class that will serve as a locking object only.
if this object is not a static, it will cause problems ( You can think of this alone :) ).
<code>
class cls
{
static final Object syncObj = new Object();
void func1()
{
.
.
.
synchronized(syncObj)
{
          // function call to a function that is not thread safe 
}
.
.
.
}

void func2()
{
.
.
.
synchronized(syncObj)
{
          // function call to a function that is not thread safe 
}
.
.
.
}
}
</code>

I still prefer the second solution and using a wrapper class because It's a well designed solution and much easier.
You still must use first solution or a mix of the two solutions in some scenarios. Consider a library that have a lot of functions that use a shared resource between these function.