-
JDK1.8新增的功能
1.Lambda表达式 2.Stream函数式操作流元素集合 3.接口新增:默认方法与静态方法 4.方法引用,与Lambda表达式联合使用 5.引入重复注解 6.类型注解 7.最新的Date/Time API (JSR 310) 8.新增base64加解密API 9.数组并行(parallel)操作 10.JVM的PermGen空间被移除:取代它的是Metaspace(JEP 122)元空间
-
字符流和字节流的区别,使用场景,相关类
1.字节流操作不会用到缓冲区,而字符流操作用到了缓冲区。 所以在操作文件时,比如字符流写入,如果没有关闭字符流,直接打开文件,发现文件是空的,因为数据还在缓存中。
那是用字符流好还是字节流好?
当然是字节流,所有文件在硬盘或文件都是以字节流方式进行的,而字符只有在内存中是。
-
线程安全的概念,实现线程安全的几种方法
线程安全就是多线程访问时,采用了加锁机制,当一个线程访问某个数据时,进行保护,其他线程无法访问,只有当该线程访问结束后,其他线程才能访问。不会出现数据不一致或者数据污染的情况。
实现线程安全的几种方法:
synchronized:包括同步方法,同步代码库等;
锁:ReentrantLock,可重入锁,独占锁
原子类:atomicInteger等
volatile:volatile只能保证内存的可见性,如果是非原子操作无法保证线程安全。
-
抽象类和接口的区别,使用场景
1.接口不能有方法的具体实现,而抽象类可以有;
2.接口里面方法都是抽象的,而抽象类可以有普通方法;
3.一个类可以实现多个接口,而只能继承一个抽象类;
4.接口里面的方法都为public的,而抽象类的可以为私有的。
5.使用场景,接口一般用于没有共同特性,每个方法都需要自己去实现;而抽象类可以有一部分公共的特性,自己去实现特有的一部分。比如Thread就是抽象类,继承Thread的类可以自己去实现run()方法,但是也可以用公用的方法,比如sleep等,而Runnable则为接口,所有实现者均需要实现run方法。
-
hash算法的实现原理,hashcode的实现原理
hashcode调用的实际是本地的方法,public native int hashCode(); 具体实现可能跟机器有关系了。
主要使用在hashMap,hashSet等中,通常用来判断一个元素存储的下班,比如一个hashMap比较大时,不可能一直调用equals来判断是否有相同的元素。使用hashcode能直接定位到数据的下标位置;
如果x.equals(y)返回“true”,那么x和y的hashCode()必须相等。
如果x.equals(y)返回“false”,那么x和y的hashCode()有可能相等,也有可能不等。
- error和exception的区别,RuntimeException和非RuntimeException的区别
erro指程序无法处理的错误,一般指与虚拟机相关的错误,一般不需要程序处理,比如内存空间不足,栈溢出等
exception是指程序本身可以处理的异常,比如空指针,数据越界等;
RuntimeException指程序运行时才会出现的错误,在定义方法时不需要声明可能会抛出的异常,比如nullpoint,arrayIndexOutOfBound等
非RuntimeException指在定义方法时,必须声明可能存在的异常,否则编译器不通过,比如IOException等。
- 继承与组合的区别,使用场景
没用过组合,不说了
-
使用静态工厂方法的好处和坏处
常用的有valueOf()等,这里以Integer.valueOf()为例。 静态工厂方法的实现在另外一篇博客中有介绍Java 静态工厂方法。
优点:
1.可以用方法名来标识,提高程序可读性;
2.不必在每次调用类时都创建一个新的对象;这里每次获取一个Integer类型的对象,不需要new一个Integer对象实例;
3.可以返回原返回类型的任何子类型对象; 比如本来要返回的对象是Fruit,如果Apple集成了Fruit,直接返回Apple也是可以的
4.代码简介
缺点:
1.如果没有public或protect方法,则无法子类化,即无法被继承;
2.和普通的静态方法没什么区别;
-
数据库设计原则、范式
这个百度搜索吧。。。
-
数据库常用的编码方式有哪几种
常用的就是GBK和UTF8
GBK文字编码采用双字节,无论中英文,均使用双字节来表示;中文规范;
UTF-8英文一个字节编码,中文三个字节编码;国际规范;
-
如果有10万条学生成绩信息,怎么获取成绩最高的那一条数据,怎么获取成绩第三的那一条数据,列举你认为性能最好的方式
可以使用limit,比如查询后按照分数排序,最后加上limit2,1,但是不确定这种是不是性能最好的方式;
-
序列化的作用,应用场景,除了网络传输
序列化的意义就是把数据换个时间,换个地点再次使用;
换个时间,比如在重启服务前把内存中的对象保存到文件或者数据库中,重启后再次使用;
换个地点,就是网络传输的场景了
-
spring的IOC、AOP的使用场景
-
解析xml的几种方法,他们的原理
SAX
sax是一个用于处理xml事件驱动的“推”模型;
优点:解析速度快,占用内存少,它需要哪些数据再加载和解析哪些内容。
缺点:它不会记录标签的关系,而是需要应用程序自己处理,这样就会增加程序的负担。
DOM
dom是一种文档对象模型;
优点:dom可以以一种独立于平台和语言的方式访问和修改一个文档的内容和结构,dom技术使得用户页面可以动态的变化,如动态显示隐藏一个元素,改变它的属性,增加一个元素等,dom可以使页面的交互性大大增强。
缺点:dom解析xml文件时会将xml文件的所有内容以文档树方式存放在内存中。
PULL
pull和sax很相似,区别在于:pull读取xml文件后触发相应的事件调用方法返回的是数字,且pull可以在程序中控制,想解析到哪里就可以停止解析。 (SAX解析器的工作方式是自动将事件推入事件处理器进行处理,因此你不能控制事件的处理主动结束;而Pull解析器的工作方式为允许你的应用程序代码主动从解析器中获取事件,正因为是主动获取事件,因此可以在满足了需要的条件后不再获取事件,结束解析。pull是一个while循环,随时可以跳出,而sax不是,sax是只要解析了,就必须解析完成。)
-
数据库连接池的实现原理,请求怎么样去获取连接,,关闭连接时,连接池是销毁连接还是回收连接
连接池的原理,主要是要维护共享的池子,需要考虑到资源竞争和池子大小的问题,实现主要考虑通过信号量和锁来实现。关闭连接不是销毁连接,是回收连接。
-
http和https的区别
安全和非安全
https用到证书,SSL
https加密
默认端口不一样
-
OOM的原因有哪几种,怎么样分析
1.OOM出现主要发生在老年代和永久代,首先查看OOM是哪种?
heap space:堆内存溢出,一般由于内存泄漏或堆大小设置太小导致。堆大小设置可以通过-Xms,Xmx来设置。内存泄漏需要通过dump工具来查看代码哪个地方出现问题。
PermGen:永久代溢出,即方法区溢出了,这种情况出现的可能比较少,一般由于出现大量的class或jsp页面,或者采用cglib反射机制导致,另外常量太多也会导致,比如string常量。一般通过调整永久代大小解决。使用类似-XX:PermSize=64m -XX:MaxPermSize=256m
stackOverFlowError;栈溢出,一般不会抛OOM,一般由于程序有深度递归调用或者死循环导致,排除代码是否有问题,以及调整栈的大小,-Xss来设置栈的大小。
OOM分析,先heapdump内存信息,再通过工具来展示
- 设置JVM参数-XX:+HeapDumpOnOutOfMemoryError,设定当发生OOM时自动dump出堆信息。不过该方法需要JDK5以上版本。
- 使用JDK自带的jmap命令。"jmap -dump:format=b,file=heap.bin <pid>" 其中pid可以通过jps获取。
dump后需要分析,一般使用下面两种工具,常用的是mat
- mat: eclipse memory analyzer, 基于eclipse RCP的内存分析工具。详细信息参见:http://www.eclipse.org/mat/,推荐使用。
- jhat:JDK自带的java heap analyze tool,可以将堆中的对象以html的形式显示出来,包括对象的数量,大小等等,并支持对象查询语言OQL,分析相关的应用后,可以通过http://localhost:7000来访问分析结果。不推荐使用,因为在实际的排查过程中,一般是先在生产环境 dump出文件来,然后拉到自己的开发机器上分析,所以,不如采用高级的分析工具比如前面的mat来的高效。
-
除了使用new关键字创建对象以外,试列举另外三种以上创建实例的方式?
1.反射机制:使用class的newInstance()方法/使用constructor的newInstance方法
2.序列化
3.clone
-
列举三种以上垃圾回收算法,并比较其优缺点?
GC介绍Java GC机制
-
编写代码实现一个线程池
可以看下线程池的分析Java 线程池分析
-
描述一下JVM加载class文件的原理机制?
关于Hashcode方法和equals?
哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率。在Java的Object类中有一个方法:
1
|
public native int hashCode(); |
根据这个方法的声明可知,该方法返回一个int类型的数值,并且是本地方法,因此在Object类中并没有给出具体的实现。
为何Object类需要这样一个方法?它有什么作用呢?今天我们就来具体探讨一下hashCode方法。
一.hashCode方法的作用
对于包含容器类型的程序设计语言来说,基本上都会涉及到hashCode。在Java中也一样,hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,这样的散列集合包括HashSet、HashMap以及HashTable。
为什么这么说呢?考虑一种情况,当向集合中插入对象时,如何判别在集合中是否已经存在该对象了?(注意:集合中不允许重复的元素存在)
也许大多数人都会想到调用equals方法来逐个进行比较,这个方法确实可行。但是如果集合中已经存在一万条数据或者更多的数据,如果采用equals方法去逐一比较,效率必然是一个问题。此时hashCode方法的作用就体现出来了,当集合要添加新的对象时,先调用这个对象的hashCode方法,得到对应的hashcode值,实际上在HashMap的具体实现中会用一个table保存已经存进去的对象的hashcode值,如果table中没有该hashcode值,它就可以直接存进去,不用再进行任何比较了;如果存在该hashcode值, 就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址,所以这里存在一个冲突解决的问题,这样一来实际调用equals方法的次数就大大降低了,说通俗一点:Java中的hashCode方法就是根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为散列值。下面这段代码是java.util.HashMap的中put方法的具体实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public V put(K key, V value) { if (key == null ) return putForNullKey(value); int hash = hash(key.hashCode()); int i = indexFor(hash, table.length); for (Entry<K,V> e = table[i]; e != null ; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess( this ); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null ; } |
put方法是用来向HashMap中添加新的元素,从put方法的具体实现可知,会先调用hashCode方法得到该元素的hashCode值,然后查看table中是否存在该hashCode值,如果存在则调用equals方法重新确定是否存在该元素,如果存在,则更新value值,否则将新的元素添加到HashMap中。从这里可以看出,hashCode方法的存在是为了减少equals方法的调用次数,从而提高程序效率。
HashMap与HashTable?
2.HashTable不允许null值(key和value都不可以),HashMap允许null值(key和value都可以)。
3.HashTable有一个contains(Object value),功能和containsValue(Object value)功能一样。
4.HashTable使用Enumeration,HashMap使用Iterator。
1. cookie 和 session 的区别
cookie机制采用的是在客户端保持状态的方案,
而session机制采用的是在服务器端保持状态的方案。
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
5、
将登陆信息等重要信息存放为SESSION
其他信息如果需要保留,可以放在COOKIE中
2. JVM 内存模型
3. SQL注入的原理
4. 悲观锁 和 乐观锁
5. 读程序,输出结果. 关于treemap的
6. Linux 基础命令,统计日志中的信息
7. java 分布式集群
8. 一道设计题,具体到数据库的表.大概是淘宝的搜索中,输入手机,会出来很多类型,按品牌按价格区间按手机种类.
还有2道题我记不住了.
面试:
1.介绍你做过的项目,用到的技术,涉及到的模块,然后从项目中问各种技术实现的细节(为了确保你是真的懂了).
2.看你的试卷,喊你讲解做题的思路,以及这样结果的原因.(考的是各位的java基础知识了,这点是绕不过去的,懂了就懂了啊,只有平时多看书)
3.团购6位验证码以及团购成功后,发送到你手机上的条码的实现方式.(第一个问题我说用随机数+时间来验证.第二个问题老实说,我也没答上来,我说用序列,面试官说序列到后期20位以上的时候,用户体验很差的)
4.淘宝上是如何保证库存和订单之间的数据准确性的.(考点是分布式事务,这个问题我也没答上来,最后他问我有什么问题问他的时候,我就反问的这个问题,面试官人挺好的,给我耐心的讲解了一遍淘宝的实现方式以及
epay的实现方式. 淘宝是通过分布式事物,中间用了一个叫协调者角色的程序,当那边点击购买时,会库存减一,保存一条预扣的状态,但是是个预准备状态,然后做成功后,协调者会在另一个数据库生成订单,然后这个订单也是预状态,等两边都准备好以后,通知协调者,又协调者统一完成这2个数据库的事物,从而达到完成一笔交易的目的,若其中一方失败,则将预扣的数字返回到库存从而实现类似回滚的操作.)
5.索引的原理.能否构建时间索引.时间索引构建后会存在什么问题.(索引原理我是回答的堆表索引的构建原理以及查询原理,但是关于时间索引的问题,我也没回答出个所以然来,看面试官的反馈,好像回答得不够好吧)
6.你们数据库的数据量有多大,(回答:我们是电信方面的系统,表上亿的数据很正常).问:如果保证效率?
(我是如此回答的,各位自行结合自身的情况参考.答:后台J OB程序会定期备份,把生产表数据移走,然后备份表也会再备份一次,如此剃度的备份,保证生产库的数据是最小的.然后备份表采用分区和子分区,加上构建战略索引(分析系统的sql,常用
查询字段构建复合索引,以减少每次查询时对表的访问次数)).
7.SQL注入的原理以及如何预防,并举例.(这个相对简单,网上一搜一大片)
8.使用过Memcache么? 用在项目中哪些地方? (答,在门户主机上使用,缓存session,分布式的时候,统一访问这台主机验证用户session是否存在,来维持回话的状态和实现回话同步.又追问:java代码中如何实现访问门户服务器的这个session池子的? 几年前的代码,确实忘记了..于是坦白的说,记不清楚了 )
这些是主要的问题,当你回答一个大问题时中间还有很多比较碎的追问性质的小问题,总体给我的感觉是,氛围很轻松+愉快的,技术层面上还是需要你真正的理解透彻一些关键技术点,才能做到应付各种追问和给出满意的答案吧.如果只是一知半解想去蒙混过关肯定是不行的,毕竟在支付宝的技术大牛面前,多追问几句,也就把你逼到死角了.
还有一点比较重要的感觉就是,他们比较在意你是否了解当下的一些比较热的技术点,比如淘宝的秒杀,是如何保证高并发下的安全性和性能,新浪微博那种大数据量的发送,怎么就保证正确性和时效性的.