Google Interview Question for SDE1s


Interview Type: In-Person




Comment hidden because of low score. Click to expand.
2
of 2 vote

A Re-EntrantLock is owned by the thread last successfully locking, but not yet unlocking it. A thread invoking lock will return, successfully acquiring the lock, when the lock is not owned by another thread. The method will return immediately if the current thread already owns the lock.

public class ReEntrantLock {
    private int count = 0;
    private boolean isLocked = false;
    private Thread lockedByThread = null;
    

    public synchronized void lock() throws InterruptedException{
        while(isLocked && Thread.currentThread() != lockedBy){
            this.wait();
        }
        isLocked = true;
        lockedByThread = Thread.currentThread();
        count++;
    }

   public synchronized void unlock(){
        if (!isLocked || lockedByThread != Thread.currentThread()) {
            return;
        }
        count--;
        if(count == 0){
            isLocked = false;
            this.notify();
        }
    }
}

- R@M3$H.N November 09, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Good solution. However, I think, it's supposed to be implemented using lock.acquire() and lock.release() methods.

- Alex M. April 23, 2016 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

In Java/C++ we would declare owner variable volatile, I suppose.

from threading import Lock, current_thread, Thread

def get_thread_id():
    return id(current_thread())

class RLock(object):
    def __init__(self):
        self.lock = Lock()
        self.owner = None
        self.count = 0

    def acquire(self):
        current = get_thread_id()
        if self.owner == current:
            self.count += 1
        else:
            self.lock.acquire()
            assert self.owner is None
            self.owner = current
            self.count = 1

    def release(self):
        current = get_thread_id()
        assert self.owner == current
        assert self.count > 0
        self.count -= 1
        if not self.count:
            self.owner = None
            self.lock.release()

    def __enter__(self):
        self.acquire()

    def __exit__(self, tp, val, tb):
        self.release()

rlock = RLock()
def factorial(n):
    with rlock:
        if n <= 0:
            return 1
        else:
            return n * factorial(n - 1)

rlock = RLock()
shared = 0
def repeat(times, n):
    for i in xrange(times):
        add_numbers(n)
def add_numbers(n):
    global shared
    with rlock:
        result = 0
        if n <= 1:
            result = 1
        else:
            result = n
            add_numbers(n - 1)
        shared += result
num_threads = 5
iterations = 100000
depth = 10
threads = [Thread(target=repeat, args=(iterations, depth))
           for _ in xrange(num_threads)]
[t.start() for t in threads]
[t.join() for t in threads]
assert shared == num_threads * iterations * depth * (depth + 1) / 2

- emb November 09, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

package com.devinline.locking;

/*
* For sake of simplicity - assume custom lock interface having only three
* methods.
*/
interface CustomLock {
public void lock();

public boolean tryLock();

public void unlock();
}

public class CustomReentrantLock implements CustomLock {
/* Maintain number of locks acquired by a thread */
int lockHoldCount;

/* Id of thread which is currently holding the lock. */
long threadId;

/**
* Creates an instance of CustomReentrantLock and Initial lock hold count is
* 0.
*/
CustomReentrantLock() {
lockHoldCount = 0;
}

@Override
public synchronized void lock() {
/*
* Acquires the lock if it is not held by another thread and set lock
* hold count to 1.
*/
if (lockHoldCount == 0) {
lockHoldCount++;
threadId = Thread.currentThread().getId();
}
/*
* If current thread already holds lock then hold count is increased by
* 1 - Chain locking.
*/
else if (lockHoldCount > 0
&& threadId == Thread.currentThread().getId()) {
lockHoldCount++;
}
// If the lock is held by another thread then the current
// thread waits for another thread to release lock.
else {
try {
wait();
lockHoldCount++;
threadId = Thread.currentThread().getId();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

@Override
public synchronized void unlock() {
/*
* If current thread is not holding the lock, if unlock is called it
* throws IllegalMonitorStateException.
*/
if (lockHoldCount == 0)
throw new IllegalMonitorStateException();
/* If lock is held, decrement lock hold count by 1 */
lockHoldCount--;

/*
* If lockHoldCount is 0, lock is released and waiting thread is
* notified.
*/
if (lockHoldCount == 0)
notify();

}

@Override
public synchronized boolean tryLock() {
/*
* Acquires the lock if it is not held by another thread and // returns
* true
*/
if (lockHoldCount == 0) {
lock();
return true;
}
// If lock is held by another thread then method return false.
else
return false;
}
}

- nikhilranjan234 June 04, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

package com.devinline.locking;

/*
 * For sake of simplicity - assume custom lock interface having only three
 * methods.
 */
interface CustomLock {
 public void lock();

 public boolean tryLock();

 public void unlock();
}

public class CustomReentrantLock implements CustomLock {
 /* Maintain number of locks acquired by a thread */
 int lockHoldCount;

 /* Id of thread which is currently holding the lock. */
 long threadId;

 /**
  * Creates an instance of CustomReentrantLock and Initial lock hold count is
  * 0.
  */
 CustomReentrantLock() {
  lockHoldCount = 0;
 }

 @Override
 public synchronized void lock() {
  /*
   * Acquires the lock if it is not held by another thread and set lock
   * hold count to 1.
   */
  if (lockHoldCount == 0) {
   lockHoldCount++;
   threadId = Thread.currentThread().getId();
  }
  /*
   * If current thread already holds lock then hold count is increased by
   * 1 - Chain locking.
   */
  else if (lockHoldCount > 0
    && threadId == Thread.currentThread().getId()) {
   lockHoldCount++;
  }
  // If the lock is held by another thread then the current
  // thread waits for another thread to release lock.
  else {
   try {
    wait();
    lockHoldCount++;
    threadId = Thread.currentThread().getId();
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }

 @Override
 public synchronized void unlock() {
  /*
   * If current thread is not holding the lock, if unlock is called it
   * throws IllegalMonitorStateException.
   */
  if (lockHoldCount == 0)
   throw new IllegalMonitorStateException();
  /* If lock is held, decrement lock hold count by 1 */
  lockHoldCount--;

  /*
   * If lockHoldCount is 0, lock is released and waiting thread is
   * notified.
   */
  if (lockHoldCount == 0)
   notify();

 }

 @Override
 public synchronized boolean tryLock() {
  /*
   * Acquires the lock if it is not held by another thread and // returns
   * true
   */
  if (lockHoldCount == 0) {
   lock();
   return true;
  }
  // If lock is held by another thread then method return false.
  else
   return false;
 }

}

- nikhilranjan234 June 04, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Lock lock = new Lock();
Condition condition = lock.newCondition();
boolean isLockHeld=false;
int threadId=-1;
int lockCount;

public void lock(){
      lock.lock();
          if(isLockHeld){
             if(threadId==Thread.currentThread.getId()){
                   lockCount++;
             }else{
                 while(isLockHeld){
                      condition.await();
                  }
                   lockCount++;
                  threadId=Thread.currentThread().getId();
                  isLockHeld=true;
             }
          }
      lock.unlock();
   }
   
}

public void unlock(){
    lock.lock();
    if(isLockHeld &&  threadId==Thread.currentThread().getId()){
         lockCount - -;
         if(lockCount==0){
              threadId=-1;
              isLockHeld=false;
              condition.notifyAll();
         }
    }
    lock.unlock();
}

- birinder.tiwana August 21, 2016 | Flag Reply


Add a Comment
Name:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More