- 浏览: 422179 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (170)
- java (77)
- javascript (5)
- jsp (1)
- servlet (6)
- struts (8)
- hibernate (3)
- spring (4)
- ajax (5)
- jquery (3)
- apache cxf (0)
- ext.js (1)
- hadoop (0)
- android (0)
- html5 (2)
- linux (5)
- flex (1)
- tomcat (1)
- jboss (0)
- nginx (0)
- mysql (16)
- sql server (3)
- oracle (4)
- div+css (0)
- mybatis (4)
- design patterns (22)
- xml (2)
- postgresql (3)
- velocity (1)
- freemarker (1)
- kendo-ui (2)
- ibatis (1)
- socket (1)
- C and C++ (1)
- C# (2)
- 程序设计----算法 (0)
- jersey (1)
- dd (0)
- perl (1)
- shell (0)
最新评论
-
书策稠浊:
兄弟,这tm是Java?
java调用百度地图和谷歌地图 -
fengyunlouyanyu:
jquery----删除指定id的div下的img -
yangjianzhouctgu:
Neoman 写道hi,我看你引入了kendo.web.min ...
kendo-ui中kendoGrid的用法 -
Neoman:
hi,我看你引入了kendo.web.min.js 这个js, ...
kendo-ui中kendoGrid的用法 -
yangjianzhouctgu:
llscp 写道这是JS吧...对的呀
java调用百度地图和谷歌地图
春节刚过,打算换一份工作,于是就开始了一段准备面试的生活,准备的这段时间内,学到很
多知识,现在做个总结,总共分java集合、java虚拟机、多线程、spring等四个部分,由于个
人知识有限,在总结过程中,难免出现不当地方,如发现,请指出。
下面就开始第一部分:java集合
一、集合结构图
图中蓝色字体标示的是接口,黑色字体标示的是具体实现
1.Collection结构图
2.Map结构图
说明:
a.List表示列表,里面的元素可重复,有顺序
Vector为List的线程安全实现,底层采用数组的作为存储结构,方法上使用synchronized来实现同步,并发性差,因为这里采用的是对象的内部锁,一个对象只有一个内部锁,当一个线程获取了这个对象(这里的对象即为Vector类型的对象)的内部锁之后,其他线程想要获取这个对象的内部锁的时候,只能等待了,关于线程安全问题,在线程部分讲解。与Vector相对应的非线程安全实现为ArrayList.
ArrayList底层采用数组作为存储结构来实现List的,当执行add操作的时候,如果数组已经装满数据了,这时就需要数组容量扩展为原来的1.5倍。
LinkedList底层使用双向链表作为存储结构,传入的泛型参数一定要是基本类型除外的其他类型,链表中的每个节点使用Node来存储,Node的定义如下:
每次进行add操作的时候默认是插在链表的末尾,也可以指定插入位置。
b.Set表示集合,即里面的元素不能重复,重复与否是通过泛型类型的实际类型的比较器来实现的,底层是通过Map来实现的,利用Map的key不能重复的特性来实现。
HashSet底层使用HashMap来实现,HashSet里面的所有元素,对应到HashMap里面就是一个Key,向HashSet里面添加元素的代码如下:
PRESENT为Object对象。
TreeSet是通过TreeMap来存储数据和排序的。
c.Queue为队列,即满足FIFO规则,对应有单向队列(从一边进,从另一边出),双向队列(两边都可以进出,从一边进,可以从两边出)。ArrayBlockingQueue、LinkedBlockingQueue主要用来实现生产者消费者模式的应用。
ArrayBlockingQueue,数组实现的单向队列,底层通过数组来实现。ArrayBlockingQueue里面的属性有:
Object数组用来存储数据,takeIndex用来存放下一个可以取得数据的索引位置,每次进行取出数据时,需要进行如下操作:
putIndex用来存放下一个可以存放元素的索引位置,存储操作时,putIndex的设置为:
lock和condition主要用来保证线程安全。
LinkedBlockingQueue使用双向链表来实现,底层数据结构为:
每次元素进入队列时都是接在last的后面,出队列时,都是从head那里出。
使用java.util.concurrent包下面的ReentrantLock、Condition、AtomicInteger来保证线程安全。
d.Deque即为double ended queue,双端队列,两边都可以进出队列。
ArrayDeque底层使用数组来实现,部分代码为:
非线程安全的双端队列实现。
LinkedBlockingDeque底层采用双向链表来实现,部分代码为:
使用ReentrantLock、Condition来保证线程安全。
e.Map的实现常用的有三种,HashMap、Hashtable、TreeMap.Map没有继承Collection,原因为:Collection一次只存储单个元素,Map一次存储需要存储Key和Value。
HashMap底层是一个数组,数组里面的类型是Entry,Entry的定义如下:
可以看出,每个Entry里面有key、hash、value、next为Entry的属性。数组中的每个位置都是一个Entry类型的数据,这个数据含有指向下一个Entry的属性,即next.在进行put操作的时候,如果当前数组里面存储的元素数量超出了事先设置的阈值,则需要进行容量扩展,需要进行数组元素值复制、rehash等操作。底层的数组及链表的数据结构为:
HashMap中的Key需要重写hashCode和equals,hashCode用来定位,equals用来比较,及hashCode的作用为将需要插入的元素的位置定位到数组的哪个索引上,equals用来和链表上的元素进行比较,看是要插入的值的key是否已经存在,如果存在,则将新value替换老value值。
Hashtable为HashMap的线程安全实现,但是有如下不同:
HashMap的key和value都可以为null,Hashtable的key和value不能为null,否则抛出异常,原因是Hashtable继承了Dictionary,Dictionary中的key和value不允许为null。
hash算法不一样。HashMap的hash算法实现如下:
Hashtable的hash算法实现如下:
Hashtable在多数方法上加上了synchronized,即多线程下不会产生并发问题,HashMap会在多线程下产生并发问题。
TreeMap是红黑树理论的一种实现,维护一个Comparator和一个Entry,Comparator为构造实例时传进来的比较器,红黑树中的每一个节点对应一个Entry,Entry的实现如下:
可以看出一个Entry有指向父节点,左右子节点的引用。TreeMap的Key需要实现一个比较器,比较好的做法是,构造TreeMap时传入一个比较器,比较器是基于key实现的。
多知识,现在做个总结,总共分java集合、java虚拟机、多线程、spring等四个部分,由于个
人知识有限,在总结过程中,难免出现不当地方,如发现,请指出。
下面就开始第一部分:java集合
一、集合结构图
图中蓝色字体标示的是接口,黑色字体标示的是具体实现
1.Collection结构图
2.Map结构图
说明:
a.List表示列表,里面的元素可重复,有顺序
private static class Node<E> { E item; Node<E> next; Node<E> prev; Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } }
每次进行add操作的时候默认是插在链表的末尾,也可以指定插入位置。
b.Set表示集合,即里面的元素不能重复,重复与否是通过泛型类型的实际类型的比较器来实现的,底层是通过Map来实现的,利用Map的key不能重复的特性来实现。
public boolean add(E e) { return map.put(e, PRESENT)==null; }
PRESENT为Object对象。
/** The queued items */ final Object[] items; /** items index for next take, poll, peek or remove */ int takeIndex; /** items index for next put, offer, or add */ int putIndex; /** Number of elements in the queue */ int count; /* * Concurrency control uses the classic two-condition algorithm * found in any textbook. */ /** Main lock guarding all access */ final ReentrantLock lock; /** Condition for waiting takes */ private final Condition notEmpty; /** Condition for waiting puts */ private final Condition notFull;
Object数组用来存储数据,takeIndex用来存放下一个可以取得数据的索引位置,每次进行取出数据时,需要进行如下操作:
takeIndex = inc(takeIndex); final int inc(int i) { return (++i == items.length) ? 0 : i; }
putIndex用来存放下一个可以存放元素的索引位置,存储操作时,putIndex的设置为:
putIndex = inc(putIndex); final int inc(int i) { return (++i == items.length) ? 0 : i; }
lock和condition主要用来保证线程安全。
static class Node<E> { E item; /** * One of: * - the real successor Node * - this Node, meaning the successor is head.next * - null, meaning there is no successor (this is the last node) */ Node<E> next; Node(E x) { item = x; } } /** * Head of linked list. * Invariant: head.item == null */ private transient Node<E> head; /** * Tail of linked list. * Invariant: last.next == null */ private transient Node<E> last;
每次元素进入队列时都是接在last的后面,出队列时,都是从head那里出。
使用java.util.concurrent包下面的ReentrantLock、Condition、AtomicInteger来保证线程安全。
d.Deque即为double ended queue,双端队列,两边都可以进出队列。
private transient E[] elements; /** * The index of the element at the head of the deque (which is the * element that would be removed by remove() or pop()); or an * arbitrary number equal to tail if the deque is empty. */ private transient int head; /** * The index at which the next element would be added to the tail * of the deque (via addLast(E), add(E), or push(E)). */ private transient int tail;
非线程安全的双端队列实现。
/** Doubly-linked list node class */ static final class Node<E> { /** * The item, or null if this node has been removed. */ E item; /** * One of: * - the real predecessor Node * - this Node, meaning the predecessor is tail * - null, meaning there is no predecessor */ Node<E> prev; /** * One of: * - the real successor Node * - this Node, meaning the successor is head * - null, meaning there is no successor */ Node<E> next; Node(E x) { item = x; } } /** * Pointer to first node. * Invariant: (first == null && last == null) || * (first.prev == null && first.item != null) */ transient Node<E> first; /** * Pointer to last node. * Invariant: (first == null && last == null) || * (last.next == null && last.item != null) */ transient Node<E> last;
使用ReentrantLock、Condition来保证线程安全。
e.Map的实现常用的有三种,HashMap、Hashtable、TreeMap.Map没有继承Collection,原因为:Collection一次只存储单个元素,Map一次存储需要存储Key和Value。
static class Entry<K,V> implements Map.Entry<K,V> { final K key; V value; Entry<K,V> next; int hash; /** * Creates new entry. */ Entry(int h, K k, V v, Entry<K,V> n) { value = v; next = n; key = k; hash = h; } 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 Objects.hashCode(getKey()) ^ Objects.hashCode(getValue()); } //省略部分代码 }
可以看出,每个Entry里面有key、hash、value、next为Entry的属性。数组中的每个位置都是一个Entry类型的数据,这个数据含有指向下一个Entry的属性,即next.在进行put操作的时候,如果当前数组里面存储的元素数量超出了事先设置的阈值,则需要进行容量扩展,需要进行数组元素值复制、rehash等操作。底层的数组及链表的数据结构为:
HashMap中的Key需要重写hashCode和equals,hashCode用来定位,equals用来比较,及hashCode的作用为将需要插入的元素的位置定位到数组的哪个索引上,equals用来和链表上的元素进行比较,看是要插入的值的key是否已经存在,如果存在,则将新value替换老value值。
hash算法不一样。HashMap的hash算法实现如下:
final int hash(Object k) { int h = hashSeed; if (0 != h && k instanceof String) { return sun.misc.Hashing.stringHash32((String) k); } h ^= k.hashCode(); // 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); }
Hashtable的hash算法实现如下:
private int hash(Object k) { // hashSeed will be zero if alternative hashing is disabled. return hashSeed ^ k.hashCode(); }
Hashtable在多数方法上加上了synchronized,即多线程下不会产生并发问题,HashMap会在多线程下产生并发问题。
static final class Entry<K,V> implements Map.Entry<K,V> { K key; V value; Entry<K,V> left = null; Entry<K,V> right = null; Entry<K,V> parent; boolean color = BLACK; //省略部分代码 }
可以看出一个Entry有指向父节点,左右子节点的引用。TreeMap的Key需要实现一个比较器,比较好的做法是,构造TreeMap时传入一个比较器,比较器是基于key实现的。
发表评论
-
spring boot应用测试框架介绍
2018-07-19 14:44 701个人原创博客:spring boot应用测试框架介绍 -
可执行jar包的配置与运行
2017-06-04 19:42 964spring boot项目可以以jar包的形式执行运行。s ... -
多线程并发
2016-05-21 23:49 0Splitter.on('|').trimResults(). ... -
jdk动态代理实现原理
2016-05-09 23:12 719jdk的动态代理即使用反射来实现,具体由Proxy、Invoc ... -
spring常见注解
2016-05-01 23:33 11821.Autowired 通过spring的依赖注入功能来 ... -
spring常见配置作用
2016-04-29 23:08 894一般应用中常见spring的 ... -
数据来自两个系统时的内存分页算法
2016-04-24 23:12 788业务数据来自a-app与b-app,其中a-app中数据的业务 ... -
linux下java web开发环境搭建
2016-04-10 14:09 1098一般的java web开发涉及到的开发工具有:jdk、tomc ... -
linux下md5sum和DigestUtils.md5Hex的关系
2015-12-19 22:30 8448本文对linux下md5sum命令和java中DigestUt ... -
基于jersey的web service
2015-11-22 22:55 971本文是基于jersey的web service 的两个小例子, ... -
面试总结----spring
2015-05-19 22:17 870spring在面试中经常被 ... -
面试总结----多线程
2015-05-18 22:10 861面试过程中,多线程被问到的概率非常大,差不多都会问的。 下面 ... -
面试总结----java虚拟机
2015-05-17 23:20 715在面试过程中,java虚拟机被问到的概率非常大,应该是每场面试 ... -
json串与对象之间转换的几种实现方式
2015-01-24 18:56 1836这里使用了gson,fastjson,jackson,json ... -
google关于事件的生产者消费者模式实现例子
2015-01-24 11:28 928google使用生产者/消费者模式实现了事件的产生传播处理过程 ... -
图形化显示---冒泡排序
2014-12-05 22:17 878代码: package com.thread.singal ... -
多线程----wait/notify
2014-11-06 22:06 652线程同步:两个线程依次对同一变量进行操作。 packag ... -
多线程-----阻塞队列
2014-11-05 22:43 807使用一个线程将一个指定目录下面的所有文件放在一个阻塞队列中,用 ... -
迷宫的最短路径
2014-08-19 00:31 3732代码如下: package com.chapterO ... -
深度优先遍历------部分和问题
2014-08-15 20:15 476代码如下: package com.chapterO ...
相关推荐
java面试-Java集合框架常见面试题 java面试-Java虚拟机(JVM)面试题 51道 java面试-Kafka知识汇总 18道 java面试-Nginx面试题 23道 java面试-RabbitMQ面试题 22道 java面试-Redis面试题(含答案) java面试-...
大数据面试复习---Java基础---集合类、多线程、JVM 大数据面试复习----常问问题分析 大数据面试复习----画重点----思维导图 大数据面试复习----简历编写 大数据面试复习----练习的面试题+笔试题 大数据面试复习----...
Java-Java集合体系-List-Set 内容概要:总结了Java集体体系中的三大集合接口LIst、Set、Map,本文...适合场景:开发和面试中必备,Java集合体系是许多框架的基础,在开发中大量使用,面试题也是必问的题目,非常重要。
java集合总结
01大数据面试复习----Java基础---集合类、多线程、JVM 02大数据面试复习----画重点----常问问题分析 03大数据面试复习----画重点----精心制作热门技术思维导图 04大数据面试复习----画重点----56家+真实互联网大公司...
java集合类面试题总结
Java集合.pdf 面试---3. Java并发.pdf 面试---4. JVM&Linux.pdf 面试---5. JavaWeb&HTTP&安全&Git&前端.pdf 面试---6. MySQL.pdf 面试---7. 分布式理论---问题.pdf 面试---8. 分布式理论---组件.pdf 面试---9. ...
Java集合面试总结复习题集
Java基础知识:包括Java语言特性、面向对象编程、集合框架、异常处理等基础知识点。 数据库和SQL:涵盖数据库基础知识、SQL语句的编写和优化、数据库事务等相关内容。 Web开发:包括常用的Web开发框架(如Spring、...
此word文档全面总结了最新面试在中遇到的面向对象分析OOA、面向对象设计OOD、面向对象编程OOP以及Java线程、Java集合类、Java垃圾收集、Java小应用程序Applet、Swing、Servlet、JSP相关面试常见问题解析,不仅对找...
Java集合专题总结:HashMap 和 HashTable 源码学习和面试总结
【Java基础】集合框架-面试题。包含: 1. ArrayList 和 Vector 的区别; 2、ArrayList,Vector, LinkedList 的存储性能和特性; 3. 快速失败 (fail-fast) 和安全失败 (fail-safe) ...等Java集合部分经常遇到的面试题总结
本次分享的资源涵盖了Java面试的各个方面,从基础知识到高级技术,从数据库到框架应用,都做了深入的探讨和总结。具体内容包括: Java基础知识点:包括数据类型、面向对象特性、异常处理、集合框架等。 Java核心...
大公司最喜欢问的Java集合类面试题.docx 大公司的Java面试题集.doc 就业相关java 广州传智播客JavaEE工程师测试题.doc 广州传智播客JavaEE工程师测试题(带答案的).doc 应聘时最漂亮的回答.docx 当面试官问「你有...
JAVA面试题集合(项目2部).chm 华为笔试题大全(史上最齐全).doc JAVA题库.doc java面试题.zip Java面试宝典2011版-1A,Java基础部分.doc jsp笔试题全集.doc Java学习笔记(必看经典).doc android和java面试大全.rar ...
Java集合/泛型面试题 Java异常面试题 Java中的IO与NIO面试题 Java反射面试题 Java序列化面试题 Java注解面试题 多线程&并发面试题 JVM面试题 Mysql面试题 Redis面试题 Memcached面试题 MongoDB面试题 Spring面试题 ...
大公司最喜欢问的Java集合类面试题.docx 大公司的Java面试题集.doc 就业相关java 广州传智播客JavaEE工程师测试题.doc 广州传智播客JavaEE工程师测试题(带答案的).doc 应聘时最漂亮的回答.docx 当面试官问「你有...
│ java程序员面试资料.zip │ JAVA笔试题(上海释锐).pdf │ MIME简介.txt │ SCJP试题详解.pdf │ SQL面试题_心灵深处.htm │ Struts+Hibernate+Spring轻量级J2EE企业应用实战.pdf │ Struts中文手册.pdf │ ...
字节大佬总结的Java面试资料 JVM 是可运行 Java 代码的假想计算机 ,包括一套字节码指令集、一组寄存器、一个栈、 一个垃圾回收,堆 和 一个存储方法域。JVM 是运行在操作系统之上的,它与硬件没有直接 的交互。 ...