interview:java-code2
Table of Contents
自定义Annotation
定义Annotation语法如下: 访问修饰符 @interface Annotation名称 { 返回类型 method1() [default 默认值]; ... } 特点:
dubbo是什么
Dubbo是什么? Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案 Dubbo有何特点 远程通讯:提供透明化的远程方法调用,提供多协议支持 集群容错:软负载均衡,失败容错,地址路由,动态配置等集群支持。 自动发现:基于注册中心目录服务,使服务消费方能动态的查找服务提供方,支持平滑减少或增加机器
dubbo&spring cloud&Zeroc ICE比较
dubbo | spring cloud | Zeroc ICE | |
---|---|---|---|
相似功能 | 注册中心,负载均衡,安全机制访问控制 | ||
不同功能 | 服务治理更多一些 | 17个子项目 | 软件补丁服务,发布-订阅服务 |
轻重程度 | 轻量级 | 重量级 | 重量级 |
支持跨语言 | dubbox | 是 | 是 |
国内活跃度(2016) | 2645 (51job上关键词搜索) | 573 | 13 |
开发语言 | Java | Java | C |
性能 | 第二 | 第三 | 第一 |
MVC,RPC,SOA的架构演进
MVC: Application -> SpringMVC(或Struts2) -> Mybatis(Hibernate) -> 数据库 RPC: Application ->服务1 -> 多个数据库 ->服务2 -> 多个数据库 ->服务3 -> 多个数据库 SOA: Application ->注册中心 ->服务1 ->多个数据库 ->服务2 ->多个数据库 ->服务3 ->多个数据库
成员内部类
成员内部类特点: 成员内部类属于外部类的实例成员,成员内部类可以有public,private, default, protected权限修饰符。 在成员内部类中访问外部类的成员方法和属性,要使用“外部类名.this.成员方法” 和 “外部类名.this.成员属性” 创建成员内部类的实例使用“外部类名.内部类名 实例名 = 外部类实例名.new 内部类构造方法(参数)” 的形式 成员内部类有以下限制: 成员内部类不能与外部类重名 不能在成员内部类中定义static属性,方法和类(static final形式的常量定义除外)。 因为一个成员内部类实例必然与一个外部类实例关联,static成员完全可以移到其外部类中去。
集合类框架 继承关系图
{SortedSet=>Set; Queue; List }=> Collection => Iterable SortedMap => Map
哈希码的产生和使用
当调用对象的hashCode()方法时就会返回当前对象的哈希码值。支持此方法是为了提高哈希表的性能。 hashCode的常规协定: 在java应用执行期间,在对同一个对象多次调用hashCode方法时,必须一致地返回相同的整数, 前提是将对象进行equals比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。 如果根据equals(Object)方法,两个对象是相等的,那么对这两个对象中的每个对象调用hashCode方法都必须产生相同的整数结果。 注:这里说的equals(Object) 是Object类中未被子类重写过的equlas方法 如果根据equals(Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用hashCode方法不要求一定产生相同的整数结果。 但是程序员应该意识到,为不相等的对象生成不同的整数结果可以提高哈希表的性能。
HashMap实现
HashMap冲突的解决方法以及原理分析:https://blog.csdn.net/abcd1430/article/details/52745155
HashMap的底层主要是基于数组和链表来实现的,它之所以有相当快的查询速度主要是因为它是通过计算散列码来决定存储的位置。HashMap中主要是通过key的hashCode来计算hash值的,只要hashCode相同,计算出来的hash值就一样。如果存储的对象对多了,就有可能不同的对象所算出来的hash值是相同的,这就出现了所谓的hash冲突。学过数据结构的同学都知道,解决hash冲突的方法有很多,HashMap底层是通过链表来解决hash冲突的。
/** Entry是单向链表。 * 它是 “HashMap链式存储法”对应的链表。 *它实现了Map.Entry 接口,即实现getKey(), getValue(), setValue(V value), equals(Object o), hashCode()这些函数 **/ static class Entry<K,V> implements Map.Entry<K,V> { final K key; V value; // 指向下一个节点 Entry<K,V> next; final int hash; // 构造函数。 // 输入参数包括"哈希值(h)", "键(k)", "值(v)", "下一节点(n)" Entry(int h, K k, V v, Entry<K,V> n) { value = v; next = n; key = k; hash = h; } public final K getKey() { return key; } public final V getValue() { return value; } public final V setValue(V newValue) { V oldValue = value; value = newValue; return oldValue; } // 判断两个Entry是否相等 // 若两个Entry的“key”和“value”都相等,则返回true。 // 否则,返回false 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; } // 实现hashCode() public final int hashCode() { return (key==null ? 0 : key.hashCode()) ^ (value==null ? 0 : value.hashCode()); } public final String toString() { return getKey() + "=" + getValue(); } // 当向HashMap中添加元素时,绘调用recordAccess()。 // 这里不做任何处理 void recordAccess(HashMap<K,V> m) { } // 当从HashMap中删除元素时,绘调用recordRemoval()。 // 这里不做任何处理 void recordRemoval(HashMap<K,V> m) { } }
HashMap其实就是一个Entry数组,Entry对象中包含了键和值,其中next也是一个Entry对象,它就是用来处理hash冲突的,形成一个链表。
public HashMap(int initialCapacity, float loadFactor) { //确保数字合法 if (initialCapacity < 0) throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity); if (initialCapacity > MAXIMUM_CAPACITY) initialCapacity = MAXIMUM_CAPACITY; if (loadFactor <= 0 || Float.isNaN(loadFactor)) throw new IllegalArgumentException("Illegal load factor: " + loadFactor); // Find a power of 2 >= initialCapacity int capacity = 1; //初始容量 while (capacity < initialCapacity) //确保容量为2的n次幂,使capacity为大于initialCapacity的最小的2的n次幂 capacity <<= 1; this.loadFactor = loadFactor; threshold = (int)(capacity * loadFactor); table = new Entry[capacity]; init(); } public HashMap(int initialCapacity) { this(initialCapacity, DEFAULT_LOAD_FACTOR); } public HashMap() { this.loadFactor = DEFAULT_LOAD_FACTOR; threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR); table = new Entry[DEFAULT_INITIAL_CAPACITY]; init(); }
interview/java-code2.txt · Last modified: 2018/07/24 08:13 by 127.0.0.1