Sunday, July 5, 2015

Java Volatile Misc


https://wxx5433.gitbooks.io/interview-preparation/content/part_i_basics/java/java_volatile_keyword.html
“… the volatile modifier guarantees that any thread that reads a field will see the most recently written value.” - Josh Bloch
"The Java language also provides an alternative, weaker form of synchronization, volatile variables, to ensure that updates to a variable are propagated predictably to other threads.
When a field is declared volatile,the compiler and runtime are put on notice that this variable is shared and that operations on it should not be reordered with other memory operations. Volatile variables are not cached in registers or in caches where they are hidden from other processors, so a read of a volatile variable always returns the most recent write by any thread." - Java Concurrency In Practice(3.1.4 Volatile Variables)
http://www.geeksforgeeks.org/volatile-keyword-in-java/
class SharedObj
{
   // Changes made to sharedVar in one thread
   // may not immediately reflect in other thread
   static int sharedVar = 6;
}
Suppose that two threads are working on SharedObj. If two threads run on different processors each thread may have its own local copy of sharedVar. If one thread modifies its value the change might not reflect in the original one in the main memory instantly. This depends on the write policy of cache. Now the other thread is not aware of the modified value which leads to data inconsistency.
Below diagram shows that if two threads are run on different processors, then value of sharedVar may be different in different threads.
volatileJava
Note that write of normal variables without any synchronization actions, might not be visible to any reading thread (this behavior is called sequential consistency). Although most modern hardware provide good cache coherence therefore most probably the changes in one cache are reflected in other but it’s not a good practice to rely on hardware for to ‘fix’ a faulty application.
class SharedObj
{
   // volatile keyword here makes sure that
   // the changes made in one thread are 
   // immediately reflect in other thread
   static volatile int sharedVar = 6;
}
  1. Mutual Exclusion: It means that only one thread or process can execute a block of code (critical section) at a time.
  2. Visibility: It means that changes made by one thread to shared data are visible to other threads.
Java’s synchronized keyword guarantees both mutual exclusion and visibility. If we make the blocks of threads that modifies the value of shared variable synchronized only one thread can enter the block and changes made by it will be reflected in the main memory. All other thread trying to enter the block at the same time will be blocked and put to sleep.
In some cases we may only desire the visibility and not atomicity. Use of synchronized in such situation is an overkill and may cause scalability problems. Here volatile comes to the rescue. Volatile variables have the visibility features of synchronized but not the atomicity features. The values of volatile variable will never be cached and all writes and reads will be done to and from the main memory. However, use of volatile is limited to very restricted set of cases as most of the times atomicity is desired. For example a simple increment statement such as x = x + 1; or x++ seems to be a single operation but is s really a compound read-modify-write sequence of operations that must execute atomically.

For Java, “volatile” tells the compiler that the value of a variable must never be cached as its value may change outside of the scope of the program itself.
https://dzone.com/articles/java-multi-threading-volatile-variables-happens-be-1
We typically use volatile keyword when we share variables with more than one thread in a multi-threaded environment, and we want to avoid any memory inconsistency errors due to the caching of these variables in the CPU cache.
Consider the following example of producer/consumer, where we are producing/consuming items one at a time .
public class ProducerConsumer {
  private String value = "";
  private boolean hasValue = false;
  public void produce(String value) {
    while (hasValue) {
      try {
        Thread.sleep(500);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    System.out.println("Producing " + value + " as the next consumable");
    this.value = value;
    hasValue = true;
  }
  public String consume() {
    while (!hasValue) {
      try {
        Thread.sleep(500);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    String value = this.value;
    hasValue = false;
    System.out.println("Consumed " + value);
    return value;
  }
}
We know that a computer consists of CPUs and Memory Units (and many other parts). Even though the main memory is where all of our program instructions and variables/data reside, during program execution CPUs can store copies of variables in their internal memory (which is known as CPU cache) for performance gain. Since modern computers now have more than one CPUs, there are more than one CPU caches as well.
In a multi-threaded environment, it’s possible for more than one threads to execute at the same time, each one in a different CPU, (although this is totally dependent on the underlying OS), and each one of them may copy variables from main memory into their corresponding CPU cache. When a thread accesses these variables, they will then then access these cached copies, not the actual ones in the main memory.
Now let’s assume that the two threads in our test are running on two different CPUs, and the hasValue flag has been cached on either one of them (or both). Now consider the following execution sequence –
  1. writerThread produces a value, and changes the hasValue to true. However, this update is only reflected in the cache, not in the main memory.
  2. readerThread is trying to consume a value, but it’s cached copy of the hasValue flag is set to false. So even though a value has been produced by the writerThread, it cannot consume it as the thread cannot break out of the sleeping loop (hasValue is false).
  3. Since the readerThread is not consuming the newly generated value, writerThread cannot proceed either as the flag is not being cleared, and hence it will be stuck in its sleeping loop.
  4. And we have a deadlock in our hands!
This situation will only change if the hasValue flag is synchronized across all caches, which totally depends on the underlying OS.
What’s the solution then? And how does volatile fit into this example?
If we just mark the hasValue flag as volatile, we can be sure that this type of deadlock will not occur –
private volatile boolean hasValue = false;
Marking a variable as volatile will force each thread to read the value of that variable directly from the main memory. Also each write to a volatile variable will be flushed into the main memory immediately. If the threads decide to cache the variable, it will be synced with the main memory on each read/write.

I See. Is This All Volatile Does, Forcing Threads to Read/Write Variables Directly From Memory?

Actually it has some further implications. Accessing a volatile variable establishes a happens-before relationship between program statements.

What is a Happens-before Relationship?

happens-before relationship between two program statements is sort a guarantee which ensures that any memory writes by one statement are visible to another statement.

How Does It Relate With Volatile?

When we write to a volatile variable, it creates a happens-before relationship with each subsequent read of that same variable. So any memory writes that have been done until that volatile variable write, will subsequently be visible to any statements that follow the read of that volatile variable.
// Definition: Some variables
private int first = 1;
private int second = 2;
private int third = 3;
private volatile boolean hasValue = false;
// First Snippet: A sequence of write operations being executed by Thread 1
first = 5;
second = 6;
third = 7;
hasValue = true;
// Second Snippet: A sequence of read operations being executed by Thread 2
System.out.println("Flag is set to : " + hasValue);
System.out.println("First: " + first);  // will print 5
System.out.println("Second: " + second); // will print 6
System.out.println("Third: " + third);  // will print 7

Let’s assume that the above two snippets being executed by two different threads – thread 1 and 2. When the first thread changes hasValue, it will not only flush this change to main memory, but it will also cause the previous three writes (and any other previous writes) to be flushed into the main memory as well! As a result, when the second thread accesses these three variables it will see all the writes made by thread 1, even if they were all cached before (and these cached copies will be updated as well)!
This is the exactly why we did not have to mark the value variable in our first example with volatile as well. Since we wrote to that variable before accessing hasValue, and read from it after reading hasValue, it was automatically synced with the main memory.
This has another interesting consequence. JVM is famous for its program optimization. Sometimes it reorders the program statements to boost performance without changing the output of the program. As an example, it can change the following sequence of statements –
first = 5;
second = 6;
third = 7;
Into this –
second = 6;
third = 7;
first = 5;
However, when the statements involve accessing a volatile variable, then it will never move a statement occurring before a volatile write after it. Which means, it will never transform this –

first = 5;  // write before volatile write
second = 6;  // write before volatile write
third = 7;   // write before volatile write
hasValue = true;
into this –

first = 5;
second = 6;
hasValue = true;
third = 7;  // Order changed to appear after volatile write! This will never happen!
Even though from the perspective of program correctness both of them seem to be equivalent. Note that the JVM is still allowed to reorder the first three writes among them as long as they all appear before the volatile write.
Similarly, the JVM will also not change the order of a statement which appears after a volatile variable read to appear before the access. Which means the following –

System.out.println("Flag is set to : " + hasValue);  // volatile read
System.out.println("First: " + first);  // Read after volatile read
System.out.println("Second: " + second); // Read after volatile read
System.out.println("Third: " + third);  // Read after volatile read
Will never be transformed by the JVM into this –

System.out.println("First: " + first);  // Read before volatile read! Will never happen!
System.out.println("Fiag is set to : " + hasValue); // volatile read
System.out.println("Second: " + second); 
System.out.println("Third: " + third);
However, the JVM can certainly reorder the last three reads among them, as long as they keep appearing after the volatile read.

I Sense a Performance Penalty Has to Be Paid For Volatile Variables.

You got that right, since volatile variables force main memory access, and accessing main memory is always way slower than accessing CPU caches. It also prevents certain program optimizations by JVM as well, further reducing the performance.

Can We Always Use Volatile Variables to Maintain Data Consistency Across Threads?

Unfortunately not. When more than one threads read and write to the same variable, then marking it as volatile is not enough to maintain consistency. Consider the following UnsafeCounter class –
public class UnsafeCounter {
  private volatile int counter;
  public void inc() {
    counter++;
  }
  public void dec() {
    counter--;
  }
  public int get() {
    return counter;
  }
}
The code is pretty self-explanatory. We are incrementing the counter in one thread, and decrementing it in another by same number of times. After running this test we expect the counter to hold 0, but this is not guaranteed. Most of the times it will be 0, and some of the times it will be -1, -2, 1, 2 i.e., any integer value between the range [-5, 5].
Why does this happen? It happens because both the increment and the decrement operation of the counter are not atomic – they do not happen all at once. Both of them consists of multiple steps, and the sequence of steps overlap with each other. 
Yup. Using the synchronized keyword also establishes a happens-before relationship between statements. Entering a synchronized method/block establishes a happens-before relationship between the statements that appear before it and the ones inside the method/block. For a full list of what establishes a happens-before relationship, please go here.
What is volatile variable in Java - When to use | Java67
volatile variable in Java is a special variable which is used to signal threads, compiler that this particular variables values is going to be updated by multiple thread inside Java application. By making a variable volatile using volatile keyword in Java, application programmer ensures that its value should always been read from main memory and thread should not used cached value of that variable from there own stack.

From JDK5 on, volatile variable also guarantees "happens-before" relationship, which means not only other thread has visibility of latest value of volatile variable but also all the variable seen by the thread which has updated value of volatile variable before this threads sees it.

When to use Volatile variable in Java
1) Any variable which is shared between multiple threads should be made variable, in order to ensure that all thread must see latest value of volatile variable.

2) A signal to compiler and JIT to ensure that compiler does not change ordering or volatile variable and moves them out of synchronized context.

3) You want to save cost of synchronization as volatile variables are less expensive than synchronization.

http://www.javacodegeeks.com/2014/07/making-operations-on-volatile-fields-atomic.html

Why not use volatile all the time?

Volatile read and write access is substantially slower.  When you write to a volatile field it stalls the entire CPU pipeline to ensure the data has been written to cache.  Without this, there is a risk the next read of the value sees an old value, even in the same thread (See AtomicLong.lazySet() which avoids stalling the pipeline)
The penalty can be in the order of 10x slower which you don’t want to be doing on every access.

What are the limitations of volatile?

A significant limitation is that operations on the field is not atomic, even when you might think it is.
http://codepub.cn/2015/04/10/Java's-volatile-boolean-AutomaticBoolean-analysis/
volatile关键字是一个类型修饰符,被设计用来修饰被不同线程访问和修改的变量,在JVM1.2之前,Java的内存模型实现总是从主存读取变量,是不需要进行特别的注意的。而随着JVM的成熟和优化,现在在多线程环境下volatile关键字的使用变得非常重要。
在当前的Java内存模型下,线程可以把变量保存在本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,造成数据的不一致。
要解决这个问题,需要把变量声明为volatile(不稳定的),以后用到该变量都会到主存中进行存取,一般多任务环境下各任务间共享的标志都应该加volatile修饰。volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值,而且当成员变量发生变化时,强迫线程将变化值回写到共享内存。
Java语言中的volatile变量可以被看作是一种“程度较轻的synchronized”;与synchronized块相比,volatile变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是synchronized的一部分。Volatile变量具有synchronized的可见性特性,但是不具备原子特性。volatile仅仅用来保证该变量对所有线程的可见性,但不保证原子性。
注意:不要将volatile用在getAndOperate场合,仅仅set或者get的场景是适合volatile的。
由以上测试用例可以看出,volatile boolean是无法保证线程安全的,在一个线程占用flag变量的时候,
其他线程也可以占用flag变量,所以多个线程均可以打印出消息。
java.util.concurrent.atomic是在JDK1.5之后引入的包,在JDK中的说明如下
A small toolkit of classes that support lock-free thread-safe programming on single variables. In essence, the classes in this package extend the notion of volatile values, fields, and array elements to those that also provide an atomic conditional update operation of the form:


1
boolean compareAndSet(expectedValue, updateValue);

This method (which varies in argument types across different classes) atomically sets a variable to the updateValue if it currently holds the expectedValue, reporting true on success. The classes in this package also contain methods to get and unconditionally set values, as well as a weaker conditional atomic update operation weakCompareAndSet described below.
该包提供了一组原子类,在多线程环境下,当有多个线程同时执行这些类的实例包含的方法时,具有排他性,即当某个线程进入方法,执行其中的指令时,不会被其他线程打断,而别的线程就像自旋锁一样,一直等到该方法执行完成,才由JVM从等待队列中选择另一个线程进入。
 public static volatile AtomicBoolean flag = new AtomicBoolean(true);
 public static void main(String[] args) {
  for (int j = 0; j < 20; j++) {
   Thread t = new Thread(new Test());
   t.start();
  }
 }
 public void run() {
  if (flag.compareAndSet(true, false)) {
   System.out.println("我成功了!");
  }
 }

Atomic类不仅仅提供了对数据操作的线程安全保证,而且提供了一系列的语义清晰的方法,如incrementAndGet() 、getAndIncrement() 等,使用方便,Atomic的内部实现使用的是更加高效的CAS(compareand swap)+volatile,从而避免了synchronized的高开销,执行效率大幅提升,出于性能考虑强烈建议使用Atomic,而不是synchronized关键字。
http://www.importnew.com/11157.html
重排序通常是编译器或运行时环境为了优化程序性能而采取的对指令进行重新排序执行的一种手段。重排序分为两类:编译期重排序和运行期重排序,分别对应编译时和运行时环境。

编译期重排序

编译期重排序的典型就是通过调整指令顺序,在不改变程序语义的前提下,尽可能减少寄存器的读取、存储次数,充分复用寄存器的存储值。

假设第一条指令计算一个值赋给变量A并存放在寄存器中,第二条指令与A无关但需要占用寄存器(假设它将占用A所在的那个寄存器),第三条指令使用A的值且与第二条指令无关。那么如果按照顺序一致性模型,A在第一条指令执行过后被放入寄存器,在第二条指令执行时A不再存在,第三条指令执行时A重新被读入寄存器,而这个过程中,A的值没有发生变化。通常编译器都会交换第二和第三条指令的位置,这样第一条指令结束时A存在于寄存器中,接下来可以直接从寄存器中读取A的值,降低了重复读取的开销。

Java存储模型中的重排序

在Java存储模型(Java Memory Model, JMM)中,重排序是十分重要的一节,特别是在并发编程中。JMM通过happens-before法则保证顺序执行语义,如果想要让执行操作B的线程观察到执行操作A的线程的结果,那么A和B就必须满足happens-before原则,否则,JVM可以对它们进行任意排序以提高程序性能。

volatile关键字可以保证变量的可见性,因为对volatile的操作都在Main Memory中,而Main Memory是被所有线程所共享的,这里的代价就是牺牲了性能,无法利用寄存器或Cache,因为它们都不是全局的,无法保证可见性,可能产生脏读。

volatile还有一个作用就是局部阻止重排序的发生,对volatile变量的操作指令都不会被重排序,因为如果重排序,又可能产生可见性问题。

在保证可见性方面,锁(包括显式锁、对象锁)以及对原子变量的读写都可以确保变量的可见性。但是实现方式略有不同,例如同步锁保证得到锁时从内存里重新读入数据刷新缓存,释放锁时将数据写回内存以保数据可见,而volatile变量干脆都是读写内存。

http://www.blogjava.net/aoxj/archive/2012/06/16/380926.html
    ++操作,无论是i++还是++i,都不是原子操作!  
    而一个非原子操作,在多线程并发下会有线程安全的问题:这里稍微解释一下,上面的"++"操作符,从原理上讲它其实包含以下:计算加1之后的新值,然后将这个新值赋值给原变量,返回原值。类似于下面的代码
          private int counter = 0;
          public int getCount ( ) {
                   int result = counter;
                   int newValue = counter + 1; // 1. 计算新值
                   counter = newValue;         // 2. 将新值赋值给原变量
                   return result;
          }
    多线程并发时,如果两个线程同时调用getCount()方法,则他们可能得到相同的counter值。为了保证安全,一个最简单的方法就是在getCount()方法上做同步:
          private int counter = 0;
          public synchronized int getCount ( ) {
                   return counter++;
          }
    这样就可以避免因++操作符的非原子性而造成的并发危险。
    我们在这个案例基础上稍微再扩展一下,如果这里的操作是原子操作,就可以不用同步而安全的并发访问吗?我们将这个代码稍作修改:
          private int something = 0;
          public int getSomething ( ) {
                   return something;
          }
          public void setSomething (int something) {
                   this.something = something;
          }
    假设有多线程同时并发访问getSomething()和setSomething()方法,那么当一个线程通过调用setSomething()方法设置一个新的值时,其他调用getSomething()的方法是不是立即可以读到这个新值呢?这里的"this.something = something;" 是一个对int 类型的赋值,按照java 语言规范,对int的赋值是原子操作,这里不存在上面案例中的非原子操作的隐患。
    但是这里还是有一个重要问题,称为"内存可见性"。这里涉及到java内存模型的一系列知识,限于篇幅,不详尽讲述,不清楚这些知识点的可以自己翻翻资料,最简单的办法就是google一下这两个关键词"java 内存模型", "java 内存可见性"。或者,可以参考这个帖子"java线程安全总结", http://www.iteye.com/topic/806990。
    解决这里的"内存可见性"问题的方式有两个,一个是继续使用 synchronized 关键字,代码如下
          private int something = 0;
          public synchronized  int getSomething ( ) {
                   return something;
          }
          public synchronized  void setSomething (int something) {
                   this.something = something;
          }
     另一个是使用volatile 关键字,
          private volatile int something = 0;
          public int getSomething ( ) {
                   return something;
          }
          public void setSomething (int something) {
                   this.something = something;
          }
    使用volatile 关键字的方案,在性能上要好很多,因为volatile是一个轻量级的同步,只能保证多线程的内存可见性,不能保证多线程的执行有序性。因此开销远比synchronized要小。
    让我们再回到开始的案例,因为我们采用直接在 getCount() 方法前加synchronized 的修改方式,因此不仅仅避免了非原子性操作带来的多线程的执行有序性问题,也"顺带"解决了内存可见性问题。
    OK,现在可以继续了,前面讲到可以通过在 getCount() 方法前加synchronized 的方式来解决问题,但是其实还有更方便的方式,可以使用jdk 5.0之后引入的concurrent包中提供的原子类,java.util.concurrent.atomic.Atomic***,如AtomicInteger,AtomicLong等。
        private AtomicInteger  counter = new AtomicInteger(0);
        public int getCount ( ) {
             return counter.incrementAndGet();
        }
    Atomic类不仅仅提供了对数据操作的线程安全保证,而且提供了一系列的语义清晰的方法如incrementAndGet(),getAndIncrement,addAndGet(),getAndAdd(),使用方便。更重要的是,Atomic类不是一个简单的同步封装,其内部实现不是简单的使用synchronized,而是一个更为高效的方式CAS (compare and swap) + volatile,从而避免了synchronized的高开销,执行效率大为提升。限于篇幅,关于“CAS”原理就不在这里讲诉。
    因此,出于性能考虑,强烈建议尽量使用Atomic类,而不要去写基于synchronized关键字的代码实现。
    最后总结一下,在这个帖子中我们讲诉了一下几个问题:
    1. ++操作不是原子操作
    2. 非原子操作有线程安全问题
    3. 并发下的内存可见性


    4. Atomic类通过CAS + volatile可以比synchronized做的更高效,推荐使用

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/package-summary.html#MemoryVisibility
http://javarevisited.blogspot.kr/2015/10/133-java-interview-questions-answers-from-last-5-years.html
Multithreading, Concurrency and Thread basics Questions
1) Can we make array volatile in Java?
Yes, you can make an array volatile in Java but only the reference which is pointing to an array, not the whole array. What I mean, if one thread changes the reference variable to points to another array, that will provide volatile guarantee, but if multiple threads are changing individual array elements they won't be having happens before guarantee provided by volatile modifier.

2) Can volatile make a non-atomic operation to atomic?
One example I have seen is having a long field in your class. If you know that a long field is accessed by more than one thread e.g. a counter, a price filed or anything, you better make it volatile. Why? because reading to a long variable is not atomic in Java and done in two steps, If one thread is writing or updating long value, it's possible for another thread to see half value (fist 32-bit). While reading/writing a volatile long or double (64 bit) is atomic.
3) What are practical uses of volatile modifier? 
One of the practical use of volatile variable is to make reading double and long atomic. Both double and long are 64-bit wide and they are read in two parts, first 32-bit first time and next 32-bit second time, which is non-atomic but volatile double and long read is atomic in Java. Another use of volatile variable is to provide a memory barrier, just like it is used inDisrupter framework. Basically, Java Memory model inserts a write barrier after you write to volatile variable and a read barrier before you read it. Which means, if you write to volatile field then its guaranteed that any thread accessing that variable will see the value you wrote and anything you did before doing that write into the thread is guaranteed to have happened and any updated data values will also be visible to all threads, because the memory barrier flushed all other writes to the cache.


4) What guarantee volatile variable provides? (answer)
volatile variables provide the guarantee about ordering and visibility e.g. volatile assignment cannot be re-ordered with other statements but in the absence of any synchronization instruction compiler, JVM or JIT are free to reorder statements for better performance. volatile also provides the happens-before guarantee which ensure changes made in one thread is visible to others. In some cases volatile also provide atomicity e.g. reading 64-bit data types like long and double are not atomic but read of volatile double or long is atomic.

Read full article from What is volatile variable in Java - When to use | Java67

No comments:

Post a Comment

Labels

Review (554) System Design (293) System Design - Review (189) Java (178) Coding (75) Interview-System Design (65) Interview (60) Book Notes (59) Coding - Review (59) to-do (45) Knowledge (39) Linux (39) Interview-Java (35) Knowledge - Review (32) Database (30) Design Patterns (29) Product Architecture (28) Big Data (27) Soft Skills (27) Miscs (25) MultiThread (25) Concurrency (24) Cracking Code Interview (24) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Distributed (20) Interview Q&A (20) OOD Design (20) System Design - Practice (19) Security (17) Algorithm (15) How to Ace Interview (15) Brain Teaser (14) Google (13) Linux - Shell (13) Spark (13) Spring (13) Code Quality (12) How to (12) Interview-Database (12) Interview-Operating System (12) Redis (12) Tools (12) Architecture Principles (11) Company - LinkedIn (11) Testing (11) Resource (10) Solr (10) Amazon (9) Cache (9) Search (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Company - Uber (8) Interview - MultiThread (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Scalability (8) Cassandra (7) Git (7) Interview Corner (7) JVM (7) Java Basics (7) Machine Learning (7) NoSQL (7) C++ (6) Design (6) File System (6) Highscalability (6) How to Better (6) Kafka (6) Network (6) Restful (6) Trouble Shooting (6) CareerCup (5) Code Review (5) Company - Facebook (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Be Architect (4) Big Fata (4) C (4) Company Product Architecture (4) Data structures (4) Design Principles (4) Facebook (4) GeeksforGeeks (4) Generics (4) Google Interview (4) Hardware (4) JDK8 (4) Optimization (4) Product + Framework (4) Shopping System (4) Source Code (4) Web Service (4) node.js (4) Back-of-Envelope (3) Company - Pinterest (3) Company - Twiiter (3) Company - Twitter (3) Consistent Hash (3) GOF (3) Game Design (3) GeoHash (3) Growth (3) Guava (3) Interview-Big Data (3) Interview-Linux (3) Interview-Network (3) Java EE Patterns (3) Javarevisited (3) Map Reduce (3) Math - Probabilities (3) Performance (3) Puzzles (3) Python (3) Resource-System Desgin (3) Scala (3) UML (3) geeksquiz (3) AI (2) API Design (2) AngularJS (2) Behavior Question (2) Bugs (2) Coding Interview (2) Company - Netflix (2) Crawler (2) Cross Data Center (2) Data Structure Design (2) Database-Shard (2) Debugging (2) Docker (2) Elasticsearch (2) Garbage Collection (2) Go (2) Hadoop (2) Html (2) Interview - Soft Skills (2) Interview-Miscs (2) Interview-Web (2) JDK (2) Logging (2) POI (2) Papers (2) Programming (2) Project Practice (2) Random (2) Software Desgin (2) System Design - Feed (2) Thread Synchronization (2) Video (2) ZooKeeper (2) reddit (2) Ads (1) Advanced data structures (1) Algorithm - Review (1) Android (1) Approximate Algorithms (1) Base X (1) Bash (1) Books (1) C# (1) CSS (1) Chrome (1) Client-Side (1) Cloud (1) CodingHorror (1) Company - Yelp (1) Counter (1) DSL (1) Dead Lock (1) Difficult Puzzles (1) Distributed ALgorithm (1) Eclipse (1) Facebook Interview (1) Function Design (1) Functional (1) GoLang (1) How to Solve Problems (1) ID Generation (1) IO (1) Important (1) Internals (1) Interview - Dropbox (1) Interview - Project Experience (1) Interview Tips (1) Interview-Brain Teaser (1) Interview-How (1) Interview-Mics (1) Interview-Process (1) Jeff Dean (1) Joda (1) LeetCode - Review (1) Library (1) LinkedIn (1) LintCode (1) Mac (1) Micro-Services (1) Mini System (1) MySQL (1) Nigix (1) NonBlock (1) Process (1) Productivity (1) Program Output (1) Programcreek (1) Quora (1) RPC (1) Raft (1) RateLimiter (1) Reactive (1) Reading (1) Reading Code (1) Refactoring (1) Resource-Java (1) Resource-System Design (1) Resume (1) SQL (1) Sampling (1) Shuffle (1) Slide Window (1) Spotify (1) Stability (1) Storm (1) Summary (1) System Design - TODO (1) Tic Tac Toe (1) Time Management (1) Web Tools (1) algolist (1) corejavainterviewquestions (1) martin fowler (1) mitbbs (1)

Popular Posts