潇湘夜雨

分类

  • 源代码阅读 (20)
  • 设计模式 (3)
  • 科研 (6)
  • 思想 (2)
  • 技术 (18)
  • 工具 (4)
  • 虚拟机 (1)
  • java (11)
  • c语言 (4)
  • 读书 (1)
  • 操作系统 (1)
  • 英语 (10)
  • 计算机系统 (3)
  • 生活 (1)

归档

  • 2014-08 (1)
  • 2014-07 (5)
  • 2014-05 (12)
  • 2014-04 (3)
  • 2014-03 (11)
  • 2014-02 (6)
  • 2014-01 (3)
  • 2013-11 (10)
  • 2013-10 (3)
  • 2010-09 (1)
  • 学习英语第十三十四周
    1. 2014-05-25
    2. 英语

    学习英语第十三十四周

    标签:英语

    阅读英文原著

    Book Time Progress
    Harry Potter And The Goblet of Fire 2014.05.12 ~ 2014.05.23 734/734
    Read More ...
  • OpenJDK 源码阅读之 ArrayList
    1. 2014-05-24
    2. 技术  java  源代码阅读

    OpenJDK 源码阅读之 ArrayList


    概要

    • 类继承关系
    java.lang.Object
        java.util.AbstractCollection<E>
            java.util.AbstractList<E>
                java.util.ArrayList<E>
    
    • 定义
    public class ArrayList<E> extends AbstractList<E>
            implements List<E>, RandomAccess, Cloneable, java.io.Serializable
    {
    }
    
    Read More ...
  • OpenJDK 源码阅读之 String
    1. 2014-05-23
    2. 技术  java  源代码阅读

    OpenJDK 源代码阅读之 String


    概要

    • 类继承关系
    java.lang.Object
        java.lang.String
    
    • 定义
    public final class String
    extends Object
    implements Serializable, Comparable<String>, CharSequence
    
    • 要点

    一旦创建就不可改变

    实现

    • storage
    /** The value is used for character storage. */
    private final char value[];
    

    可以看出 String 中的数据是如何存储的。

    • 初始化
        public String(String original) {
            this.value = original.value;
            this.hash = original.hash;
        }
    

    可以看出使用 String 类型初始化,新 String 实际上与原来的 String 指向同一块内存。

    public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
    }
    

    如果用 char[] 初始化,可以看出,新分配了内存,并复制,保证了两者相互独立,只是内容相同。

        public String(StringBuffer buffer) {
            synchronized(buffer) {
                this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
            }
        }
    

    注意用 StringBuffer 初始化时,对同一 buffer 是线程安全的,即初始化 String 的过程中,其它线程不会改变 buffer 的内容。

    另外,能告诉我下面这段代码是怎么回事么?

       public String(StringBuilder builder) {
            this.value = Arrays.copyOf(builder.getValue(), builder.length());
        }
    

    为啥这次不同步了呢?

    Read More ...
  • OpenJDK 源码阅读之 HashSet
    1. 2014-05-22
    2. 技术  java  源代码阅读

    OpenJDK 源代码阅读之 HashSet


    概要

    • 类继承关系
    java.lang.Object
        java.util.AbstractCollection<E>
            java.util.AbstractSet<E>
                java.util.HashSet<E>
    
    • 定义
    public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, Serializable
    
    • 要点
    1. 不保证元素次序,甚至不保证次序不随时间变化
    2. 基本操作(add, remove, contains, size)常量时间
    3. 迭代操作与当前元素个数加底层容量大小成正比
    4. 不保证同步

    思考

    • 总体实现

    底层是用 HashMap 实现的,Set 中的数据是 HashMap 的 key,所有的 key 指向同一个 value, 此 value 定义为:

    // Dummy value to associate with an Object in the backing Map
        private static final Object PRESENT = new Object();
    

    再看一下 add,大概就能明白了

    /**
     * Adds the specified element to this set if it is not already present.
     * More formally, adds the specified element <tt>e</tt> to this set if
     * this set contains no element <tt>e2</tt> such that
     * <tt>(e==null&nbsp;?&nbsp;e2==null&nbsp;:&nbsp;e.equals(e2))</tt>.
     * If this set already contains the element, the call leaves the set
     * unchanged and returns <tt>false</tt>.
     *
     * @param e element to be added to this set
     * @return <tt>true</tt> if this set did not already contain the specified
     * element
     */
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
    
    • load factor
        public HashSet(Collection<? extends E> c) {
            map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
            addAll(c);
        }
    

    初始化中,注意使用的 HashMap 的 load factor 设置为 0.75,如果太小,就设置成 16. 为什么要 0.75 呢? 有什么依据吗?

    Read More ...
  • OpenJDK 源码阅读之 LinkedList
    1. 2014-05-21
    2. 技术  java  源代码阅读

    OpenJDK 源码阅读之 LinkedList


    定义

    public class LinkedList<E>
        extends AbstractSequentialList<E>
        implements List<E>, Deque<E>, Cloneable, java.io.Serializable
    {
    }
    

    盲点

    • serialVersionUID
        private static final long serialVersionUID = 876323262645176354L;
    

    序列化版本号,如果前一版本序列化后,后一版本发生了很大改变,就使用这个号告诉虚拟机,不能反序列化了。

    问题

    • writeObject

    比例一下 ArrayList 与 LinkedList 中的 writeObject

        private void writeObject(java.io.ObjectOutputStream s)
            throws java.io.IOException{
            // Write out element count, and any hidden stuff
            int expectedModCount = modCount;
            s.defaultWriteObject();
    
            // Write out array length
            s.writeInt(elementData.length);
    
            // Write out all elements in the proper order.
            for (int i=0; i<size; i++)
                s.writeObject(elementData[i]);
    
            if (modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
    
        }
    
        private void writeObject(java.io.ObjectOutputStream s)
            throws java.io.IOException {
            // Write out any hidden serialization magic
            s.defaultWriteObject();
    
            // Write out size
            s.writeInt(size);
    
            // Write out all elements in the proper order.
            for (Node<E> x = first; x != null; x = x.next)
                s.writeObject(x.item);
        }
    

    注意后者没有检查 modCount,这是为什么呢?之前看 ArrayList的时候觉得是为线程安全考虑的,可是现在为什么又不检查了呢?虽然两个文件的注释中都说到,如果有多个线程操作此数据结构,应该从外部进行同步。但是一个检查,一个不检查是几个意思呀?

    思考

    • 维护数据结构一致性
        private void linkFirst(E e) {
            final Node<E> f = first;
            final Node<E> newNode = new Node<>(null, e, f);
            first = newNode;
            if (f == null)
                last = newNode;
            else
                f.prev = newNode;
            size++;
            modCount++;
        }
    

    注意代码第 5行对 f 的检查,6 行对 last 的调整。一定要细心,保证操作后, 所有可能 涉及的数据都得到相应更新。

    • 隐藏实现
        public E getFirst() {
            final Node<E> f = first;
            if (f == null)
                throw new NoSuchElementException();
            return f.item;
        }
    

    注意返回的是数据,而不是Node,外部根本不需要知道 Node 的存在。 另外,为什么 f == null 要抛出异常而不是返回 null?

    Read More ...
« Prev 1 2 3 4 5 6 7 8 9 10 11 Next »
Copyright (c) minixalpha 2014