Showing posts with label Soft Skills. Show all posts
Showing posts with label Soft Skills. Show all posts

How to be More Productive


What Problems to Solve

  • is it worth?
  • to what extent?
  • Should we fix it now? or put it into backlog and solve it later?
    • Our brain will work on the problem in background, after we work on more same problem/domain, it may be much easier to solve it.
  • what you try to achieve or learn

Priority

  • work on the most important thing
    • put trivial things into backlog

Proactive

Track + Notification

  • Use Timer for wakeup
  • Use Calendar to track event, deadline
  • Use Keep to track ideas/todo

Less Distraction

Turn off unnecessary notification

  • Gmail
    • Gmail App only notifies email from primary category
    • Figure our why it’s marked as important and remove its filter or move it out from Primary category

Schedule

Health

  • sleep and wake up at the same time

Sleep & Rest

Music

  • to wake up
  • get excited

Wake up

  • My wife is a teacher, so she wakes up very early at 6:00 am
  • It’s best for me to adjust accordingly: wake up early.

Track TODO

Developer TODO

  • TODO
  • leave a compile error

Motivation

  • Have a thing to do/wake up tomorrow

Get Things Done

  • the problem/pain-point, find a way to fix it
  • Write things down

How to Read Internal docs to Solve Problems


Often, we need find some docs in internal website and read them to figure out how to do some task.

Internal vs Internet
This is different from searching internet, which usually we can find plenty of resources, after read multiple articles, we can usually have a sense how to do it. It's fine if we don't read some articles carefully, - not ideal, but usually we can find related/similar articles and can understand or get it at that time.

Usually there would be only a few docs/pages for internal docs: they are well documented, and give all information we need.

But if you don't read them carefully or miss some key information, you would be mot able to solve the problem by just reading the docs. - you can still ask help from others. 

Be organized when read the docs
- Maybe open all related docs in a different browser, in one window
- Maybe start with the entrance page (maybe given by someone) , and follow the links while read it

Notice/Write down what you don't understand or is strange to you
-- Usually they are the keys to solve the problem

Use tools like evernote to help read the docs
- add note, highlight content etc

First find/know all internal websites that are useful
Search them, read them carefully
Examples: docker sidecar, yubikey-ssh

Lessons Learned about Programming and Soft Skills - 2017


How to compare different approaches
- Always think about different approaches (even if you already finished/committed code)

- Don't just choose one that looks good
- List them and compare them
- Always ask you why choose this approache
- Try hard to find problems in your current approach, and how to fix them
For small coding
- Implement them if possible
- Then compare which makes code cleaner, less change etc
Example: Exclude source and javadoc from -jar
APP_BIN=$APP_BIN_DIR/$(ls $APP_BIN_DIR | grep -E 'jarName-version.*jar' | grep -v sources | grep -v javadoc | grep -v pom)

How to quickly scan/learn new classes
Sometimes we need quickly scan/check a bunch of related classes to check how to implement a function, use a method etc
- Check the class's Javadoc
- Check the class signature
- Check main methods:
  - static methods
  - using ctrol+o or outline view
- Check call hierarchy in source code
- Check test code/examples
- Google search code example


When refactor/change the code, also check/change/improve its related code.

Find related doc, check/read the doc carefully.
- Mark/Note the important part of the doc.

For some task, we can use the trial and error approach, just do it, then fix it.
But for some task(production or physical hardware related), it's better to figure out the right way to do it first.

Evaluate the outcome of the action. 
- best/worst outcome

How to implement/work on a feature
- what's goal, what to achieve
- how to test/verify/deploy/enable it in test or production environment easily 
  - useful tricks: dry-run, 
  - able to enable/disable default configuration automatically, but override it manually
- how to measure whether the change makes improvement

Think different/3+/more approaches
Compare them
Don't stop until find a solution that looks good to you
Use tools(notebook, whiteboard)
- Usually we are not happy with the first approach that comes to our minds, and find out a different approach: maybe it's a little better or maybe just be different. In some cases, we stop there: maybe we started to talk it with others or present it (to get others' ideas)
-Example: add Explanation to transform actions

Before ask a question
- Try to Solve it by yourself
- Make sure you read all related code/doc: from top to bottom(quickly, scan but don't ignore any code that may be important)

- Example: NightlyTestRunner

Verify the assumption
- Be aware of the the assumption we or others made in the design or the code.
- Verify whether it's true or not
- Example: one line one record in csv, one-to-one between tms id and bam_id

Alternatives
- Check and realize alternatives
Sometimes, we want A, but maybe B also works and is even better.
- Example: asset letter or account statement

Use tools
Write down in whiteboard or notebook or app
Take a picture now 
- always bring the phone

Check carefully and verify your claim before blame others or think others are wrong
We incline to think others are wrong or made a mistake even if someone told you he/she did that - we made a very brief search and didn't check carefully, then started to think they are wrong.

Prefer to use code to enforce the rule than documentation
Example: all tests must extends XbaseUnitTest.

Make API/feature easier
- to use
- to test/rollback in production (feature flag)

Realize your assumption/decision and verify it first
- Otherwise you may go farther but on the wrong path
Step by step and verify each step

Identify useful info and active quickly (or you may forget about it)
Don't let your past experience affect you
- Try it, it may be different this time
Example: big item delivery

When some thing totally doesn't make sense:
- maybe they are totally different things, you are comparing Apple with Banaba
Example: 12/15, 1/15

Related
Lessons Learned about Programming and Soft Skills - 2016

How to Review and Discuss - Software Design


Talk/Think about all related
- how do we store data, 
- client api 
- ui change
- back compatibility: how to handle old data/client

But focus on most important stuff (first)

Talk/think about design principles/practices
- such as idempotent, parallelization,monitoring, etc
- Check more at System Design - Summary

What's the impact of other (internal and cross-team) components?


How others components use it?

What're the known and potential constraints/issues/flaws in current design?
Don't only talk about its advantages, 
Also talk about issues, don't hide them

What are alternatives?
Think alternative and different approaches, this can help find better solution
We can't really review and compare if there is no alternatives

Welcome different approaches
- although it doesn't mean it's better, or we will use it


Development Cost
- How difficult it takes to implement?

What may change and How to evolve

What may change in (very) near future?

Visibility/Monitoring
How do can we know when the new feature works or doesn't work
How can we know problems happen

Feature Flag
Can we enable/disable the feature at runtime

Be Prepared
Ok to have informal/impromptu discussion with one or two colleagues

But make sure everyone is prepared for the formal team design discussion
All attendees should know the topic: how they would design it

Don't make design decision immediately - for things that really matters
Take time to reflect and develop disagreement, talk it again later

Attitude
Listen first

When you don't agree with other's approaches
Don't get too defensive
Talk about ideas not people

Be prepared

Make API/Feature easier
- to use
- to test/rollback in production (feature flag)

Related
System Design - Summary

How to Be a Great Technical Lead


How to choose tech stack
- List your current/near-future features
- Consider multiple/different options and how to use them to implement features 
- Compare their pros and cons: manageability, scalability 
- What techs are used in your team and departments
    - But this doesn't mean always use same tech stacks used before 
- What tech are supported by operation team

Build reputation
- be useful and help others

Know your team members
- their strength or weakness
  - programming skills
  - design skills
  - trouble shooting skills
- what they are interested, what are not
- what they want to learn and improve
Help them to grow and improve their skills

Know yourself
Know how/what you can help the team
- your programming/design/communication skills
Know when to stand alone and when to step in
Know when to let others shine

Delegation
- don't try to do everything
- let other people do the job they are good at and observe
- let others contribute and take ownership/leadership

Journey to be A Great Engineer


Self-Awareness
- strength, weaknesses
- have a plan to overcome the weaknesses that matters
Brand yourself/build reputation
- join discussion, other projects proactively
- make presentation, give a talk
- be useful and help others grow
Be better everyday
- writer better code, design system better
- try new/different/best approach
Never give up
- exhausts All Resources to solve the problem
- ask more questions and dig deeper
Follow up
- be inquisitive
- how others eventually fix/solve the problem
- what's the real root cause

Reflection
Keep Learning everyday
- in different ways
  - learn from books/blog/video/podcast
  - learn from others: no matter whether developers are senior or junior than you
  - be open-minded
- learn related/important skills that matters
  - how to search in codebase, log, git(hub) efficiently
  - troubleshoot, IDE
  - how to review code
- learn tech stack used by other team (members)
- understand trends and new techs
  - what's the advantage, when should use it when not
  - how it works, how it's designed
Maintain your learning log 
- blog, notes, doc etc
Maintain your toolbox
- languages/frameworks/ide/bash, new features

Keep calm and be happy/excited
- when meet some difficult problems
- when hear suggestions

Preparation
- prepare for next meeting/discussion/feature/project
- learning the techs that may be used in current or next feature/project
- learn the techs that may be different(better) and can improve your current solution
- don't blindly repeat same approach/design/code

Use time efficiently
Meetings
- Know the topics, what you can get and what you can contribute
- Whether it's important to you, if not and you are not required, skip it

- Avoid fragmented time; if can't, use it efficiently(reading, podcast)
- don’t lose state when context switch
- use tools to automate

Think/Discuss/design more before take action
- full algorithm/design before coding
- don't take action blindly: make change then test it or debug it
- check and infer first
Admit what you don’t know
- don't pretend
- ask questions and learn it

Share knowledge
- share more and learn more

How to Ask questions
Ask more and deeper questions to yourself
Ask questions to others
- don't ask simple knowledgeable questions too often
  -- learn/read/google first
- But don't hesitate to ask questions to any one if needed

How to answer questions
- first understand the question and what's the real question and issue
- don't just assume others are asking simple or stupid questions
- if not 100% sure, check it before answer

Quickly vs Slowly
Know when to solve problem or do things quickly when to do things slowly
- Solve problems quickly so others can move on
- But take time to find root cause or reflect if it matters

Career Development
- be initiative
- talk with your managers
- express your interest/passion and goal
- work on interesting/challenging projects
- prefer yes over no

How to Solve Problems


Don't overcomplicate it.
In most case, the solution is actually quite easy.
Try simplest solution first.

Understand the problem/environment first
Understand the problem.
-- Look carefully at the logging, the symptom.
Think about it first before google search otherwise it may just lead you to totally wrong directions.

Make sure you understand the root cause and the final solution.

Troubleshooting problem is thinking what may go wrong
- how it's likely caused by this?
- how easy we can verify the assumption?
- if not likely and not easily to verify it, try/list other possible root cause/approaches first

Try different approaches
Try to ask different questions (probable solution) and google it.

Track what change you have made
Check when it stops working, and what change u have made.


When help others
Ask what related change they have done

Ask help from others.
But be sure to understand the problem and have tried to fix by yourself.
Provide log or any information that may help others understand the problem.

When work with others
If you are trouble shooting problems together with others, communicate with them, know each other progress, doubt, what u will try next etc. They may try different approaches that may help to get final solution.

If no progress and too late or tired, go to rest and try it later or talk with others.

Solve problem quickly and Learn from it
Solve the problem first (so the project or others can move on) then try to learn related stuff later.
Write down what to check or learn later.

Take the chance to expand your knowledge.

Think More
Think over the code/problem, try to find better solution even it's already "fixed"

Check whether the problem also happens in other places(code, different server etc), if so, fix them.

Misc
Check configuration
-- If it works in dev-line, but fails in product line.

-- Happy hacking

JBoss Tips


Commands
shutdown.sh -S
run.sh -b 0.0.0.0 -c default
run.bat –Djboss.server.log.dir=d:/log
Change ports
In jboss 5, in $JBoss\server\default\conf\bindingservice.beans\META-INF\bindings-jboss-beans.xml, change the port offset of PortsDefaultBindings.
<bean name="PortsDefaultBindings"  class="org.jboss.services.binding.impl.ServiceBindingSet">
  <constructor>
     <!-- The port offset -->
     <parameter>1000</parameter>
     <!-- Set of bindings to which the "offset by X" approach can't be applied -->
     <parameter><null/></parameter>
  </constructor>
</bean>
To use the port assignments defined by the Ports01Bindings bean, set the jboss.service.binding.set system property to ports-01 when starting the application server.
run -c myconfig2 -Djboss.service.binding.set=ports-01
Configuring logging

The log4j configuration file is located at server/xxx/conf/jboss-log4j.xml.
Defining a rolling log appender
<appender name="FILE">
    <param name="Append" value="true"/>
    <param name="MaxFileSize" value="10MB"/>
    <param name="MaxBackupIndex" value="20"/>
    <param name="Threshold" value="ERROR"/>
</appender>
Defining logging for your application
You can log your application by adding category entries to the jboss-log4j.xml file.
<appender name="JBIA" ...>
    <param name="File" value="${jboss.server.log.dir}/jbia.log"/>
</appender>
<category name="org.jbia">
    <priority value="DEBUG"/>
    <appender-ref ref="JBIA" />
</category>

Edit the server.xml file. For the default server in the default location, it is ${jboss.home}\server\default\deploy\jbossweb.sar\server.xml.
Uncomment the "Access logger" section. The log file will show up in server/default/log/localhost_access_log.{todays_date}.log

<Valve className="org.apache.catalina.valves.AccessLogValve"
                prefix="localhost_access_log." suffix=".log"
                pattern="common" directory="${jboss.server.log.dir}" 
                resolveHosts="false" />


Configuring startup parameters
Rename run.bat for example to run-old.bat.
Create another run.bat file and put this line to it:
set JAVA_OPTS=%JAVA_OPTS% -Xms512m -Xmx1024m -XX:MaxPermSize=512m
run-old.bat -b 0.0.0.0 -c default
Dump SOAP Messages
For the case that is not easy to model as a simple DFS request, it is useful to enable the SOAP dump.
For client side, set "com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true";
For server side, set "com.sun.xml.ws.transport.http.HttpAdapter.dump=true";
In Jboass, put the following line in newly created run.bat:
set JAVA_OPTS=%JAVA_OPTS% -Dcom.sun.xml.ws.transport.http.HttpAdapter.dump=true
Enable remote debug
In newly created run.bat:
rem set JAVA_OPTS=%JAVA_OPTS% -Xrunjdwp:transport=dt_socket,address=9999,server=y,suspend=n
Configure apache httpd.conf:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
<Proxy balancer://mycluster>
Order deny,allow
Allow from all
BalancerMember http://node1.mycluster.lan:8080/ route=node1 timeout=15
BalancerMember http://node2.mycluster.lan:8080/ route=node2 timeout=15
ProxySet stickysession=JSESSIONID|jsessionid
# other values: bybusyness|byrequests|bytraffic
ProxySet lbmethod=bytraffic 
</Proxy>
ProxyPass /jmx-console balancer://mycluster/jmx-console 
ProxyPassReverse /jmx-console  http://localhost:9080/jmx-console stickysession=JSESSIONID|jsessionid



Configure JBoss
In jboss, modify {jboss.home}\server\default\deploy\jbossweb.sar\server.xml to configure the jvmRoute for sticky sessions:
<Engine name="jboss.web" defaultHost="localhost" jvmRoute="node1">

Modify {jboss.home}\server\default\deployers\jbossweb.deployer\META-INF\war-deployers-jboss-beans.xml:
<bean name="WebAppClusteringDefaultsDeploye" class="org.jboss.web.tomcat.service.deployers.ClusteringDefaultsDeployer">
  <property name="useJK">true</property>
</bean>

Resources:

Notes on Annotations


Notes on Annotations

Annotations
Annotations are tags that we insert into we source code so that some tool can process them. The tools can operate on the source level, or they can process class files into which the compiler has placed annotations.
Annotations provide a formalized way to add information to the code so that we can easily use that data at some later point.
Annotations are partly motivated by a general trend toward combining metadata with source-code files, instead of keeping it in external documents.

Using annotations, we can keep this metadata in the Java source code, and have the advantage of cleaner looking code, compile-time type checking and the annotation API to help build processing tools for our annotations.
To benefit from annotations, we need to select a processing tool. We insert annotations into our code that our processing tool understands, and then apply the processing tool.

Annotations can be processed at runtime, at the source code level, or at the bytecode level.
Defining annotations
Defining annotations is very easy; Annotation type declarations are similar to normal interface declarations. An at-sign (@) precedes the interface keyword. Then we declare meta-annotations on the annotation interface such as @Target to define where we can apply this annotation (a method or a field, for example), @Retention to define whether the annotations are available in the source code (SOURCE), in the class files (CLASS), or at run time (RUNTIME).

Then we declare elements in this annotation interface, elements look like interface methods, except that we can declare default values.
Methods can have default values. Method declarations must not have any parameters or a throws clause. Return types are restricted to primitives, String, Class, enums, annotations, and arrays of the preceding types.
Annotations can be read from source files, class files, or reflectively at run time.

The annotations don't do anything by themselves, without tools to read them; annotations are hardly more useful than comments.
We need write annotation processors to read and process annotations. Java SE5 provides extensions to the reflection API to read annotations defined in java class.
Annotation Syntax

An annotation without any elements is called a marker annotation.
An annotation is defined by an annotation interface, Each element declaration has the form: type elementName() default value;
Each annotation has the format
@AnnotationName(elementName1=value1, elementName2=value2, . . .)
The order of the elements does not matter.
Two special shortcuts can simplify annotations:
If no elements are specified, then we don't need to use parentheses: @BugReport
The other shortcut is the single value annotation. If an element has the special name value, and no other element is specified, then we can omit the element name and the = symbol.
@ActionListenerFor("yellowButton") is same as @ActionListenerFor(value="yellowButton")
Limitations when implement annotations
The methods of an annotation interface can have no parameters and no throws clauses, and they cannot be generic.
The type of an annotation element is one of the following: A primitive type, String, Class (with an optional type parameter such as Class), an enum type, an annotation type, 1-dimensional arrays of the preceding types (an array of arrays is not a legal element type)
The compiler will report an error if you try to use any other types. Note that you are not allowed to use any of the wrapper classes, but because of autoboxing this isn’t really a limitation. You can also have elements that are themselves annotations.
//When a Target meta-annotation is not present on an
//annotation type declaration, the declared type may be used on any
//program element.
//If no Retention annotation is present on an annotation type declaration,
//the retention policy defaults to RetentionPolicy.CLASS.
public @interface BugReport {
    enum Status {
       UNCONFIRMED, CONFIRMED, FIXED, NOTABUG
    };
    boolean showStopper() default false;
    String assignedTo() default "[none]";
    Class testCase() default Void.class; // we can use class
    Status status() default Status.UNCONFIRMED; // we can use enum
    Reference ref() default @Reference(); // an annotation type
    String[] reportedBy();
    // Compile error: Invalid type Object for the annotation attribute
    // BugReport.object; only primitive type, String,
    // Class, annotation, enumeration are permitted or 1-dimensional arrays thereof
    Object object();
}
Annotation values must be compile-time constants, so you can't call method to set annotation values.
// Compile error: The value for annotation attribute ActionListenerFor.source must be a constant expression
@ActionListenerFor(source = "blueButton" + anyMethod())
An annotation element can never be set to null. Not even a default of null is permissible.
Annotations don’t support inheritance, you cannot use the “extends” keyword with @interfaces.
If annotations (retention class) are evaluated by the compiler, all element values must be compile-time constants.
An item can have multiple annotations, provided they belong to different types. We cannot use the same annotation type more than once when annotating a particular item.
If this is a problem, we can design an annotation that has a value of an array of simpler annotations.
Default value constraints
The compiler is quite picky about default element values. No element can have an unspecified value. This means that elements must either have default values or values provided by the class that uses the annotation.
There is another restriction, which is that none of the non-primitive type elements are allowed to take null as a value, either when declared in the source code or when defined as a default value in the annotation interface. You need define special value as default value.
It is legal to apply an annotation to itself. For example, the @Documented annotation is itself annotated as @Documented.
Annotations for local variables can only be processed at the source level. Class files do not describe local variables. Therefore, all local variable annotations are discarded when a class is compiled. Similarly, annotations for packages are not retained beyond the source level.
Implementation detail
All annotation interfaces implicitly extend the interface java.lang.annotation.Annotation. That interface is a regular interface, not an annotation interface.
Standard Annotations
Meta-Annotations
@Target
The @Target meta-annotation restricts the items to which the annotation applies.
@Target(ElementType.ANNOTATION_TYPE)
public enum ElementType
{TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE,,ANNOTATION_TYPE,PACKAGE}
An annotation without an @Target restriction can be applied to any program element. The compiler checks that we apply an annotation only to a permitted item.
@Retention
The @Retention meta-annotation specifies how long an annotation is retained. We specify at most one of the values.
@Retention(RetentionPolicy.RUNTIME)
SOURCE Annotations are not included in class files.
CLASS   Annotations are included in class files, but the virtual machine need not load them.
RUNTIME Annotations are included in class files and loaded by the virtual machine. They are available through the reflection API.
public enum RetentionPolicy {
   * Annotations are to be discarded by the compiler.
  SOURCE,
   * Annotations are to be recorded in the class file by the compiler
   * but need not be retained by the VM at run time. This is the default behavior.
  CLASS,
   * Annotations are to be recorded in the class file by the compiler and
   * retained by the VM at run time, so they may be read reflectively.
  RUNTIME
}
If no Retention annotation is present on an annotation type declaration, the retention policy defaults to RetentionPolicy.CLASS.
The @Documented meta-annotation gives a hint to documentation tools such as Javadoc.
@Inherited
The @Inherited meta-annotation applies only to annotations for classes. When a class has an inherited annotation, then all of its subclasses automatically have the same annotation.
Annotations for Compilation
@Deprecated
The @SuppressWarnings annotation tells the compiler to suppress warnings of a particular type: @SuppressWarnings("unchecked")
The @Override annotation applies only to methods. The compiler checks that a method with this annotation really overrides a method from the superclass.
The @Generated annotation is intended for use by code generator tools. Any generated source code can be annotated to differentiate it from programmer-provided code.
Annotations for Managing Resources
@PostConstruct, @PreDestroy, @Resource
Practical usage
Source-Level Annotation Processing
One use for annotation is the automatic generation of "side files" that contain additional information about programs
Bytecode Engineering
We can process class files using Bytecode Engineering Library (BCEL).
Generating external files
How Junit process annotation.

Resources:

Learning JDK Code - Collection



Learning JDK Code - Collection
HashMap vs Hashtable
The Hashtable is among the original collection classes in Java.Hashtable extends the Dictionary class, which as the Javadocs state, is obsolete and has been replaced by the Map interface. HashMap is part of the new Collections Framework, added with Java 2.

The key difference between the two is that access to the Hashtable is synchronized on the table while access to the HashMap is not synchronized.This makes HashMap better for non-threaded applications, as unsynchronized Objects typically perform better than synchronized ones

HashMap has a more complex hashing algorithm then Hashtable. It takes the hash value from the key and then hashes it again (double hashing). This can improve the distribution of the keys and hence the performance of the Map.

Another difference is that iterator in the HashMap is fail-safe while the enumerator for the Hashtable isn't. If we change the map while iterating, it will throw exception.

Third difference is that HashMap permits null values in it, while Hashtable doesn't. Also note that only one NULL value is allowed as a key in HashMap. HashMap does not allow multiple keys to be NULL. Nevertheless, it can have multiple NULL values.
1. Initial size and resize
HashMap uses power-of-two length tables, default capacity is 16.
static final int DEFAULT_INITIAL_CAPACITY = 16;
static final int MAXIMUM_CAPACITY = 1 << 30;
static final float DEFAULT_LOAD_FACTOR = 0.75f;
public HashMap(int initialCapacity, float loadFactor) {
    // Find a power of 2 >= initialCapacity
    int capacity = 1;
    while (capacity < initialCapacity)
        capacity <<= 1;
}
User can specify map size, hashmap would find a pow of 2 whose value is just larger than user specified size.
resize(2 * table.length);

Hashset would construct a new, empty hashtable with the specified initial capacity.
Default size is 11.
public Hashtable(int initialCapacity, float loadFactor) {
    if (initialCapacity==0)
        initialCapacity = 1;
this.loadFactor = loadFactor;
table = new Entry[initialCapacity];
threshold = (int)(initialCapacity * loadFactor);
}
public Hashtable() {
    this(11, 0.75f);
}
int newCapacity = oldCapacity * 2 + 1;

HashMap hash function
The way the HashMap is implemented relies on the hashCode function being sufficiently well implemented. If you have many collisions on the lower bits, the HashMap will not perform well.

Because the implementation of hashCode is outside of the control of HashMap (every object can implement their own), they supply an additional hash function that shifts the object's hashCode around a little to ensure that the lower bits are distributed more randomly.

HashMap uses power-of-two length tables, and hashes keys by masking away the higher bits and taking only the lower bits of their hash code.

So hash() attempts to bring relevancy to the higher bits, which otherwise would get masked away (indexFor basically discards the higher bits of h and takes only the lower k bits where length == (1 << k)).

int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
* Applies a supplemental hash function to a given hashCode, which
 * defends against poor quality hash functions.  This is critical
 * because HashMap uses power-of-two length hash tables, that
 * otherwise encounter collisions for hashCodes that do not differ
 * in lower bits. Note: Null keys always map to hash 0, thus index 0.
static int hash(int h) {
    // This function ensures that hashCodes that differ only by
    // constant multiples at each bit position have a bounded
    // number of collisions (approximately 8 at default load factor).
    h ^= (h >>> 20) ^ (h >>> 12);
    return h ^ (h >>> 7) ^ (h >>> 4);
}
static int indexFor(int h, int length) {
    return h & (length-1);
}          
Hashtable hash function
By doing the more expensive % operation (instead of simple bit masking), the performance of Hashtable is less sensitive to hash codes with poor distribution in the lower bits (especially if table.length is a prime number).
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
HashMap[Sun JDK]
 public class HashMap extends AbstractMap implements Map, Cloneable, Serializable  
 {  
   // The next size value at which to resize (capacity * load factor).  
   int threshold;    
   public HashMap() {  
     this.loadFactor = DEFAULT_LOAD_FACTOR;  
     threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR); //  
     table = new Entry[DEFAULT_INITIAL_CAPACITY];  
     init(); // subclass would overwite this  
   }  
   public V put(K key, V value) {  
     if (key == null)  
       return putForNullKey(value); // We can put null key and null value to HashMap.  
     int hash = hash(key.hashCode());  
     int i = indexFor(hash, table.length);  
     for (Entry e = table[i]; e != null; e = e.next) {  
       Object k;  
       if (e.hash == hash && ((k = e.key) == key || key.equals(k))) // call e.key == key  
       {  
         V oldValue = e.value;  
         e.value = value;  
         e.recordAccess(this);  
         return oldValue;  
       }  
     }  
     modCount++;  
     addEntry(hash, key, value, i);  
     return null;  
   }  
   public V get(Object key) {  
     if (key == null)  
       return getForNullKey();  
     int hash = hash(key.hashCode());  
     for (Entry e = table[indexFor(hash, table.length)];  
        e != null;  
        e = e.next) {  
       Object k;  
       if (e.hash == hash && ((k = e.key) == key || key.equals(k)))  
         return e.value;  
     }  
     return null;  
   }  
   void addEntry(int hash, K key, V value, int bucketIndex) {  
    Entry e = table[bucketIndex];  
     table[bucketIndex] = new Entry(hash, key, value, e);  
     if (size++ >= threshold)  
       resize(2 * table.length);  
 }  
   public boolean containsKey(Object key) {  
     return getEntry(key) != null;  
   }  
   final Entry<K,V> getEntry(Object key) {  
     int hash = (key == null) ? 0 : hash(key.hashCode());  
     for (Entry<K,V> e = table[indexFor(hash, table.length)];  
        e != null;  
        e = e.next) {  
       Object k;  
       if (e.hash == hash &&  
         ((k = e.key) == key || (key != null && key.equals(k))))  
         return e;  
     }  
     return null;  
 }  
    /**  
    * Applies a supplemental hash function to a given hashCode, which  
    * defends against poor quality hash functions. This is critical  
    * because HashMap uses power-of-two length hash tables, that  
    * otherwise encounter collisions for hashCodes that do not differ  
    * in lower bits. Note: Null keys always map to hash 0, thus index 0.  
    */  
   static int hash(int h) {  
     // This function ensures that hashCodes that differ only by  
     // constant multiples at each bit position have a bounded  
     // number of collisions (approximately 8 at default load factor).  
     h ^= (h >>> 20) ^ (h >>> 12);  
     return h ^ (h >>> 7) ^ (h >>> 4);  
   }  
   static int indexFor(int h, int length) {  
     return h & (length-1);  
 }  
   public boolean containsValue(Object value) {  
      if (value == null)  
       return containsNullValue();  
      Entry[] tab = table;  
     for (int i = 0; i < tab.length ; i++)  
       for (Entry e = tab[i] ; e != null ; e = e.next)  
         if (value.equals(e.value))  
           return true;  
      return false;  
 }  
   static class Entry<K,V> implements Map.Entry<K,V> {  
     final K key;  
     V value;  
     Entry<K,V> next;  
     final int hash;  
     public final boolean equals(Object o) {  
       if (!(o instanceof Map.Entry))  
         return false;  
       Map.Entry e = (Map.Entry)o;  
       Object k1 = getKey();  
       Object k2 = e.getKey();  
       if (k1 == k2 || (k1 != null && k1.equals(k2))) {  
         Object v1 = getValue();  
         Object v2 = e.getValue();  
         if (v1 == v2 || (v1 != null && v1.equals(v2)))  
           return true;  
       }  
       return false;  
     }  
     public final int hashCode() {  
       return (key==null  ? 0 : key.hashCode()) ^  
           (value==null ? 0 : value.hashCode());  
     }  
   }  
   private abstract class HashIterator<E> implements Iterator<E> {  
     Entry<K,V> next;     // next entry to return  
     int expectedModCount;     // For fast-fail  
     int index;          // current slot  
     Entry<K,V> current;     // current entry  
     HashIterator() {  
       expectedModCount = modCount;  
       if (size > 0) { // advance to first entry  
         Entry[] t = table;  
         while (index < t.length && (next = t[index++]) == null)  
           ;  
       }  
     }  
     public final boolean hasNext() {  
       return next != null;  
     }  
     final Entry<K,V> nextEntry() {  
       if (modCount != expectedModCount)  
         throw new ConcurrentModificationException();  
       Entry<K,V> e = next;  
       if (e == null)  
         throw new NoSuchElementException();  
       if ((next = e.next) == null) {  
         Entry[] t = table;  
         while (index < t.length && (next = t[index++]) == null)  
           ;  
       }  
        current = e;  
       return e;  
     }  
     public void remove() {  
       if (current == null)  
         throw new IllegalStateException();  
       if (modCount != expectedModCount)  
         throw new ConcurrentModificationException();  
       Object k = current.key;  
       current = null;  
       HashMap.this.removeEntryForKey(k);  
       expectedModCount = modCount;  
     }  
   void resize(int newCapacity) {  
     Entry[] oldTable = table;  
     int oldCapacity = oldTable.length;  
     if (oldCapacity == MAXIMUM_CAPACITY) {  
       threshold = Integer.MAX_VALUE;  
       return;  
     }  
     Entry[] newTable = new Entry[newCapacity];  
     transfer(newTable);  
     table = newTable;  
     threshold = (int)(newCapacity * loadFactor);  
   }  
   void transfer(Entry[] newTable) {  
     Entry[] src = table;  
     int newCapacity = newTable.length;  
     for (int j = 0; j < src.length; j++) {  
       Entry<K,V> e = src[j];  
       if (e != null) {  
         src[j] = null;  
         do {  
           Entry<K,V> next = e.next;  
           int i = indexFor(e.hash, newCapacity);  
           e.next = newTable[i];  
           newTable[i] = e;  
           e = next;  
         } while (e != null);  
       }  
     }  
   }  
   private final class ValueIterator extends HashIterator<V> {  
     public V next() {  
       return nextEntry().value;  
     }  
   }  
   private final class KeyIterator extends HashIterator<K> {  
     public K next() {  
       return nextEntry().getKey();  
     }  
   }  
   private final class EntryIterator extends HashIterator<Map.Entry<K,V>> {  
     public Map.Entry<K,V> next() {  
       return nextEntry();  
     }  
   }  
   // Subclass overrides these to alter behavior of views' iterator() method  
   Iterator<K> newKeyIterator()  {  
     return new KeyIterator();  
   }  
   Iterator<V> newValueIterator()  {  
     return new ValueIterator();  
   }  
   Iterator<Map.Entry<K,V>> newEntryIterator()  {  
     return new EntryIterator();  
   }  
   // Views  
   private transient Set<Map.Entry<K,V>> entrySet = null;  
 }  
   public Set<K> keySet() {  
     Set<K> ks = keySet;  
     return (ks != null ? ks : (keySet = new KeySet()));  
   }  
   private final class KeySet extends AbstractSet<K> {  
     public Iterator<K> iterator() {  
       return newKeyIterator();  
     }  
     public int size() {  
       return size;  
     }  
     public boolean contains(Object o) {  
       return containsKey(o);  
     }  
     public boolean remove(Object o) {  
       return HashMap.this.removeEntryForKey(o) != null;  
     }  
     public void clear() {  
       HashMap.this.clear();  
     }  
 }  
   public Collection<V> values() {  
     Collection<V> vs = values;  
     return (vs != null ? vs : (values = new Values()));  
   }  
   private final class Values extends AbstractCollection<V> {  
     public Iterator<V> iterator() {  
       return newValueIterator();  
     }  
     public int size() {  
       return size;  
     }  
     public boolean contains(Object o) {  
       return containsValue(o);  
     }  
     public void clear() {  
       HashMap.this.clear();  
     }  
 }  
   private void writeObject(java.io.ObjectOutputStream s)  
     throws IOException  
   {  
      Iterator<Map.Entry<K,V>> i =  
        (size > 0) ? entrySet0().iterator() : null;  
      // Write out the threshold, loadfactor, and any hidden stuff  
      s.defaultWriteObject();  
      // Write out number of buckets  
      s.writeInt(table.length);  
      // Write out size (number of Mappings)  
      s.writeInt(size);  
     // Write out keys and values (alternating)  
      if (i != null) {  
        while (i.hasNext()) {  
           Map.Entry<K,V> e = i.next();  
           s.writeObject(e.getKey());  
           s.writeObject(e.getValue());  
        }  
     }  
   }  
   private void readObject(java.io.ObjectInputStream s)  
      throws IOException, ClassNotFoundException  
   {  
      // Read in the threshold, loadfactor, and any hidden stuff  
      s.defaultReadObject();  
      // Read in number of buckets and allocate the bucket array;  
      int numBuckets = s.readInt();  
      table = new Entry[numBuckets];  
    init(); // Give subclass a chance to do its thing.  
      // Read in size (number of Mappings)  
      int size = s.readInt();  
      // Read the keys and values, and put the mappings in the HashMap  
      for (int i=0; i<size; i++) {  
        K key = (K) s.readObject();  
        V value = (V) s.readObject();  
        putForCreate(key, value);  
      }  
 }  
 }  
Hashtable
 public class Hashtable<K,V>  
   extends Dictionary<K,V>  
 implements Map<K,V>, Cloneable, java.io.Serializable {  
   private transient Entry[] table;  
   private transient int count;  
   private int threshold;  
   private float loadFactor;  
   public Hashtable(int initialCapacity, float loadFactor) {  
      this.loadFactor = loadFactor;  
      table = new Entry[initialCapacity];  
      threshold = (int)(initialCapacity * loadFactor);  
   }  
   public Hashtable(Map<? extends K, ? extends V> t) {  
      this(Math.max(2*t.size(), 11), 0.75f);  
      putAll(t);  
 }  
   public synchronized V get(Object key) {  
      Entry tab[] = table;  
      int hash = key.hashCode();  
      int index = (hash & 0x7FFFFFFF) % tab.length;  
      for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {  
        if ((e.hash == hash) && e.key.equals(key)) {  
           return e.value;  
        }  
      }  
      return null;  
   }  
   public synchronized V put(K key, V value) {  
      // Make sure the value is not null  
      if (value == null) {  
        throw new NullPointerException();  
      }  
      // Makes sure the key is not already in the hashtable.  
      Entry tab[] = table;  
      int hash = key.hashCode();  
      int index = (hash & 0x7FFFFFFF) % tab.length;  
      for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {  
        if ((e.hash == hash) && e.key.equals(key)) {  
           V old = e.value;  
           e.value = value;  
           return old;  
        }  
      }  
      modCount++;  
      if (count >= threshold) {  
        // Rehash the table if the threshold is exceeded  
        rehash();  
       tab = table;  
       index = (hash & 0x7FFFFFFF) % tab.length;  
      }  
      // Creates the new entry.  
      Entry<K,V> e = tab[index];  
      tab[index] = new Entry<K,V>(hash, key, value, e);  
      count++;  
      return null;  
 }  
   protected void rehash() {  
      int oldCapacity = table.length;  
      Entry[] oldMap = table;  
      int newCapacity = oldCapacity * 2 + 1;  
      Entry[] newMap = new Entry[newCapacity];  
      modCount++;  
      threshold = (int)(newCapacity * loadFactor);  
      table = newMap;  
      for (int i = oldCapacity ; i-- > 0 ;) {  
        for (Entry<K,V> old = oldMap[i] ; old != null ; ) {  
           Entry<K,V> e = old;  
           old = old.next;  
           int index = (e.hash & 0x7FFFFFFF) % newCapacity;  
           e.next = newMap[index];  
           newMap[index] = e;  
        }  
      }  
 }  
   public synchronized V remove(Object key) {  
      Entry tab[] = table;  
      int hash = key.hashCode();  
      int index = (hash & 0x7FFFFFFF) % tab.length;  
      for (Entry<K,V> e = tab[index], prev = null ; e != null ; prev = e, e = e.next) {  
        if ((e.hash == hash) && e.key.equals(key)) {  
           modCount++;  
           if (prev != null) {  
             prev.next = e.next;  
           } else {  
             tab[index] = e.next;  
           }  
           count--;  
           V oldValue = e.value;  
           e.value = null;  
           return oldValue;  
        }  
      }  
      return null;  
   }  
   public synchronized void putAll(Map<? extends K, ? extends V> t) {  
     for (Map.Entry<? extends K, ? extends V> e : t.entrySet())  
       put(e.getKey(), e.getValue());  
   }  
   public synchronized void clear() {  
      Entry tab[] = table;  
      modCount++;  
      for (int index = tab.length; --index >= 0; )  
        tab[index] = null;  
      count = 0;  
 }  
   public synchronized boolean containsKey(Object key) {  
      Entry tab[] = table;  
      int hash = key.hashCode();  
      int index = (hash & 0x7FFFFFFF) % tab.length;  
      for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {  
        if ((e.hash == hash) && e.key.equals(key)) {  
           return true;  
        }  
      }  
      return false;  
 }  
 }  
 public abstract class AbstractMap<K,V> implements Map<K,V> {  
   public int hashCode() {  
      int h = 0;  
      Iterator<Entry<K,V>> i = entrySet().iterator();  
      while (i.hasNext())  
        h += i.next().hashCode();  
      return h;  
   }  
    */  
   public boolean equals(Object o) {  
      if (o == this)  
        return true;  
      if (!(o instanceof Map))  
        return false;  
      Map<K,V> m = (Map<K,V>) o;  
      if (m.size() != size())  
        return false;  
     try {  
       Iterator<Entry<K,V>> i = entrySet().iterator();  
       while (i.hasNext()) {  
         Entry<K,V> e = i.next();  
           K key = e.getKey();  
         V value = e.getValue();  
         if (value == null) {  
           if (!(m.get(key)==null && m.containsKey(key)))  
             return false;  
         } else {  
           if (!value.equals(m.get(key)))  
             return false;  
         }  
       }  
     } catch (ClassCastException unused) {  
       return false;  
     } catch (NullPointerException unused) {  
       return false;  
     }  
      return true;  
 }  
 }  

LinkedHashMap[TODO]
public class LinkedHashMap extends HashMap  implements Map
{
    // The head of the doubly linked list.
    private transient Entry header;
  
     * The iteration ordering method for this linked hash map: true
     * for access-order, false for insertion-order.
    private final boolean accessOrder;  
    void init() {
        header = new Entry(-1, null, null, null);
        header.before = header.after = header;
    }  
}
HashSet
public class HashSet extends AbstractSet implements Set, Cloneable, java.io.Serializable
{
    private transient HashMap map;
    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();
    public HashSet() {map = new HashMap();}
    public boolean add(E e) {return map.put(e, PRESENT)==null;}
}
TreeMap
public class TreeMap extends AbstractMap
    implements NavigableMap, Cloneable, java.io.Serializable
// it does not extend HashMap    
{
    private final Comparator comparator;
private transient Entry root = null;
    private transient int modCount = 0;
    // private Entry getEntry(Object key)
     * Returns a Set view of the keys contained in this map.  The set's
     * iterator will return the keys in ascending order.  The map is backed by
     * this TreeMap instance, so changes to this map are reflected in
     * the Set, and vice-versa.  The Set supports element removal, which
     * removes the corresponding mapping from the map, via the
     * Iterator.remove, Set.remove, removeAll,
     * retainAll, and clear operations.  It does not support
     * the add or addAll operations.
     * @return a set view of the keys contained in this TreeMap.
    public Set keySet() {
        if (keySet == null) {
            keySet = new AbstractSet() {
                public Iterator iterator() {
                    return new KeyIterator();
                }

                public int size() {
                    return TreeMap.this.size();
                }

                public boolean contains(Object o) {
                    return containsKey(o);
                }

                public boolean remove(Object o) {
                    int oldSize = size;
                    TreeMap.this.remove(o);
                    return size != oldSize;
                }

                public void clear() {
                    TreeMap.this.clear();
                }
            };
        }
        return keySet;
    }    
    public Collection values() {
        if (values == null) {
            values = new AbstractCollection() {
                public Iterator iterator() {
                    return new ValueIterator();
                }

                public int size() {
                    return TreeMap.this.size();
                }

                public boolean contains(Object o) {
                    for (Entry e = firstEntry(); e != null; e = successor(e))
                        if (valEquals(e.getValue(), o))
                            return true;
                    return false;
                }

                public boolean remove(Object o) {
                    for (Entry e = firstEntry(); e != null; e = successor(e)) {
                        if (valEquals(e.getValue(), o)) {
                            deleteEntry(e);
                            return true;
                        }
                    }
                    return false;
                }

                public void clear() {
                    TreeMap.this.clear();
                }
            };
        }
        return values;
    }
    public boolean containsValue(Object value) {
        return (root==null ? false :
                (value==null ? valueSearchNull(root)
                             : valueSearchNonNull(root, value)));
    }
    private boolean valueSearchNull(Entry n) {
        if (n.value == null)
            return true;

        // Check left and right subtrees for value
        return (n.left  != null && valueSearchNull(n.left)) ||
               (n.right != null && valueSearchNull(n.right));
    }
    private boolean valueSearchNonNull(Entry n, Object value) {
        // Check this node for the value
        if (value.equals(n.value))
            return true;
        // Check left and right subtrees for value
        return (n.left  != null && valueSearchNonNull(n.left, value)) ||
               (n.right != null && valueSearchNonNull(n.right, value));
    }    
    static final class Entry implements Map.Entry {
        K key;
        V value;
        Entry left = null;
        Entry right = null;
        Entry parent;
        boolean color = BLACK;
     }
    // Returns the first Entry in the TreeMap (according to the TreeMap's
    // key-sort function).  Returns null if the TreeMap is empty.
    final Entry getFirstEntry() {
        Entry p = root;
        if (p != null)
            while (p.left != null)
                p = p.left;
        return p;
    }
    public boolean containsValue(Object value) {
        for (Entry e = getFirstEntry(); e != null; e = successor(e))
            if (valEquals(value, e.value))
                return true;
        return false;
    }    
    //final Entry getLastEntry()
    // Returns the successor of the specified Entry, or null if no such.
    static TreeMap.Entry successor(Entry t) {
        if (t == null)
            return null;
        else if (t.right != null) {
            Entry p = t.right;
            while (p.left != null)
                p = p.left;
            return p;
        } else {
            Entry p = t.parent;
            Entry ch = t;
            while (p != null && ch == p.right) {
                ch = p;
                p = p.parent;
            }
            return p;
        }
    }
    // Returns the predecessor of the specified Entry, or null if no such.
    static Entry predecessor(Entry t) {
        if (t == null)
            return null;
        else if (t.left != null) {
            Entry p = t.left;
            while (p.right != null)
                p = p.right;
            return p;
        } else {
            Entry p = t.parent;
            Entry ch = t;
            while (p != null && ch == p.left) {
                ch = p;
                p = p.parent;
            }
            return p;
        }
    }
}
[TODO]
How BlockingQueue and ConcurrentHashMap are implemented?
ThreadLocal
public class ThreadLocal {
    public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null)
                return (T)e.value;
        }
        return setInitialValue();
    }
    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }
    void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }  
    ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }  
}

Labels

ANT (6) Algorithm (69) Algorithm Series (35) Android (7) Big Data (7) Blogger (14) Bugs (6) Cache (5) Chrome (19) Code Example (29) Code Quality (7) Coding Skills (5) Database (7) Debug (16) Design (5) Dev Tips (63) Eclipse (32) Git (5) Google (33) Guava (7) How to (9) Http Client (8) IDE (7) Interview (88) J2EE (13) J2SE (49) JSON (7) Java (186) JavaScript (27) Learning code (9) Lesson Learned (6) Linux (26) Lucene-Solr (112) Mac (10) Maven (8) Network (9) Nutch2 (18) Performance (9) PowerShell (11) Problem Solving (11) Programmer Skills (6) Scala (6) Security (9) Soft Skills (38) Spring (22) System Design (11) Testing (7) Text Mining (14) Tips (17) Tools (24) Troubleshooting (29) UIMA (9) Web Development (19) Windows (21) adsense (5) bat (8) regex (5) xml (5)