面试杂项

延迟消息队列的实现方式---考察架构设计和逻辑思维性--架构设计----NO;
cms 垃圾回收期的高阶—答不上来

持久带是否发生fullGC ok


jps----ok
jstack----ok
jmap jhat------dump日志,jhat 不清楚
jstat----不清楚

dump文件中的分析
jstack Dump 日志文件中的线程状态
dump 文件里,值得关注的线程状态有:
死锁,Deadlock(重点关注)
执行中,Runnable
等待资源,Waiting on condition(重点关注)
等待获取监视器,Waiting on monitor entry(重点关注)
暂停,Suspended
对象等待中,Object.wait() 或 TIMED_WAITING
阻塞,Blocked(重点关注)
停止,Parked

分析过dump文件但是,不深入;

cpu彪高----》线上问题解决 no

jvm理解程度一般,线上解决问题能力较弱

=========

grep 命令各种线上日志查询 yes

tail 命令 ok

find -type f -size +1000m |xargs 有点忘记了,但是知道这样写

tar -zcvf ok

maven release SNAPSHOT的区别 no

git命令reset rebase的区别 no

工程素质中等水平

========

=========
mySql 索引的数据结构 B+数 yes
为什么?yes


mySql联合索引的最左前置规则 yes


分库分表经验-易购索引的注意事项:yes

mysql 以及使用 以及遇到问题的意识 OK 数据库还是不错的

==========

工作线程数究竟要设置为多少?
没有好的思路

5.

a) dubbo 集群的工作方式,同步,异步 方式接触较少。

b) redis 数据结构,5种, OK , redis CLUSTER 方式: 数据分片,数据持久化: AOF ,rdb 方式 OK 。
c) MQ : 使用过kafka, 注册topic, ok 。 相对较了解。 kafka 增加节点,系统会有什么变化
d) GIT : 大部分使用 ide 方式。 rebase 用法,不了解。 stash 用法,没用过。

1. 个人介绍及项目介绍(考察沟通能力)

2. 在公司项目的业务情况(考察业务需求把握能力)

3. 团队情况和直接管理人员情况,任务开发分配情况(考察基本项目管理技能)

4. spring mvc的工作流程,微服务不采用spring boot 原因(考察开发技能和架构把握能力)

5. 具体技术细节提问(考察技术深度)

a)dubbo 集群的工作方式

b)redis 基本数据结构,cluster方式,持久化方式

c)rabbitMq,ecchange,channel概念解析,集群的有几种方式,使用场景和优缺点。

d). git : rebase/merge 区别,团队使用注意点,stash 用法

6. 离职原因(工作稳定性)

7. 工作中出彩的地方和困难介绍(考察项目实战能力)

8. 职业规划和长短板

新生代用什么垃圾回收算法---no
老年代的垃圾回收算法---no
1 看完书之后知识没有成体系

jvm 命令-jps -no


========
工程素质:
线上日志查询---no

grep ok

netstat no

tail -f yes

find 命令 no

xargs no

maven 看依赖树 yes

maven release SNAPSHOT的区别 no

git reset rebase的区别 no

=========

kafka --一点也不了解
rabbitMQ用什么语言实现的 no

5.MySql了解tree和hash两种所以,具体区别一般;

联合索引知识了解比较少;

git reset 、rebase和 revert的区别?–OK

Maven的Snapshot版本与Release版本的区别-了解一些,但是不全面

线上CPU彪高问题排查–NO

线上OOM问题排查-NO

JVM内存模型以及CMS垃圾回收器的相关-OK

JVM基础命令-个别命令不熟悉;

Linux基础以及加深-linux基础良好,复杂命令不牢固

java多线程的理解和设置工作线程数方案以及思路-有一定的经验,但是不完善

分库分表的设计经验以及领域划分经验-回答的不太好

延迟消息的架构设计-OK,这个问题答的思路很清晰

5.知道基本优化参数,不知道OOM如何产生;也不知道栈内存溢出如何复现;

单例:饿汉、懒汉、双锁、静态内部类

java类加载机制,不ok

1.
String StringBuffer StringBuilder 区别String ok StringBuffer StringBuilder区别回答不正确 不OK
HaspMap 结构:数据+链表;下标算法:没回答上来;新元素放到链表位置:记不清了 不OK
HashMap与HashTable: HashMap是线程安全的(回答错误)与HashTable区别:不知道 不OK
concurrenthashmap: 比HashMap并发好。效率高 锁分段算法:没看过 不OK
object equals == 区别:OK String equals ==: ok
二叉树结构:ok 特点:回答的不完善 红黑树:忘记了 不OK
2.
状态:就绪 运行 结束 等待 堵塞; sleep wait 区别:sleep 不释放锁 wait 释放锁 notify后流程:回答不完善
sync : 原理基本OK, 加在不同地方: 锁类、锁对象 基本OK
lock : CAS实现
volatile:可见性、不能保证线程安全,应用场景:写少读、并发少
ThreadLocal:原理OK;子线程用父线程TheadLocal对象:可以,不知道如何实现

3.
IOC:默认:多例
AOP: 动态代理:(提示出)jdk cglib 区别:不知道
bean 循环依赖:SPRING解决方案 没看过
事务传播:原理基本知道AOP实现
4.
OOM: 堆、方法区会引起
回收机制:新生代 用标记清除比较多 老年代忘记了
5.
策略:场景题:计算器设计 OK

6.
引擎:innodb\myisam 对锁的区别: 回答不透彻 ;对事务的区别:innoDB,myisam都支持事务
隔离级别:回答有5、6种 幻读含义:回答正确
索引:explain profiling
联合索引: 走索引方式 回答基本OK
7.
架构方面能力比较不错,知识面比较广
沟通能力比较好,项目背景可以清晰描述出

1.
HaspMap 结构:ok
concurrenthashmap: 实现原理不ok
hashSet数据结构:ok

2.
状态:就绪 运行 结束 等待 堵塞; sleep wait 区别:sleep 不释放锁 wait 释放锁 notify后流程:回答不完善
sync : 原理基本OK, 加在不同地方: 锁类、锁对象 基本OK
volatile:可见性、不能保证线程安全 ,ok 应用场景:不ok
ThreadLocal:原理OK;子线程用父线程TheadLocal对象:可以,不知道如何实现

线程池:知道核心参数,原理ok。

3.
AOP: 动态代理:(提示出)jdk cglib 区别:基本ok

spring事务机制没怎么使用过。

4.
回收机制:堆的划分,回收算法。ok

5.

引擎:innodb\myisam 底层存储结构不了解
联合索引: 原理OK,有查询计划分析经验

聚簇索引和非聚簇索引之间的区别:ok
6.
沟通能力比较好,项目背景可以清晰描述出

系统之间使用http交互,未使用rpc框架

3.不了解IOC, 简单了解SpringMVC处理流程,一般

4.mysql基本索引存储结构:B+树;

聚簇索引和非聚簇索引的区别:不ok;

5.基本查看命令了解,一般,不ok

6.只会基本使用,maven的生命周期,ok;

7.mget优化:本地分组,同一连接一次传输多组数据,减少传输次数;

缓存如何保证高可用性  redis分片,一致性hash   

本地缓存,集中缓存,如何保持数据一致性:通过mq消息;

线程导致cpu飙高:ok;

但是,对cglib没用过,不清楚优缺点;

1、针对淘宝的网站竞品抓取经历,

提问:

{1} 如何针对各个竞品的防抓取策略,提出反向突破策略,抓取到有效数据?

结果:通过代理池,针对各个竞品调整固定抓取频次;

{2} 如果自己实现代理IP池,如何保证代理池内的代理全部有效?

回答:通过数组,多线程进行分切筛选(类似2分法);

{3}算法实现:

实现上逻辑合理,复杂度处理有考虑,实现了一个多线程管理数组队列的机制;但遗漏了ip超时淘汰机制会造成数组空位的问题,提示后补充完毕‘

{4} 针对车辆管理,QPS 400左右的mysql写库的解决方案,考虑kafka有做异步处理方面的方案存在遗漏,考虑分库方案回答基本到位,但方案缺点回答不全;

{5}JVM常规OOM、GC过频繁、CPU过高等问题,有排查经验,但回答的并不到位,不能精确确认发生问题点;

{6}MYSQL的数据索引结构B+树算法,针对数据的更新、删除更新机制回答基本正确,但写此磁盘方面的机制不到位;

总结:

优点,项目经验真实,有一定算法经验,有现场排查问题经验;

缺点,考虑问题不够全面,解除的技术不够宽泛

1.
String StringBuffer StringBuilder 区别String ok StringBuffer 安全 StringBuilder不安全 stringbuilder使用场景不知道
HaspMap 看过部分原码 深层就不知道了
concurrenthashmap: 没有看过及用过
object equals == 区别:OK String equals ==: ok
二叉树结构:不太了解了
2.
状态:就绪 运行 结束 等待 堵塞; sleep wait 区别:sleep 不释放锁 wait 释放锁 notify后流程:先获取锁再执行
sync : 底层原理不清楚, 加在不同地方: 锁类、锁对象 理解不对
lock : 与sync区别:不知道 使用场景:没使用
volatile:可见性、原子性
automic:原理没研究过
ThreadLocal:原理OK;子线程用父线程TheadLocal对象:可以,不知道如何实现

3.
IOC:默认:多例
AOP: 动态代理:jdk cglib 区别:ok
bean 循环依赖:没遇到场景

4.
jvm : 了解不多
OOM: 不清楚
回收机制:没有细研究过

5.
策略:场景题:计算器设计 不OK

6.
是否走索引:不知道

HaspMap 结构:数据+链表;下标算法:不知道;新元素放到链表位置:头部 不OK
HashMap与HashTable: HashTable是线程安全的,加锁方式:不确定是sync还是lock 不OK
concurrenthashmap: 比HashMap并发好。效率高 锁分段算法:不知道 不OK
object equals == 区别:OK String equals ==: ok
二叉树结构:对数据结构比较弱 不OK
2.
状态:就绪 运行 结束 等待 堵塞; sleep wait 区别:sleep 释放锁 wait 不释放锁 不OK
sync : 原理不太了解, 加在不同地方: 不OK
volatile:可见性、原子性,应用场景:比较模糊
ThreadLocal:原理OK;子线程用父线程TheadLocal对象:不可以(回答不正确)

3.
IOC:默认:单例 可以多例
AOP: 动态代理:jdk cglib 区别:不知道 不OK
bean 循环依赖:没研究过
事务传播:原理基本知道AOP实现
4.
OOM: PC不会引起
回收器:不太了解 不OK
回收对象机制:了解比较浅 不OK
5.
策略:场景题:计算器设计 不OK

6.
引擎:innodb\myisam
区别:
 锁: innoDB行级锁,myisam表级
 事务:innoDB支持,myisam不支持,
 索引:innoDB BTree,myisam 压缩 不OK
隔离级别:4种OK 幻读含义:回答不正确 不可重复读:回答不正确 不OK
索引:explain
联合索引: 走索引方式 回答基本OK
7.
scp top du

基础理论能力

主要考察面试者基础语法概念(面向对象、java基础语法)、常用框架概念(SSI、AOP、IOC、值栈等)、基础网络知识(http协议、cookie、CDN、request等)、多线程(锁)、同步异步、文件IO、消息队列、设计模式等

基础

  • 你如何理解什么是面向对象?
  • int和Integer有什么区别?
  • String 和StringBuffer的区别
  • 什么是Servlet?Servlet的生命周期?
  • 同步和异步有何异同,在什么情况下分别使用他们?举例说明。
  • 页面间对象传递的方法(request,session,application,cookie等)
  • .etc

中等

  • 多线程安全(也可以是困难的)
  • sleep() 和 wait() 有什么区别?(前者占用CPU,后者空闲CPU)
  • 静态变量和实例变量之间的差别
  • forward 和redirect的区别?
  • 多线程有几种实现方法,是什么?同步有几种实现方法,是什么?
  • 常见的设计模式有哪些,随便挑一两个简单考察。
  • 当你在浏览器中输入一个网址,敲下回车发生了什么?
  • 对JAVA多线程中“锁”的概念的理解
  • 所有的递归实现都可以用循环的方式实现,请描述一下这两种实现方式各自的优劣。 并举例说明在什么情况下可以使用递归,而在什么情况下只能使用循环而不能使用递归?
  • 请阐述下你对IOC(Inversion of Control)的理解。(以Spring的IOC作为例子说明他们在实现上各自的特点)
  • .ect

困难

  • 分布式场景下的问题
  • 大数据场景下的问题
  • 大流量场景下的问题
  • 说说java7新特性?
  • java中异常处理机制的原理和应用
  • 为什么在重写了equals()方法之后也必须重写hashCode()方法?

编码能力

考察面试者基础编码能力,不可以写伪代码,注重检查点:能否跑通work,功能是否满足,逻辑是否严谨(边界),编码习惯是否nice(变量定义),实现方式是否最佳(时间、空间)

基础

  • 将两个升序排列的数组,合并成一个新的升序排列的数组。
    public int[] merge(int[] a, int[] b) {
    }
  • 将一个字符串反转,如将”abcdef“反转成”fedcba“。
    public String reverse(String source) {
    }
  • 知道哪些排序方法,时间空间复杂度,随便挑选一个让其写实现代码

中等

  • 写一个名为Singleton的单例模式类,并说出它的特点和适用场景。单例模式有哪些缺点,在哪些情况下单例语义会遭到破坏,或者说可以产生多于一个实例?
    public class Singleton {
    }
  • 将一个无序整数序列中两个元素和为100的元素对打印输出到控制台,如输入为8,19,-7,92,26,81,99,107,则输出对应序号(0,3),(1,5),(2,7)。
    public void matches(Iterator in) {
    }
  • 设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1;写出程序。

    参考demo:http://w4c.dp/doc/r/KxmwjcFlGrKoDmiWvddruqSUEyJNZFbtYWYszCaQDjeiIebWhQ:preview
  •  

困难

  • 解析一段URL的query string(key/value对用’&’和’=’分隔)。如:“a=b&a=c&d=e&e=fgh”
    public Map parse(String queryString) {
    }

设计能力

考察面试者项目设计能力,注意检查点:项目关键功能点拆解&理解能力、设计是否满足全部项目功能、数据库表设计是否合理(字段设计、关联主附表、索引是否合理)、扩展灵活性等

基础(针对在校生、应届和工作1-2年者)

  • 图书馆需要建设一个借阅还书系统,请为该系统进行数据库建模。要求如下:
    • 每个借阅者均需要办理读者证。每个读者证可以同时借阅10本书。
    • 拥有读者证的借阅者可以借阅图书和归还图书
    • 可以查阅图书及在馆状态
    • 借阅者可以通过图书馆网站进行续借,仅可续借一次
  • 公司会议室比较紧张,需要提前预定,请为该系统进行数据库建模。要求如下:
    • 需提前预订会议室,不可预定两周之后的会议室
    • 每个会议室可容纳的人数及设备(投影、多媒体等)均可能不一致
    • 可以查阅每个会议室的预定状况
    • 思考:如何可以提高会议室的使用效率

中度(针对有36年工作经验者)

  • 产品/套系各类目对于结构化信息的要求不一致。如婚纱摄影需要描述服装、场景、拍摄、摄影师等信息;婚庆公司需要描述布置、道具、司仪、摄像等信息,幼儿教育则需要描述课程、老师等信息。如何解决这个问题?

困难(针对6年以上经验者)

  • 请设计一个公交换乘系统,要求如下:
    • 可以实现“较快捷”,“少换乘”,“少步行”等类型的换乘方案
    • 每次输出不超过3个的备选最优方案
    • 要求系统的响应速度快,并发量高
    • 可根据需要增加难度或减少难度
    o 如:轨道交通间的换乘不算换乘等
  • 新美大的业务按照行业分为美食、结婚、亲子、家装等,这些业务是由不同的团队开发。这样就存在多个团队开发一个相同的业务,如商户页。各行业商户页上,有些功能是相同的,有些则不同。如各业务独立开发,则有些功能需要开发多次,优点是团队间的耦合性好;各行业共同维护一套,则互相之间的依赖太高。如何解决这个问题?

排错能力

碰到过什么的问题以及如何解决,举例子说明,开放式问题,主要根据应聘者的回答来判断对方的经验,从问题现象到具体排错手段的思维过程。

基础

某种条件下能稳定重现的问题;解决方法从日志堆栈上能直接看出来的问题,

中等

不能稳定重现的问题,一般和多线程相关;解决方法可以是通过code review和压测验证,调整代码来增加多线程复现的概率;懂得利用jvm相关工具分析线程堆栈,内存主要使用情况,死锁等;懂得查看宿主机的情况(cpu, 磁盘,内存,网络io等),能够结合现象说明一定的排错逻辑(不一定非常强,很多时候会猜测);事后能提出一些有效的防范措施

困难

不能稳定重现的问题;除了"一般"的回答,还有运维知识,思路上能够非常清晰的分析出可能的几种情况并能按照可能性排序.对计算机系统非常熟悉,明白进程线程切换调度的成本,内存不足的表现,网络通信原理等并能将分析推测落地到这些基础知识和业务情况(不是凭空乱猜);熟悉nginx,tomcat,memcached等组件的工作原理,参数配置等;事后能从多维度预防,监控等;

工具使用

主要考察点面试者在日常开发时的必备工具,考察其工具的知识广度、实际掌握深度、对工具活学活用与自主创新的能力等

简单

你用过或知道哪些开发工具?比如:
IDE:eclipse,intellij idea
package:gradle,maven,ant
linux:grep,awk,sed,vmstat,iostat
java:jstack,jmap,jprofiler
network:tcpdump,wireshark
web:fiddler(Charles),chrome inspector
editor:vim/emacs
scm: git, github

======================================================

中等

开放性问题,面试者通过以上这些工具在日常开发中有效地解决过什么问题?

困难

开放性问题

  • 有没有自己研发过工具?工具解决的是一个什么问题?
  • 现有的工具为何解决不了此问题?工具的价值如何衡量?工具实现的难点在哪里?
  • 如何推广自己的工具?
  • 自己的工具还有什么改进点?

产品&项目能力

考察own过的项目或业务。

  • 项目规模大小
  • 业务复杂度
  • 遇到的挑战
  • 解决问题的思路是否开阔
  • 项目的拆解是否合理清晰,有无明确是时间点
  • 监控&风险控制是否完善,项目指标如何量化衡量
  • 有限资源下,业务压力和技术的平衡

学习能力

开放性问题,主要考察面试者的学习主动性,属于加分项。比如

  • 最近看过哪些技术相关的书
  • 掌握多种开发语言、js?ruby?python?等等
  • github有没有开源项目
  • 有没有做过提高效率的工具等

潜力兴趣度

开放了解其本身对技术的热情,可以结合上面的学习能力进行提问了解。

沟通表达能力

考察关键点:需要区分和啰嗦的差别

  • 描述清楚项目的背景和功能点
  • 描述清楚整体方案
  • 描述清楚具体模块or关键功能的细节
  • 其他

理解能力

暂时没有想好。。。

  • 提问的时候对方有无认真听讲,
  • 提题的问题有无正确理解
  • 有无正面回答问题
  • 其他…

1、链表有没有环,入环点
2、servlet
3、HashMap

4、ConcurrentHashMap

5、线程池:不ok

1、开始理解错误,经过引导得到对的逻辑,但是代码风格混乱,同时有错误,指出后改正。

2、不ok

3、JDK1.7 OK

4、JDK1.7知道加了锁,但是不知道如何加的锁,不知道锁原理 不ok

5、不ok

  1.  TreeSet数据结构
  2. 红黑树的特点
  3. TreeSet和TreeMap 的关系:
  1.  volatile 关键字含义 ?
  2. atomic类型变量
  3. CyclicBarrier 和 CountDownLatch的区别
  4. threadLocal 原理
  5. java线程池中的各个参数的意义?
  6.  java垃圾回收,为啥新生代要用复制算法,老年代用标记-整理算法?
  7. mysql索引的数据结构 ?
  8. mysql 联合索引的最左前置索引
  9. 查询cup负载用什么命令 load average 的含义 ?
  10. 查询日志 tail cat tac grep   命令
  11. tar命令 打成 tar.gz -zcvf
  12. grep ok
  13. top 不ok
  14. netstat 知道这个命令 没怎么用过,一般
  15. tail ok
  16. 红黑树是二叉树 不ok
  17. mysql知道索引是B+树,不知道为啥用B+树
  18. HashMap JDK1.6,1.7OK, 1.8知道用红黑树,但是不知道红黑树的原理
  19. 知道核心参数有哪些,但是不知道workQueue和拒绝策略的用法
  20. 链表是否有环,入环点 ,引导之后ok
  21.  查询CPU负载彪高的问题
  22. 查询一个50G访问日志文件 前100个出现最多的IP
  23. 技术深度和广度 kafka、rabbitMQ、ActiveMQ 相关

ps ok

grep ok

jstat  没用过

jstack 用过,不记得内容了

线程池 用过Spring的,java原生的不ok

红黑树 不ok

Servlet ok

JVM 

java内存模型OK

线上CPU彪高问题查询—no

java虚拟机 调整参数----no

java虚拟机 cms垃圾回收期—no

java多线程相关----忘记差不多了

常用linux命令—ok

mysql索引的数据结构----no

1、servlet

2、线程池 

3、JVM

1、ok

2、候选人不记得线程池细节。但是自己可以设计出线程池的工作模型 ok

3、jstat、jstack、jmap ok

Java内存模型 一般了解的不透彻

1.架构师,不想做管理

什么是架构:整理业务需求,资源系统整体设计。定技术指标。稳定性。可拓展性。具体问题处理,总揽全局,需求转化实现,设计能力,设计预拓展,稳定性,持续重构改建。

2. 知道top,不知道怎么算出load

3.不ok,画出了堆和栈。写出了堆的年轻代老年代,知道年轻代用复制算法。但不知道为什么使用

4. 不ok,不知道红黑树

5.知道数据库用的B+树,知道B+树是什么树,但是不知道树的左旋右旋

6. ThreadLocal 不ok

整体技术深度与技术规划不匹配。基础较差。

Java线程池

ThreadLocal

volatile

redis

红黑树

HashMap

TreeMap

ok

ok

ok

主备模型,主从模型OK

不知道红黑树原理,知道是平衡二叉树的一种,知道树的旋转,一般

知道JDK1.7是桶 + 链表。 JDK1.8桶+红黑树,但是不知道红黑树,一般

不ok

管理经验:没有

CUP彪高的线上问题;没有相关经验
load avg 的含义:说不出来


线上 OOM的问题解决:没有相关经验

服务器内存缓存用过什么,注意什么?回答一般


JVM的调优:没有实践过
jvm 老年代 垃圾回收器CMS 的配对回收器是什么


CountDownLatch 解决什么问题的?了解程度

用过什么消息队列
kafka 了解还可以,用过


hadoop系列 没有使用过

linux 命令 free du
查询日志中的关键字的上下10行 不知道 但是用过grep
打包命令 ok

大抽奖系统设计:抓不住重点,模块划分不清晰

1.Redis

2.SpringMVC

3.RabbitMQ

4.Dubbo

5.zookeeper

1.主从同步ok。一致性哈希不ok

2.Servlet生命周期ok。执行过程ok。细节不ok。 

3.使用OK,设计延迟队列有思路ok

4. 不ok,RPC和SOA概念不清晰

5. 不ok

1.zookeeper选举模式

2.Kafka工作模型

3.AMQP协议

4.延迟队列

5.Servlet生命周期

6.SpringMVC 

1.不ok

2.ok

3.不ok

4.有思路,没有得到可行性方案,一般 

5. ok

6.知道执行过程,但是不知道细节,一般

TreeMap的数据结构 no

TreeSet的数据结构 no

红黑树:no

HaseSet的数据结构:no

System.gc()干什么用的? no

volatile 变量和 atomic 变量有什么不同? no

java atomic实现原理 ok


CyclicBarrier 和 CountDownLatch 都可以用来让一组线程等待其它线程。no

java线程池中的各个参数的意义 no


java虚拟机复制算法:说不清楚

cpu彪高的问题:说不清楚

jmap:说不清楚
jstack:说不清楚

top 命令 load avg :说不清楚

OOM的问题 :说不清楚

grep 命令 ok

tail 命令 ok

在一个目录下,删除10G以上的文件 no

清除一个大文件;ok


数据库的索引是什么数据结构?no

1.zookeeper选举模式

2.RocketMQ

3.AMQP协议

4.延迟队列

5.SpringMVC 

6.线程池 

7.ThreadLocal 

1.不ok

2.可以描述P2P模式,不知道广播模式,一般

3.不ok

4.有思路,没有得到可行结果,一般 

5.ok

6.ok 

7.不ok

1.grep 不ok,cat 不ok,find 不ok

2.Mysql索引 最左匹配不ok,索引结构不ok

3.线程池不ok,ThreadLocal 不ok

4.不ok

5.不ok

1.线程池

2.ThreadLocal 

3.kafka 

4.红黑树 

1.不ok

2.不ok 

3.kafka消费者模型不ok 

4.红黑树不ok,平衡二叉树不ok,树旋转ok 

1.基础数据结构;

2.线程安全并发数据集合相关

3.jvm结构和调优

4.垃圾回收算法

5.设计模式

6.中间件:Dubbo

7.mysql

1.ok

2.不ok;

3.了解基本概念,不能系统表达;不知道内部结构;无法写出栈溢出示例;一般

4.不ok;

5.知道概念,但是无法写出或描述线程安全的单例需要的注意点,不ok

6.能够使用;但是不知道各个模块的职责和架构特点;但是正在准备转型。一般

7.对于索引使用规则不是很清晰,不ok

git reset 和rebase的区别 no

top 命令 不知道
free 命令 不知道
在一个目录下删除 1个G 的日志 不知道

grep命令 不了解

系统监控日志 不了解

full GC 不了解
jvm 不了解

mysql索引是什么数据结构?

mysql联合索引的最左前置规则?


kafka:topic group partition
底层机制不是很了解

1.ok

2.volatile了解大概机制,concurrenthashmap了解多段锁,但没有实际使用经验;

3.只知道最大线程数和最小线程数,其它不了解,更不用说队列缓冲这些东西了,而且基本没用过

4.会用tail,top,netstat命令,但查询历史中特定数据,不知道使用grep;

5.知道gc基本概念,但没有实际经验,没用过mat等工具,jstack仅会查看线程是否存在,不太了解线程状态;

不了解64位机器压缩指针的概念;

1.ok

2.volatile了解大概机制,concurrenthashmap了解多段锁,了解size函数的优化;

3.了解线程池相关配置参数,有使用经验,了解无界队列的问题。

4.会用top,lsof,netstat命令,会用shell脚本,会查看

5.知道gc基本概念,了解相关参数,新生代,老年代分配,

有相关使用经验jstat,jmap,jps,jstack,mat,

了解jstack 和top命令,但无法串联起来,不知道jstack的线程id需要转换。

OOM,jmap观察对象持续增长,联想到hibernate缓存,未调用session.clear(),导致session未释放。

6.了解innodb和myisam的索引数据结构实现,了解联合索引,并会应用。

 线上CPU彪高问题-代码定位

2 java线程池

3 system.gc() 是否会立即执行,为什么?

4设计模式 都用过哪些?

5 老年带 CMS垃圾回收器

6 tar 相关命令

2.volatile了解用法,concurrenthashmap了解多段锁,size函数实现,sleep和wait的区别不了解,;

3.线程池参数配置了解大概,但不够深入,了解锁的实现方式和用法。

4.会用grep命令,vi打开1G文件,ps查找进程负载,top不了解,不知道怎么看进程的子线程问题。

5.知道gc基本概念,线上服务器只有2g,知道大概的分配原理,不知道如何查看某个class加载自哪个jar包。

6.知道联合索引,了解应用原理。

2.volatile不了解用法,threadlocal不太了解,synchronized关键字加在普通方法和static方法的区别不确定;

3.线程池参数配置不了解。

4.会用grep命令,会使用lsof查看端口占用,大文件使用more或less查看,top了解,知道怎么看进程的子线程负载。

5.知道gc基本概念。

6.知道联合索引,会使用explain查看计划,不了解innodb底层数据结构。

7.了解spring的aop实现方式

2.volatile了解用法,concurrenthashmap了解多段锁,size函数实现,sleep和wait的区别不了解,;

3.线程池参数配置了解,但不够深入,不了解synchronized关键字在static方法上和普通方法上有什么区别。

4.会用grep命令,ps查找进程负载,top不了解,不知道怎么看进程的子线程问题。

5.知道gc基本概念,线上配置过hbase的jvm参数,但是对内存分配规则不太了解。

6.知道联合索引,了解应用原理,了解innodb的存储结构。

2.volatile了解用法,不了解原理,StringBuilder和StringBuffer的区别了解:synchronized和lock:知道释放,synchronized知道加在static方法和非static方法上的区别;

concurrenthashmap知道有多段锁,不了解实现细节,不了解size函数的实现和优化;

3.用过线程池,了解配置参数用法;但没深究过线程池的源代码。

4.会用grep,但是不会用管道符,top仅知道命令。

cpu飙高线程定位:top,jstack;照网上文章来做,记不太清楚了

jdk命令:不太了解;

5.知道堆的基本概念。

6.了解联合索引概念,不会灵活应用,不了解存储引擎数据结构。

2.volatile了解用法,concurrenthashmap了解多段锁,但是对于锁机制和synchronize没有深入区别。不ok

3.线程池参数配置了解,自己实现有思路.ok

4.会用grep命令,ps查找进程负载,load负载高的问题有基本思路,一般。

5.知道gc基本概念,线上配置过hbase的jvm参数,但是对垃圾回收算法内部实现,gc可达性分析原理,内存分配,无法清晰表达。不ok

6.知道基本优化方式,但是不深入,没有做过优化。不ok

7.听说过,没有用过。不ok

受限于工作年限和公司技术场景;多线程,分布式中间件,MySQL等互联网主流技术和工具都不擅长。

1.不ok,hashmap如何解决冲突不ok。

2.volatile不了解,synchronized不了解加在static和非static方法上的区别,

concurrenthashmap知道多个segement,但不知道有锁。

stringbuilder和stringbuffer的区别搞反了。

使用过countdownlatch的用法。

3.线程池参数配置不ok。

4.会用grep命令,会写shell脚本,会用top命令,查找cpu飙高的线程不ok。

oom内存溢出诊断思路不ok,jstack和jmap命令不了解。

5.两种持久化方式ok,pipeline方式导入数据导致redis线程阻塞问题不了解。

6.mysql的存储引擎数据结构不ok,联合索引知道简单用法,不会灵活应用。

7.了解jvm概念,仅会调整堆大小,

1.无法说出hashmap和concurrentHashMap的底层实现,不ok

2.不ok;

3.了解基本概念,不知道内部结构;无法写出堆和栈溢出示例;不ok

4.知道概念,底层原理不清晰不ok;

5.知道概念,但是无法写单例,有些设计模式理解错误,不ok

6.用过;但是不知道各个模块的职责和架构特点。不ok

7.对于索引使用规则不是很清晰,不ok

1线上解决问题的能力(top命令,看每个cpu的负载,load avg的含义,jstack使用,日志定位)

2 各种linux的操作,查看网路,找10G以上的日志并删除,打包命令

3 jvm相关 各种回收算法,cms配对回收算法

1.ok,hashmap如何解决冲突ok。

2.volatile不ok,synchronized加在static和非static方法上的区别不ok,stringbuffer和stringbuilder区别ok,concurrenthashmap了解多段锁,size函数优化不ok。

3.线程池参数配置不ok。

4.文本查找关键字ok,netstat不ok,查找cpu飙高的线程不ok,oom没遇到过。

5.mysql存储引擎数据结构不ok,联合索引原理不ok,其它mysql命令不了解。

6.堆的划分ok

7.模块设计能力不足,目前互联网工作中仅涉及到报表模块设计,功能比较简单。

1.ok,hashmap如何解决冲突ok。

2.synchronized了解加在static和非static方法上的区别,concurrenthashmap了解,size函数细节不ok。

3.线程池参数配置ok。

4.文本查找关键字ok,会用top命令,会用netstat,查找cpu飙高的线程ok。

5.mysql存储引擎数据结构ok,联合索引原理ok,查schema相关表解决死锁问题,其它mysql命令了解explain,profile。

6.堆的划分ok

1.ok,hashmap如何解决冲突ok。

2.volatile不ok,synchronized加在static和非static方法上的区别ok,stringbuffer和stringbuilder区别不ok,concurrenthashmap了解,size函数优化不ok。

3.线程池参数配置不ok。

4.文本查找关键字ok,会用top命令,查找cpu飙高的线程不ok,oom问题不ok。

5.不ok。

6.堆的划分ok,32位和64位的jvm实现区别不ok。

1.ok,hashmap如何解决冲突ok。

2.volatile用法ok,synchronized加在static和非static方法上的区别不ok,wait和sleep方法的区别,stringbuffer和stringbuilder区别ok,concurrenthashmap了解1.7和1.8的区别,size函数优化不ok。

3.线程池参数配置不ok。

4.文本查找关键字ok,查找端口占用不ok,查找cpu飙高的线程不ok,oom问题不ok。

5.不ok。

6.堆的划分ok,32位和64位的jvm区别不ok。

7.数据存储引擎数据结构不ok,

8.原理不ok

1.ok,hashmap如何解决冲突ok。

2.volatile不ok,synchronized加在static和非static方法上的区别ok,stringbuffer和stringbuilder区别ok,concurrenthashmap不ok,但是,知道1.8中解决冲突时使用红黑树优化。

3.线程池参数配置ok。

4.文本查找关键字ok,会用top命令,查找cpu飙高的线程不ok,oom问题ok。

5.堆的划分ok,32位和64位的jvm实现区别ok,实际配置经验较少。

6.mysql的存储引擎数据结构不ok,联合索引ok,explain有了解,缺乏实战经验。

1 ok;

2 一般,top命令深度了解一般

grep 命令,用过,但是好多参数忘了

tar 打包命令,ok

找到一个目录下的大于10G的文件并删除,no

3 对设计模式有了解,并且在编码中有用到

4 了解,并且知道优缺点

1.ok,hashmap如何解决冲突ok。

2.volatile不ok,synchronized加在static和非static方法上的区别ok,stringbuffer和stringbuilder区别ok,simpledateformate不了解是线程安全的,concurrenthashmap了解分段锁,不了解size方法的优化。

3.线程池参数配置不ok。

4.文本查找关键字不ok,会用top命令,查找cpu飙高的线程不ok,oom问题ok。

5.堆的划分ok,32位和64位的jvm实现区别ok,实际配置经验较少。

6.mysql的存储引擎数据结构不ok,explain有了解,也使用过。

1.ok

2.synchronized和lock知道,有使用countdownlatch,concurrentHashMap内部结构和原理。但是线程安全相关数据结构不清晰,不ok。

3.内部数据结构都比较了解,ok

4.知道基本使用的命令,查看线程命令不知道,查找cpu线程飙高不ok;

5.mysql存储引擎数据结构不ok;

6.能大体说出内部结构,了解垃圾回收算法原理;没有线上调优经验。一般

7.知道单例,工厂,模版,其他能大致说清楚使用场景。单例模式双重检查方法的缺点不了解,一般。

8.了解大体架构原理ok。

jvm深度理解 cms垃圾回收期算法,以及为啥要搭配SerialOld回收器,原因是什么

1.ok

2.了解grep命令,查询端口被谁占用ok,查找cpu飙高不ok,但知道jstack,jmap等命令。

3.存储引擎的数据结构知道是btree结构,但是为什么这么设计不了解,有explain的实际使用经验,联合查询不ok

4.了解节点类型,了解用途,优缺点不了解,没有实际使用经验。

5.jvm了解大体架构,知道年轻代,年老代,没有实际调优经历。

6.ok

7.但是对mybatis的插件机制等不是很清楚,候选人回复说代码有些时间长了,准备不够充分;

1.ok

2.volatile会锁住对象,不ok,concurrentHashMap了解分段锁,不了解size的优化,

3.了解grep命令,查询端口被谁占用不ok,查找cpu飙高不ok,查找内存溢出问题ok,

4.存储引擎的数据结构知道是tree结构,具体哪种不知道, 有explain的实际使用经验,

6.了解节点类型,了解分布式锁的一种实现,优缺点不了解,没有实际使用经验。

7.jvm了解大体架构,知道年轻代,年老代,没有实际调优经历。

8.memcache内存分配方式不ok,redis的pipeline方式没听说过。

soa相关概念不了解,基础比较差,线上问题处理比较少。

1.不ok,hashmap如何解决冲突,treemap数据结构不了解。

2.了解vi,但不了解grep命令,查询端口被谁占用ok,jdk相关命令不怎么用。

3.mysql的存储引擎有哪些不了解,SHOW PROCESSLIST有用过,索引优化没有经验。

4.jvm了解大体架构,没有实际调优经验。

6.redis的pipeline方式没听说过。

7.zookeeper节点类型了解,了解分布式锁实现,了解惊群现象,但不知道解决,kafka不了解partition概念。

8.maven查找jar包冲突不了解。

扩容方案依赖redis的从节点,redis-cluster方案不了解

synchronized关键字加在static方法和非static方法的区别不ok。

stringbuilder和stringbuffer区别ok。

redis-cluster和mongdb仅停留在会使用api,相关架构不太了解。

mysql存储引擎,了解b+树结构,但是为什么这么设计和相关细节不了解。

1.ok,了解hashmap如何解决冲突,了解resize导致的cpu飙高问题。

2.volatile ok,synchronized使用monitorenter和monitorexit指令,lock可重入锁,知道AQS,其它就不清楚了。

3.线程池参数配置ok。

4.了解top,了解如何定位线程异常导致cpu飙高问题,用过mat。

5.堆的划分ok。

6.mysql的存储引擎数据结构,myisam使用b树,不ok,innodb使用b+树,了解聚簇索引和非聚簇索引的区别,联合索引了解概念,

7.使用乐观锁解决并发问题。

1.不ok

2.不清楚线程安全;不OK

3.不清楚索引数据结构;不OK

4. 无法写出OOM的程序;不OK

1.ok,

了解hashmap的扩容时,并发环境cpu飙高,

了解concurrentMap的原理,size函数优化讲的不对,

treemap内部实现不ok。

2.不清楚线程安全;不OK

3.mysql存储引擎,innodb存储结构b树,聚簇索引,存储每行数据,
为什么用b树,因为有序,不ok;

myisam存储结构不ok;

4. 了解jvm基本概念和参数,细节不ok,没有实际经验。

5.了解top,了解jstack,了解cpu飙高的问题解决思路,听过相关的分享,没有遇到过oom相关的问题。

公司内部soa原理了解,负载均衡策略了解,了解数据压缩。

服务升降级不了解。

5.redis的cluster优缺点不ok。

7.zookeeper知道监听机制,节点类型不ok。

spring aop的实现方式ok,动态代理,cglib。

3.mysql存储引擎,数据存储结构不ok;

了解联合索引,注意事项,常用检索频率,不ok。

4.jvm了解cms原理,可达性了解,。

5.线上日志查找使用awk,

端口占用netstat,ok;

机器负载top,ok,单核负载不ok,所有线程负载不ok;

了解jstack和jmap命令。

6.kafka原理ok,了解分区概念,有使用经验。

7.spark原理ok,有使用经验。

2.string与object equal区别

1.hashmap数据结构能清楚说出,不知道扩容机制;不OK

2. 没有看过;不OK

3.只用过FixedThreadPool,优缺点不知道;不OK

4.可以用自己的话说清楚;多线程顺序问题只知道用join;不OK

5.volatile原理不知道,threadLocal没用过;不OK

6.能清楚说出3者的区别;OK

7.内存结构可以说清楚;GC不知道;OOM说不清楚;不OK

8.知道使用TOP、jstack等查看处理;OK

9.只知道单例、工厂、代理;不OK

10.HTTP method只知道get、post、put,put实际没用过;不OK
知道HTTP是网络协议及UDP,TCP是网络协议;Ok
TCP请求响应握手机制;OK 
HTTP status,只知道200 400 500; 不OK 

11.数据库隔离机制不知道;不OK
知道如何设置慢SQL,但不知道更深层的进行排查;不OK
不知道MVCC ;不OK
 12.spring事务不知道,实际项目中没有用到;不OK

Java:

1)阅读过常用JDK类的源代码,了解实现逻辑;

2)对常用第三方类库非常熟悉;

3)能够自主调研、学习并应用第三方类库、插件等;

4)能及时跟进新版JAVA特性。

1.知道hashMap的数据结构,解决冲突:ok

2.jdk线程池:线程队列,线程个数;基本ok;

concurrentHashMap:分段segment锁,ok;

spring aop:两种实现方式ok。

4.联合索引基本ok;索引存储结构不ok;分库分表:使用阿里云

5.基础命令了解,linux cpu线程飙高不ok,oom溢出不ok;

日志导出ok;一般

6.soa原理ok,被谁调用,其它机制不太了解,拦截器不了解

7.使用redis实现:setnotExist + expire,基本ok

TreeMap的数据结构 TreeSet的数据结构 不清楚;
红黑树是专门解决什么问题;答不上来

CMS垃圾回收器的深度理解:回答不上来

持久带是否会发生fullgc?会,为什么,答不上来

MySQL InnoDB默认的事务隔离级别是什么?

忘记了

MySQL索引默认实现是用的什么数据结构,为什么采用这种?  记不清了

如何解决线上 环境的CPU彪高的问题?如何定位到具体的代码 ?

不怎么好,但是有思路

linux 基础命令:一般

maven release SNAPSHOT的区别 回答错误
mvn命令看依赖树 mvn dependency tree 忘记了

git命令
reset rebase的区别 no

kafka 没有用过


es 和别人一起用过,但是属于使用范畴,深度理解不ok


 

大转盘抽奖设计:可以写出关键算法,模块划分合理;

字符串转成数字编写代码:OK,虽然性能不好,但是没有错误;

HashMap的数据结构 HaseSet的数据结构? 不清楚
TreeMap的数据结构 TreeSet的数据结构 红黑树;
红黑树是专门解决什么问题;不清楚

java 虚拟机的深度理解:

cms垃圾回收器过程、容易出现的问题,虚拟机内存模型,jvm调优:

回答一般,对java虚拟机了解不是很深入

mysql:索引诗句结构,知道,但是不知道为啥用B+数

InnoDB默认的事务隔离级别是什么?清楚

如何解决线上 环境的CPU彪高的问题,如何定位到具体的代码  不怎么好,之前做过此类操作;

linux基础命令:ok

maven release SNAPSHOT的区别 no
mvn命令看依赖树 mvn dependency tree 没有用过该命令

reset rebase的区别   回答不上来

kafka 没有用过


es 用过 是否支持横向扩展 ok

监控系统使用:zabbix

基本情况:

1. 个人介绍及项目介绍(考察沟通能力)

2. 在在乐视网及十五所负责的项目/业务情况(考察业务需求把握能力)

3. 负责项目的技术架构图(考察技术架构把握情况)

4. 团队情况和直接管理人员情况,任务开发分配情况(考察基本项目管理技能)

5. 具体技术细节提问(考察技术深度)

a)redis 基本数据结构,cluster原理,持久化原理,原子操作原理.

b)ws 聊天室稳定性,弱网环境下的处理,踩过的坑?

c)dubbo架构,服务治理的管理,对接使用问题。

d). git : rebase/merge 区别,团队使用注意点,stash 用法

6. 工作中出彩的地方和困难介绍(考察项目实战能力)

7. 大数据开发经验?

8. 职业规划和长短板

  1. 答:能清晰介绍个人工作内容,工作经历,项目情况,沟通能力OK
  2. 答:对工作内容介绍清晰,对所负责的业务实现的功能以及业务诉求把握清晰,业务把握OK
  3. 答:对技术架构把握OK ,画架构图比较清晰,追问:SLB 后面挂nginx再后面是web server,原因是什么,答,主要是方便增减web server节点和转换请求路径,回答基本ok,但是感觉可能公司基础框架原因对此架构更深了解稍有缺失。
  4. 答:团队7人,直接管理2-3人,一个前端,一个后端,开发模式是迭代式,印象:有一定的项目管理能力,在乐视没有带过大团队,在十五所带7人,类似外包开发模式,工作内容较杂。
  5. 答:
    • redis 的数据结构熟悉,cluster了解不够深入,持久化方式了解,采用jredis对接,对redis操作原子性了解一般。
    • ws 使用 netty框架,稳定性为深入了解,不能出具数据支持观点,弱网环境下问题考虑较少,采用redis订阅分发实现 聊天信息的分发,印象对架构和使用方面的问题深入思索较少。
    • 架构了解,知道集群及服务治理的概念,深入了解不足,局限在使用层面。
    • 使用merge ,使用rebase 无,不了解stash。
  6. 答:后台CPU/内存飙高的问题分析和解决,分析说明比较透彻
    前端页面崩溃问题:聊天室点赞功能引发,分析相对透彻。
  7. 介绍 交管局项目,使用大数据发现套牌车,业务理解透彻,大数据技能及组件介绍含糊(可认为基本无深入使用经验)
  8. 职业规划长短板: 技术-》架构发展路径,短板:组件的深入了解不够,做业务较多。
  9.  
  10. 聚集索引和非聚集索引有什么差别;不ok

  11. 2.jdk线程池原理和实现,参数了解ok,执行过程ok;

执行完后的回收机制不ok:

  1.  

8.spring aop的实现原理,jdk动态代理和cglib实现

spring实现

9.mybatis插件机制不了解。

一级缓存和二级缓存的区别ok;

2.jdk线程池原理和实现,只用过,原理不知道;不OK

lock和synchronized的用法区别ok,实现原理不OK;

volatile保证内存可见性,不保证原子性;OK

 线程概念:OK;sleep、wait区别 : 不OK

 ThreadLocal:不清楚,没用过;不OK

3.String、StringBuffer、StringBuilder,区别原理;OK

 泛型生命周期:不了解;不OK

6.mysql引擎: 说不出名字,原理知道 2种;不OK
 慢查询:不知道;不OK;
 排查是否走索引:知道用explain,但具体内容不清楚;不OK
 索引可用情况:不确定;不OK
 隔离机制:OK
B+树,细节不了解;不OK

7.简单命令:scp,telnet,netstat,top,jump;OK
 查看使用日志grep;OK
 查看cpu负载;OK
 查某个线程导致cpu飙高,引导下可以说出;OK

8.知道method几种类型:实际中只用过post,get;不OK
 restful没用过,不知道;不OK

6.查看使用日志awk;OK

了解top命令,每个核负载不ok,子线程负载不ok;

1.

  • String StringBuffer StringBuilder 区别OK, 具体原理不OK
  • hashMap的数据结构:原理能说清,key冲突知道如何解决的,新的值不知道放在链表的哪个位置
  • concurrenthashmap:与HASHMAP区别OK,性能解释OK,自己模拟不出安全代码。
  • equal与hashcode 区别OK,String类的equal与hashcode不知道,不OK
  • 树结构不知道;不OK

2.

  • 线程状态:能说出状态,具体对应不上; 不OK
  • 线程等待:能说出countdown join group 等 OK
  • sleep、wait区别 : 基本能说清;OK
  • 死锁:生产者 消息者 模式 不太了解 不OK
  • 实现线程安全:形式:
    • sync : 原理OK;
    • lock :了解不多 不OK
    • volatile:可见、原子性;OK
    • threadLocal:知道内部实现是MAP,但不知道KEY是什么 不OK
    • atomic:无锁原理:OK
  • 线程池:Fix, cache,区别OK,自己实现不了,原理不知道 不OK

3.

  • IOC:概念OK,默认:单例 可以多例 OK
  • AOP: 代理:JDK(invacationHandle) cglib(反射) OK

String、StringBuffer、StringBuilder,区别原理;OK
 spring事务隔离级别:能明确说出;OK
 IOC:OK;AOP:能说出实现原理及动态代理2种方式;OK

4.

  • 大体结构OK
  • 回收机制:不太清楚什么样的对象可以回收;不OK

5.

  • 单例:饿、懒、枚举 静态内部类,OK
  • 工厂:概念OK,类图OK
  • 策略:没用过;不OK
  • 状态:没用过;不OK

6.

  • 引擎:innodb支持事务B+tree\mysam不支持事务 基本OK tree不OK
  • 隔离机制:4种概念OK,幻读、不可重复读 弄不清楚
  • 索引:是否走索引:explain 列含意:基本说出 OK
  • 联合索引顺序:OK
  • 加索引规则:基本OK
  • redis:只用过,没有深入研究

7.

  • 只用过简单命令:ssh cat tail ps top grep 

CMS的过程中会产生2个最让人头痛的问题:
promotion failed
concurrent mode failure

能说明出现问题的原因,以及JVM如何处理 ok

MySQL联合索引使用是有什么规则?如果对A,B,C做索引,那么SQL语句写成where C=X and B=X and A=X,是否还能用到该索引?如果SQL语句写成where A=X and B>X and C=X是否还能用到该索引? ok

如何解决线上 环境的CPU彪高的问题,如何定位到具体的代码 ?是有思路,但是没有实际操作过 回答一般

grep 命令相关 ok

maven release SNAPSHOT的区别 yes
mvn命令看依赖树 mvn dependency tree yes
mvn clean install -U -Dmaven.test.skip=true 不编译测试版本 有点忘记了,但是有印象

git命令
reset rebase的区别 没用过rebase

kafka 用过
kafka的相关概念及用法 ok

  1. 答: 能清晰介绍个人工作内容,项目情况,较清晰的介绍项目的架构情况,沟通能力OK
  2. 答: 能较清晰的对数据流程业务流程做相关阐述,项目1人负责,问及实时监控和准实时监控,准实时监控理解清晰,实时监控阐述一般。
  3. 答,支付对接情况了解清楚,支付平台对内系统的对接流程阐述一般。
  4. 主要开发人员,负责部分支付通道的对接开发,同内部对接主要通过IM 群解决。
  5. 支付宝对接中存在异步回调的情况,回调校验可能出错,但是最终是成功的,造成延迟,通过任务循环方式解决
  6. 使用 IDEA集成的git 环境,命令行很少用,主要用merge,rebase 没用过,不清楚两种方式对团队使用造成的影响,及注意要点,stash 未使用过。
  • AOP: 动态代理,用的少;CGLIB与jdk区别:不清楚;不OK

2.

  • 分段锁, 了解,无法说出全局size的保证。一般
  • Lock与synchronized:了解区别, 一般
    countDownLatch: 不OK;
  • 死锁:无法说出死锁依赖条件。不OK

能说出策略模式和单例模式注意点。OK

jvm CMS垃圾回收器的 垃圾回收过程:no

cpu彪高----》线上问题解决
有思路,在去哪的时候有过相关问题解决;

top load average 三个值的含义 no

grep 命令各种线上日志查询 ok


maven release SNAPSHOT的区别 no

git命令
reset rebase的区别 no

kafka
相关概念–不熟悉

mySql 索引的数据结构 B+数 为啥? 回答错误
红黑树数据结构:no


mySql联合索引的最左前置规则 OK


分库分表经验-易购索引的注意事项:NO

分布式系统最终一致性 ---容错处理 YES

“123456” 字符串转数字 基础不牢固,没有写出

了解Redis基本使用,但是不知道sortSet传参数。不OK

2.

  • concurrenthashMap,分段锁, 了解size方法的优化
  • volatile了解用法和原理,不保证原子性
  • Lock与synchronized区别:基本用法的区别ok。

知道偏向锁,轻量级锁,重量级锁区别,但是说成lock的实现了

  1. 答: 个人介绍清晰,沟通顺畅
  2. 答: app开发的后端.,技术团队10人,3个后台,2android 1 ,ios 1 人,前端1人, 个人处于开发人员角色。
  3. 答: 能简单介绍开发流程,具体流程中自己的定位不是太清晰
  4. 答:redis 缓存改造,缓存学院的课程数据,缓存学员本节课程内容和LOGO 内容,追问:量化效果如何,回答:没有具体数据统计
  5. 答:数据结构介绍清晰,事务操作方式不太了解,持久化方式知道RDB, aof。
  6. 答: 不了解
  7. 答:没用过
  8. 答:介绍清晰,对于H5页面采用cdn 方式进行加速,nginx静态化大部分内容,回答清晰。
  9. 答:springMVC框架了解,过滤器会用,详细技术细节回答模糊,问及分布式情况下对登录和权限控制方面需要考虑的内容,回答一般
  10. 答:知道rebase/merge的命令含义,单对具体使用的区别回答一般
  11. 答:使用eclipse jpbm设计器进行流程开发,对应节点驱动流程,问及并签的处理方式,及回退流程,回答一般,从设计上可以实现,但是不能预见到工作流回退时涉及到的问题
  12. 答: 目前比较闲,工作内容不饱满
  13. 答: 做了不少前端的工作,个人期望在后端方面发展
  14. 答:期望较长时间进行技术开发工作。

1.集合类源码都看过,OK

  • 树结构基本OK

2.

  • synchronized和Lock区别,可以说清楚,OK
  • 多线程使用场景都比较清晰,OK
  • 死锁:概念:OK,产生原因:OK,  
  • 信号量,countDownLatch:知道使用场景,OK
  • 线程池:Fix, cache,区别OK,自己实现有思路。一般

3.

  • IOC:概念OK,默认:单例 可以多例 OK
  • AOP: 事物控制,知道切面,动态代理方式,OK

4.

  • JVM结构清晰:OK
  • 回收机制,不同代使用不同回收算法:OK

5.

  • 单例:OK
  • 命令模式:OK

6.

  • MySQL最大数据量:300W
  • 优化思路:
    • 执行计划,sql 优化
    • 分库分表
  • 知道索引数据结构,能说出B+ 树内部结构:OK

持久带是否发生fullGC 回答 ok
 

cms回收器的标记过程
回答: yes

cms 垃圾回收期的高阶----没打上来
CMS并行GC是大多数应用的最佳选择,然而, CMS并不是完美的,在使用CMS的过程中会产生2个最让人头痛的问题:
promotion failed
concurrent mode failure

cpu彪高----》线上问题解决
有思路,没有解决过,经提示可以回答出

grep 命令各种线上日志查询  yes

maven release  SNAPSHOT的区别  ok

git命令
reset rebase的区别 no

kafka—没用过

mySql 索引的数据结构 B+数 yes
为什么?ok


mySql联合索引的最左前置规则 OK


分库分表经验-易购索引的注意事项:no

  1. 个人介绍
  2. 对图书贸易系统的项目介绍
  3. 高并发的一些问题解决方案
  4. zookeeper 了解情况和机制
  5. redis
  6. mq
  7. springMVC 架构介绍,及相关问题提问
  8. 系统或者服务器出现问题后的解决办法
  9. 自己工作中出彩的地方
  10. 职业规划
  11. 个人长短板
  12. 答:沟通顺畅,思路清晰
  13. 答: 架构了解清晰,知道其中的优缺点,追问对dubbo的架构了解情况:回答一般
  14. 答:当前系统业务量 每月200W 人民币交易,每月订单<1000, 高并发情况没有遇到过
  15. 答:自己搭建过,具体了解不多
  16. 答:数据结构能答上来,对cluster没有了解过,事务没有了解过
  17. 答: 了解MQ 使用场景,实际了解一些activeMQ,没生产使用过,rabbmitMQ,KAFAKA 未实际使用过
  18. 答:架构了解清晰,对具体问题可以有对应的解决办法
  19. 答: 有解决思路,自己一般查看CPU情况和查看应用日志,系统层面上的一般由运维来做
  20. 答:自行开发过工作流,追问:工作流的定时问题,和会签问题,以及撤回和打回带来的一些问题,回答OK ,思路较清晰
  21. 答: 职业规划: 原来做的是传统行业,期望在互联网电商行业有开发研究,可深度实践高并发,大流量的系统。
  22. 短板: 技术不精,分布式,高压力系统未做过
    长版: 接触前后端比较多,不深入。

1.

  • String StringBuffer StringBuilder 区别OK, 常用 StringBuilder
  • hashMap的数据结构:不太清楚,不OK;
  • hashmap与hashtable 区别:线程安全,ok,基本实现思路了解; OK
  • concurrentHashmap:与hashmap 区别OK,看资料得知
  • equals hashCode 区别:OK    String equals hashCode: 没有研究过 不OK
  • 树结构不知道,不OK

2.

  • 线程安全:状态:5种 sleep wait 区别:sleep 不释放锁  wait 释放锁方面 回答错误(多线程 高并发方面经验少);不OK
  • 线程等待:callback方式 不OK
  • 死锁:产生原因:不OK,  生产者 消息者 模式 不太了解; 不OK 
  • 实现线程安全:形式:
    • sync : 加在不同地方区别: 不OK
    • lock :没用过 不OK
    • volatile:没用过, 不OK
    • threadLocal:概念OK,原理:基本能说出,但源码没看过,子线程用父线程的 实现不知道 
    • atomic:不知道 没听过 不OK
  • 线程池:Fix, cache,区别OK,原理:init max 创建 释放, 基本OK

3.

  • IOC: 概念OK,默认:单例 可以多例 OK
  • AOP: 不太清楚,代理:JDK(invacationHandle) cglib(反射) 区别:不知道 不OK
  • 事务传播:req、not_sp、req_new、sp OK

4.

  • 大体结构没有研究过; 不OK
  • 回收机制:没有研究过;不OK

5.

  • 单例:饿、懒 OK 各自优缺点 不明确 ;不OK
  • 策略:没用过;不OK
  • 状态:没用过;不OK

6.

  • 引擎:innodb支持事务B+tree\myisam不支持事务 基本OK 两者索引区别不知道 不OK
  • 隔离机制:4种 OK 幻读与不可重复读区别:不知道 只知道脏读;不OK
  • 索引:explain 具体列: 不OK
  • 联合索引:出现范围的就不走索引

7.

  • tail ps top grep  netstat scp tar df等; OK

1.

  • hash冲突了解,ok。

2.

  • 线程池:用过,了解参数,但是参数之间的限制不了解。
  • 线程之间的同步机制:
  • 如何创建线程:thread,runnable,ok。
  • synchronized加在static和非static的区别,ok。
  • java的synchronized的实现方式了解:偏向锁,轻量级锁,重量级锁,ok。
  • volatile用法和原理,ok

3.

  • AOP: 实现原理:说不清楚;不OK

4.

  • 大体堆内存结构:知道新生代、老年代 

5.

  • 引擎:innodb存储结构,索引优化,不ok

6. 查看cpu负载,不了解各个核负载,不了解多线程的负载如何查看。

每个线程cpu负载情况如何查看不ok

查看当前产生死锁的线程,思路不ok

1.

  • String StringBuffer StringBuilder 区别OK, 常用 StringBuffer, 方法内知道使用StringBuilder OK
  • HaspMap 结构:数组+链表;key冲突:不知道, 数组下标 算法 不知道 与hashtable: OK,具体用啥锁的 OK
  • currentHashmap:与hashmap 区别OK,性能解释OK,分段锁 OK
  • concurrenthashmap:与HASHMAP区别,OK
  • 与hashtable区别:不OK,具体原理不知道不OK
  • equal hashcode 区别:OK    String equal hashcode: OK
  • tree: 数据结构不太知道 看够一些 不OK

2.

  • 线程:状态:就绪、运行、阻塞、等待、死亡; sleep wait 区别:能明确说明,调用notify方法后的状态:引导下能说清 OK
  • 线程等待:countDownLatch join 忘记了 基本OK 
  • 死锁:概念:OK,产生原因:OK,  避免:尽量不要使用公共资产,生产者 消息者:基本能说清;基本OK
  • 实现线程安全:形式:
    • sync : 底层原理:不知道;加在不同地方区别: 锁对象、锁类,OK,线程阻塞;OK
    • lock :比sync轻量,可以设置时间,具体原理不太清楚;不OK
    • volatile:变量可见性,禁止重排序,原子操作;OK
    • threadLocal:听过,没用过; 不OK
    • atomic:没看过源码,cas不知道; 不OK
  • 线程池:Fix, cache,single, sch 区别说的不太正确,自己实现:最大线程数,空闲线程数、最大连接数、超时时间、jujue策略,异常后处理,初始化线程数 基本OK

3.

  • IOC: 默认:单例 可以多例 设置方式OK,实例化冲突解决:spring如何解决没看过,自己方式:不知道
  • AOP: 动态代理:JDK(invacationHandle)基本接口 cglib(反射):基本类 OK 日志使用:异步日志,如果实现异步的:不记得

4.

  • 结构:计数器,本地方法栈、栈、堆(新生代、交换区2,老年代,永久代)OK
  • 年龄:默认15次,GC,大对象直接进入老年代 OK
  • 不会发生OOM:计数器;OK
  • 回收算法:复制,标记清除,标记整理;OK
  • GC收集器:串、并、CMS;OK

5.

  • 单例:饿、懒(会有线程安全,双重锁)内部静态类 枚举; OK
  • 门面:不太好表达 不OK
  • 装饰者:类图没记住,可以举例:Collections 基本OK
  • 模板:原理基本说清;OK
  • 策略:没用过;不OK
  • 状态:没用过;不OK

6.

  • 引擎:innodb支持事务\myisam不支持事务 基本OK 索引:B+tree 索引内容不同;OK 
  • B+TREE:深度浅, 时间复杂度低
  • 隔离机制:脏、幻、不可重复、序列化;幻与不可重复区别:基本表达明白了;OK
  • 索引:explain,具体列描述:基本能说出;OK
  • redis
    • 用过hash,string,知道其他数据类型:list set zset
    • 单线程
    • 没有太深入研究

持久带是否发生fullGC ok
java ---元数据区
================linux基础较好,线上解决问题能力一般

cpu彪高----》NO 没有实际操作过

op load average 三个值的含义 ok

 grep 命令各种线上日志查询 yes

tail 命令 ok

netstat -ano ok

tar -zcvf ok

=======工程素质一般
maven release SNAPSHOT的区别 ok

 git命令

使用IDE集成的,NO

=========消息中间件

kafka
相关概念--熟悉
能举出使用消息队列的场景吗? ok

 =========mysql基础一般

mySql 索引的数据结构 B+数 yes
为什么?有了解


mySql联合索引的最左前置规则 OK


分库分表经验-异构索引的注意事项:no

====架构
能将之前做的事情讲清楚,但是架构经验不足

1.个人介绍

2. 项目介绍

3. 团队人员介绍

4.springMVC,架构介绍

5.项目中redis使用情况了解

6. MQ 使用及了解程度

7.kafaka

8.git

9:出彩工作

10:长短板

11. 离职原因

12. 职业规划

13. 其他

  1. 答:沟通顺畅,思路清晰
  2. 答:打非应用平台项目介绍,前后台功能介绍清晰,架构比较了解,同其他平台对接介绍清晰,为何这样架构不是太了解,只是根据项目安排做项目。
  3. 答:项目组50人左右,所参与项目组4人,1个前台,3个后台,职责角色比较了解,候选人为成员之一无管理经验
  4. 答:MVC 架构比较了解,各个模块交互交代比较清楚,追问过滤器,拦截器原理,回答相对清晰。
  5. 答:redis数据结构介绍清晰,集群及持久化不是太熟悉,事务不了解
  6. 答:仅知道概念和简单使用,具体不了解
  7. 答:不了解
  8. 答:rebase/merge 区别不了解,常用操作主要使用IDE
  9. 答:
    查询部分:优化聚合函数,标准化mongodb查询,组内推广
     舆情调用速度瓶颈:多线程处理获取和统计。
  10. 答:
    长板:学习能力OK 
     短板: 对底层的原理结构了解不深
  11. 答:涨薪承诺未兑现,绩效考核全体未执行,没有兑现奖金
  12. 答:
    前5年专心学习技术,深度和广度都需要 加强。
  13. 拉钩已经发OFFER 周四入职,亚信也发offer,已经拒绝,比较急迫知道面试结果。

读锁,写锁的区别:基本了解使用场景。一般。

1.

  • String StringBuffer StringBuilder 区别OK, 常用 StringBuilder 方法内使用 OK
  • HaspMap  结构:数据+链表;key冲突:ok, 数组下标 算法 OK put链表尾部(不确定)
  • hashmap与hashtable: 区别:线程安全, sync实现锁     OK
  • concurrenthashmap:与hashTable java8之间 区别比较大,效率;OK    segment算法不知道
  • equals hashCode 区别:OK    String equals hashCode: OK
  • tree: 数据结构  平衡二叉树 基本OK 红黑树 记不清了 B+树 OK

2.

  • 状态:说不太清楚 sleep wait 区别:sleep 不释放锁  wait 释放锁 notify:获取锁在运行运行 OK
  • 线程等待:join、countdownlatch callable OK
  • 死锁:产生原因:OK, 解决方式: 设置超时时间、 顺序一致 OK 解决死锁生产者、消息者模式: 不太了解
  • 实现线程安全:形式:
    • sync : class指定加锁, 加在不同地方: 基本OK 具体细节不太清晰了
    • lock :并发大效率好 具体不太了解 不OK
    • volatile:1. 可见性 2. 防止重排序  3. 必需是原子性
    • threadLocal:原理:类似于MAP,key为:当前线程唯一标识; 子线程用父线程的 回答:应该不可以 不OK
    • atomic:CAS原理:OK 缺点:浪费CPU   OK
  • 线程池:知道Fix,single,cache忘记了 区别OK,自己实现:容量(初始化线程数),满了处理方式、最大线程数 基本OK

3.

  • IOC:概念OK,默认:单例 可以多例  OK
  • AOP: 动态代理:JDK接口 cglib字节码上 区别:OK
  • 事务传播:原理基本知道,具体的忘记了

4.

  • 结构:堆、栈、方法区、PC
  • OOM:除了PC
  • 回收机制:复制、标记清除、标记压缩; 串、并行、并发、CMS、G1

5.

  • 单例:饿、懒 OK 各自优缺点 :OK
  • 策略:类图基本OK
  • 命令:带有撤销功能
  • 桥接:不清楚

6.

  • 引擎:innodb支持事务B+tree、索引合在一起、支持行锁\myisam不支持事务、B+tree、不支持外键、索引分开的、表锁\momenry 基本OK
  • 隔离机制:脏、提交读、不可重复读、幻读 4种 OK 幻读与不可重复读区别:OK
  • 索引:dsc explain 具体列: 能说一两,其他记不清楚了
  • 联合索引: 走索引方式 回答不正确 不OK

7.

  • cat tail top grep vmstat jps jstack jmap jstat

kafka
相关概念–很熟悉,知道细节用法;

能很好的说出 消息中间件的应用场景

1.

  • String StringBuffer StringBuilder 区别OK, 常用 StringBuilder 方法内使用 OK
  • HaspMap  结构:数据+链表;key冲突:ok, 数组下标 算法 OK put链表尾部(不确定)
  • hashmap与hashtable: 区别:线程安全, sync实现锁     OK
  • concurrenthashmap:与hashTable java8之间 区别比较大,效率;OK    segment算法不知道
  • equals hashCode 区别:OK    String equals hashCode: OK
  • tree: 数据结构  平衡二叉树 基本OK 红黑树 记不清了 B+树 OK

2.

  • 状态:说不太清楚 sleep wait 区别:sleep 不释放锁  wait 释放锁 notify:获取锁在运行运行 OK
  • 线程等待:join、countdownlatch callable OK
  • 死锁:产生原因:OK, 解决方式: 设置超时时间、 顺序一致 OK 解决死锁生产者、消息者模式: 不太了解
  • 实现线程安全:形式:
    • sync : class指定加锁, 加在不同地方: 基本OK 具体细节不太清晰了
    • lock :并发大效率好 具体不太了解 不OK
    • volatile:1. 可见性 2. 防止重排序  3. 必需是原子性
    • threadLocal:原理:类似于MAP,key为:当前线程唯一标识; 子线程用父线程的 回答:应该不可以 不OK
    • atomic:CAS原理:OK 缺点:浪费CPU   OK
  • 线程池:知道Fix,single,cache忘记了 区别OK,自己实现:容量(初始化线程数),满了处理方式、最大线程数 基本OK

3.

  • IOC:概念OK,默认:单例 可以多例  OK
  • AOP: 动态代理:JDK接口 cglib字节码上 区别:OK
  • 事务传播:原理基本知道,具体的忘记了

4.

  • 结构:堆、栈、方法区、PC
  • OOM:除了PC
  • 回收机制:复制、标记清除、标记压缩; 串、并行、并发、CMS、G1

5.

  • 单例:饿、懒 OK 各自优缺点 :OK
  • 策略:类图基本OK
  • 命令:带有撤销功能
  • 桥接:不清楚

6.

  • 引擎:innodb支持事务B+tree、索引合在一起、支持行锁\myisam不支持事务、B+tree、不支持外键、索引分开的、表锁\momenry 基本OK
  • 隔离机制:脏、提交读、不可重复读、幻读 4种 OK 幻读与不可重复读区别:OK
  • 索引:dsc explain 具体列: 能说一两,其他记不清楚了
  • 联合索引: 走索引方式 回答不正确 不OK

7.

  • cat tail top grep vmstat jps jstack jmap jstat

=============jvm相关

java内存模型、复制回收算法、持久带是否发生fullGC等 jvm基础 ok

cms 垃圾回收期的高阶
CMS
CMS并行GC是大多数应用的最佳选择,然而, CMS并不是完美的,在使用CMS的过程中会产生2个最让人头痛的问题:
promotion failed
concurrent mode failure

对该项问题是否清晰认识:NO

================linux以及线上问题解决

cpu彪高----》线上问题解决
有思路,在提示下得出可行方案;


grep 命令各种线上日志查询 yes

tail 命令 ok

netstat -ano ok

tar -zcvf no

=================工程素质及技术广度
maven release SNAPSHOT的区别 yes

git命令
reset rebase的区别 OK

kafka
相关概念–很熟悉,知道细节用法;

能很好的说出 消息中间件的应用场景

=========MySql相关
mySql 索引的数据结构 B+数 yes
为什么?忘记了


mySql联合索引的最左前置规则 no


分库分表经验-异构索引的注意事项:no

4.了解JVM回收算法,知道YongGC和FullGC的垃圾回收机制,但是GCRoot不清楚。一般。

1.基础的集合类都清楚。一般;

2.知道线程池参数和使用场景ok。

了解synchronized和Lock区别ok。知道偏向锁,轻量级锁和重量级锁,

知道lock的实现类AQS,并做过相关实现。

3.知道IOC和AOP实现机制。OK

AOP的两种实现方式了解,区别,ok。

4.了解JVM回收算法,知道YongGC和FullGC的垃圾回收机制,gcroot可达性分析了解。

5.单例,工厂,适配器等都使用过。OK

6.oracle用的比较多,MySQL不知道索引B+树的数据结构。不OK

7.统计某个端口上连接数,不ok。

端口被哪个进程占用,ok。

遇到过内存溢出,使用过图形化工具,如jprofile,但是命令记不起来了。

cpu内存飙高,了解pidstat和jstack,但不知道之间的pid需要转换。

8.mybatis插入返回主键机制不了解,插件机制不了解。

netty3和netty4区别:堆外内存的优化,不了解。

netty4线程模型,epoll原理ok。

表链接算法不知道。MYSQL了解较少。

1.

  • String StringBuffer StringBuilder 区别OK, 常用 StringBuilder 具体何时用说不清楚
  • HaspMap 结构:数组+链表;key冲突:不知道, 数组下标 算法 不知道
  • HaspMap与hashtable: 区别 OK,具体用啥锁的 OK
  • concurrentHashmap:与hashtable 区别OK,性能解释OK,分段锁 OK 具体原理不知道 (如何达到高效的)
  • equal hashcode 区别:OK String equal hashcode: OK 具体重写内容不知道
  • tree: 数据结构不太知道 不OK

2.

  • 线程:状态:就绪、运行、阻塞、死亡; sleep wait 区别:能明确说明,调用notify方法后的过程:引导下能说清 OK
    线程等待:future
  • sleep、wait区别 : 基本能说清;OK
  • 死锁:概念:产生原因:不OK,  生产者 消息者 模式 不太了解 不OK 
  • 实现线程安全:形式:
    • sync : 底层原理:不知道;加在不同地方区别: 不太明确
    • lock :只说了 比sync灵活
    • volatile:变量可见性,原子操作;OK
    • atomic:实现原理不知道 cas不知道; 不OK
  • 线程池:用过,但回答不上来具体用过哪些,不OK

3.

  • IOC: 默认:单例 可以多例,实例化冲突解决:spring如何解决没看过,自己方式:不知道
  • AOP: 动态代理:JDK cglib:两个代理区别:不知道; 应用场景:记录东西

4.

  • 结构:静态方法区、栈、堆(新生代、交换区2,老年代)
  • 是否可以直接进入老年代: 不清楚
  • 不会发生OOM:静态方法区
  • 回收算法:不知道
  • GC收集器:不了解

5.

  • 引擎:innodb支持事务、行锁\myisam不支持事务 (表的存储方式顺序不同) 基本OK innodb索引:B+tree myisam索引:不知道
  • 隔离机制:脏、幻、不可重复、序列化(ruc,rc,pc,se);幻:解决基本OK 不可重复:比较模糊
  • 索引:explain,具体列描述:基本能说出;OK

1.treemap使用红黑树;

2.线程池参数使用和原理ok;

newFix方式有哪些需要注意,不ok;

volitale原理:不保证原子性,Ok;

synchronized和lock区别:ok;但是原理部分不够深入

concurrentHashmap和hashtable区别,ok;

concurrentHashmap的size方法有什么优化,不ok;

3.spring AOP:两种实现方式;不ok;

4.jdk提供的命令:

某线程导致cpu飙高,ok;

jmap使用发现内存溢出问题,ok;

5.jvm原理:

6.数据库优化:

mysql相关存储结构,b+树,存储结构ok;

聚族索引和非聚族索引区别,ok;

7.jvm

8.中间件

用公司队列,大概了解mafka架构,但是保证全局有序,不ok;

1、试分析进程下某一线程OOM,对其他线程的影响及对进程的影响。

有一定理论知识,回答50%,结构化思维不是很好。思路比较散

2、多线程相关知识,应用OK,但原理性的东西了解不多,一问一挂。

3、coresize设置考虑

核数,其他基本没有考虑。

4、mysql 基础一般,可以应用,原理性的东西了解的不多。

5、lucence,解决关联查询。

没有思路,查两次。

6、redisHA

知道配置,原理不知道。

问题:

数据库 分表问题,订单表按照订单ID来分,那么查询用户下的所有的订单怎么处理:

异构索引的方式;回答OK

在做异构索引中,可不可以冗余订单信息,减少查询?

回答可以;实际上这种处理有数据一致性的问题,以及有订单变更-如主子订单的风险;

消息队列的使用场景问题:

回答没有问题;

对于订单中心这种,订单状态变更的时候,何时使用消息,何时不该使用消息?

界定的不是很清晰,对于消息使用的理解还不是很深入;

大抽奖模型的设计:

系统设计以及划分比较合理

关键抽奖算法等,需要提示,头脑反应一般;

能对系统并发有意识,并能描述如何去处理;

Maven的Snapshot版本与Release版本的区别?不能明显区别;

git reset 、rebase和 revert的区别?—ok

Linux命令-寻找超过100M的文件,并将其删除?如果这个文件是日志文档需要清空?—NO

JVM CPU高负载的排查办法—ok

JVM 内存模型-–ok

JVM 命令及使用,包括遇到的问题,回答一般

工作线程数究竟要设置为多少?—回答不到点子上,no

mysql数据库 innoDB索引的数据结构—no

mysql-分表-异构索引-注意事项–ok,并且能回答到应该注意的点上

延迟消息队列的设计思路,DelayQueue的使用—no

ES、消息队列、缓存使用:一般,很多没有用过,技术广度很差

系统监控报警系统----没有相关概念,互联网相关经验不足;

系统稳定性、性能、扩展性等注意点:没有形成系统支撑体系;

因为之前带过人,问了人力模型,培养方式,无法正面回答,管理经验较弱;

1.

String StringBuffer StringBuilder 区别OK, 常用 StringBuffer stringBuilder使用场景:方法内使用 OK

HaspMap 结构:数据+链表;key冲突:ok, 数组下标 算法 OK put链表首部OK

hashmap与hashtable: 区别:线程安全, sync实现锁 hashtable不能存NULL OK

concurrenthashmap:与hashTable 效率;OK segment算法 没看过

equals hashCode 区别:基本OK String equals hashCode: 基本OK 深入的 忘记了

tree: 数据结构 树结构OK 二叉树结构OK 平衡二叉树 说不太清楚 红黑树 不了解了 B+树 没太深入

2.

状态:5种 就绪 运行 结束 等待 堵塞 sleep wait 区别:sleep 释放锁 wait 不释放锁 notify:直接就绪 不OK 。。。。。。

线程等待:join引导下说出、countdownlatch没用过 

死锁:产生原因:OK, 解决方式:顺序一致 OK 解决死锁生产者、消息者模式: 知道

实现线程安全:形式:

sync : 原理OK class指定加锁, 加在不同地方: 基本OK

lock :原理没看过

volatile:可见性 原子性

threadLocal:原理:类似于MAP,key为:thread对象; 子线程用父线程的 回答:不清楚

atomic:CAS原理:OK 缺点:浪费CPU OK

线程池:Fix,single,cache 区别OK,自己实现:最大线程数 拒绝策略 最小等待时间 队列 核心数 还可以 不太全面

3.

IOC:概念OK,默认:单例 可以多例 OK

AOP: 动态代理:JDK接口 cglib字节码上 区别:OK

bean 依赖注入:解决不清楚

事务传播:原理基本知道

4.

结构:堆、栈、方法区、本地方法区、PC

OOM:除了PC

回收机制:复制、标记清除、标记压缩; 只记得G1

5.

工厂、代理

单例:饿、懒 OK 各自优缺点 :OK

策略:听过,没用过

命令:听过,没用过

桥接:没用过

6.

引擎:innodb支持事务B+tree、索引合在一起、支持行锁\myisam不支持事务

隔离机制:脏、提交读、不可重复读、幻读 4种 OK 幻读与不可重复读区别:OK

索引:不知道

联合索引: 走索引方式 回答基本不正确 不OK

7.

tail scp tar 基本命令

HaspMap 结构:数据+链表;key冲突:取模 底层代码没看过; put链表首部OK

hashmap与hashtable: 没用过也没了解过 不OK

concurrenthashmap: 线程安全的。数据结构:忘记了 不OK

equals hashCode 区别:基本OK String equals hashCode: 基本OK 深入的 忘记了 

tree: 数据结构 树结构OK 二叉树结构OK 平衡二叉树 ok 红黑树 基本了解点,记不太清了 B+树 了解OK

2.

状态:5种引导下说出 就绪 运行 结束 等待 堵塞; sleep wait 区别:sleep 不释放锁 wait 不释放锁 notify:直接进行就绪,等待CPU执行,不确定 不OK

线程等待:join、futureTask、线程池 

死锁:产生原因:OK, 解决方式:超时、少用共享数据、消息传递方式传参 OK 解决死锁生产者、消息者模式: (消息传递)

实现线程安全:形式:

sync : 原理基本OK class指定加锁, 加在不同地方: 基本OK

lock : 原理基本OK,比sync灵活

volatile:可见性 原子性; happens before: 了解过 重排序具体实现不太明确,知道用锁

threadLocal:原理:类似于MAP,key为:thread对象; 子线程用父线程的 回答:得拿到父线程对象,具体怎么拿不知道 

atomic:知道CAS这个词,不知道内部机制 不OK

线程池:只知道 Fix和自动扩容的;两种区别OK,自己实现:最大线程数 拒绝策略 等待队列 每个线程状态 

3.

IOC:概念OK,默认:单例 可以多例 OK

AOP: 动态代理:JDK接口 cglib字节码上 区别:不太了解过 不OK

bean 循环依赖:SPRING会不会自动解决,没注意过 不OK

事务传播:原理基本知道 ,具体应用一般,一些问题自己不太明确 不OK

4.

结构:堆、栈、class区、native、runtime(新对象直接放到 s1中) 不OK

OOM:不清楚 不OK

回收机制:不看过; xxx(记不起来了)、并行、gms、G1 不OK

5.

单例:工厂、表态方法

策略:听过,应用还可以

命令:没用过

6.

引擎:innodb支持事务B+tree、支持行锁\myisam支持事务 HASH索引 表级锁

隔离机制:脏、提交读、不可重复读、幻读(不知道名词了,说的具体内容) 4种 OK 幻读与不可重复读区别:不知道 不OK

索引:explain 

联合索引: 走索引方式 回答基本OK

7.

基本命令、top awk sed grep less

5.只知道单例模式和动态代理;动态代理实现方式,不清晰。不OK

  1. hashmap如何解决hash冲突,涉及到对象哪些的方法,不ok;
    hashtable和concurrenthashmap之间区别,不ok;

  2. 2.1线程池:知道线程池相关参数,达到最大线程数后,才会放到队列里去,不ok;
     newFix和newSingle注意事项,不ok;

2.2synchronized和lock的区别:

jdk1.5对synchronized的优化,不ok;

lock内部实现不ok;

3.spring aop实现方式:jdk代理和cglib,两者之间区别,ok;

4.mysql的存储引擎innodb实现方式,使用b tree,不ok;

联合索引优化,不ok;

 聚簇索引和非聚簇索引区别,不ok;

5.linux命令:

了解top命令,每个核的cpu负载,每个线程cpu负载,不ok;

6.netty3,netty4,netty5几本版本的区别,不ok;

3.spring的aop原理:了解编译期和非编译器两种方式,

了解是动态代理和反射实现,但是不知道深层机制。不OK

1.
String StringBuffer StringBuilder 区别OK,StringBuffer是线程安全的,StringBuilder是线程不安全的 回答错误 常用 StringBuffer 没怎么用StringBuilder是线程不安全的
HaspMap 结构:数据+链表;key算法:取模 ; 回答:新元素放到链表最后 X 基本OK
hashmap与hashtable: 同步锁 OK
concurrenthashmap: 线程安全的。锁分段算法:忘了
equals hashCode 区别:基本OK String equals hashCode: 基本OK
tree: 数据结构 树结构OK 二叉树结构OK 平衡树 ok 红黑树 没了解过
2.
状态:5种引导下说出 就绪 运行 结束 (等待) 堵塞; sleep wait 区别:sleep 不释放锁(对应堵塞) wait 释放锁(对应wait) notify:获取锁->就绪,等待CPU执行
线程等待:join、future
死锁:产生原因:OK, 解决方式:超时、可以中断、少用锁 OK 解决死锁生产者、消息者模式: 没有看过
实现线程安全:形式:
sync : 原理基本OK class指定加锁, 加在不同地方: 基本OK
lock : 原理基本OK,可以中断,可以获取锁结果 应用场景:中断时、获取锁结果、超时 LOCK 平时用sync比较多 没有评测过
volatile:可见性 原子性; happens before: 没听过 重排序:以前看过
threadLocal:底层:没看过
atomic:CAS
线程池:Fix、cache、single;区别OK,自己实现:最大线程数 默认线程数 回收 拒绝策略 队列
3.
IOC:概念OK,默认:单例 可以多例 OK
AOP: 动态代理:apspact cglib字节码上 区别:没了解过
bean 循环依赖:SPRING解决方案 没看过
事务传播:原理基本知道AOP实现,事务应用不OK
4.
结构:堆、栈、方法区、PC 本地方法栈
OOM: PC 不太确定
回收机制:GC:串行、并行、gms、G1 基础理论OK

5.

单例:可以写出标准的懒汉及饿汉

策略:场景:计算器:思路比较清晰

1.
String StringBuffer StringBuilder 区别OK,StringBuffer是线程安全的,StringBuilder是线程不安全的 回答错误 常用 StringBuffer 没怎么用StringBuilder是线程不安全的
HaspMap 结构:数据+链表;key算法:取模 ; 回答:新元素放到链表最后 X 基本OK
hashmap与hashtable: 同步锁 OK
concurrenthashmap: 线程安全的。锁分段算法:忘了
equals hashCode 区别:基本OK String equals hashCode: 基本OK
tree: 数据结构 树结构OK 二叉树结构OK 平衡树 ok 红黑树 没了解过
2.
状态:5种引导下说出 就绪 运行 结束 (等待) 堵塞; sleep wait 区别:sleep 不释放锁(对应堵塞) wait 释放锁(对应wait) notify:获取锁->就绪,等待CPU执行
线程等待:join、future
死锁:产生原因:OK, 解决方式:超时、可以中断、少用锁 OK 解决死锁生产者、消息者模式: 没有看过
实现线程安全:形式:
sync : 原理基本OK class指定加锁, 加在不同地方: 基本OK
lock : 原理基本OK,可以中断,可以获取锁结果 应用场景:中断时、获取锁结果、超时 LOCK 平时用sync比较多 没有评测过
volatile:可见性 原子性; happens before: 没听过 重排序:以前看过
threadLocal:底层:没看过
atomic:CAS
线程池:Fix、cache、single;区别OK,自己实现:最大线程数 默认线程数 回收 拒绝策略 队列
3.
IOC:概念OK,默认:单例 可以多例 OK
AOP: 动态代理:apspact cglib字节码上 区别:没了解过
bean 循环依赖:SPRING解决方案 没看过
事务传播:原理基本知道AOP实现,事务应用不OK
4.
结构:堆、栈、方法区、PC 本地方法栈
OOM: PC 不太确定
回收机制:GC:串行、并行、gms、G1 基础理论OK

5.

单例:可以写出标准的懒汉及饿汉

策略:场景:计算器:思路比较清晰

线上CPU问题彪高的解决思路:ok

工程素质,maven,linux OK,没有用过git,用的SVN

redis,kafka相关,OK

数据库分库分表经验;

1.系统架构
能简单给出架构。
2.Gateway挂掉系统如何降级?
没有太多的概念。
3.怎么解决server的可用性?
监控;负载均衡;
4.netty怎么管理bytebuffer?

树形管理。

5.netty优化有哪些?
业务线程的分离。
6.netty相关的套接字怎么优化的?
没有特别优化
7.netty时间调度方面怎么处理的?
不了解
8.不同GC算法应用的场景。
CMS吞吐高。GC优化欠缺。
9.Socket server的younggc 和oldGC多长时间。
40ms; 10秒。
10.Lock和Synchronized的区别?
一个基于CAS,synchronized monitor对象标记。
11.JDK Queue用过哪些?
有用过LinkedBlockingQueue。

12.搜索的原理。
了解Luncene的使用,但不了解原理。
13.MySQL的索引为什么用B+ Tree
不太了解。

14.书写二分查找

有瑕疵

15.写懒线程安全懒加载

y

1.

String StringBuffer StringBuilder 区别OK,StringBuffer是线程安全的,StringBuilder是线程不安全的 常用 StringBuilder 

HaspMap 结构:数据+链表;key算法:取模 ; 回答:新元素放到链表头部 OK java8 红黑树

hashmap与hashtable: sync锁 线程安全 OK

concurrenthashmap: 分段锁 线程安全的。分段算法:没看过

equals hashCode 区别:基本OK String equals hashCode: 基本OK 场景: equals 相等 hashcode 是否相等 ,反过来 没回答上来

tree: 数据结构 树结构OK 二叉树结构OK 平衡树 ok 红黑树 回答不正确

2.

状态:5种 就绪 运行 结束 等待 堵塞; sleep wait 区别:sleep 会释放锁 wait 释放锁 notify:获取锁->就绪,等待CPU执行

线程等待:join(没具体使用过) 、countdownLatch

死锁:产生原因:OK, 解决方式:不用多线程、资源隔离、私有资源 

实现线程安全:形式:

sync : 没问

lock : 没问

volatile:可见性 原子性; happens before: 防止重排序 

threadLocal:底层:不记得了

atomic:CAS 缺点:没观注

--线程池:Fix、cache、single;区别OK,自己实现:最大线程数 默认线程数 回收 拒绝策略 队列 

3.

IOC:概念OK,默认:单例 可以多例 OK

AOP: 动态代理:jdk cglib 区别:类与接口

bean 循环依赖:SPRING解决方案 没看过 

事务传播:原理基本知道AOP实现,事务应用 OK

4.

结构:堆、栈、方法区、常量池、PC、本地方法栈

OOM: PC

回收机制:young 复制 old CMS、标记清除。 

5.

单例:饿汉、懒汉、静态内部类

策略:场景应用:基本OK

6.

引擎:innodb支持事务B+tree、支持行锁\myisam不支持事务 表级锁 索引:没研究过

隔离机制:脏、提交读、不可重复读、幻读 4种 OK 幻读与不可重复读区别:幻读不知道 不可重复读OK

索引:explain 具体列:3个 用到索引相关的3个

联合索引: 走索引方式 回答基本OK

7.

ps、less tail top ping telnet rd scp jmap

zookeeper应用场景:

做过MCC 或者lion之类的配置中心,利用zookeper的特性;

消息队列---没有用过:
消息队列的使用场景;
延迟消息队列的实现方式---考察架构设计和逻辑思维性;
之前实现系统的架构—很简单

======

架构设计能力较弱

======

cms 垃圾回收期的高阶 知道cms一些问题,但是具体原因忘记了

promotion failed
concurrent mode failure

持久带是否发生fullGC ok

jps、jstack,jmap, jhat,jstat—ok

dump文件中的分析-----曾经分析过,但是不精细
jstack Dump 日志文件中的线程状态
dump 文件里,值得关注的线程状态有:
死锁,Deadlock(重点关注)
执行中,Runnable
等待资源,Waiting on condition(重点关注)
等待获取监视器,Waiting on monitor entry(重点关注)
暂停,Suspended
对象等待中,Object.wait() 或 TIMED_WAITING
阻塞,Blocked(重点关注)
停止,Parked

cpu彪高----》线上问题解决—没有思路

===============

grep 命令各种线上日志查询 ok

tail 命令 ok

find -type f -size +1000m |xargs 忘了

netstat -ano ok

tar -zcvf 忘了

=======
maven release SNAPSHOT的区别 了解部分,没踩过坑

git命令---没有用过

=========
mySql 索引的数据结构 B+数 yes
为什么?说不清楚


mySql联合索引的最左前置规则 yes

分库分表经验-易购索引的注意事项:yes 了解数据不一致问题的严重性和处理方式

=========

==========
RPC服务相关
如何实现负载均衡?ok
如何实现故障转移?ok
如何实现发送超时?no

对RPC服务有一定的了解

==========

工作线程数究竟要设置为多少?
没有好的思路,没有实践过

基本情况:

1. 个人介绍及项目介绍(考察沟通能力)

2. 在亚信公司项目的业务情况(考察业务需求把握能力)

3. 团队情况和直接管理人员情况,任务开发分配情况(考察基本项目管理技能)

4. spring mvc的工作流程,微服务不采用spring boot 原因(考察开发技能和架构把握能力)

5. 具体技术细节提问(考察技术深度)

a)dubbo 集群的工作方式

b)redis 基本数据结构,cluster方式,持久化方式

c)MQ概念解析,集群的有几种方式,使用场景和优缺点。

d). git : rebase/merge 区别,团队使用注意点,stash 用法

6. 现公司离职原因,(工作稳定性)

1.了解hashMap的基本实现原理。OK

2.知道synchronized和Lock的区别:了解;

volatile不能保证原子性,只能保证可见性,ok;

线程池参数和原理,ok;

newFix注意事项,不ok;

3.了解AOP的基本实现思路,底层动态代理实现不清楚。不OK

4.知道JVM基本组成结构,ok;

64位机器如何优化。不OK

5.知道jdk提供的工具:jstack,jconsole,其它不ok;内存dump也不了解;

如和分析内存中的异常数据,如何分析,不ok;

某线程导致的cpu利用率飙高,不ok;

6.mysql存储引擎的索引结构,不ok;

聚簇索引和非聚簇索引区别,不ok;

1.
String StringBuffer StringBuilder 区别OK,StringBuffer是线程不安全的,StringBuilder是线程安全的 回答不正确 常用 StringBuffer 不OK
HaspMap 结构:数组+链表;key算法:没看过 ; 回答:新元素放到链表尾部 不OK; 不OK
hashmap与hashtable: sync锁 线程安全 OK
concurrenthashmap: 用的比较少,原理结构没了解过 不OK
equals hashCode :Object String equals hashCode: OK ; equals 相等 hashcode ,反过来 回答不确定
tree: 二叉树结构:忘记了; 平衡树:左右子树不超过1,左xuan右xuan算法; 红黑树:所有红色子节点都是黑色的 所有黑色子节点都是红色的
2.
状态:5种 起始 运行 结束 等待 堵塞; sleep wait 区别:sleep 不释当前获取资源 wait 释放当前获取资源 notify:直接进入就绪,等待CPU执行 不OK
线程等待:lockstash、加标示检测线程状态
死锁:产生原因:OK, 解决方式:保持对资源访问顺序、加锁 不OK
实现线程安全:形式:
sync : 底层原理: 基本OK 场景: 锁定类、对象 : 不OK
lock : 区别:忘记了 不OK
volatile:可见性 原子性; happens before: 重排序 没了解过
threadLocal:底层:不是很熟 不OK
atomic:CAS:控制原子操作(知道一点) 不OK

3.
IOC:概念OK,默认:单例 可以多例 OK
AOP: 动态代理:cglib 不OK
bean 循环依赖:SPRING解决方案 没注意 不OK
事务传播:只知道4种, 基础使用OK
4.
结构:堆、栈、方法区、常量池、本地方法栈
OOM: 栈、本地方法栈 不OK
5.
策略:场景应用:计算器 不OK
6.
引擎:innodb支持索引 B+tree\myisam不支持索引 不OK
隔离机制:幻读与不可重复读区别:不可重复读不知道
联合索引: 走索引方式 OK

不知道分库分表的原理。不OK;

8.不知道zookeeper选举机制。不OK

数据结构
已知一颗二叉树,如果先序遍历的顺序是ADCEFGHB,后续遍历是CFHGEDBA,则中序遍历顺序是什么?(B)

A:CDFEGHAB
B:CDEFHGAB
C:  DEFCHGAB
D:DCEFHGAB

对于线性表(7, 34, 55, 25,64,46,20,10)进行散列存储时,若选用H(K)= K%9作为散列函数,则散列地址为1的元素有()个?(D)

A:1
B:2
C:3
D:4

在一棵度为3的树中,度为3的节点个数为3,度为2的节点个数为3,则度为0的节点数为()?(C)

A:8
B:9
C:10
D:11

若进栈序列为1,2,3,4,5,6,且进栈出栈可穿插进行,则可能出现的出栈序列为()?(D)

A:3,2,6,4,5,1
B:5,6,4,2,3,1
C:1,2,5,3,4,6
D:3,4,2,1,6,5

二维数组A[3][3]按行优先顺序存储,若数组元素A[1][1]的存储地址为1087,A[2][2]的存储地址为1095,则A[0][0]的存储地址为(C)

A:1060
B:1078
C:1079
D:1080

计算机基础

1.下列操作耗时第二短的是?C
 A. 将一个1字节的数从寄存器移动到CPU的加法器中
B. 将一个1字节的数从内存移入CPU的加法器中
 C. 将一个1字节的数从CPU缓存移入到CPU的加法器中
D. 将一个1字节的数据从磁盘移入CPU的加法器中

2. 递归函数最终会结束,那么这个函数一定?B
 A. 使用了局部变量
B. 有一个分支不调用自身
 C. 使用了全局变量或者一个或多个参数
D. 没有循环调用

3. 编译过程中,语法分析器的任务是。B
 A. 分析单词是怎样构成的
B. 分析单词串是如何构成语句和说明的
 C. 分析语句和说明是如何构成程序的
D.分析程序的结构

4. 计算机网络传输数据过程中,非直连的两个物理节点,发送方的包顺序和接收方的包顺序满足下列哪种关系?C
 A. 完全一致
B. 完全不一致
 C. 很可能一致
D. 很可能不一致

5. HTTP协议里的端口和TCP协议里的端口是指同一个概念么?A
 A. 是
B. 否

6. IP对应了OSI中的哪几层?D
 A.Application layer
B. Presentationlayer
C. Transport layer
D. Network layer

Java基础

1.下列不可作为java语言修饰符的是(D)
A) a1
B) $1
C) _1
D) 11

2. 下列说法正确的是(AC)
A LinkedList继承自List
B AbstractSet继承自Set
C HashSet继承自AbstractSet
D WeakMap继承自HashMap

3. 下面哪个流类属于面向字符的输入流( D)
A BufferedWriter B FileInputStream C ObjectInputStream D InputStreamReader

4.下列哪些语句关于Java内存回收的说明是正确的? ( B )
 A、程序员必须创建一个线程来释放内存
B、内存回收程序负责释放无用内存
C、内存回收程序允许程序员直接释放内存
D、内存回收程序可以在指定的时间释放内存对象

5. A派生出子类B,B派生出子类C,并且在Java源代码中有如下声明:
1. A a0=new A();
2. A a1 =new B();
3. A a2=new C();
问以下哪个说法是正确的?(D)
A、只有第1行能通过编译
B、第1、2行能通过编译,但第3行编译出错
C、第1、2、3行能通过编译,但第2、3行运行时出错
D、第1行、第2行和第3行的声明都是正确的

6.有语句String s=”hello world”; ,以下操作哪个是不合法的?(B)
A、int i=s.length();
B、s>>>=3;
C、String s=s.trim();
D、s += s+”!”;

7.下列关于for循环和while循环的说法中哪个是正确的?( B )
 A.while循环能实现的操作,for循环也都能实现
B.while循环判断条件一般是程序结果,for循环判断条件一般是非程序结果
C.两种循环任何时候都可替换
D.两种循环结构中都必须有循环体,循环体不能为空

8.编译运行以下程序后,关于输出结果的说明正确的是 ( C )
public class Conditional{
 public static void main(String args[ ]){
 int x=4;
 System.out.println(“value is “+ ((x>4) ? 99.9:9));
 }
 }
A.输出结果为:value is 99.9
B.输出结果为:value is 9
C.输出结果为:value is 9.0
D.编译错误

9.执行语句int i = 1, j = ++i; 后i与j的值分别为( D )

A、1与1 

B、2与1 

C、1与2 

D、2与2

10. 给出下面代码段, 哪行将引起一个编译时错误?( D ) 

1) public class Test { 

2) int n = 0; 

3) int m = 0; 

4) public Test(int a) { m=a; } 

5) public static void main(String arg[]) { 

6) Test t1,t2; 

7) int j,k; 

8) j=3; k=5; 

9) t1=new Test(); 

10) t2=new Test(k); 

11) } 

12) }

A. 行1 

B. 行4 

C. 行6 

D. 行9


下面正确的选项有( )
A.string str = new string("abc");
B.byte b = -12;
C.Byte b = -12;
D.double d = new double(1.0);
E.以上都不正确

能用来修饰interface的有。B
A. Priate
B. Public
C. protected
D. static

下面对String StringBuffer StringBuilder说法正确的是 D
A String类中equals方法与Object类的equals方法一样
B StringBuffer是被final修饰的
C StringBuilder是线程安全的
D 三者效率:StringBuilder>StringBuffer>String


设计模式将抽象部分与它的实现部分相分离。 B
A. Singleton(单例)
B. Bridge(桥接)
C. Composite(组合)
D. Facade(外观)


下面哪个不能直接导致一个线程停止执行?( C )
A. 调用 yield() 方法
B. 在一个对象上调用 wait() 方法
C. 在一个对象上调用 notify () 方法
D. 在一个对象上调用 Interrupt() 方法


关于 Java 流的叙述错误的是( D )
A. 流是 Java 语言处理 I/O 的方式
B. 从概念上讲,流就是一系列的字节序列或字符序列
C. 引入流的概念的目的是使得在处理不同的数据输入输出时编程更加方便
D. 流是Java惟一的非面向对象的语言构成

数据库

在一棵二叉树上第5层的结点数最多是__B___。
A. 8
B. 16
C. 32
D. 15

下列叙述中正确的是__C___。

A、数据库是一个独立的系统,不需要操作系统的支持
B、数据库设计是指设计数据库管理系统
C、数据库技术的根本目标是要解决数据共享的问题
D、数据库系统中,数据的物理结构必须与逻辑结构一致

SQL语句中修改表结构的命令是__C___。
A、MODIFY TABLE
B、MODIFYSTRUCTURE
C、ALTER TABLE
D、ALTERSTRUCTURE

数据库DB、数据库系统DBS、数据库管理系统DBMS三者之间的关系是__A___。
A、DBS包括DB和DBMS
B、DBMS包括DB和DBS
C、DB包括DBS和DBMS
D、DBS就是DB,也就是DBMS

在关系模型中,实现”关系中不允许出现相同的元组”的约束是通过___B__。
A、候选键
B、主键
C、外键
D、超键

下列表达式中结果不是日期型的是__C___。
A、CTOD(“2000/10/01″)
B、{^99/10/01}+365
C、VAL(“2000/10/01″)
D、DATE()

只有满足联接条件的记录才包含在查询结果中,这种联接为__C___。
A、左联接
B、右联接
C、内部联接
D、完全联接

在命令窗口执行SQL命令时,若命令要占用多行,续行符是__D___。
A、冒号(:)
B、分号(;)
C、逗号(,)
D、连字符(-)

设有图书管理数据库:
图书(总编号C(6),分类号C(8),书名C(16),作者C(6),出版单位C(20),单价N(6,2))
读者(借书证号C(4),单位C(8),姓名C(6),性别C(2),职称C(6),地址C(20))
借阅(借书证号C(4),总编号C(6),借书日期D(8))
对于图书管理数据库,检索借阅了《现代网络技术基础》一书的借书证号。下面SQL语句正确的是__B___。
SELECT 借书证号 FROM 借阅 WHERE 总编号=;
______
A、(SELECT 借书证号 FROM 图书 WHERE 书名=”现代网络技术基础”)
B、(SELECT 总编号 FROM 图书 WHERE 书名=”现代网络技术基础”)
C、(SELECT 借书证号 FROM 借阅 WHERE 书名=”现代网络技术基础”)
D、(SELECT 总编号 FROM 借阅 WHERE 书名=”现代网络技术基础”)


设有图书管理数据库:
图书(总编号C(6),分类号C(8),书名C(16),作者C(6),出版单位C(20),单价N(6,2))
读者(借书证号C(4),单位C(8),姓名C(6),性别C(2),职称C(6),地址C(20))
借阅(借书证号C(4),总编号C(6),借书日期D(8))
对于图书管理数据库,分别求出各个单位当前借阅图书的读者人次。下面的SQL语句正确的是__A___。
SELECT 单位,______ FROM 借阅,读者 WHERE;
借阅.借书证号=读者.借书证号 ______
A、COUNT(借阅.借书证号) GROUP BY 单位 
B、SUM(借阅.借书证号) GROUP BY 单位
C、COUNT(借阅.借书证号) ORDER BY 单位 
D、COUNT(借阅.借书证号) HAVING 单位

LINUX

 显示文件目录命令: A

A. ls  
B. cd
C. pwd
D. ps

改变当前目录命令:C

A. pwd
B. ls
C. cd
D. vi

建立子目录命令:C

A. pwd
B. fdisk
C. mkdir
D. scp

删除子目录命令:B

A. rm
B. rmdir
C. mkdir
D. cd

删除文件命令:C

A. cd
B. pwd
C. rm
D. mkdir

文件复制命令:D

A. pwd
B. touch
C. cd
D. cp

vi有哪种模式:A

A. 命令模式
B. 重启模式
C. 待机模式
D. 指示器模式

进程的查看和调度命令:A

A. ps
B. touch
C. fdisk
D. cpu

Linux操作系统的核心?A

A. 内核
B. CPU
C. 内存
D. 硬盘

Linux属于哪种类型的操作系统?:D

A. 单用户
B. 单线程
C. 单机
D. 多线程

如何查看当前路径?:C

A. cd
B. touch
C. pwd
D. ls

查看指定帮助?:D

A. help
B. mkdir
C. touch
D. man

ls命令参数-l 功能?:C

A. 全部文件
B. 只显示目录
C. 详细信息
D. 没有这个参数

创建目录什么命令?:A

A. mkdir
B. touch
C. vi
D. man

文件修改权限命令?D

A. touch
B. vi
C. pwd
D. chmod

git rebase命令的含义 不知道 

查看CPU负载 top ,load averge的含义 查看每个核的负载 不清楚

 grep 命令 不熟悉 tail 命令 知道 tar 命令 ok 

maven --没有用过 volatile 关键字含义 操作是否是原子性的? 回答正确

volatile的原理和实现机制 了解一般

atomic 不了解

CyclicBarrier 和 CountDownLatch 的区别 不知道

CMS垃圾回收期为什么会有配对回收器;不知道

java线程池中的各个参数的意义;不知道

=====

工厂模式和创建者模式的区别 答不上来 no

====

mysql的索引是什么数据结构? B+ 为什么?

no mysql索引 最左前缀索引 no

问题1:

解决CPU标高的问题

问题2:

设计一个大抽奖的系统

1、什么是架构

2、线程池

3、设计log4j

4、JVM模型

1、做过架构师,但是没有系统架构模型停留在需求阶段没有整理方法论 不ok

2、知道线程池数量参数,其他参数及作用 不ok

3、log4j的模型无法设计出来,给了提示依旧不可以 不ok

4、可以描述java内存模型,但是无法完成全部的JVM模型

 不知道为什么从引用计数算法 变更成可达性算法 一般

1、java内存模型

2、确认链表是否有环,并确认入环点

3、业务

  1. HashMap的数据结构:
  2. treeMap 的数据结构 红黑树;
  3. 红黑树的特点,以及解决的是什么问题: no
  4. treeSet和TreeMap的关系
  5. volatile 关键字含义 操作是否是原子的;no
  6. volatile 通过什么机制来保证?no
  7. CyclicBarrier 和 CountDownLatch 的区别 no
  8. Java线程池中的各个参数的意义 no
  9. Java垃圾回收,为啥新生代要用复制算法,老年代用标记-整理算法?no
  10. “12345”字符串转换成数字
  11. HashMap的数据结构:
  12. HashMap的=是否可以用对象当Key
  13. HashSet 的数据结构 no
  14. treeMap 的数据结构 红黑树;
  15. 红黑树的特点,以及解决的是什么问题:
  16. volatile 关键字含义 操作是否是原子的;
  17. volatile 通过什么机制来保证?
  18. CyclicBarrier 和 CountDownLatch 的区别
  19. java线程池中的各个参数的意义 keepAliveTime
  20. java垃圾回收,为啥新生代要用复制算法,老年代用标记-整理算法?
  21. 查询一个cup的负载?
  22. 查询一个关键字的日志?
  23. HashMap的数据结构:no
  24. treeMap 的数据结构 红黑树;no
  25. 红黑树的特点,以及解决的是什么问题: no
  26. volatile 关键字含义 操作是否是原子的;no
  27. volatile 通过什么机制来保证?no
  28. CyclicBarrier 和 CountDownLatch 的区别 no
  29. java线程池中的各个参数的意义 keepAliveTime no
  30. java垃圾回收,为啥新生代要用复制算法,老年代用标记-整理算法?no
  31. 查询一个cup的负载?yes
  32. load averge 含义?no
  33. 打包命令 tar -zcvf yes
  34. 查询一个关键字的日志? cat xxx.log |grep -A10 ‘关键字’ yes
  35. cup负载标高的问题查询:没有思路;no

1、什么是架构

2、Servlet生命周期

3、JVM模型

java

 Java基础知识

 1、jdk的类加载机制和类似tomcat类web容器的类加载机制的不同  

参考答案:
http://blog.csdn.net/codolio/article/details/5027423
解题思路:基础知识
考察点:java类加载机制、web容器类加载机制
分类:java、web
难度分级:P2-3

2、浅克隆和深克隆?深克隆的方法?

参考答案:
浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。 
深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。
深克隆的方法:Cloneable接口、序列化的方法

 http://www.itzhai.com/java-based-notebook-the-object-of-deep-and-shallow-copy-copy-copy-implement-the-cloneable-interface-serializing-deep-deep-copy.html 
解题思路:基础知识
考察点:java基础知识
分类:java
难度分级:P2-3

3、Java 泛型的实现原理是什么?

参考答案: 
Java的泛型是伪泛型,Java中的泛型基本上都是在编译器这个层次来实现的,在生成的Java字节码中是不包含泛型中的类型信息的,使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉;

范型  展开原码

    public void test(List<String> ls){

     }

     public void test(List<Integer> li){

     }

以上代码会编译报错,报错信息为:Erasure of method test(List<String>) is the same as another method in type; 

解题思路:范型类型擦除概念
考察点:java基础知识
分类:core java
难度分级:P4,P5

4、泛型的使用场景 
参考答案:
JAVA中泛型的使用:java中集合使用了泛型,Future<T>,WeakReference<T>,Class<T>也都使用了泛型
一些使用场景:
不想写多个重载函数的场景。
约束对象类型的场景,可以定义边界(T extends ...),如JDK集合List,Set。
用户希望返回他自定义类型的返回值场景,如Json返回Java bean。
在用反射的应用中,也经常会用到泛型,如Class<T>。
对网页,对资源的分析,返回场景,一般都有泛型。
解题思路:基础知识
考察点:java基础知识
分类:java
难度分级:P4, P5

5、Integer缓存?Integer比较大小注意问题。==和equals的区别考察 

 参考答案:

 Integer是有缓冲池的,java.lang.Integer.valueOf(int)方法默认情况下如果参数在-128到127之间,则返回缓存中的对象,否则返回new Integer(int)。java使用该机制是为了达到最小化数据输入和输出的目的,这是一种优化措施,提高效率

 其他的包装器:

 Boolean: (全部缓存)

 Byte:    (全部缓存)

 Character (   <=127 缓存)

 Short     (-128~127 缓存)

 Long      (-128~127 缓存)

 Float     (没有缓存)

 Doulbe    (没有缓存)

 可以设置系统属性 java.lang.Integer.IntegerCache.high 修改缓冲区上限,默认为127。参数内容应为大于127的十进制数形式的字符串,否则将被忽略。取值范围为127-Long.MAX_VALUE,但是用时将强转为int。当系统中大量使用Integer时,增大缓存上限可以节省小量内存。 

 区别“==”和equals():“==”是比较两个对象是不是引用自同一个对象。   “equals()”是比较两个对象的内容。 

 解题思路:基础知识

 考察点:java基础知识

 分类:java

 难度分级:P4

Integer使用代码  展开原码

Integer i1 = 127; 

 Integer i2 = 127; 

 if (i1 == i2) 

      System.out.println(true); 

 else 

      System.out.println(false); 

  

    

 i1 = 128; 

 i2 = 128; 

 if (i1 == i2) 

      System.out.println(true); 

 else 

      System.out.println(false);

  //以上代码默认情况下将输出:true false 

6、自动装箱机制,阅读以下代码,指出有问题的地方 

 展开原码

public static void testNotNullPointer() {

     Integer numNull;

     int numInt = 1;

     int numInt2 = 2;

     Integer numInteger = null;

     //if else

     if (numInt == 1) {

         numInt2 = numInteger;  // numInteger为null赋值给int类型变量,自动解箱时报空指针异常

     } else {

         numNull = numInt2;

     }

     //三目运算符和if else的区别, numInteger为null参与三目运算时,自动解箱时报空指针异常

     numNull = numInt == 1 ? numInteger : numInt2;

参考答案:

http://developer.51cto.com/art/201203/325314.htm

解题思路:基础知识

考察点:java基础知识

分类:java

难度分级:P4

7、java的类加载器体系结构和双亲委托机制,应用场景举例  

参考答案:

http://blog.csdn.net/lovingprince/article/details/4317069

解题思路:java类加载机制

考察点:java类加载机制

分类:java

难度分级:P4, P5 

8、红黑树有哪些特性,在Java源码中那部分有应用?

参考答案:

红黑树是一种类平衡树,但不是一种严格的平衡二叉树, 红黑树并不追求“完全平衡”——它只要求部分地达到平衡要求,降低了对旋转的要求,从而提高了性能。对比AVL,红黑树查找的性能比AVL稍差,但插入删除稍好(平衡操作最多旋转3次)。
java源码中的应用:TreeMap和TreeSet是利用红黑树实现的  
关于红黑树可以参考:
http://blog.csdn.net/v_july_v/article/details/6105630 
解题思路:基础知识
考察点:java基础知识,数据结构
分类:java,数据结构
难度分级:P4 ,P5 

9、简述一下java的异常体系,什么是受检异常,什么是运行时异常;封装一个API的时候什么情况下抛出异常。

 参考答案:

java的异常体系: 

 在 Java 中,所有的异常都有一个共同的祖先 Throwable(可抛出)。Throwable 指定代码中可用异常传播机制通过 Java 应用程序传输的任何问题的共性。
Throwable 有两个重要的子类:Exception(异常)和 Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类。
Exception(异常)是应用程序中可能的可预测、可恢复问题。一般大多数异常表示中度到轻度的问题。异常一般是在特定环境下产生的,通常出现在代码的特定方法和操作中。在 EchoInput 类中,当试图调用 readLine 方法时,可能出现 IOException 异常。
Error(错误)表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。例如,当 JVM 不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。
Exception 类有一个重要的子类 RuntimeException。RuntimeException 类及其子类表示“JVM 常用操作”引发的错误。例如,若试图使用空值对象引用、除数为零或数组越界,则分别引发运行时异常(NullPointerException、ArithmeticException)和 ArrayIndexOutOfBoundException。 

受检异常:
可检测异常经编译器验证,对于声明抛出异常的任何方法,编译器将强制执行处理或声明规则,例如:sqlExecption 这个异常就是一个检测异常。你连接 JDBC 时,不捕捉这个异常,编译器就通不过,不允许编译。

非检测异常:

非检测异常不遵循处理或声明规则。在产生此类异常时,不一定非要采取任何适当操作,编译器不会检查是否已解决了这样一个异常。例如:一个数组为 3 个长度,=E5__你使用下标为3时,就会产生数组下标越界异常。这个异常 JVM 不会进行检测,要靠程序员来判断。有两个主要类定义非检测异常:RuntimeException 和 Error。

Error 子类属于非检测异常,因为无法预知它们的产生时间。若 Java 应用程序内存不足,则随时可能出现 OutOfMemoryError;起因一般不是应用程序的特殊调用,而是 JVM 自身的问题。另外,Error 一般表示应用程序无法解决的严重问题。

RuntimeException 类也属于非检测异常,因为普通 JVM 操作引发的运行时异常随时可能发生,此类异常一般是由特定操作引发。但这些操作在 Java 应用程序中会频繁出现。因此,它们不受编译器检查与处理或声明规则的限制。

封装一个API的时候什么情况下抛出异常

如果调用方可以从异常中采取措施进行恢复的,就使用checked exception,如果客户什么也做不了,就用unchecked exception。这里的措施指的是,不仅仅是记录异常,还要采取措施来恢复。

解题思路:基础知识
考察点:java基础知识
分类:java
难度分级:P4

9、string常量池的考核 

参考答案: 

http://blog.sina.com.cn/s/blog_5203f6ce0100tiux.html 

解题思路:基础知识
考察点:String
分类:String {校招,社招}
难度分级:P4,P5

10、在项目中用到了哪些java面向对象的特性,跟面向过程有什么不同?

 参考答案:
这个属于开放性试题,主要考察面试者是否对面向对象有清晰的认识,一般来说会围绕着“继承”、“封装”、“多态”面向对象三大特征来描述;比如做了相同流程下不同特征数据的异构;比如抽象的定时任务模板,缓存模板,监听者模板等等。

解题思路:基础知识
考察点:面向对象
分类:面向对象 {校招,社招}
难度分级:P4,P5

11、是否发现过jdk的bug或者踩过jdk的一些坑 ?

 参考答案:

一般很少有面试者能发现jdk的bug,但是踩坑的不是少数,主要看看面试者有没有总结,java的api用的多不多,理解的到不到位。这个没有参考答案,比如java中sublist的陷阱等等

解题思路:基础知识
考察点:面向对象
分类:面向对象 {校招,社招}
难度分级:P4,P5

Java Util

1、Hash冲突,有哪几种常见的解决方法,Java中HashMap用的是哪一种?
 参考答案:
(1)开放定址法;
(2)拉链法;http://www.cnblogs.com/jillzhang/archive/2006/11/03/548671.html
Java中HashMap使用的是拉链法。
解题思路:基础知识
考察点:Hash冲突,HashMap的底层数据结构实现
分类:数据结构,Java集合框架
难度分级:P4

2、Java HashMap,已知整个生命周期内不会放入超过100个元素,那么占用内存大小最优且设置完初始值后无需自动扩容,该初始值应该设置为多少?

参考答案:

如果默认使用H ashMap内置的负载因子loadFactor为0.75。鉴于HashMap初始化设置大小为2的n次方,则100/0.75=133. 大于133的最小2的n次方为256个。
解题思路:基础知识
考察点: 考察HashMap的负载因子以及构造函数的理解
分类:Java集合框架{校招,社招}
难度分级:P4 

3、Java HashMap在高并发情况下不当使用,可能会导致什么样极端情况,为什么?

参考答案:

在并发的多线程使用场景中,在resize扩容的时候,使得HashMap形成环链,造成死循环,CPU飙升至100%。可以举例子说明。

参考链接:http://wiki.sankuai.com/x/oUl9BQ
解题思路:
考察点:HashMap的并发性
分类:{校招,社招}
难度分级:P4,P5

4、HashMap/ConcurrentHashMap的数据结构实现,扩容机制,HashMap hash的冲突处理。

参考答案:

答案参考前面。
补充:扩容机制考察扩容时机,扩容容量变化机制,扩容具体实现步骤-源码resize() 函数。
解题思路:
考察点:HashMap/ConcurrentHashMap的底层实现
分类:{校招,社招}
难度分级:P4,P5 

5、LinkedHashMap 数据结构实现 

参考答案:

首先搞清楚HashMap得实现;然后重点考察和HashMap的区别。
LinkedHashMap实现与HashMap的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序可以是插入顺序或者是访问顺序。最好画个图解释下。Entry对象在HashMap的时候包含key,value,hash值,以及一个next;而在LinkedHashMap中新增了before和after。
解题思路:基础知识
考察点:HashMap和LinkedHashMap 的数据结构的区别
分类:{校招,社招}
难度分级:P4,P5

 6、ArrayList和LinkedList的区别,数据结构实现,扩容机制 

参考答案:
(1) ArrayList是实现了基于动态数组的数据结构,LinkedList基于双向循环链表的数据结构。
(2) 对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
(3) 对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
(4) 查找操作indexOf,lastIndexOf,contains等,两者差不多。
(5) 随机查找指定节点的操作get,ArrayList速度要快于LinkedList.
当操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能;当你的操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。
扩容: 针对ArrayList,在新增的时候,容量不够就需要扩容,2倍。
解题思路:基础知识
考察点:ArrayList和LinkedList的区别,ArrayList的扩容
分类:{校招,社招}
难度分级:P4

7、哈希函数的构造方法常见的有哪几种?

参考答案:
(1)直接寻址法:取关键字或关键字的某个线性函数值为散列地址。即H(key)=key或H(key) = a·key + b为散列函数。若其中H(key)中已经有值了,就往下一个找,直到H(key)中没有值了,就放进去。
(2) 数字分析法:就是找出数字的规律,尽可能利用这些数据来构造冲突几率较低的散列地址。
(3)平方取中法:取关键字平方后的中间几位作为散列地址。
(4) 折叠法:将关键字分割成位数相同的几部分,最后一部分位数可以不同,然后取这几部分的叠加和(去除进位)作为散列地址。
(5)随机数法:选择一随机函数,取关键字的随机值作为散列地址,通常用于关键字长度不同的场合。
(6)除留余数法:取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即 H(key) = key MOD p,p<=m。不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p的选择很重要,一般取素数或m,若p选的不好,容易产生同义词。      
解题思路:基础知识
考察点:哈希函数的构造方法
分类:数据结构
难度分级:P4

8、HashMap的实现原理(内部数据结构,null key,rehash);为什么说hashMap不是线程安全的。

参考答案:
(1)内部数据结构实现:数组+链表 (最好画个图能解释清楚)
(2)key值不能重复,只能put一个key为null的键值对。可以更深层次考察对put(null,value)以及get(null)的 理解。
(3)HashMap在put时,经过了两次hash,一个是JDK自带的对对象key的hash,然后再对结果使用HashMap内部函数hash(int h);hash(int h)方法根据key的hashCode重新计算一次散列。可以更深入考察对hash(int h)以及indexFor(int h, int length)两个函数的理解。
(4)在put时如果空间不够就需要扩容resize(),考察扩容过程--重新计算复制。
(5)在并发的多线程使用场景中,使用HashMap形成环链,造成死循环,CPU飙升至100%。例子见链接。
http://wiki.sankuai.com/pages/viewpage.action?pageId=89609604
解题思路:基础知识
考察点: 考察HashMap的底层实现远离
分类:Java集合框架{校招,社招}
难度分级:P4 

9、List有哪些实现,实现原理,如何选择实现;是否比较过性能差异?contains方法是怎么比较对象的?  

参考答案:

(1)List的直接实现是两个抽象类,AbstactList和AbstractSequentialList.其中,AbstractList为随即访问(如数组)实现方案提供尽可能的封装,AbstractSequentialList为连续访问(如链表)实现方案提供了尽可能的封装。ArrayList,直接父类是AbstractList,数据结构是大小可变的数组,它不是同步的。LinkedList,直接父类是AbstractSquentialList,数据结构是双向链表,它不是同步的,它同时实现了Deque(双向队列)和Queue(队列)接口。同时它还提供了push和pop这两个堆栈操作的接口。Vector,直接父类是AbstractList,特性和ArrayList一样,只是它是线程同步的。Stack,直接父类是Vector,_=9E现堆栈这种数据结构。
(2)通过对象的equals方法。
解题思路:基础知识
考察点:考察对List的理解和运用以及equals的理解
分类:Java集合框架{校招,社招}
难度分级:P4

10、如何拷贝数组,怎样效率最高?为什么?

参考答案:
(1)使用循环结构 这种方法最灵活。唯一不足的地方可能就是代码较多
(2)使用Object类的clone()方法, 这种方法最简单,得到原数组的一个副本。灵活形也最差。效率最差,尤其是在数组元素很大或者复制对象数组时。
(3) 使用Systems的arraycopy这种方法被告之速度最快,并且灵活性也较好,可以指定原数组名称、以及元素的开始位置、复
制的元素的个数,目标数组名称、目标数组的位置。
浅拷贝和深拷贝得理解:定义一个数组int[] a={3,1,4,2,5}; int[] b=a;  数组b只是对数组a的又一个引用,即浅拷贝。
如果改变数组b中元素的值,其实是改变了数组a的元素的值,要实现深度复制,可以用clone或者System.arrayCopy
clone和System.arrayCopy都是对一维数组的深度复制;因为java中没有二维数组的概念,只有数组的数组。所以二维数组a中存储的实际上是两个一维数组的引用。当调用clone函数时,是对这两个引用进行了复制。  
解题思路:基础知识
考察点:数组拷贝,浅拷贝和深拷贝的区别
分类:{校招,社招}
难度分级:P4,P5

JVM&GC

1、 Jvm堆内存区,有两个S区有什么作用?

参考答案

S区即Survivor区,位于年轻代。年轻代分三个区。一个Eden 区,两个Survivor 区。大部分对象在Eden 区中生成。当Eden 区满时,还存活的对象将被复制到Survivor 区(两个中的一个),当这个Survivor 区满时,此区的存活对象将被复制到另外一个Survivor 区,当这个Survivor 去也满了的时候,从第一个Survivor 区复制过来的并且此时还存活的对象,将被复制年老区(Tenured)。需要注意,Survivor 的两个区是对称的,没先后关系,所以同一个区中可能同时存在从Eden 复制过来对象,和从前一个Survivor 复制过来的对象,而复制到年老区的只有从第一个Survivor 去过来的对象。而且,Survivor 区总有一个是空的。
解题思路:基础知识
考察点:JVM 内存结构
分类:JVM GC {校招,社招}
难度分级:P4

2、有遇到过OOM么,什么情况,怎么发现的,怎么查原因的?

参考答案:

http://outofmemory.cn/c/java-outOfMemoryError(OOM分类)

http://www.51testing.com/html/92/77492-203728.html(jstat使用)

http://my.oschina.net/shaorongjie/blog/161385(MAT使用)

解题思路:基础知识
考察点:jstat mat工具 jvm 
分类:JVM GC {校招,社招}
难度分级:P4,P5

3、内存分配策略 

参考答案:

1)对象优先在Eden分配;2)大对象直接进入老年代;3)长期存活的对象将进入老年代;4)动态对象年龄判定

参考文献:http://www.cnblogs.com/liangzh/archive/2012/07/03/2575252.html

解题思路:基础知识
考察点: jvm 
分类:JVM GC {校招,社招}
难度分级:P4,P5

4、线程内存和主内存是如何交互的? 

参考答案:

假设某条线程执行一个synchronized代码段,其间对某变量进行操作,JVM会依次执行如下动作:
(1) 获取同步对象monitor (lock)
(2) 从主存复制变量到当前工作内存 (read and load)
(3) 执行代码,改变共享变量值 (use and assign)
(4) 用工作内存数据刷新主存相关内容 (store and write)
(5) 释放同步对象锁 (unlock)

解题思路:基础知识
考察点: jvm 
分类:JVM GC {校招,社招}
难度分级:P4,P5 

5、线上环境JVM参数Xms Xmx是如何设置的, 如果大小是一至,为什么这样设置?

参考答案:

Xmx设置JVM 的最大可用内存,Xms 设置JVM实际使用内存,一般Xmx和Xms相同,这是因为当Xmx内存空间不够用时,将进行扩容导致Full GC。将Xmx和Xms设置成相同的值,避免因Xms偏小导致频繁重新分配内存,影响应用使用。

解题思路:基础知识
考察点: jvm 
分类:JVM GC {校招,社招}
难度分级:P4,P5  

6、如何定位一个CPU Load过高的Java线程?

参考答案:        

1、jps -v列出所有的java进程 , top找出cpu占用过高的对应的java 进程pid 

2、使用top -H -p PID 命令查看对应进程里的哪个线程占用CPU过高,取该线程pid 

3、将线程的pid 转成16进制

4、jstack [进程pid]|grep -A 100 [线程pid的16进制]  dump出jvm该线程的后100行,或者整个输出到文件

jstack -l pid > xxxfile

参考文献:Crm线上机器发布时load过高案例分析阶段总结以及监控工具介绍 

解题思路:基础知识
考察点: jvm 
分类:JVM GC {社招}
难度分级:P5   

 7、JmapDump的文件大小和MAT分析工具里显示的大小不一致一般是什么原因导致的?

参考答案:

  JmapDump的文件一般比MAT工具大。创建索引期间,MAT会删除部分垃圾收集算法遗留下的不可达的object,因为回收这些较小的object代价较大,一般这些object占比不超过4%。另外不能正确的写JmapDump的文件。尤其在较老的jvm(1.4,1.5)并且使用jmap命令获取JmapDump的文件的时候。

解题思路:基础知识
考察点: jvm 
分类:JVM GC {社招}
难度分级:P5  

 8、如何在Jmap未响应的情况下Dump出内存?

参考答案:

加-F参数

解题思路:基础知识
考察点: jvm 
分类:JVM GC {社招}
难度分级:P5 

9、说出5个JVM的参数以及含义,怎么样配置这样参数?

参考答案:

JVM参数设置

解题思路:基础知识
考察点: jvm 
分类:JVM GC {校招,社招}
难度分级:P4,P5 

 10、JVM的一些健康指标和经验值,如何配置最优?

参考答案:
这个是比较开发性试题,偏社招,考察面试者对系统的掌控力,一般都会从垃圾回收的角度来解释,比如用jstat或者gc日志来看ygc的单次时间和频繁程度,full gc的单次时间和频繁程度;ygc的经验时间100ms以下,3秒一次;full gc 1秒以下 1小时一次,每次回收的比率70%等等,也会用jstack和jmap看系统是否有太多的线程和不必要的内存等等。关于如何才能让配置最优,有一些理论支撑,比如高吞吐和延迟低的垃圾收集器选择,比如高并发对象存活时间不长,可以适当加大yong区;但是有经验的面试者会调整一些参数测试来印证自己的想法。

解题思路:基础知识
考察点: jvm 
分类:JVM GC {校招,社招}
难度分级:P4,P5

11、对象存活算法,常见的有哪几种,JAVA采用的是哪种?

参考答案:

(1)引用计数算法

原理:给对象添加一个引用计数器,每当有一个地方引用它时,计数器加1;引用失效时,计数器减1;计数器为0说明可被回收。
缺点:很难解决对象相互循环引用的问题(对象相互循环引用,但其实他们都已经没有用了。

(2)可达性分析算法

 原理:通过一些列称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。在java语言中,可作为GC Roots的对象包括下面几种:虚拟机栈(栈帧中的本地变量表)中引用的对象、方法区类静态属性引用的对象、方法区中常量引用的对象、本地方法栈中JNI引用的对象、

参考文献:http://blog.csdn.net/chaofanwei/article/details/19541421

解题思路:基础知识
考察点:JVM GC 
分类:JVM GC {校招,社招}
难度分级:P4,P5 

12、JVM新生代ParNew用的是什么垃圾收集算法?
参考答案:复制
解题思路:基础知识
 考察点:JVM GC 
 分类:JVM GC {校招,社招}
 难度分级:P4,P5

13、JVM垃圾收集复制算法中,Eden:Form:To,为什么是8:1:1,而不是1:1:1?
参考答案:
一般情况下,新生代中的对象大多生命周期很短,也就是说当进行垃圾收集时,大部分对象都是垃圾,只有一小部分对象会存活下来,所以只要保留一小部分内存保存存活下来的对象就行了。在新生代中一般将内存划分为三个部分:一个较大的Eden空间和两个较小的Survivor空间(一样大小),每次使用Eden和一个Survivor的内存,进行垃圾收集时将Eden和使用的Survivor中的存活的对象复制到另一个Survivor空间中,然后清除这两个空间的内存,下次使用Eden和另一个Survivor,HotSpot中默认将这三个空间的比例划分为8:1:1,这样被浪费掉的空间就只有总内存的1/10了。
参考文献:http://www.cnblogs.com/angeldevil/p/3803969.html
解题思路:基础知识
考察点:JVM GC 
分类:JVM GC {校招,社招}
难度分级:P4,P5

14、JVM老年代CMS用的是什么垃圾收集算法?
参考答案:

CMS以获取最短回收停顿时间为目标的收集器,使用“标记-清除”算法,分为以下6个步骤

1.STW initial mark:第一次暂停,初始化标记,从root标记old space存活对象(the set of objects reachable from roots (application code))

2.Concurrent marking:运行时标记,从上一步得到的集合出发,遍历old space,标记存活对象 (all live objects that are transitively reachable from previous set)

3.Concurrent precleaning:并发的标记前一阶段被修改的对象(card table)

4.STW remark:第二次暂停,检查,标记,检查脏页的对象,标记前一阶段被修改的对象 (revisiting any objects that were modified during the concurrent marking phase)

5.Concurrent sweeping:运行过程中清理,扫描old space,释放不可到达对象占用的空间 

6.Concurrent reset:此次CMS结束后,重设CMS状态等待下次CMS的触发
或者4个大步骤:

1,initial mark 2,concurrent mark 3,remark 4,concurrent sweep

 解题思路:基础知识

考察点:JVM GC 

 分类:JVM GC {校招,社招}

 难度分级:P4,P5

15、young gc和full gc触发条件 
参考答案:
young gc :eden空间不足
full gc :显示调用System.GC、旧生代空间不足、Permanet Generation空间满、CMS GC时出现promotion failed和concurrent mode failure、
RMI等的定时触发、YGC时的悲观策略、dump live的内存信息时
参考文献:http://blog.csdn.net/vernonzheng/article/details/8460128
http://blog.sina.com.cn/s/blog_7581a4c301019hsc.html
解题思路:基础知识
考察点:JVM GC 
分类:JVM GC {校招,社招}
难度分级:P4,P5

16、垃圾回收器种类,垃圾回收扫描算法(root扫描),回收算法(复制,标记清除,标记整理)
参考答案:
垃圾回收器种类:
Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS(ConCurrent Mark Sweep)、G1(Garbage First)

垃圾回收扫描算法:

垃圾检测通过建立一个根对象的集合(局部变量、栈桢中的操作数,在本地方法中引用的对象,常量池等)并检查从这些根对象开始的可触及性来实现。根对象总是可访问的,如果存在根对象到一个对象的引用路径,那么称这个对象是可触及的或活动对象,否则是不可触及的,不可触及的对象就是垃圾对象。 

 回收算法: 

 标记清除 

 分为标记=E5__清除两个阶段,在标记阶段,垃圾收集器跟踪从根对象的引用,在追踪的过程中对遇到的对象打一个标记,最终未被标记的对象就是垃圾对象,在清除阶段,回收垃圾对象占用的内存。可以在对象本身添加跟踪标记,也可以用一个独立的位图来设置标记。标记清除法是基础的收集           算法,其他算法大多时针对这个算法缺点的改进。存在效率和碎片问题。 

 复制算法

 将内存划分为大小相等的两个区域,每次只使用其中的一个区域,当这个区域的内存用完了,就将可触及的对象直接复制到新的区域并连续存放以消除内存碎片,当可触及对象复制完后,清除旧内存区域,修改引用的值。这种算法明显缺点是浪费内存,故实际使用中常将新生代划分成8:1:1三        个区。

 标记整理

 标记整理算法中标记的过程同标记清理一样,但整理部分不是直接清除掉垃圾对象,而是将活动对象统一移动一内存的一端,然后清除边界外的内存区域,这样就避免了内存碎片。也不会浪费内存,不需要其他内存进行担保

 分代收集 

 大多数程序中创建的大部分对象生命周期都很短,而且会有一小部分生命周期长的对象,为了克服复制收集器中每次垃圾收集都要拷贝所有的活动对象    的缺点,将内存划分为不同的区域,更多地收集短生命周期所在的内存区域,当对象经历一定次数的垃圾收集存活时,提升它的存在的区域。一般是划    分为新生代和老年代。新生代又划分为Eden区,From Survior区和To Survior区 

 自适应收集器

 监听堆中的情形,并且对应地调用合适的垃圾收集技术。 

  参考文献:http://www.cnblogs.com/angeldevil/p/3803969.html

  解题思路:基础知识
 考察点:JVM GC 
 分类:JVM GC {校招,社招}
 难度分级:P4,P5

17、 cms回收器的标记过程,内存碎片问题 

  参考答案:

 cms回收器的标记过程:         

 1.STW initial mark:第一次暂停,初始化标记,从root标记old space存活对象(the set of objects reachable from roots (application code)) 

 2.Concurrent marking:运行时标记,从上一步得到的集合出发,遍历old space,标记存活对象 (all live objects that are transitively reachable from previous set)

  3.Concurrent precleaning:并发的标记前一阶段被修改的对象(card table)

 4.STW remark:第二次暂停,检查,标记,检查脏页的对象,标记前一阶段被修改的对象 (revisiting any objects that were modified during the concurrent marking phase)

 内存碎片问题:

 CMS基于“标记-清除”算法,进行垃圾回收后会存在内存碎片,当申请大的连续内存时可能内存不足,此时需要进行一次Full GC,可以通过参数指定进行Full GC后或进行多少次Full GC后进行一次内存压缩来整理内存碎片。

解题思路:基础知识

考察点:JVM GC 

分类:JVM GC {校招,社招}

难度分级:P4,P5

18、GC Log分析,给面试者一段具体GC Log 
参考 jvm gc介绍和日志说明 

19、画一下JVM内存结构图,各块分别有什么的作用?
参考答案:

各模块作用:
程序技术器:是一块很小的内存区域,主要作用是记录当前线程所执行的字节码的行号。
虚拟机栈:是线程私有的,存放当前线程中局部基本类型的变量、部分的返回结果以及Stack Frame,非基本类型的对象的引用。Sun JDK的实现中JVM栈的空间是在物理内存上分配的,而不是从堆上分配。
堆:存储对象实例和数组区域
方法区域:是全局共_=AB的,存放了所加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义为final类型的常量、类中的Field信息、类中的方法信息。
本地方法堆栈:支持native方法的执行,存储每个native方法调用的状态。
解题思路:基础知识
考察点:JVM  
分类:JVM  {校招,社招}
难度分级:P4,P5

 20、JVM垃圾收集在ParNew+CMS条件下,哪些情况下会让JVM认为产生了一次FULL GC?

 参考答案:

JVM认为在老年代或者永久区发生的gc行为就是Full GC,在ParNew+CMS条件下,发生Full GC的原因通常为:
a) 永久区达到一定比例。
b) 老年代达到一定比例。
c) 悲观策略。
d) System.gc(), jmap -dump:live, jmap -histo:live 等主动触发的。
解题思路:
考察点:GC收集器 Full GC 
分类:JVM GC {校招,社招}
难度分级:P4,P5 

21、如何查看StringPool大小? 

参考答案:

通过java -XX:+PrintStringTableStatistics命令查看,Number of buckets显示的就是StringPool的默认大小,在jdk7 u40版本以前,它的默认大小是1009,之后便调整为60013。

解题思路:JVM基础知识
考察点:StringPool 
分类:JVM GC {校招,社招}
难度分级:P4,P5 

22、JmapDump的文件中是否包括StringPool?

 参考答案:

StringPool在jdk6中是在永久区,dump heap时,无法输出。在jdk7中,stringpool移到heap中,可以输出。

解题思路:JVM基础知识
考察点:StringPool 
分类:JVM GC {校招,社招}
难度分级:P4,P5            

多线程

1、Java线程有哪些状态?并画出状态转换图 

参考答案:

解题思路:基础知识
考察点:java 线程 
分类:java 线程 {校招,社招}
难度分级:P4,P5

2、举例Java线程安全的实现方法,原理、区别?

参考答案:

互斥同步:synchronized关键字 , Lock  ReentrantLock,volatile
非阻塞同步:原子变量 atomicLong   原理:sun.misc.Unsafe类,CAS指令

解题思路:基础知识
考察点:java 线程 
分类:java 线程 {校招,社招}
难度分级:P4,P5

3、多次调用线程的start方法会怎么样?

 参考答案:
线程的start()只能被调用一次,否则会报java.lang.IllegalThreadStateException

Thread类的start()方法  展开原码

public synchronized void start() {

     if (threadStatus != 0)

         throw new IllegalThreadStateException();

     ......

 }

解题思路:基础知识
考察点:java 线程 
分类:java 线程 {校招,社招}
难度分级:P4,P5

4、线程sleep()和yield()的区别是什么?

 参考答案: 

sleep()使当前线程进入停滞状态,所以执行sleep()的线程在指定的时间内肯定不会执行;yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行_=82
sleep()可使优先级低的线程得到执行的机会,当然也可以让同优先级和高优先级的线程有执行的机会;yield()只能使同优先级的线程有执行的机会。

解题思路:基础知识
考察点:java 线程 
分类:java 线程 {校招,社招}
难度分级:P4,P5 

5、线程同步问题 

 参考答案:
1) 在需要同步的方法的方法签名中加入synchronized关键字。
2)使用synchronized块对需要进行同步的代码段进行同步。
3)使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象。
4)锁的粒度:类级别和对象级别
5)读写锁,CountDownLatch等的使用
6)  Lock与synchronized 的区别
http://houlinyan.iteye.com/blog/1112535

解题思路:基础知识
考察点:java 线程 
分类:java 线程 {校招,社招}
难度分级:P4,P5 

6、wait()和notify(),wait和sleep的区别  
参考答案:
wait()和notify()的区别: 
http://blog.csdn.net/oracle_microsoft/article/details/6863662
wait和sleep的区别:
(1)sleep是Thread类的方法,是线程用来 控制自身流程的,比如有一个要报时的线程,每一秒中打印出一个时间,那么我就需要在print方法前面加上一个sleep让自己每隔一秒执行一次。就像个闹钟一样。
wait是Object类的方法,用来线程间的通信,这个方法会使当前拥有该对象锁的进程等待知道其他线程调用notify方法时再醒来,不过你也可以给他指定一个时间,自动醒来。这个方法主要是用走不同线程之间的调度的。
(2)关于锁的释放 ,在这里假设大家已经知道了锁的概念及其意义。调用sleep方法不会释放锁(自己的感觉是sleep方法本来就是和锁没有关系的,因为他是一个线程用于管理自己的方法,不涉及线程通信)
(3)使用区域
由于wait函数的特殊意义,所以他是应该放在同步语句块中的,这样才有意义 。
注意:两个方法都需要抛出异常
解题思路:基础知识
考察点:
分类:{校招,社招}
难度分级:P4

7、IO密集型和CPU密集型与线程池大小的关系 
参考答案:

任务性质不同的任务可以用不同规模的线程池分开处理。CPU密集型任务配置尽可能小的线程,如配置Ncpu+1个线程的线程池。IO密集型任务则由于线程并不是一直在执行任务,则配置尽可能多的线程,如2*Ncpu。混合型的任务,如果可以拆分,则将其拆分成一个CPU密集型任务和一个IO密集型任务,只要这两个任务执行的时间相差不是太大,那么分解后执行的吞吐率要高于串行执行的吞吐率,如果这两个任务执行时间相差太大,则没必要进行分解。我们可以通过Runtime.getRuntime().availableProcessors()方法获得当前设备的CPU个数。
参考资料:http://www.infoq.com/cn/articles/java-threadPool

解题思路:基础知识
考察点:
分类:{校招,社招}
难度分级:P4,P5 

8、ThreadLocal 作用和实现机制 

 参考答案:

http://wowlinda80.iteye.com/blog/228600  

解题思路:基础知识
考察点:
分类:{校招,社招}
难度分级:P4,P5 

9、java线程池corePoolSize,maxPoolSize,queueCapacity这些参数的意义,如何考虑这些参数的设置
参考答案:
corePoolSize(线程池的基本大小):核心线程数,核心线程会一直存活,即使没有任务需要处理。当线程数小于核心线程数时,即使现有的线程空闲,线程池也会优先创建新线程来处理任务,而不是直接交给现有的线程处理。
maximumPoolSize(线程池最大大小):当线程数大于或等于核心线程,且任务队列已满时,线程池会创建新的线程,直到线程_=95_量达到maxPoolSize。如果线程数已等于maxPoolSize,且任务队列已满,则已超出线程池的处理能力,线程池会拒绝处理任务而抛出异常。
queueCapacity(任务队列容量):从maxPoolSize的描述上可以看出,任务队列的容量会影响到线程的变化,因此任务队列的长度也需要恰当的设置。

参数的设置参考http://blog.csdn.net/zhouhl_cn/article/details/7392607  
解题思路:最好搞清楚线程池的主要处理流程。
考察点:线程池的理解与使用
分类:{校招,社招}
难度分级:P4,P5  

10、ThreadLocal是什么,有什么典型的应用场景?

 参考答案:
http://wowlinda80.iteye.com/blog/228600

解题思路:最好搞清楚线程池的主要处理流程。
考察点:线程池的理解与使用
分类:{校招,社招}
难度分级:P4,P5  

11、考虑设计一个计数器程序,场景一,一个线程写,多个线程读;场景二,多个线程写,多个线程读。分别应对这2种场景设计一个计数器程序,要保证线程安全 
参考答案:
一写多读的情况主要需要考虑读到最新的数据,所以加volatile关键字即可
多写多读的情况就需要考虑原子操作,可以利用CAS原理
解题思路:基础知识
考察点:多线程,异步
分类:{校招,社招}
难度分级:P4,P5

12、多线程的使用场景,为了解决什么样的问题。不适用于什么场景 
参考答案:
这几点阐述的不完全正确
多线程优势
1.发挥多核处理器的强大能力,如果没有多核处理器,用多线程也只是形式而已,提升处理速度,常见的是一个任务用多线程跑比单线程跑快
2.建模简单,可以把一系列的复杂交互,变成简单的同步编程模型;比如我们在写controller时不用在考虑线程创建、销毁、调度优先级等;如果用单线程模型会变得非常复杂。
3.异步事件的简化处理,参见NIO的实现
多线程的风险
1.线程安全性
2.活跃性(死锁)问题
3.性能问题,频繁切换上下文,调度
想要同时处理多件事:单线程处理不了的,必须使用多线程。(类似于分身术)
多个线程分解大任务:用单线程可以做,但是使用多线程可以更快。(类似于左右开弓)
可以引申到异步和多线程的区别上。
解题思路:基础知识
考察点:多线程,异步
分类:{校招,社招都可以用}
难度分级:P4,P5

 13、线程池的实现原理
参考答案:

 线程池的作用是有效的降低频繁创建销毁线程所带来的额外开销。一般来说,线程池都是采用预创建的技术,在应用启动之初便预先创建一定数目的线程。应用在运行的过程中,需要时可以从这些线程所组成的线程池里申请分配一个空闲的线程,来执行一定的任务,任务完成后,并不是将线程销毁,而是将它返还给线程池,由线程池自行管理。如果线程池中预先分配的线程已经全部分配完毕,但此时又有新的任务请求,则线程池会动态的创建新的线程去适应这个请求。当然,有可能,某些时段应用并不需要执行很多的任务,导致了线程池中的线程大多处于空闲的状态,为了节省系统资源,线程池就需要动态的销毁其中的一部分空闲线程。因此,线程池都需要一个管理者,按照一定的要求去动态的维护其中线程的数目。线程池将频繁创建和销毁线程所带来的开销分摊到了每个具体执行的任务上,执行的次数越多,则分摊到每个任务上的开销就越小。当然,如果线程创建销毁所带来的开销与线程执行任务的开销相比微不足道,可以忽略不计,则线程池并没有使用的必要。

 这个例子不错:
 多线程就是通过线程调用线程实现的;打个比方来说就像“摆渡”,河的一岸有很多的人,他们想过河,过河的过程做什么就是他们自己的逻辑,只要他符合我的要求我就送你过河(线程池的要求就是实现Runnable或继承Thread类),然后我开了几条船去送人,只要河的这一岸有满足的人,我就送你过河。这个例子中河一岸的人就是我们要执行的任务,是一个集合,船就是线程池中的线程,由我们自己控制,过河这个动作就是要执行的逻辑,我们只负责把船调给你,怎么划桨怎么过河就是程序自己的逻辑了。 
解题思路:基础知识
考察点:线程池
分类:{校招,社招都可以用}
难度分级:P4,P5

 14、常见的线程工具(同步器、线程安全集合类、原子类),什么场景下使用 
参考答案:

 【java】【分享】java多线程
解题思路:基础知识
考察点:Java线程状态
分类:{校招,社招}
难度分级:P4

15、常见的线程状态,以及相互转换图;WAITING和BLOCK的区别 
参考答案:
线程状态以及相互转换图已有答案。
blocked是内部对象锁阻塞,另外blocked激活需要线程调度器允许其持有对象,waiting是等待其他线程通知线程调度器一个条件;
BLOCK产生的原因:I/O等待阻塞,suspend挂起等
WAITING产生原因:Thread.sleep,Object.wait等
解题思路:基础知识
考察点:Java线程状态
分类:{校招,社招}
难度分级:P4

16、常见的同步方式 synchronized 和 lock 如何选择 
参考答案:
参考:http://houlinyan.iteye.com/blog/1112535
解题思路:基础知识
考察点:线程同步方式
分类:{校招,社招}
难度分级:P4

17、死锁的几种场景,如何避免死锁  
参考答案:
参考http://www.cnblogs.com/cxd4321/archive/2012/05/28/2521542.html
解题思路:基础知识
考察点:死锁
分类:{校招,社招}
难度分级:P4

18、利用缓存机制优化一个复杂计算程序 

 展开原码

public class Memoizer<A, V> implements Computable<A, V> {

     private final ConcurrentMap<A, Future<V>> cache

         = new ConcurrentHashMap<A, Future<V>>();

     private final Computable<A, V> c;

     public Memoizer(Computable<A, V> c) { this.c = c; }

     public V compute(final A arg) throws InterruptedException {

         while (true) {

             Future<V> f = cache.get(arg);

             if (f == null) {

                 Callable<V> eval = new Callable<V>() {

                     public V call() throws InterruptedException {

                         return c.compute(arg);

                     }

                 };

                 FutureTask<V> ft = new FutureTask<V>(eval);

                 f = cache.putIfAbsent(arg, ft);

                 if (f == null) { f = ft; ft.run(); }

             }

             try {

                 return f.get();

             } catch (CancellationException e) {

                 cache.remove(arg, f);

             } catch (ExecutionException e) {

                 throw launderThrowable(e.getCause());

             }

         }

     } }

 

19、Java方法体中用到了多线程,使用了ThreadPool,但是方法体内程序员没有显式调用ShutDown关闭线程池,那么该方法执行结束后,JVM是否能自动的关闭线程池,销毁线程?

标准答案:
答案是JVM不能自动关闭线程池,销毁线程。
可以参考海丰的CRM每天第一次发布导致cpu load过高报警的问题 
解题思路:基础知识
考察点:线程池
分类:{校招,社招都可以用}
难度分级:P4,P5  

 20、ThreadPool中线程是如何做到重用的?

参考答案:
线程池在执行execute方法的时候,会根据初始化参数的大小以及线程池已有的线程数,来创建核心线程或者把task塞入任务队列;其中创建的核心线程创建后会启动,run方法内会执行一个runWork函数,此函数会不断地从任务队列中获取task执行。
解题思路:线程池的工作原理和工作流程。
考察点:线程池
分类:{校招,社招都可以用}
难度分级:P4,P5  

网络

1、 HTTP是网络七层协议中哪一层的协议?

参考答案:应用层。

解题思路:基础知识

考察点:OSI七层协议的基础知识

分类:HTTP,基础知识,网络,{校招,社招都可以用}

难度分级:P4

2、Get和Post区别?

参考答案: 

HTTP定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE。这里主要讨论前2种GET和POST。  

GET - 从指定的资源请求数据。

POST - 向指定的资源提交要被处理的数据。 

在开始对比前,需要理解1个概念,幂等(idempotent) 

在HTTP/1.1规范中幂等性的定义是:

Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.

幂等的意味着对同一URL的多个请求应该返回同样的结果。根据HTTP规范,GET用于信息获取,而且应该是安全的和幂等的。

所谓安全的意味着该操作用于获取信息而非修改信息。换句话说,GET 请求一般不应产生副作用。

就是说,它仅仅是获取资源信息,就像数据库查询一样,不会修改,增加数据,不会影响资源的状态 

  GET POST

后退按钮/刷新 无害 数据会被重新提交(浏览器应该告知用户数据会被重新提交)。

书签 可收藏为书签 不可收藏为书签

缓存 能被缓存 不能缓存

编码类型 application/x-www-form-urlencoded application/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码。

历史 参数保留在浏览器历史中。 参数不会保存在浏览器历史中。

对数据长度的限制 是的。当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。 无限制。

对数据类型的限制 只允许 ASCII 字符。 没有限制。也允许二进制数据。

安全性 与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。

在发送密码或其他敏感信息时绝不要使用 GET ! POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。

可见性 数据在 URL 中对所有人都是可见的。 数据不会显示在 URL 中。

解题思路:HTTP基础知识,从面向数据提交方式、安全性等方面进行对比,如果能阐述幂等性更好

考察点:幂等性,GET和POST信息的提交方式

分类:网络应用层,HTTP基础知识{校招,社招都可以用}

难度分级:P4,P5

 3、描述一下一次HTTP请求从请求到返回的过程,越详细越深入越好。 (或者,访问一个url 都经历过了哪些事情,越详细越好。) 

参考答案:

1)把URL分割成几个部分:协议、网络地址、资源路径。

其中网络地址指示该连接网络上哪一台计算机,可以是域名或者IP地址,可以包括端口号;

协议是从该计算机获取资源的方式,常见的是HTTP、FTP,不同协议有不同的通讯内容格式;资源路径指示从服务器上获取哪一项资源。

例如:http://www.guokr.com/question/554991/

协议部分:http

网络地址:www.guokr.com

资源路径:/question/554991/

2)如果地址不是一个IP地址,通过DNS(域名系统)将该地址解析成IP地址。

IP地址对应着网络上一台计算机,DNS服务器本身也有IP,你的网络设置包含DNS服务器的IP。

例如:www.guokr.com 不是一个IP,向DNS询问请求www.guokr.com 对应的IP,获得IP: 111.13.57.142。

这个过程里,你的电脑直接询问的DNS服务器可能没有www.guokr.com 对应的IP,就会向它的上级服务器询问_=8C

上级服务器同样可能没有,就依此一层层向上找,最高可达根节点,找到或者全部找不到为止。

(DNS缓存和解析过程是一个考察点,有些面试者能叙述出完整的过程,有些只能给出笼统的结果,以下是DNS缓存策略)

浏览器缓存 – 浏览器会缓存DNS记录一段时间。 有趣的是,操作系统没有告诉浏览器储存DNS记录的时间,这样不同浏览器会储存个自固定的一个时间(2分钟到30分钟不等)。
系统缓存 – 如果在浏览器缓存里没有找到需要的记录,浏览器会做一个系统调用(windows里是gethostbyname)。这样便可获得系统缓存中的记录。
路由器缓存 – 接着,前面的查询请求发向路由器,它一般会有自己的DNS缓存。
ISP DNS 缓存 – 接下来要check的就是ISP缓存DNS的服务器。在这一般都能找到相应的缓存记录。
递归搜索 – 你的ISP的DNS服务器从跟域名服务器开始进行递归搜索,从.com顶级域名服务器到Facebook的域名服务器。一般DNS服务器的缓存中会有.com域名服务器中的域名,所以到顶级服务器的匹配过程不是那么必要了。

3)如果地址不包含端口号,根据协议的默认端口号确定一个。

端口号之于计算机就像窗口号之于银行,一家银行有多个窗口,每个窗口都有个号码,不同窗口可以负责不同的服务。

端口只是一个逻辑概念,和计算机硬件没有关系。

例如:www.guokr.com 不包含端口号,http协议默认端口号是80。

如果你输入的url是http://www.guokr.com:8080/ ,那表示不使用默认的端口号,而使用指定的端口号8080。

4)向2和3确定的IP和端口号发起网络连接。
例如:向111.13.57.142的80端口发起连接

5)根据http协议要求,组织一个请求的数据包,里面包含大量请求信息,包括请求的资源路径、你的身份
例如:用自然语言来表达这个数据包,大概就是:请求 /question/554991/ ,我的身份是xxxxxxx。

6)服务器响应请求,将数据返回给浏览器。数据可能是根据HTML协议组织的网页,里面包含页面的布局、文字。数据也可能是图片、脚本程序等。现在你可以用浏览器的“查看源代码”功能,感受一下服务器返回的是什么东东。如果资源路径指示的资源不存在,服务器就会返回著名的404错误。

7)如果(6)返回的是一个页面,根据页面里一些外链的URL,例如图片的地址,按照(1)-(6)再次获取。

8)开始根据资源的类型,将资源组织成屏幕上显示的图像,这个过程叫渲染,网页渲染是浏览器最复杂、最核心的功能。

9)将渲染好的页面图像显示出来,并开始响应用户的操作。

以上只是最基本的步骤,实际不可能就这么简单,一些可选的步骤例如网页缓存、连接池、加载策略、加密解密、代理中转等等都没有提及。

即使基本步骤本身也有很复杂的子步骤,TCP/IP、DNS、HTTP、HTML:每一个都可以展开成庞大的课题,而浏览器的基础——操作系统、编译器、硬件等更是一个比一个复杂。

这道题说难不难,说容易不容易,不同层次不同水平的面试者可能会有不同的表现和见解,上面仅是答题要点,面试人员的表现和他的理解层次需要面试官酌情判定。

解题思路:从一个请求的时间上顺序进行阐述,涉及多个过程,最好能做深入

考察点:网络综合知识

分类:基础知识,网络{校招,社招都可以用}

难度分级:P4,P5,P6

4、举出6个http的状态码,502 和 504有什么区别。

参考答案:

大类区分见下表  

状态码范围 作用

100-199 用于指定客户端应相应的某些动作。

200-299 用于表示请求成功。

300-399 用于已经移动的文件并且常被包含在定位头信息中指定新的地址信息。

400-499 用于指出客户端的错误。

500-599 用于支持服务器错误。 

具体每个码的含义见右边的链接->HTTP状态码大全

502 Bad Gateway:作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。

504 Gateway Time-out:作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应。

502 Bad Gateway:Tomcat没有启动起来 

504 Gateway Time-out: Nginx报出来的错误,一般是Nginx做为反向代理服务器的时候,所连接的应用服务器譬如Tomcat无相应导致的 

解题思路:基础知识

考察点:HTTP的基础知识,要求能记住工作中常见的几个错误码

分类:网络应用层,HTTP,基础知识{社招}

难度分级:P5

5、UDP,TCP是网络七层协议中哪一层的协议,区别是什么,分别适用于什么场景?

参考答案:

传输层。
      在TCP/IP模型中,传输层的功能是使源端主机和目标端主机上的对等实体可以进行会话。
在传输层定义了两种服务质量不同的协议。即:传输控制协议TCP(transmission control protocol)和用户数据报协议UDP(user datagram protocol)。  

  TCP协议是一个面向连接的、可靠的协议。它将一台主机发出的字节流无差错地发往互联网上的其他主机。
需要三次握手建立连接,才能进行数据传输。在发送端,它负责把上层传送下来的字节流分成报文段并传递给下层。
在接收端,它负责把收到的报文进行重组后递交给上层。TCP协议还要处理端到端的流量控制,以避免缓慢接收的接收方没有足够的缓冲区接收发送方发送的大量数据。  
  UDP协议是一个不可靠的、无连接协议,不与对方建立连接,而是直接就把数据包发送过去。主要适用于不需要对报文进行排序和流量控制的场合。
UDP适用于一次只传送少量数据、对可靠性要求不高的应用环境。比如,我们经常使用“ping”命令来测试两台主机之间TCP/IP通信是否正常,
其 实“ping”命令的原理就是向对方主机发送UDP数据包,然后对方主机确认收到数据包,如果数据包是否到达的消息及时反馈回来,那么网络就是通的。 

  TCP UDP

是否连接 面向连接 面向非连接 

传输可靠性 可靠 不可靠 

应用场合 传输大量数据 少量数据

速度 慢 快 

解题思路:基础知识,从面向连接、可靠性、应用场合上进行分析对比

考察点:七层协议中传输层的基础知识,着重从TCP vs UDP的区别上考察

分类:七层协议,基础知识,网络,{校招,社招都可以用}

难度分级:P4,P5

6、互联网服务的默认端口是多少?

参考答案:

          HTTP  80  
          SMTP  25
          POP3  110
          FTP  21    20
          TELNET  23 

解题思路:

考察点:网络协议,端口

分类:网络应用层,基础知识{校招,社招都可以用}

难度分级:P5

7、tcp的三次握手,如何用java实现tcp的广播,如果发现网段内的所有集群节点?(未解答)

操作系统

1、有界队列和无界队列,无锁队列 
参考答案: ArrayBlockingQueue/LinkedBlockingQueue/Disruptor
http://blog.csdn.net/mn11201117/article/details/8671497
http://blog.163.com/zongyuan1987@126/blog/static/131623156201271021955717/

解题思路:

考察点:

分类:基础知识{校招}

难度分级:P4

2、如何更改文件夹权限。755是什么意思 

参考答案: 

文件权限的改变使用的是chmod这个指令,但是,权限的设定方法有两种, 分别可以使用数字或者是符号来进行权限的变更。

1、 数字类型改变文件权限

Linux文件的基本权限就有=E4__个,分别是owner/group/others三种身份各有自己的read/write/execute权限。

文件的权限字符为:『-rwxrwxrwx』, 这九个权限是三个三个一组的!其中,我们可以使用数字来代表各个权限,各权限的分数对照表如下:
r:4
w:2
x:1
每种身份(owner/group/others)各自的三个权限(r/w/x)分数是需要累加的,例如当权限为: [-rwxrwx---] 分数则是:
owner = rwx = 4+2+1 = 7
group = rwx = 4+2+1 = 7
others= --- = 0+0+0 = 0

数字方式改变文件权限  展开原码

chmod [-R] xyz 文件或目录

2、符号类型改变文件权限

还有一个改变权限的方法呦!从之前的介绍中我们可以发现,基本上就九个权限分别是(1)user (2)group (3)others三种身份啦!

那么我们就可以藉由u, g, o来代表三种身份的权限!此外, a 则代表 all 亦即全部的身份!那么读写的权限就可以写成r, w, x!也就是可以使用底下的方式来看:

解题思路:chmod的2种使用方式

考察点: 文件权限,chmod

分类:Linux文件权限基本概念和主要操作{校招,社招}

难度分级:P4

3、1024个1btye文件,大约占用磁盘空间多大?

参考答案:

不考虑i-node的占用,假定4KB一个block。

文件大小的计算公式:实际大小 = ceil(字节数/1个block的大小) * 1个block的大小,其中,ceil表示对实数进行上取整。

所以1024个1byte文件要占用1024*4KB=4MB的大小。

解题思路:先给出占用空间的公式,再根据这个公式进行计算

考察点:文件系统,磁盘空间占用的计算

分类:Linux文件系统{校招,社招都可以用}

难度分级:P4,P5

4、Linux文件系统中Inode,Block分别是什么?

参考答案:

文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector)。每个扇区储存512字节(相当于0.5KB)。

操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个"块"(block)。

这种由多个扇区组成的"块",是文件存取的最小单位。"块"的大小,最常见的是4KB,即连续八个 sector组成一个 block。

文件数据都储存在"块"中,那么很显然,我们还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。

这种储存文件元信息的区域就叫做inode,中文译名为"索引节点"。每一个文件都有对应的inode,里面包含了与该文件有关的一些信息。

解题思路:分析阐述什么是inode和block

考察点:磁盘的结构,及在文件系统上的逻辑组织

分类:IO,文件系统知识{校招,社招都可以用}

难度分级:P4,P5

5、LRU如何实现,是否只跟时间有关?

参考答案:

首先,来看看LRU的定义: Least recently used. 可以理解为, 最少使用的被淘汰。
今天主要来讨论基于双链表的LRU算法的实现, 在讨论之前,我们需要了解一下,传统LRU算法的实现,与其的弊端。
传统意义的LRU算法是为每一个Cache对象设置一个计数器,每次Cache命中则给计数器+1;
而Cache用完,需要淘汰旧内容,放置新内容时,就查看所有的计数器,并将最少使用的内容替换掉。
它的弊端很明显,如果Cache的数量少,问题不会很大;但是如果Cache的空间过大,达到10W或者100W以上,一旦需要淘汰,则需要遍历所有计算器,其性能与资源消耗是巨大的。效率也就非常的慢了。
基于这样的情况,所有就有新的LRU算法的实现----基于双链表 的LRU实现。
它的原理: 将Cache的所有位置都用双连表连接起来,当一个位置被命中之后,就将通过调整链表的指向,将该位置调整到链表头的位置,新加入的Cache直接加到链表头中。
这样,在多次进行Cache操作后,最近被命中的,就会被向链表头方向移动,而没有命中的,就向链表后面移动,链表尾则表示最近最少使用的Cache。
当需要替换内容时候,链表的最后位置就是最少被命中_=9A_位置,我们只需要淘汰链表最后的部分即可。

直接决定一个元素是否被淘汰的因素,是这个元素多久没被访问了,而与该元素在一段时间内被访问的频率无关。举例说明,1个10个元素的缓存,如果一段时间内A元素被连续访问了100次,但是最后9次分别访问B,C,...,I,J,则会出现在队尾。这时,尽管A的访问频率是100次,B,C,...,J只有1次,但是如果有新内容要进缓存,A还是会被替换。因此,缓存内容被替换,只与时间有关,与频率无关。

解题思路:对比LRU的传统实现和双向链表实现,LRU的英文是Latest Recently Used,有些面试者会认为缓存替换与频率有关,其实真正决定因素是元素最后被访问的时间

考察点:对LRU的理解,双向循环链表,重点在于对频率和时间的区分

分类:算法与数据结构,缓存{社招}

难度分级:P5,P6

6、Disk seek的时间量级是什么?

参考答案:

多数磁盘工作在7200RPM状态下,即一分钟转7200转,因此,一转占用1/120秒,大概8.3ms。 平均地,可以认为磁盘转到一半的时候发现我们要寻找的信息,但这又被移动磁盘磁头的时间抵消。因此,我们得到访问时间为8.3ms。(这是非常宽松的估计,9~11ms的时间更为普通)。

解题思路:分析阐述什么是disk seek time,再给出目前硬件技术水平下的disk seek time量级。

考察点:硬件的技术指标,磁盘寻道时间

分类:服务器硬件{校招,社招都可以用}

难度分级:P4,P5

7、构造一个或画一个会出现死锁的场景?如何避免它?如何解决可能出现的死锁?

参考答案:

死锁的四个必要条件

  1. 互斥(Mutual exclusion
  2. 占有并等待(Hold and wait
  3. 不可剥夺(No preemption
  4. 环形等待(Circular wait

避免死锁(死锁预防):

  1.  破坏“互斥”条件: 就是在系统里取消互斥。若资源不被一个进程独占使用,那么死锁是肯定不会发生的。但一般来说在所列的四个条件中,“互斥”条件是无法破坏的。因此,在死锁预防里主要是破坏其他几个必要条件,而不去涉及破坏“互斥”条件。
  2. 破坏“占有并等待”条件:就是在系统中不允许进程在已获得某种资源的情况下,申请其他资源。即要想出一个办法,阻止进程在持有资源的同时申请其他资源。
     方法一:创建进程时,要求它申请所需的全部资源,系统或满足其所有要求,或么什么也不给它。这是所谓的  一次性分配”方案。
     方法二:要求每个进程提出新的资源申请前,释放它所占有的资源。这样,一个进程在需要资源S时,须先把它先前占有的资源R释放掉,然后才能提出对S的申请,即使它可能很快又要用到资源R
  3.  破坏“不可抢占”条件:就是允许对资源实行抢夺。
    方法一:如果占有某些资源的一个进程进行进一步资源请求被拒绝,则该进程必须释放它最初占有的资源,如果有必要,可再次请求这些资源和另外的资源。
    方法二:如果一个进程请求当前被另一个进程占有的一个资源,则操作系统可以抢占另一个进程,要求它释放资源。只有在任意两个进程的优先级都不相同的条件下,方法二才能预防死锁。
  4. 破坏“循环等待”条件:破坏“循环等待”条件的一种方法,是将系统中的所有资源统一编号,进程可在任何时刻提出资源申请,但所有申请必须按照资源的编号顺序(升序)提出。这样做就能保证系统不出现死锁。
  5. 还有经典的银行家算法,是避免死锁最具代表性的算法。它允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。

解决死锁?

如果死锁已经发生,那么如何解决死锁呢?

基本思路是撤销或者挂起一些进程(线程),回收一些资源,满足其他进程(线程)的需求。

  1. 撤消陷于死锁的全部进程;
  2. 逐个撤消陷于死锁的进程,直到死锁不存在;
  3. 从陷于死锁的进程中逐个强迫放弃所占用的资源,直至死锁消失。
  4. 从另外一些进程那里强行剥夺足够数量的资源分配给死锁进程,以解除死锁状态。

考察点:死锁的四个必要条件,如何避免死锁和如何解决死锁

分类:操作系统,=E6__锁{校招、社招均可}

难度分级:P4,P5

8、 IO密集型,线程是多好还是少好?CPU密集型呢?

参考答案:

IO密集型应用应用利用并发提高效率的原理 

常需要阻塞等待的程序,比如说因为网络环境阻塞等待,因为IO读取阻塞等待。

当一个任务阻塞在IO操作上时,我们可以立即切换执行其他任务或启动其他IO操作请求,这样并发就可以帮助我们有效地提升程序执行效率。

CPU密集型应用利用并发提高效率的原理:

并发计算,将问题拆分为子任务、并发执行各子任务并最终将子任务的结果汇总合并。

利用并发提高应用的效率,要根据CPU的核心数估计合适的线程数。 

应用程序最小线程数应该等于可用的处理器核数。如果所有的任务都是计算密集型的,则创建处理器可用核心数这么多个线程就可以了,这样已经充分利用了处理器,也就是让它以最大火力不停进行计算。创建更多的线程对于程序性能反而是不利的,因为多个线程间频繁进行上下文切换对于程序性能损耗较大。 

但如果任务都是IO密集型的,那我们就需要创建比处理器核心数大几倍数量的线程。为何?当一个任务执行IO操作时,线程将被阻塞,于是处理器可以立即进行上下文切换以便处理其他就绪线程。如果我们只有处理器核心数那么多个线程的话,即使有待执行的任务也无法调度处理了。

因此,线程数与我们每个任务处于阻塞状态的时间比例相关。假如任务有50%时间处于阻塞状态,那程序所需线程数是处理器核心数的两倍。我们可以计算出程序所需的线程数,公式如下:

线程数=CPU可用核心数/(1 - 阻塞系数),其中阻塞系数在在0到1范围内。 

计算密集型程序的阻塞系数为0,IO密集型程序的阻塞系数接近1。
确定阻塞系数,我们可以先试着猜测,或者采用一些性能分析工具或java.lang.management API 来确定线程花在系统IO上的时间与CPU密集任务所耗的时间比值。

解题思路:先分析并发如何提高程序效率, 

考察点:并发提高程序效率的原理、应用程序线程数的估算 

分类:线程,实践{社招} 

难度分级:P6

9、缓存失效算法常见的有哪几种?

参考答案:
LRU
FIFO
LFU

解题思路:
考察点:

 分类:编码能力

难度分级:P4 P5

Linux

shell

1、Linux Top有哪些重要参数值得关注,这些参数有什么具体含义?

参考答案:

 Linux的top命令详解见http://www.2cto.com/os/201209/157960.html

解题思路:不同水平的面试人员有不同层次的理解,面试官应视其回答情况酌情给分

考察点:Linux运行情况的查看、top命令的使用熟练程度

分类:Linux基本操作{校招,社招都可以用}

难度分级:P4

2、Linux上用什么命令看在线日志?

参考答案:

 Linux 日志都以明文形式存储,所以用户不需要特殊的工具就可以搜索和阅读它们。

还可以编写脚本,来扫描这些日志,并基于它们的内容去自动执行某些功能。

Linux 日志存储在 /var/log 目录中。这里有几个由系统维护的日志文件,但其他服务和程序也可能会把它们的日志放在这里。

大多数日志只有root账户才可以读,不过修改文件的访问权限就可以让其他人可读。

可以用cat、head、tail等查看,用grep搜索过滤,用cut取字段(列数据),更高级的可以用awk和sed重排日志。

解题思路:日志文件的格式多是文本文件,从文本文件的处理方式的考虑

考察点:日志的存储,Linux查看、搜索文本文件的方式,坑在直接用VI看,如果稍有经验的人这么做,那么基本可以送走了

分类:Linux基本操作{校招,社招都可以用}

难度分级:P4

3、如何输出时间到time.txt文件?

参考答案:

date >> time.txt

解题思路:重定向的应用

考察点: Linux命令输出重定向、简单的Linux命令

分类:Linux基本操作{校招,社招都可以用}

难度分级:P4

4、有一个文本文件source.txt,每行有个字符串,请使用shell命令查找包含“beijing”的行,并将结果保存到文件result.txt中 

参考答案: 

grep -i beijing source.txt > result.txt

解题思路:用grep来对文本文件搜索,注意-i选项用来忽略大小写

考察点: Linux命令输出重定向、grep简单应用

分类:Linux基本操作{校招,社招都可以用}

难度分级:P4

5、查看当前TCP/IP连接的状态和对应的个数?

参考答案:

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

解题思路:用netstat来查看连接和端口,用awk进行统计

考察点: netstat和awk的应用

分类:Linux组合操作{校招,社招都可以用}

难度分级:P5

7、分析apache访问日志,找出访问页面的次数排名前100的ip?

参考答案:

awk '{print $1}' localhost_access_log.txt | sort | uniq -c | sort -n -k 1 -r | head -n 100

解题思路:用awk或者cut来取文本中的第一列,再用sort排序,uniq去重,数字排序,最后输出前100名

考察点: awk、sort、head等文本处理工具组合的应用

分类:Linux组合操作{社招}

难度分级:P5

8、符号链接(symbolic link)和硬链接的区别?

参考答案: 

硬链接(hard links): 为文件创建了额外的条目。使用时,与文件没有区别;删除时,只会删除链接,不会删除文件;
硬链接的局限性: 1. 不能引用自身文件系统以外的文件,即不能引用其他分区的文件;2. 无法引用目录;
操作: ln file link, 只能link文件;

符号链接(symbolic links): 克服硬链接的局限性,类似于快捷方式,使用与硬链接相同. 
如果先删除文件,则会成为坏链接(broken),ls会以不同颜色(Ubuntu, 红色)显示;
操作: ln -s item link,可以link文件和目录; 

解题思路:hard link和soft link的区别,结合i-node的知识

考察点: i-node,文件链接

分类:Linux文件系统基本概念{校招,社招}

难度分级:P4

数据库

 1、InnoDB 默认什么隔离级别,为什么选用这种级别。选其他的可以么?

参考答案:

http://www.cnblogs.com/vinchen/archive/2012/11/19/2777919.html

解题思路:数据库事务

考察点:数据库事务 

分类:数据库事务{校招,社招}

难度分级:P4

2、RR级别下,都有哪些锁?有遇到过死锁么,什么情况下发生的死锁?
参考答案:

http://hedengcheng.com/?p=771 

解题思路:数据库事务

考察点:数据库事务  

分类:数据库事务{校招,社招} 

难度分级:P4

3、数据服务端的一些命令(show processlist等等)

参考答案:  

a. show tables或show tables from database_name; -- 显示当前数据库中所有表的名称
b. show databases; -- 显示mysql中所有数据库的名称
c. show columns from table_name from database_name; 或show columns from database_name.table_name; -- 显示表中列名称
d. show grants for user_name; -- 显示一个用户的权限,显示结果类似于grant 命令
e. show index from table_name; -- 显示表的索引
f. show status; -- 显示一些系统特定资源的信息,例如,正在运行的线程数量
g. show variables; -- 显示系统变量的名称和值
h. show processlist; -- 显示系统中正在运行的所有进程,也就是当前正在执行的查询。大多数用户可以查看他们自己的进程,但是如果他们拥有process权限,就可以查看所有人的进程,包括密码。
i. show table status; -- 显示当前使用或者指定的database中的每个表的信息。信息包括表类型和表的最新更新时间
j. show privileges; -- 显示服务器所支持的不同权限
k. show create database database_name; -- 显示create database 语句是否能够创建指定的数据库
l. show create table table_name; -- 显示create database 语句是否能够创建指定的数据库
m. show engies; -- 显示安装以后可用的存储引擎和默认引擎。
n. show innodb status; -- 显示innoDB存储引擎的状态
o. show logs; -- 显示BDB存储引擎的日志 
p. show warnings; -- 显示最后一个执行的语句所产生的错误、警告和通知
q. show errors; -- 只显示最后一个执行语句所产生的错误 
r. show [storage] engines; --显示安装后的可用存储引擎和默认引擎
s. show procedure status --显示数据库中所有存储的存储过程基本信息,包括所属数据库,存储过 程名称,创建时间等                                               
t. show create procedure sp_name --显示某一个存储过程的详细信息

解题思路:

考察点: mysql 

分类:数据库,硬技能{校招,社招}

难度分级:P4、P5

 4、为什么MySQL的索引要使用B+树而不是其它树形结构?为什么不用B树 

参考答案: 

为什么不用B树?:因为B树的所有节点都是包含键和值的,这就导致了每个几点可以存储的内容就变少了,出度就少了,树的高度会增高,查询的时候磁盘I/O会增多,影响性能。由于B+Tree内节点去掉了data域,因此可以拥有更大的出度,拥有更好的性能。

解题思路:Mysql 索引数据结构

考察点: Mysql索引数据结构,B+树 B-树

分类:Mysql、数据结构{校招,社招}

难度分级:P4,P5

5、为什么InnoDB中表的主键最好要自增?

参考答案: 

自增主键,

InnoDB使用聚集索引,数据记录本身被存于主索引(一颗B+Tree)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放,因此每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(InnoDB默认为15/16),则开辟一个新的页(节点)。如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页。这样就会形成一个紧凑的索引结构,近似顺序填满。由于每次插入时也不需要移动已有数据,因此效率很高,也不会增加很多开销在维护索引上。

如果使用非自增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置,此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。

因此,只要可以,请尽量在InnoDB上采用自增字段做主键。

解题思路:InnoDB 主键选择

考察点:InnoDB 索引数据结构,Mysql应用技能

分类:Mysql{校招,社招}

难度分级:P4,P5

 6、数据库为什么要使用MVCC,使用MVCC有什么缺点?

参考答案: 

Multi-Version Concurrency Control 多版本并发控制,因为锁机制是一种预防性的,读会阻塞写,写也会阻塞读,当锁定粒度较大,时间较长时并发性能就不会太好;而MVCC是一种后验性的,读不阻塞写,写也不阻塞读,等到提交的时候才检验是否有冲突,由于没有锁,所以读写不会相互阻塞,从而大大提升了并发性能。

缺点:通过MVCC机制,虽然让数据变得可重复读,但我们读到的数据可能是历史数据,是不及时的数据,不是数据库当前的数据!这在一=E4__对于数据的时效特别敏感的业务中,就很可能出问题。

解题思路:MVCC 

考察点: mysql 锁机制与MVCC 

分类:Mysql、锁机制、MVCC{校招,社招}

难度分级:P5

 7、如何分析慢查询,慢查询的分析步骤? 

参考答案: 

 慢查询优化基本步骤

0.先运行看看是否真的很慢,注意设置SQL_NO_CACHE
1.where条件单表查,锁定最小返回记录表。这句话的意思是把查询语句的where都应用到表中返回的记录数最小的表开始查起,单表每个字段分别查询,看哪个字段的区分度最高
2.explain查看执行计划,是否与1预期一致(从锁定记录较少的表开始查询)
3.order by limit 形式的sql语句让排序的表优先查
4.了解业务方使用场景
5.加索引时参照建索引的几大原则
6.观察结果,不符合预期继续从0分析

参考:http://tech.meituan.com/mysql-index.html 

解题思路: 

考察点:mySql查询优化 

分类:数据库,硬技能{校招,社招}

难度分级:P5

8、MySQL索引默认实现是用的什么数据结构,为什么采用这种? 

参考答案: 

B+树。

索引也是磁盘上的,磁盘的I/O存取的消耗是比内存高出几个数量级的,索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数,所以要尽量降低树的高度。要降低树的高度,因此用多分支的树,并且要树的每层的节点尽量的多,B+树将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入,由于B+Tree内节点去掉了data域,因此可以拥有更大的出度,拥有更好的性能。 

参考:http://www.marksaas.com/2014/04/mysql%E7%B4%A2%E5%BC%95%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86.html

解题思路:Mysql 索引数据结构

考察点: Mysql索引数据结构,B+树 B-树

分类:Mysql、数据结构{校招,社招}

难度分级:P4,P5

9、MySQL联合索引使用是有什么规则?如果对A,B,C做索引,那么SQL语句写成where C=X and B=X and A=X,是否还能用到该索引?如果SQL语句写成where A=X and B>X and C=X是否还能用到该索引?

参考答案:  

联合索引有最左前缀匹配原则。

where C=X and B=X and A=X能用到该索引,因为=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式。

where A=X and B>X and C=X可以用到该索引,但C是用不到索引的,因为mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配。

解题思路:联合索引最左前缀匹配原则

考察点: 是否对联合索引的匹配原则,以及所以的数据结构有过了解

分类:Mysql索引基础知识{校招,社招}

难度分级:P4,P5

10、MySQL引擎MyISAM,InnoDB有什么区别,各有什么特点?

参考答案: 

MySQL有多种存储引擎,MyISAM和InnoDB是其中常用的两种。这里介绍关于这两种引擎的一些基本概念(非深入介绍)。

MyISAM是MySQL的默认存储引擎,基于传统的ISAM类型,支持全文搜索,但不是事务安全的,而且不支持外键。每张MyISAM表存放在三个文件中:frm 文件存放表格定义;数据文件是MYD (MYData);索引文件是MYI (MYIndex)。

InnoDB是事务型引擎,支持回滚、崩溃恢复能力、多版本并发控制、ACID事务,支持行级锁定(InnoDB表的行锁不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表,如like操作时的SQL语句),以及提供与Oracle类型一致的不加锁读取方式。InnoDB存储它的表和索引在一个表空间中,表空间可以包含数个文件。 

主要区别:

MyISAM是非事务安全型的,而InnoDB是事务安全型的。

MyISAM锁的粒度是表级,而InnoDB支持行级锁定。

MyISAM支持全文类型索引,而InnoDB不支持全文索引。

MyISAM相对简单,所以在效率上要优于InnoDB,小型应用可以考虑使用MyISAM。

MyISAM表是保存成文件的形式,在跨平台的数据转移中使用MyISAM存储会省去不少的麻烦。

InnoDB表比MyISAM表更安全,可以在保证数据不会丢失的情况下,切换非事务表到事务表(alter table tablename type=innodb)。

应用场景: 

MyISAM管理非事务表。它提供高速存储和检索,以及全文搜索能力。如果应用中需要执行大量的SELECT查询,那么MyISAM是更好的选择。

InnoDB用于事务处理应用程序,具有众多特性,包括ACID事务支持。如果应用中需要执行大量的INSERT或UPDATE操作,则应该使用InnoDB,这样可以提高多用户并发操作的性能。

解题思路:MyISAM和InnoDB引擎区别 

考察点: MyISAM和InnoDB引擎的了解

分类:Mysql 

难度分级:P5

11、从性能上考虑,MySQL InnoDB 表主键如何选择,为什么?

参考答案: 

自增主键

InnoDB使用聚集索引,数据记录本身被存于主索引(一颗B+Tree)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放,因此每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(InnoDB默认为15/16),则开辟一个新的页(节点)。如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页。这样就会形成一个紧凑的索引结构,近似顺序填满。由于每次插入时也不需要移动已有数据,因此效率很高,也不会增加很多开销在维护索引上。

如果使用非自增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置,此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。 

因此,只要可以,请尽量在InnoDB上采用自增字段做主键。

解题思路:InnoDB 主键选择

考察点:InnoDB 索引数据结构,Mysql应用技能

分类:Mysql

难度分级:P4,P5

12、MySQL InnoDB默认的事务隔离级别是什么?

参考答案: 

Repeatable Read(可重复读)

解题思路:Repeatable Read(可重复读)

考察点: 数据库事务了解

分类:Mysql、事务

难度分级:P4,P5

13、应用中怎么做到对数据库的读写分离,如何避免主从延迟造成的影响?

参考答案: 

解题思路: 

考察点:  

分类:

难度分级:P5

14、如何处理组织机构树的联合查询问题?

参考答案: 

 树形结构来表征组织机构的关联关系,具体实现参考

 http://blog.csdn.net/monkey_d_meng/article/details/6647488

http://blog.csdn.net/biplusplus/article/details/7433625

解题思路:

考察点: 

分类:

难度分级:P5 

15、MySQL Explain分析,给面试者一段具体的SQL Explain 

参考答案: 

http://wiki.sankuai.com/x/-JMRBQ

解题思路:

考察点: 

 分类:

难度分级:P5

16、如何删除一个表的重复数据 

 参考答案: 

 展开原码

CREATE TABLE `poi_menu_test` (

   `id` bigint(30) NOT NULL AUTO_INCREMENT COMMENT '自增ID',

   `poi_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '门店id',

   `name` varchar(64) NOT NULL DEFAULT '' COMMENT '菜名',

   PRIMARY KEY (`id`)

 ) ENGINE=InnoDB AUTO_INCREMENT=17621402 DEFAULT CHARSET=utf8 COMMENT='poi菜品';

  

 delete pmt from poi_menu_test pmt inner join (

 select id,poi_id,name from poi_menu_test group by poi_id,name having count(*) > 1

 )tmp on tmp.poi_id = pmt.poi_id and tmp.name = pmt.name and tmp.id <> pmt.id; 

解题思路:

考察点: 

分类:社招

难度分级:P5

17、数据库事物隔离级别,每种的特点;SPRING事物传播与隔离级别的关系,如果配置的。

参考答案: 

数据事务的四种隔离级别

在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别。我们的数据库锁,也是为了构建这些隔离级别存在的。

隔离级别 脏读(Dirty Read) 不可重复读(NonRepeatable Read) 幻读(Phantom Read

未提交读(Read uncommitted) 可能 可能 可能

已提交读(Read committed) 不可能 可能 可能

可重复读(Repeatable read) 不可能 不可能 可能

可串行化(Serializable ) 不可能 不可能 不可能

未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据

提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)

可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读

串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

spring的事务隔离级别 
ISOLATION_DEFAULT:使用数据库默认的隔离级别。 
ISOLATION_READ_UNCOMMITTED:允许读取改变了的还未提交的数据,可能导致脏读、不可重复读和幻读。
ISOLATION_READ COMMITTED:允许并发事务提交之后读取,可以避免脏读,可能导致重复读和幻读。 
ISOLATION_REPEATABLE_READ:对相同字段的多次读取结果一致,可导致幻读。 
ISOLATION_SERIALIZABLE:完全服从ACID的原则,确保不发生脏读、不可重复读和幻读。 
可以根据自己的系统对数据的要求采取适应的隔离级别,因为隔离牵涉到锁定数据库中的记录,对数据正性要求越严格,并发的性能也越差。 
spring的事务传播行为 
spring事务的传播行为说的是当一个方法调用另一个方法时,事务该如何操作。 
PROPAGATION_MANDATORY:该方法必须运行在一个事务中。如果当前事务不存在则抛出异常。 
PROPAGATION_NESTED:如果当前存在一个事务,则该方法运行在一个嵌套的事务中。被嵌套的事务可以从当前事务中单独的提交和回滚。如果当前不存在事务,则开始一个新的事务。各厂商对这种传播行为的支持参差不齐,使用时需注意。 
PROPAGATION_NEVER:当前方法不应该运行在一个事务中。如果当前存在一个事务,则抛出异常。 
PROPAGATION_NOT_SUPPORTED:当前方法不应该运行在一个事务中。如果一个事务正在运行,它将在该方法的运行期间挂起。 
PROPAGATION_REQUIRED:该方法必须运行在一个事务中。如果一个事务正在运行,该方法将运行在这个事务中。否则,就开始一个新的事务。 
PROPAGATION_REQUIRES_NEW:该方法必须运行在自己的事务中。它将启动一个新的事务。如果一个现有的事务正在运行,将在这个方法的运行期间挂起。 
PROPAGATION_SUPPORTS:当前方法不需要事务处理环境,但如果一个事务已经在运行的话,这个方法也可以在这个事务里运行。 

配置方法:

<property name="transactionAttributes"> <props> <prop key="save*">PROPAGATION_REQUIRED</prop> <prop key="update*">PROPAGATION_REQUIRED</prop> <prop key="delete*">PROPAGATION_REQUIRED</prop> <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="find*">PROPAGATION_REQUIRED,ISOLATION_READ_UNCOMMITTED</prop> </props>

解题思路:

考察点: 

分类: 数据库,spring

难度分级:P5

18、如何优化查询语句,explain每个字段的含义,如果优化OR语句,IN 会用到索引吗?创建索引的顺序 
参考答案:
explain每个字段含义:Mysql explain学习总结
or语句:where语句里如果带有or条件,是可以用到索引,前提是有针对or条件所有字段的单独索引
in会用到索引
优化or语句:or条件建立单独索引,用union替代

解题思路:

考察点: mysql 索引,优化 

分类:mysql

难度分级:P5

19、每个表的数据大小是否有限制,数据过大会对性能造成影响吗?常见的一些分库分表策略  
参考答案:
mysql单表大小限制可以参考这篇文章:http://database.51cto.com/art/201011/234308.htm

这里引用一个问题为什么要分库分表呢?MySQL处理不了大的表吗?
其实是可以处理的大表的.我所经历的项目中单表物理上文件大小在80G多,单表记录数在5亿以上,而且这个表
属于一个非常核用的表:朋友关系表.

但这种方式可以说不是一个最佳方式. 因为面临文件系统如Ext3文件系统对大于大文件处理上也有许多问题.
这个层面可以用xfs文件系统进行替换.但MySQL单表太大后有一个问题是不好解决: 表结构调整相关的操作基
本不在可能.所以大项在使用中都会面监着分库分表的应用.

从Innodb本身来讲数据文件的Btree上只有两个锁, 叶子节点锁和子节点锁,可以想而知道,当发生页拆分或是添加
新叶时都会造成表里不能写入数据.

关于分表分库策略:
http://my.oschina.net/cmcm/blog/175104

解题思路:

考察点: mysql 

分类:mysql 

难度分级:P5 P6

20、如何实现主从分离,如何解决主从不一致带来的问题?

参考答案:
参考:数据库读写分离相关调研

解题思路:

考察点: MySQL

分类:MySQL

难度分级:P5 P6
21、数据库锁,如何防止覆盖更新,如何用数据库模拟队列?

参考答案:
覆盖更新可以用for update和 where 要更新的字段=更新之前的状态,判断影响记录数来实现。模拟队列需要考虑类型,优先级字段,同时用锁来避免重复同一条记录

解题思路:

考察点: MySQL,数据库

分类:数据库

难度分级:P5 P6

22、什么是乐观锁与悲观锁,如何实现乐观锁? 

参考答案: 

  • 悲观锁

正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。

  • 乐观锁

 相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。

而乐观锁机制在一定程度上解决了这个问题。乐观锁,大多是基于数据版本( Version )记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个 “version” 字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。

--补充, 当主键采用数据库表生成时(GenerationType.TABLE),采用乐观锁好还是采用悲观锁好?

这个要考虑决具体的策略? 

一般来讲,我们会根据数据生长速度(考察点,需要考虑)来申请一定数量的主键ID,比如100个,这样可以最大限度的增加主键生成的效率,减少不必要的数据库交互

这样即使在集群环境下,表访问的竞争压力并不大,因此采用=E6__观锁就可以;而且乐观锁并不一定能够防止数据的"脏写",会导致主键重复的情况发生。

要说明的是,MVCC的实现没有固定的规范,每个数据库都会有不同的实现方式,这里讨论的是InnoDB的MVCC。

参考: Innodb中的事务隔离级别和锁的关系

解题思路:

考察点:  悲观锁 乐观锁

分类: 数据库

 难度分级:P5

23、数据库连接池有哪些重要配置参数,分别起到什么作用?

标准答案: 

C3P0 拥有比 DBCP 更丰富的配置属性,通过这些属性,可以对数据源进行各种有效的控制: 
acquireIncrement :当连接池中的连接用完时, C3P0 一次性创建新连接的数目; 
acquireRetryAttempts :定义在从数据库获取新连接失败后重复尝试获取的次数,默认为 30 ; 
acquireRetryDelay :两次连接中间隔时间,单位毫秒,默认为 1000 ; 
autoCommitOnClose :连接关闭时默认将所有未提交的操作回滚。默认为 false ; 
automaticTestTable : C3P0 将建一张名为 Test 的空表,并使用其自带的查询语句进行测试。如果定义了这个参数,那么属性 preferredTestQuery 将被忽略。你 不能在这张 Test 表上进行任何操作,它将中为 C3P0 测试所用,默认为 null ; 
breakAfterAcquireFailure :获取连接失败将会引起所有等待获取连接的线程抛出异常。但是数据源仍有效保留,并在下次调 用 getConnection() 的时候继续尝试获取连接。如果设为 true ,那么在尝试获取连接失败后该数据源将申明已断开并永久关闭。默认为 false ; 
checkoutTimeout :当连接池用完时客户端调用 getConnection() 后等待获取新连接的时间,超时后将抛出 SQLException ,如设为 0 则无限期等待。单位毫秒,默认为 0 ; 
connectionTesterClassName : 通过实现 ConnectionTester 或 QueryConnectionTester 的类来测试连接,类名需设置为全限定名。默认为 com.mchange.v2.C3P0.impl.DefaultConnectionTester ; 
idleConnectionTestPeriod :隔多少秒检查所有连接池中的空闲连接,默认为 0 表示不检查; 
initialPoolSize :初始化时创建的连接数,应在 minPoolSize 与 maxPoolSize 之间取值。默认为 3 ; 
maxIdleTime :最大空闲时间,超过空闲时间的连接将被丢弃。为 0 或负数则永不丢弃。默认为 0 ; 
maxPoolSize :连接池中保留的最大连接数。默认为 15 ; 
maxStatements : JDBC 的标准参数,用以控制数据源内加载的 PreparedStatement 数量。但由于预缓存的 Statement 属 于单个 Connection 而不是整个连接池。所以设置这个参数需要考虑到多方面的因素,如果 maxStatements 与 maxStatementsPerConnection 均为 0 ,则缓存被关闭。默认为 0 ; 
maxStatementsPerConnection :连接池内单个连接所拥有的最大缓存 Statement 数。默认为 0 ; 
numHelperThreads : C3P0 是异步操作的,缓慢的 JDBC 操作通过帮助进程完成。扩展这些操作可以有效的提升性能,通过多线程实现多个操作同时被执行。默认为 3 ; 
preferredTestQuery :定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个参数能显著提高测试速度。测试的表必须在初始数据源的时候就存在。默认为 null ; 
propertyCycle : 用户修改系统配置参数执行前最多等待的秒数。默认为 300 ; 
testConnectionOnCheckout :因性能消耗大请只在需要的时候使用它。如果设为 true 那么在每个 connection 提交的时候都 将校验其有效性。建议使用 idleConnectionTestPeriod 或 automaticTestTable 
等方法来提升连接测试的性能。默认为 false ; 
testConnectionOnCheckin :如果设为 true 那么在取得连接的同时将校验连接的有效性。默认为 false 。

解题思路:同答案

考察点: 数据库连接池

分类:Spring,Mysql {社招}

难度分级:P5,P6 

Web

1、如何解决重复提交?

参考答案: 

(1)最简单:页面提交后转到另一个页面而不是本页面

      缺点: 框架内页面无法跳转. ajax无法实现.

(2)提交表单后提交按钮变灰/隐藏提交按钮

      缺点:js出错失效. 

(3)在js里设置全局变量,提交后修改该变量的值,依据变量的值判断是否重复提交

var flag=false;

function checkForm(){

    if (flag==true){

       return false;

    }

    flag=true;

    document.form1.submit();

}

    缺点: 代码冗杂, 不易维护. 代码不优雅.

(4)在登录用户的Session中,放置一个随机数作为同步标记,并在初始化新增或编辑页面时就返回到前台页面中,用隐藏域赋值,当form被提交时,form中的同步标记就和Session中的同步标记作对比。在form首次提交的时候,这两个标记应该是一样的。如果标记不一样,那么该form就会禁止提交,一个错误就会返回给用户。在用户提交一个form时,如果按下浏览器中的后退按钮并尝试重新提交同一个form时,标记就会出现不匹配的现象。
       另一方面,如果两个标记值匹配,那么我们就可以确信整个流程是正确的。在这种情况下,Session中的标记值就会被修改为一个新的值,同时允许提交该form。

    缺点: 不支持分布式. 耦合strtus框架. 

(5)为了解决(4)中不支持分布式的问题,将服务端生成的随机数存储在memcached里。

解题思路:

前端防重复提交与前后端结合防重复提交

考察点: session、分布式、web

分类:web

难度分级:P4、P5

2、如何解决跨域的SSO?

参考答案:

参考:跨域sso的实现

解题思路:

考察点:  SSO

分类:web

难度分级:P5

3、Java Servlet,Spring Control,Struts2 Action是否是单例的,为什么使用单例?

参考答案:

Java Servlet和Spring Controller 默认是单例的:性能好、不需要多例

Struts2 Action默认是原型的:struts 2的Action中包含数据,例如你在页面填写的数据就会包含在Action的成员变量里面。如果Action是单实例的话,这些数据在多线程的环境下就会相互影响,例如造成别人填写的数据被你看到了。

单例可以避免创建和销毁的开销,另外还节省空间。 

解题思路:  

考察点:web、单例模式  

分类: Spring MVC,web,设计模式 

难度分级:P4、P5

4、JDK Proxy和Cglib Proxy有什么区别?

参考答案:

jdk动态代理是由java内部的反射机制来实现的,cglib动态代理底层则是借助asm来实现的。

CGLib全称为Code Generation Library,是一个强大的高性能,高质量的代码生成类库,可以在运行期扩展Java类与实现Java接口,CGLib封装了asm,可以再运行期动态生成新的class。CGLib采用非常底层的字节码技术,可以为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,并顺势织入横切逻辑。

对比:

CGLib所创建的动态代理对象的性能比JDK所创建的代理对象性能高不少,大概10倍,但CGLib在创建代理对象时所花费的时间却比JDK动态代理多大概8倍,所以对于singleton的代理对象或者具有实例池的代理,因为无需频繁的创建新的实例,所以比较适合CGLib动态代理技术,反之则适用于JDK动态代理技术。另外,由于CGLib采用动态创建子类的方式生成代理对象,所以不能对目标类中的final,private等方法进行处理。

解题思路:

考察点: jdk动态代理、cglib动态代理  

分类:java,spring

难度分级:P4、P5

5、Spring AOP使用中是否有坑?同一个类中的方法嵌套调用,是否能用到AOP,为什么?

参考答案:

不能用到AOP,原因分析可以参考http://huqilong.blog.51cto.com/53638/732088

解题思路:

考察点:Spring AOP 

分类: java,spring

难度分级:P4、P5

6、Servlet单例  

参考答案:

Servlet容器如何采用单实例多线程的方式来处理请求。

解题思路:

考察点:  servlet容器

分类:java,web

难度分级:P4、P5

7、Spring IOC/AOP机制及其实现原理 

 参考答案:

IOC:反射

AOP:JDK 动态代理、cglib动态代理

解题思路:

考察点:

Spring IOC AOP

分类:Java,Spring

难度分级:P4、P5

8、Spring 事务的传播属性和隔离级别

参考答案: 

Spring在TransactionDefinition接口中定义这些属性

在TransactionDefinition接口中定义了五个不同的事务隔离级别

ISOLATION_DEFAULT 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.另外四个与JDBC的隔离级别相对应 
ISOLATION_READ_UNCOMMITTED 这是事务最低的隔离级别,它充许别外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读

ISOLATION_READ_COMMITTED 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。

ISOLATION_REPEATABLE_READ 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。

ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。 

在TransactionDefinition接口中定义了七个事务传播行为。

PROPAGATION_REQUIRED 如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。

PROPAGATION_SUPPORTS 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。但是对于事务同步的事务管理器,PROPAGATION_SUPPORTS与不使用事务有少许不同。

PROPAGATION_MANDATORY 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。

PROPAGATION_REQUIRES_NEW 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。

PROPAGATION_NOT_SUPPORTED 总是非事务地执行,并挂起任何存在的事务。

PROPAGATION_NEVER 总是非事务地执行,如果存在一个活动事务,则抛出异常

PROPAGATION_NESTED如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行 

解题思路:

考察点: Spring事务

分类:Java,Spring,事务

难度分级:P4、P5

安全

1、用户在登录的时候如何防止黑客拦截网络获取用户的密码 
参考答案:
http://coolshell.cn/articles/5353.html

2、SSO原理,如何解决跨域(a.meituan.com/b.meituan.com)的问题,如何解决cookie安全的问题 
参考答案:

 

原理如上图,另外可以考察一下其在应用层如何实现验证(filter)
一般情况下,ticket都是存放在cookie中,cookie是有domain概念的,即可以设置cookie域
cookie的安全问题主要是xss攻击可以盗取用户的cooike,这个可以考虑在ticket中加入一些客户端信息来解决(比如用户IP、浏览器内核信息)

3、什么是SQL注入,如何解决?

参考答案:

所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令的目的。

要防御SQL注入,用户的输入就绝对不能直接被嵌入到SQL语句中。恰恰相反,用户的输入必须进行过滤,或者使用参数化的语句。

参数化的语句使用参数而不是将用户输入嵌入到语句中。在多数情况中,SQL语句就得以修正。

解题思路:从SQL注入的概念出发,阐述如何解决

考察点: SQL注入

分类:Web安全基础{校招,社招都可以用}

难度分级:P4、P5

4、权限模型中RBAC是什么,RBAC0-3分别指什么?

在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。在一个组织中,角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以很容易地从一个角色被指派到另一个角色。角色可依新的需求和系统的合并而赋予新的权限,而权限也可根据需要而从某角色中回收。角色与角色的关系可以建立起来以囊括更广泛的客观情况。

RBAC0定义了能构成一个RBAC控制系统的最小的元素集合。在RBAC之中,包含用户users(USERS)、角色roles(ROLES)、目标objects(OBS)、操作operations(OPS)、许可权permissions(PRMS)五个基本数据元素,权限被赋予角色,而不是用户,当一个角色被指定给一个用户时,此用户就拥有了该角色所包含的权限。会话sessions是用户与激活的角色集合之间的映射。RBAC0与传统访问控制的差别在于增加一层间接性带来了灵活性,RBAC1、RBAC2、RBAC3都是先后在RBAC0上的扩展。 

 RBAC1引入角色间的继承关系,角色间的继承关系可分为一般继承关系和受限继承关系。一般继承关系仅要求角色继承关系是一个绝对偏序关系,允许角色间的多继承。而受限继承关系则进一步要求角色继承关系是一个树结构。 

RBAC2模型中添加了责任分离关系。RBAC2的约束规定了权限被赋予角色时,或角色被赋予用户时,以及当用户在某一时刻激活一个角色时所应遵循的强制性规则。责任分离包括静态责任分离和动态责任分离。约束与用户-角色-权限关系一起决定了RBAC2模型中用户的访问许可。 

RBAC3包含了RBAC1和RBAC2,既提供了角色间的继承关系,又提供了责任分离关系。

5、什么Session固定攻击?
Session fixation attack(会话固定攻击)是利用服务器的session不变机制,借他人之手获得认证和授权,然后冒充他人。
1.Mallory先打开一个网站http://unsafe,然后服务器会回复他一个session id。比如SID=mjg4qid0wioq。Mallory把这个id记下了。 
2.Mallory给Alice发送一个电子邮件,他假装是银行在宣传自己的新业务,例如,我行推出了一项新服务,率先体验请点击:http://unsafe/?SID=mjg4qid0wioq,SID后面是Mallory自己的session id。 
3.Alice被吸引了,点击了 http://unsafe/?SID=mjg4qid0wioq,像往常一样,输入了自己的帐号和口令从而登录到银行网站。 
4.因为服务器的session id不改变,现在Mallory点击 http://unsafe/?SID=mjg4qid0wioq 后,他就拥有了Alice的身份。可以为所欲为了。

6、什么是XSS攻击,如何预防和解决?

XSS(Cross Site Script),跨域(站)脚本.通过嵌入恶意构造的javascript/vbscript代码到页面中,当用户浏览时,嵌入的恶意代码会执行.

常见的XSS攻击类型有两种:

一种是反射型,攻击者诱使用户点击一个嵌入恶意脚本的链接,达到攻击的目的。如用户A可在发评论时嵌入一个带恶意js脚本的URL,当其他用户

看到评论后点击该URL,点击后就会执行一段恶意js,该js可以获取当前用户的cookie,密码等重要数据,进而伪造交易,盗窃用户财产,情报等。

另一种XSS攻击是持久型XSS攻击,黑客提交含有恶意脚本的请求,保存在被攻击站点的数据库中,用户浏览网页时,恶意脚本被包含在正常页面中,达到攻击的目的。

如在评论框中输入<script>while(true){alert(11111111);}</script>,如果未做过滤就保存到数据库中,当展示评论是,页面就会执行该段脚本,后果可想而知。

防范XSS攻击的手段主要是通过消毒和设置httponly来解决,主要有下面几种情况(相应的case请google):

对任何用户输入的内容需要进行安全过滤

对于需要进行富文本展示的,需要进行富文本过滤(情况很复杂,一方面要过滤部分标签,一方面要不影响展示)

对于不需要富文本来展示的,需要进行纯文本过滤,利用apache 的StringEscapeUtils中的方法可实现。

返回的JSON串中含有HttpRequest参数的,要对参数进行纯文本过滤

禁止将用户提交的内容不经过任何过滤就放入到页面或者直接返回(放置在javascript中)

关闭服务器的TRACE功能

禁止在页面javascript中使用未经处理的Location.hash需要对Location.hash进行encodeURI()

注意flash xss攻击

数据结构和算法

1、 LruCache或FastLruCache的实现  

参考答案:http://www.chepoo.com/lru-cache-vs-fast-lru-cache.html

2、 优先级队列的实现  

 参考答案:http://blog.csdn.net/hudashi/article/details/6942789

3、死锁的实现 

死锁的实现  展开原码

public class DeadLockTest implements Runnable {

             public boolean flag = true;

             static Object res1 = new Object();

             static Object res2 = new Object();

             public void run() {

                 if(flag) {

             /* 锁定资源res1 */

                     synchronized(res1) {

                         System.out.println("Resource 1 is locked. Waiting for Resource 2.");

                         try {

                             Thread.sleep(1000);

                         }

                         catch (InterruptedException e) {}

                 /* 锁定资源res2 */

                         synchronized(res2) {

                             System.out.println("Complete.");

                         }

                     }

                 }

                 else {

             /* 锁定资源res2 */

                     synchronized(res2) {

                         System.out.println("Resource 2 is locked. Waiting for Resource 1.");

                         try {

                             Thread.sleep(1000);

                         }

                         catch (InterruptedException e) {}

                 /* 锁定资源res1 */

                         synchronized(res1) {

                             System.out.println("Complete.");

                         }

                     }

                 }

             }

             public static void main(String[] args) {

                 DeadLockTest r1 = new DeadLockTest();

                 DeadLockTest r2 = new DeadLockTest();

                 r2.flag = false;

                 Thread t1 = new Thread(r1);

                 Thread t2 = new Thread(r2);

                 t1.start();

                 t2.start();

             }

         }

         运行结果:

         Resource 1 is locked.

         Waiting for Resource 2.

         Resource 2 is locked.

         Waiting for Resource 1.

         。。。(死锁) 

 26 实现一个线程池 

参考答案:代码略长,参考
http://blog.sina.com.cn/s/blog_825085b60101bem3.html
解题思路:
创建好一个池子(就是线程数组),然后启动每个线程(每个线程先询问任务队列(一个链表),查看队列里是否有任务,如果没有,则wait(),醒来的时候在判断任务队列,这里用wait是因为睡着后它能够十分节省资源),刚开始的时候都因为没有任务而进入阻塞状态,如果有任务加入,用Notify来唤醒线程,线程执行结束后,又进入循环等待任务,这个过程就是一个线程池的思想。
       因为每个线程处理时间不长,如果我们是按照来一个请求才创建一个线程,(1)那么服务器大部分的都是用来创建和销毁线程以及线程管理,这使得服务器使用效率低,(2)而且有多少服务就产生多少线程,这对于服务器来说是十分可怕的,虽然现在内存都大的足够了
考察点:线程池技术。

Btree+和Hash索引有什么区别?

参考答案:

Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-Tree 索引。

可能很多人又有疑问了,既然 Hash 索引的效率要比 B-Tree 高很多,为什么大家不都用 Hash 索引而还要使用 B-Tree 索引呢?任何事物都是有两面性的,Hash 索引也一样,虽然 Hash 索引效率高,但是 Hash 索引本身由于其特殊性也带来了很多限制和弊端,主要有以下这些。

(1)Hash 索引仅仅能满足"=","IN"和"<=>"查询,不能使用范围查询。

由于 Hash 索引比较的是进行 Hash 运算之后的 Hash 值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的 Hash 算法处理之后的 Hash 值的大小关系,并不能保证和Hash运算前完全一样。

(2)Hash 索引无法被用来避免数据的排序操_=9C。

由于 Hash 索引中存放的是经过 Hash 计算之后的 Hash 值,而且Hash值的大小关系并不一定和 Hash 运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算;

(3)Hash 索引不能利用部分索引键查询。

对于组合索引,Hash 索引在计算 Hash 值的时候是组合索引键合并后再一起计算 Hash 值,而不是单独计算 Hash 值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash 索引也无法被利用。

(4)Hash 索引在任何时候都不能避免表扫描。

前面已经知道,Hash 索引是将索引键通过 Hash 运算之后,将 Hash运算结果的 Hash 值和所对应的行指针信息存放于一个 Hash 表中,由于不同索引键存在相同 Hash 值,所以即使取满足某个 Hash 键值的数据的记录条数,也无法从 Hash 索引中直接完成查询,还是要通过访问表中的实际数据进行相应的比较,并得到相应的结果。

(5)Hash 索引遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高。

对于选择性比较低的索引键,如果创建 Hash 索引,那么将会存在大量记录指针信息存于同一个 Hash 值相关联。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能低下。

hash相当于把key通过hash函数计算,得到key的hash值,再用这个hash值做指针,查找hash表中是否存在key,如果存在就返回 key所对应的value,选定一个好的hash函数很重要,好的hash函数可以使计算出的hash值分布均匀,降低冲突,只有冲突减小了,才会降低 hash表的查找时间。

b-tree完全基于key的比较,和二叉树相同的道理,相当于建个排序后的数据集,使用二分法查找算法,实际上也非常快,而且受数据量增长影响非常小。

解题思路:

同参考答案

考察点: 

hash索引、B+树索引

分类:

mysql,数据结构

难度分级:P4、P5

TOP N问题,如果从最大的M个数字取最大的N个数字? 

最大的N个数  展开原码

#include <stdio.h>  

 #include <stdlib.h>  

 #define MAXLEN 123456  

 #define K 100  

   

 //  

 void HeapAdjust(int array[], int i, int Length)  

 {  

     int child,temp;  

     for(temp=array[i];2*i+1<Length;i=child)  

     {  

         child = 2*i+1;  

         if(child<Length-1 && array[child+1]<array[child])  

             child++;  

         if (temp>array[child])  

             array[i]=array[child];  

         else  

             break;  

         array[child]=temp;  

     }  

 }  

   

 void Swap(int* a,int* b)  

 {  

     *a=*a^*b;  

     *b=*a^*b;  

     *a=*a^*b;  

 }  

   

 int GetMin(int array[], int Length,int k)  

 {  

     int min=array[0];  

     Swap(&array[0],&array[Length-1]);  

       

     int child,temp;  

     int i=0,j=k-1;  

     for (temp=array[0]; j>0 && 2*i+1<Length; --j,i=child)  

     {  

         child = 2*i+1;  

         if(child<Length-1 && array[child+1]<array[child])  

             child++;  

         if (temp>array[child])  

             array[i]=array[child];  

         else  

             break;  

         array[child]=temp;  

     }  

       

     return min;  

 }  

   

 void Kmin(int array[] , int Length , int k)  

 {  

     for(int i=Length/2-1;i>=0;--i)   

         //初始建堆,时间复杂度为O(n)  

         HeapAdjust(array,i,Length);  

       

     int j=Length;  

     for(i=k;i>0;--i,--j)   

         //k次循环,每次循环的复杂度最多为k次交换,复杂度为o(k^2)  

     {  

         int min=GetMin(array,j,i);  

         printf("%d,", min);  

     }  

 }  

   

 int main()  

 {  

     int array[MAXLEN];  

     for(int i=MAXLEN;i>0;--i)  

         array[MAXLEN-i] = i;  

       

     Kmin(array,MAXLEN,K);  

     return 0;  

 }  

 打印字符串的全排列 --by 岳小均

打印字符串的全排列  展开原码

 #include<iostream>  

 using namespace std;  

 #include<assert.h>  

 void Permutation(char* pStr, char* pBegin)  

 {  

    assert(pStr && pBegin);  

     if(*pBegin == '\0')  

         printf("%s\n",pStr);  

     else  

     {  

        for(char* pCh = pBegin; *pCh != '\0'; pCh++)  

         {  

             swap(*pBegin,*pCh);  

             Permutation(pStr, pBegin+1);  

             swap(*pBegin,*pCh);  

         }  

     }  

 } 

  

 //k表示当前选取到第几个数,m表示共有多少个数  

 void Permutation(char* pStr,int k,int m)  

 {  

     assert(pStr);    

     if(k == m)  

     {  

         static int num = 1;  //局部静态变量,用来统计全排列的个数  

         printf("第%d个排列\t%s\n",num++,pStr);  

     }  

     else  

     {  

         for(int i = k; i <= m; i++)  

         {  

            swap(*(pStr+k),*(pStr+i));  

             Permutation(pStr, k + 1 , m);  

             swap(*(pStr+k),*(pStr+i));  

         }  

     }  

 }   

分析访问日志中排名前一百的IP或url的次数排名,使用脚本实现  --by 岳小均

输入样例  展开原码

10.64.22.234 - - [05/Aug/2014:16:06:28 +0800] "GET /api/monitor/alive HTTP/1.0" 200 0

 10.64.15.17 - - [05/Aug/2014:16:06:28 +0800] "GET /requestAudit/list?claim=1&allocate=1&dealStatus=1&cityId=0&begin=2014-07-31&end=2014-08-05 HTTP/1.0" 200 0

 10.64.15.9 - - [05/Aug/2014:16:06:28 +0800] "GET /predeal/schedule/list?cityid=9999 HTTP/1.0" 200 0

 10.64.15.17 - - [05/Aug/2014:16:06:28 +0800] "GET /planTask/create?contractId=1bcb5bad-1b9d-11e4-bd47-561e9284ddc9&productId=d6ec15af-1ba8-11e4-bd47-561e9284ddc9 HTTP/1.0" 200 0

 10.64.15.9 - - [05/Aug/2014:16:06:28 +0800] "GET /bankInfo/bankBranch/list?cityId=52&bankId=6&q= HTTP/1.0" 200 0

 10.64.15.9 - - [05/Aug/2014:16:06:28 +0800] "POST /requestAudit/list/data HTTP/1.0" 200 0

 10.64.15.9 - - [05/Aug/2014:16:06:29 +0800] "GET /product/show?contractId=2ce88139-a3a8-11e3-8fb0-a254baaa25bb HTTP/1.0" 200 0

 10.64.15.9 - - [05/Aug/2014:16:06:29 +0800] "POST /apply/list2 HTTP/1.0" 200 0

 10.64.15.17 - - [05/Aug/2014:16:06:29 +0800] "POST /plan/schedule/workbench/queue/check HTTP/1.0" 200 0

 10.64.15.17 - - [05/Aug/2014:16:06:29 +0800] "GET /change/show?contractId=010be30e-6081-11e2-b10d-782bcb477890 HTTP/1.0" 200 0

标注答案:

awk '{print $1}' source.txt|uniq -c|sort -rn|head -100

解题思路:

考察点:shell 命令

分类:shell

难度分级:P5

打印目录树 

参考:打印文件树形结构目录_张赛勇

将十进制转为N进制 

参考:http://blog.csdn.net/cslience/article/details/16842643

工程实践 

1、如果简单用HashMap实现一个本地缓存,集群环境下同memcache相比存在哪些问题?

参考答案: 

1、本地内存缓存随着应用服务器的重启将会失效;

2、不同机器缓存不一致;

3、如果内存容量不够,可能溢出,缺乏淘汰机制;

4,并发问题;

解题思路:

考察点: Ehcache Memcached

分类:开发经验{社招}

难度分级:P5

2、什么是一致性Hash,是在Sever端还是Client端实现?

标准答案:

一致性Hash采用某种Hash算法,将整个Hash值空间组成一个虚拟的圆环,整个空间按照顺时针方向组织,然后以服务器的ip或者主机名为关键字进行Hash,确定服务器在圆环的位置。存储数据时采用Hash函数计算数据在圆环的位置。查找数据时根据hash获取数据位于哪台服务器,并按照顺时针方向查找。在动态变化的Cache环境环境中,一致性Hash满足平衡性、单调性、分散性和负载。

一致性Hash在客户端实现。

解题思路:

考察点: Memcached

分类:开发经验{社招}

难度分级:P5

Solr

1、什么是GeoHash?

参考答案:

GeoHash是一种基于Base32的编码方式,根据一定规则将二纬经纬度坐标转变成一维字符串,将基于地理位置相关的搜索由对坐标的匹配转变成计算坐标对应的字符串的相似度。以坐标(116.3906,39.9232)为例,采用二分法将经度编码,每次二分时如果目标经度116.3906在低区间则编码为0否则编码为1,假设划分15次则得到的经度116.3906的0、1编码为1 1 0 1 0 0 1 0 1 1 0 0 0 1 0,划分过程如图。同理得到39.9232的编码为1 0 1 1 1 0 0 0 1 1 0 0 0 1 1,以奇数位纬度编码,偶数位经度编码得到二进制字符码,然后采用基于Base32的编码方式得到该坐标对应的字符串。在GeoHash编码中字符串越长精度越高,字符串相似度越高,两坐标点距离越近,利用字符串的这个性质可是进行基于地理位置的搜索。 

解题思路:

考察点:  solr空间搜索 GeoHash 

分类:_=BC_发经验{社招}

难度分级:P5

Lucene

1、Lucene索引过程 

a)将待索引文档传给分词组件  (Tokenizer)。
分词组件(Tokenizer)会做以下几件事情(此过程称为 Tokenize):
1.  将文档分成一个一个单独的单词。
2.  去除标点符号。
3.  去除停词(Stop word)

b)将 得 到 的 词 元 (Token) 传给语言处理组件(Linguistic Processor)。
语言处理组件(linguistic processor)主要是对得到的词元(Token)做一些同语言相关的处理。
对于英语,语言处理组件(Linguistic Processor)一般做以下几点:
1.  变为小写(Lowercase)。
2.  将单词缩减为词根形式,如“cars”到“car”等。这种操作称为:stemming。
3.  将单词转变为词根形式,如“drove”到“drive”等。这种操作称为:lemmatization。

c)将得到的词传(Term)给索引组件 (Indexer)

1.利用得到的词 (Term)创建一个字典

2.对字典按字母顺序进行排序

3.合并相同的词(Term)成为文档倒排(Posting List)链表

2、Lucene搜索过程 --by 曾绿麟

      搜索的过程总的来说就是将词典及倒排表信息从索引中读出来,根据用户输入的查询语句合并倒排表,得到结果文档集并对文档进行打分的过程。

  1. IndexReader打开索引文件,读取并打开指向索引文件的流。
  2. 用户输入查询语句
  3. 将查询语句转换为查询对象Query对象树
  4. 构造Weight对象树,用于计算词的权重Term Weight,也即计算打分公式中与仅与搜索语句相关与文档无关的部分(红色部分)。
  5. 构造Scorer对象树,用于计算打分(TermScorer.score())。
  6. 在构造Scorer对象树的过程中,其叶子节点的TermScorer会将词典和倒排表从索引中读出来。
  7. 构造SumScorer对象树,其是为了方便合并倒排表对Scorer对象树的从新组织,它的叶子节点仍为TermScorer,包含词典和倒排表。此步将倒排表合并后得到结果文档集,并对结果文档计算打分公式中的蓝色部分。打分公式中的求和符合,并非简单的相加,而是根据子查询倒排表的合并方式(与或非)来对子查询的打分求和,计算出父查询的打分。
  8. 将收集的结果集合及打分返回给用户。

3、Lucene 实时搜索设计(2 ram 1disk,zoie) 

参考答案:

 http://sling2007.blog.163.com/blog/static/84732713201352011445771/ 

http://www.cnblogs.com/forfuture1978/archive/2010/11/29/1891476.html

4、Lucene tf/idf公式理解 

参考答案:

Lucene在进行关键词查询的时候,默认用TF-IDF算法来计算关键词和文档的相关性,用这个数据排序

TF:词频,IDF:逆向文档频率,TF-IDF是一种统计方法,或者被称为 向量空间模型,名字听起来很复杂,但是它其实只包含了两个简单规则

  1. 某个词或短语在一篇文章中出现的次数越多,越相关
  2. 整个文档集合中包含某个词的文档数量越少,这个词越重要

所以一个term的TF-IDF相关性等于 TF * IDF

这两个规则非常简单,这就是TF-IDF的核心规则,第二个的规则其实有缺陷的,他单纯地认为文本频率小的单词就越重要,文本频率大的单词就越无用,显然这并不是完全正确的。并不能有效地反映单词的重要程度和特征词的分布情况,比如说搜索web文档的时候,处于HTML不同结构的特征词中对文章内容的反映程度不同,应该有不同的权重

TF-IDF的优点是算法简单,运算速度很快

Lucene为了提高可编程行,在上述规则做了一些扩充,就是加入一些编程接口,对不同的查询做了权重归一化处理,但是核心公式还是TF * IDF

Lucene算法公式如下

score(q,d) = coord(q,d) · queryNorm(q) · ∑ ( tf(t in d) · idf(t)2 · t.getBoost() · norm(t,d) )

  • tf(t in d ), = frequency½
  • idf(t) = 1 +log(文档总数/(包含t的文档数+1))
  • coord(q,d) 评分因子,。越多的查询项在一个文档中,说明些文档的匹配程序越高,比如说,查询"A B C",那么同时包含A/B/C3个词的文档 是3分,只包含A/B的文档是2分,coord可以在query中关掉的
  • queryNorm(q)查询的标准查询,使不同查询之间可以比较
  • t.getBoost() 和 norm(t,d) 都是提供的可编程接口,可以调整 field/文档/query项 的权重

各种编程插口显得很麻烦,可以不使用,所以我们可以把Lucence的算分公式进行简化

score(q,d) = coord(q,d) · ∑ ( tf(t in d) · idf(t)2 )

总之

TF-IDF 算法是以 term为基础的,term就是最小的分词单元,这说明分词算法对基于统计的ranking无比重要,如果你对中文用单字切分,那么就会损失所有的语义相关性,这个时候 搜索只是当做一种高效的全文匹配方法

按照规则1 某个_=8D或短语在一篇文章中出现的次数越多,越相关 一定要去除掉stop word,因为这些词出现的频率太高了,也就是TF的值很大,会严重干扰算分结果

TF在生成索引的时候,就会计算出来并保存,而IDF是在query的时候获取,包含t的文档数= length(term的posting list)

5、Lucene 自定义排序 

参考答案: http://zhxmyself.iteye.com/blog/478638 

6、 FieldComparatorSource,similarity,collector 

参考答案:

通过继承FieldComparatorSource实现其newComparator方法,可以根据自己的业务规则实现自定义排序

similarity:Lucene的搜索结果打分控制模块.参考文献:http://my.oschina.net/BreathL/blog/51498

Lucene Collector用于收集搜索之后的文档,可以方便做filter等,主要接口有setScorer,collect,setNextReader,acceptsDocsOutOfOrder

7、Lucene采用了什么样的数据结构提高查询的性能?--by 刘柳

跳跃表 倒排索引

设计模式

1、写一个Double Check的单例模式 

参考答案:

双重检查单例模式代码  展开原码

public class Singleton(){

         private volatile static Singleton singleton;

         private Singleton(){};

         public static Singleton getInstance(){

            if(singleton == null){

                synchronized (Singleton.class);

                if(singleton == null){

                    singleton = new Singleton();

                }

            }

            return singleton;

         }

 } 

解题思路:Double Check地方 volatile关键字使用 私有构造方法

考察点: 单例模式  

分类:设计模式{校招,社招} 

难度分级:P4,P5

2、单例模式中,Java关键字Volatile的作用是什么?

参考答案:

Java中new一个对象并不是原子操作,其中由于Java编译器允许处理器乱序执行(out-of-order),以及JDK1.5之前JMM(Java Memory Medel)中Cache、寄存器到主内存回写顺序的规定,初始化构造器和将对象指向分配的内存空间执行顺序不确定,如果第一个线程创建实例的顺序是先分配空间,再初始化构造器。这是如果在这两个步骤之间切换线程,则另外一个线程判断实例不为空,将直接取走实例,这是实例被没有被初始化。JDK1.5之后引入Volatile解决这个问题。

解题思路:理解java new构造方法并不是原子操作,举出出问题场景

考察点: 单例模式多线程问题 java new构造方法操作 

分类:设计模式{社招}

难度分级:P5

3、在JAVA源码里,哪里用到了单例模式?

参考答案:

RunTime类(Calendar不是设计模式) 

解题思路: 

考察点: java开发经验 自学能力  

分类:设计模式 自学能力{社招}

难度分级:P5

4、Tomcat源码中使用了哪些重要的设计模式,分别用在做什么?

参考答案:

外观模式 观察模式 责任链模式 命令模式 模板模式 

应用参考:http://imtiger.net/blog/2013/11/08/tomcat-design-pattern/

解题思路: 

考察点: java开发经验 自学能力  设计模式 Tomcat 

分类:设计模式 自学能力 Tomcat{社招}

难度分级:P5 

5、单例模式与静态方法类的区别,单例模式的两种写法,在哪种场景下选择哪种写法,多线程下的问题;spring采取的是那种单例模式,为什么? 

参考答案: 

单例模式与静态=E6__法区别:1、静态类比单例具有更好的性能。2、静态类方法不能覆盖,单例类可以通过继成方式覆盖。3、静态类很难模拟,难于单例测试。4、静态类适合维护状态信息。5、单例类可以懒加载。6、许多依赖注入的框架对单例都有良好的管理,使用它们非常容易。

此处只列举单例模式两种简单的写法:

单例模式写法  展开原码

饿汉式单例模式

 public class SingletonKerrigan {  

           

     private static SingletonKerrigan instance = new SingletonKerrigan();  

      

     public static SingletonKerrigan getInstance() {  

         return instance;  

     }  

 }

  

 懒汉式单例模式

 public class SingletonKerrigan {  

            

     private static SingletonKerrigan instance = null;  

      

     public static SingletonKerrigan getInstance() {  

         if (instance == null) {                                

             instance = new SingletonKerrigan();            

         }  

         return instance;  

     }  

 }

多线程下问题:Java中new一个对象并不是原子操作,其中由于Java编译器允许处理器乱序执行(out-of-order),以及JDK1.5之前JMM(Java Memory Medel)中Cache、寄存器到主内存回写顺序的规定,初始化构造器和将对象指向分配的内存空间执行顺序不确定,如果第一个线程创建实例的顺序是先分配空间,再初始化构造器。这是如果在这两个步骤之间切换线程,则另外一个线程判断实例不为空,将直接取走实例,这时实例被没有被初始化。JDK1.5之后引入Volatile解决这个问题。可以采用Double Check的单例模式解决多线程问题

Double Check单例模式  展开原码

public class Singleton(){

         private volatile static Singleton singleton;

         private Singleton(){};

         public static Singleton getInstance(){

            if(singleton == null){

                synchronized (Singleton.class);

                if(singleton == null){

                    singleton = new Singleton();

                }

            }

            return singleton;

         }        

 }

Spring 采用注册表的方式实现单例模式。Spring默认是提前实例化Bean,即采用饿汉式方式实现。可以通过配置default-lazy-init="true"实现延迟加载,即懒汉式单例模式。一般工程采用延迟加载模式,避免系统启动初期创建大量的Bean占用资源,影响性能。

解题思路: 

考察点: java开发经验 自学能力  设计模式 Spring

分类:设计模式 自学能力 Spring{社招}

难度分级:P5 

6、代理模式和装饰模式的区别的是什么,实现代理模式有几种方式,优缺点,spring是怎么实现的,为什么? 

参考答案:

代理模式和装饰模式的区别:1)代理模式主要是控制对象的访问行为,装饰器模式主要是为对象添加行为。2)静态代理和装饰器模式实现非常相似,而动态代理则基于反射机制实现。3)代理模式并不关心被代理的对象,装饰器模式必须明确知道被装饰的对象。

代理模式实现:代理模式分为静态代理和动态代理。静态代理由程序员创建或特定工具自动生成源代码,再对其编译,使用时已经存在。动态代理主要基于Java反射机制实现。动态代理实现分为JDK动态代理和Cglib动态代理。

代理模式实现方式优缺点:静态代理每一个代理类只能为一个接口服务,这样一来程序开发中必然会产生过多的代理和重复代码,所以工程实践中常用动态代理。JDK动态代理依赖于接口实现,如果被代理类并、没有实现接口,则不能使用JDK代理。cglib代理采用继承方式实现,故不能对final修饰的类进行代理。

解题思路: 

考察点: java开发经验 自学能力  设计模式 Spring

分类:设计模式 自学能力 Spring{社招}

难度分级:P5

7、当前有一个缓存模块需要重构,你能想到几种设计模式?

参考答案:

工厂模式 单例模式 享元模式,监听者模式,模板方法模式

解题思路: 

考察点: java开发经验 自学能力  设计模式 缓存

分类:设计模式 自学能力{社招}

难度分级:P5

8、面向对象设计中is-a和has-a的关系?

参考答案: 

is-a表示的是属于关系,_=9F_于类继承或接口实现,比如兔子属于一种动物(继承关系)。

has-a表示组合,包含关系,是基于用法(即引用)而不是继承,比如兔子包含有腿,头等组件,不能说兔子腿是属于一种兔子。

解题思路:基本概念

考察点: 面向对象基本概念

分类:设计模式{校招,社招都可以用}

难度分级:P4

9、简单工厂模式和工厂模式的区别? 

参考答案:

实现角度:简单工厂具有工厂类、抽象产品、具体产品三个角色,其中工厂类统一负责生成所有的类实例。工厂模式具有抽象工厂、具体工厂、抽象产品、具体产品四个角色。根据类的属性定义不对的具体工厂。

使用角度:简单工厂适用于类关系不复杂的情况、工厂模式适用于类关系复杂,对扩展要求高的情况。

解题思路:从简单工厂和工厂类实现方面思考,不是简单背诵

考察点: 设计模式工厂模式

分类:设计模式{校招}

难度分级:P4

系统设计

1、日志报警系统设计 

参考答案:

开放性设计题,无标准答案。收集,存储,分类,处理,报警

解题思路:

考察点: 日志系统,报警系统

分类:{社招}

难度分级:P5 

2、Memcached 缓存系统设计 

参考答案:

 开放性设计题,无标准答案。一致性hash,内存分配,扩容处理,cache穿透导致的雪崩效应的处理

解题思路:

考察点: 缓存系统

分类:{社招}

难度分级:P5

3、SOA,服务化的好处 

参考答案:

soa 通讯协议,序列化协议,服务注册,服务降级,水平扩展等

减少数据库连接,压榨服务器性能等

解题思路:

考察点: SOA,服务化

分类:{社招} 

难度分级:P5

4、lvs/F5,ngnix,tomcat/jetty

四层负载均衡和7层负载均衡,负载均衡策略算法(rr,ip hash,weight rr)

反向代理

5、对于高可用和一致性的理解 

参考答案:

CAP定理

解题思路:

考察点: 可用性,一致性

分类:{社招}

难度分级:P5

6、性能指标 

参考答案:

95%,90%,50%响应时间,qps等

解题思路:

考察点:

分类:{社招} 

难度分级:P5

7、系统可扩展性设计 

参考答案:akf cube

解题思路:

考察点:

分类:{社招} 

难度分级:P6

8、垃圾邮件分类    

参考答案:

朴素贝叶斯分类器,复合概率公式

解题思路:

考察点:

分类:{社招} 

难度分级:P5

9、是否用过缓存,如何保持数据库与缓存的一致性?

参考答案:

主动失效、被动失效、定期更新、事务保证。

解题思路:

考察点:

分类:{社招} 

难度分级:P5

10、动态表单的设计思路 

参考答案:

业务表单表、业务元素表、业务元素与表单对应表、基础元素表;

解题思路:

考察点:

分类:{社招} 

难度分级:P5

面试理念

Java涉及面较广。

基础知识:有些工作中常用到的细节,必须过关,起码要意识到有疑问,知道要确认一下才能用。能够从Java底层概念、Java应用层概念、Java设计理念推理出这些细节的,融会贯通的,尤佳。一些跟特定领域相关的知识细节,视候选人情况而定。一般结合候选人能力来看,以其能力,掌握到这个知识水平就能保证不出问题或达到更高要求即可。

大厂面经:一般考察的比较底层,比较深入。可以用来考察是否有研究精神,潜力是否足够。最好结合候选人的实践经历来面。

时事政治:一般是做JVM定制化的某大神,日常的小研究。

基础题目

一般而言,即便没有专门刷过题,也会在工作中自然而然就已掌握(否则代码质量就堪忧了)。但若候选人其他方面展示了强大的学习能力或其他美好素质,一些知识性的(尤其是某些领域特定的)题目可不作要求。

  1. 面向对象的特征有哪些方面?
  2. 简述一下面向对象的"六原则一法则"。 
     参考答案
     
  3. 简述一下你了解的设计模式。
     参考答案
     
  4. 访问修饰符public,private,protected,以及不写(默认)时的区别?
  5. String 是最基本的数据类型吗?
  6. float f=3.4;是否正确?
  7. short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗?
  8. Java有没有goto?
  9. int和Integer有什么区别?
  10. &和&&的区别?
  11. 解释内存中的栈(stack)、堆(heap)和方法区(method area)的用法。
  12. Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?
  13. switch 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上?
  14. 用最有效率的方法计算2乘以8?
  15. 数组有没有length()方法?String有没有length()方法?
  16. 在Java中,如何跳出当前的多重嵌套循环?
  17. 构造器(constructor)是否可被重写(override)?
  18. 两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
  19. 是否可以继承String类?
  20. 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
  21. String和StringBuilder、StringBuffer的区别?
  22. 重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?
  23. 描述一下JVM加载class文件的原理机制?
  24. char 型变量中能不能存贮一个中文汉字,为什么?
  25. 抽象类(abstract class)和接口(interface)有什么异同?
  26. 静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同?
  27. Java 中会存在内存泄漏吗,请简单描述。
  28. 抽象的(abstract)方法是否可同时是静态的(static),是否可同时是本地方法(native),是否可同时被synchronized修饰?
  29. 阐述静态变量和实例变量的区别。
  30. 是否可以从一个静态(static)方法内部发出对非静态(non-static)方法的调用?
  31. 如何实现对象克隆?
  32. GC是什么?为什么要有GC?
  33. String s = new String("xyz");创建了几个字符串对象? ??
  34. 接口是否可继承(extends)接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concrete class)?
  35. 一个".java"源文件中是否可以包含多个类(不是内部类)?有什么限制?
  36. Anonymous Inner Class(匿名内部类)是否可以继承其它类?是否可以实现接口?
  37. 内部类可以引用它的包含类(外部类)的成员吗?有没有什么限制?
  38. Java 中的final关键字有哪些用法?
  39. 指出下面程序的运行结果。
     展开原码
  40. Error和Exception有什么区别? 
  41. try{}里有一个return语句,那么紧跟在这个try后的finally{}里的代码会不会被执行,什么时候被执行,在return前还是后? 
  42. Java语言如何进行异常处理,关键字:throws、throw、try、catch、finally分别如何使用? 
  43. 运行时异常与受检异常有何异同? 
  44. 说出下面代码的输出是什么?
     展开原码
  45. 列出一些你常见的运行时异常?
  46. 阐述final、finally、finalize的区别。
  47. List、Set、Map是否继承自Collection接口? 
  48. 阐述ArrayList、Vector、LinkedList的存储性能和特性。 
  49. Collection和Collections的区别? 
  50. List、Map、Set三个接口存取元素时,各有什么特点? 
  51. TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素? 
  52. Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别? 
     参考答案
     
  53. 线程的sleep()方法和yield()方法有什么区别?
     参考答案
     
  54. 当一个线程进入一个对象的synchronized方法A之后,其它线程是否可进入此对象的synchronized方法B?
     参考答案
     
  55. 请说出与线程同步以及线程调度相关的方法。 
     参考答案
     
  56. synchronized关键字的用法?
  57. 举例说明同步和异步。 
  58. 启动一个线程是调用run()还是start()方法? 
  59. 什么是线程池(thread pool)?
     参考答案
     
  60. 线程的基本状态以及状态之间的关系?
     参考答案
     
  61. 简述synchronized 和java.util.concurrent.locks.Lock的异同?
  62. Java中如何实现序列化,有什么意义?
  63. Java中有几种类型的流? 
  64. 阐述JDBC操作数据库的步骤。
  65. Statement和PreparedStatement有什么区别?哪个性能更好? 
  66. 使用JDBC操作数据库时,如何提升读取数据的性能?如何提升更新数据的性能? 
  67. 在进行数据库编程时,连接池有什么作用? 
  68. 什么是DAO模式? 
  69. 事务的ACID是指什么? 
     参考答案
     
  70. JDBC中如何进行事务处理? 
     参考答案
     
  71. JDBC能否处理Blob和Clob? 
     参考答案
     
  72. 简述正则表达式及其用途。
  73. Java中是如何支持正则表达式操作的?
  74. 获得一个类的类对象有哪些方式? 
     参考答案
     
  75. 如何通过反射创建对象? 
     参考答案
     
  76. 如何通过反射获取和设置对象私有字段的值? 
     参考答案
     
  77. 如何通过反射调用对象的方法?
  78. 用Java写一个单例类。
  79. 什么是UML? 
  80. UML中有哪些常用的图?
     参考答案
     
  81. 阐述Servlet和CGI的区别?
  82. Servlet接口中有哪些方法? 
     参考答案

     
  83. 转发(forward)和重定向(redirect)的区别?
     仅作参考
     
  84. get和post请求的区别? 
     仅作参考
     
  85. 常用的Web服务器有哪些? 
  86. 讲解JSP中的四种作用域。
     参考答案
     
  87. 实现会话跟踪的技术有哪些? 
     参考答案
     
  88. 过滤器有哪些作用和用法? 
     参考答案
     
  89. 监听器有哪些作用和用法?
  90. web.xml文件中可以配置哪些内容? 
  91. Servlet 3中的异步处理指的是什么? 
  92. 什么是IoC和DI?DI是如何实现的?
     参考答案
     
  93. Spring中Bean的作用域有哪些? 
     参考答案
     
  94. 解释一下什么叫AOP(面向切面编程)? 
  95. 你是如何理解"横切关注"这个概念的? 
  96. 你如何理解AOP中的连接点(Joinpoint)、切点(Pointcut)、增强(Advice)、引介(Introduction)、织入(Weaving)、切面(Aspect)这些概念? 
     参考答案


     
  97. Spring中自动装配的方式有哪些? 
     参考答案


     
  98. Spring中如何使用注解来配置Bean?有哪些相关的注解?
     参考答案


     
  99. Spring支持的事务管理类型有哪些?你在项目中使用哪种方式?
     参考答案


     
  100. Spring MVC的工作原理是怎样的? 
     参考答案


     
  101. 选择使用Spring框架的原因(Spring框架为企业级开发带来的好处有哪些)? 
     参考答案
     
  102. Spring IoC容器配置Bean的方式?
     参考答案
     
  103. 阐述Spring框架中Bean的生命周期?
     参考答案
     

大厂面经

Volatile的特征:

A、原子性 B、可见性

Volatile的内存语义:

当写一个volatile变量时,JMM会把线程对应的本地内存中的共享变量值刷新到主内存。

当读一个volatile变量时,JMM会把线程对应的本地内存置为无效,线程接下来将从主内存中读取共享变量。

Volatile的重排序

1、当第二个操作为volatile写操做时,不管第一个操作是什么(普通读写或者volatile读写),都不能进行重排序。这个规则确保volatile写之前的所有操作都不会被重排序到volatile之后;

2、当第一个操作为volatile读操作时,不管第二个操作是什么,都不能进行重排序。这个规则确保volatile读之后的所有操作都不会被重排序到volatile之前;

3、当第一个操作是volatile写操作时,第二个操作是volatile读操作,不能进行重排序。

这个规则和前面两个规则一起构成了:两个volatile变量操作不能够进行重排序;

除以上三种情况以外可以进行重排序。

比如:

1、第一个操作是普通变量读/写,第二个是volatile变量的读; 2、第一个操作是volatile变量的写,第二个是普通变量的读/写;

内存屏障/内存栅栏

内存屏障(Memory Barrier,或有时叫做内存栅栏,Memory Fence)是一种CPU指令,用于控制特定条件下的重排序和内存可见性问题。Java编译器也会根据内存屏障的规则禁止重排序。(也就是让一个CPU处理单元中的内存状态对其它处理单元可见的一项技术。)

内存屏障可以被分为以下几种类型:

LoadLoad屏障:对于这样的语句Load1; LoadLoad; Load2,在Load2及后续读取操作要读取的数据被访问前,保证Load1要读取的数据被读取完毕。

StoreStore屏障:对于这样的语句Store1; StoreStore; Store2,在Store2及后续写入操作执行前,保证Store1的写入操作对其它处理器可见。

LoadStore屏障:对于这样的语句Load1; LoadStore; Store2,在Store2及后续写入操作被刷出前,保证Load1要读取的数据被读取完毕。

StoreLoad屏障:对于这样的语句Store1; StoreLoad; Load2,在Load2及后续所有读取操作执行前,保证Store1的写入对所有处理器可见。它的开销是四种屏障中最大的。

在大多数处理器的实现中,这个屏障是个万能屏障,兼具其它三种内存屏障的功能。

内存屏障阻碍了CPU采用优化技术来降低内存操作延迟,必须考虑因此带来的性能损失。为了达到最佳性能,最好是把要解决的问题模块化,这样处理器可以按单元执行任务,然后在任务单元的边界放上所有需要的内存屏障。采用这个方法可以让处理器不受限的执行一个任务单元。合理的内存屏障组合还有一个好处是:缓冲区在第一次被刷后开销会减少,因为再填充改缓冲区不需要额外工作了。

happens-before原则

Java是如何实现跨平台的?

跨平台是怎样实现的呢?这就要谈及Java虚拟机(Java Virtual Machine,简称 JVM)。

JVM也是一个软件,不同的平台有不同的版本。我们编写的Java源码,编译后会生成一种 .class 文件,称为字节码文件。Java虚拟机就是负责将字节码文件翻译成特定平台下的机器码然后运行。也就是说,只要在不同平台上安装对应的JVM,就可以运行字节码文件,运行我们编写的Java程序。

而这个过程中,我们编写的Java程序没有做任何改变,仅仅是通过JVM这一”中间层“,就能在不同平台上运行,真正实现了”一次编译,到处运行“的目的。

JVM是一个”桥梁“,是一个”中间件“,是实现跨平台的关键,Java代码首先被编译成字节码文件,再由JVM将字节码文件翻译成机器语言,从而达到运行Java程序的目的。

注意:编译的结果不是生成机器码,而是生成字节码,字节码不能直接运行,必须通过JVM翻译成机器码才能运行。不同平台下编译生成的字节码是一样的,但是由JVM翻译成的机器码却不一样。

所以,运行Java程序必须有JVM的支持,因为编译的结果不是机器码,必须要经过JVM的再次翻译才能执行。即使你将Java程序打包成可执行文件(例如 .exe),仍然需要JVM的支持。

注意:跨平台的是Java程序,不是JVM。JVM是用C/C++开发的,是编译后的机器码,不能跨平台,不同平台下需要安装不同版本的JVM。

手机扫二维码登录是怎么实现的?

友情链接:扫码登录是如何实现的?

Java 线程有哪些状态,这些状态之间是如何转化的?

  1. 新建(new):新创建了一个线程对象。
  2. 可运行(runnable):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权 。
  3. 运行(running):可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。
  4. 阻塞(block):阻塞状态是指线程因为某种原因放弃了cpu 使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有机会再次获得cpu timeslice 转到运行(running)状态。阻塞的情况分三种:

(一). 等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中。

(二). 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。

(三). 其他阻塞:运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。

  1. 死亡(dead):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。

List接口、Set接口和Map接口的区别

友情链接:List接口、Set接口和Map接口的区别

Cookie和Session的区别?

友情链接:Cookies 和 Session的区别

Java中的equals和hashCode方法详解

友情链接:Java提高篇——equals()与hashCode()方法详解

Java中CAS算法

友情链接:乐观的并发策略——基于CAS的自旋

TimSort原理

友情链接:TimSort原理

comparable与comparator的区别?

友情链接:Comparable和Comparator的区别

手写单例模式(线程安全)

友情链接:快速理解Java中的五种单例模式

Java线程间的通信方式?

友情链接:Java 多线程(七) 线程间的通信——wait及notify方法 友情链接:Java线程间的通信方式详解

Java8的内存分代改进

友情链接:Java7、Java8的堆内存有啥变化?

对Java内存模型的理解以及其在并发当中的作用?

友情链接:对Java内存模型的理解以及其在并发当中的作用?

Arrays和Collections 对于sort的不同实现原理?

1、Arrays.sort() 该算法是一个经过调优的快速排序,此算法在很多数据集上提供N*log(N)的性能,这导致其他快速排序会降低二次型性能。

2、Collections.sort() 该算法是一个经过修改的合并排序算法(其中,如果低子列表中的最高元素效益高子列表中的最低元素,则忽略合并)。此算法可提供保证的N*log(N)的性能,此实现将指定列表转储到一个数组中,然后再对数组进行排序,在重置数组中相应位置处每个元素的列表上进行迭代。这避免了由于试图原地对链接列表进行排序而产生的$ n^2log(n)$性能。

Java中object常用方法

1、clone() 2、equals() 3、finalize() 4、getclass() 5、hashcode() 6、notify() 7、notifyAll() 8、toString()

对于Java中多态的理解

所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。

多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)

Java实现多态有三个必要条件:继承、重写、父类引用指向子类对象。

继承:在多态中必须存在有继承关系的子类和父类。

重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。

父类引用指向子类对象:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。

实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。

多态的作用:消除类型之间的耦合关系。

Session机制?

友情链接 :Session机制详解

Java序列化与反序列化是什么?为什么需要序列化与反序列化?如何实现Java序列化与反序列化?

友情链接 : Java序列化与反序列化

Spring AOP 实现原理?

友情链接 :Spring AOP 实现原理

Servlet 工作原理?

友情链接 :Servlet 工作原理解析

Java NIO和IO的区别?

友情链接 :Java NIO和IO的区别

Java中堆内存和栈内存区别?

友情链接 :Java中堆内存和栈内存详解

反射讲一讲,主要是概念,都在哪需要反射机制,反射的性能,如何优化?

反射机制的定义:

是在运行状态中,对于任意的一个类,都能够知道这个类的所有属性和方法,对任意一个对象都能够通过反射机制调用一个类的任意方法,这种动态获取类信息及动态调用类对象方法的功能称为java的反射机制。

反射的作用:

1、动态地创建类的实例,将类绑定到现有的对象中,或从现有的对象中获取类型。

2、应用程序需要在运行时从某个特定的程序集中载入一个特定的类。

如何保证RESTful API安全性 ?

友情链接: 如何设计好的RESTful API之安全性

如何预防Mysql注入?

友情链接:MySQL 及 SQL 注入与防范方法

时事政治

阅读代码,回答问题。

 展开原码

为什么进入wait和notify的时候要加synchronized锁?

既然加了synchronized锁,那当某个线程调用了wait的时候明明还在synchronized块里,其他线程怎么进入到锁里去执行notify的?

为什么wait方法可能会抛出InterruptedException异常?

如果有多个线程都进入wait状态,那某个线程调用notify唤醒线程时是否按照顺序唤起那些wait线程?

wait的线程是在某个线程执行完notify之后立马就被唤起吗?

notifyAll又是怎么实现全唤起的?

wait的线程是否会影响load?

友情链接:JVM源码分析之Object.wait/notify(All)完全解读

链表是最基本的数据结构,面试官也常常用链表来考察面试者的基本能力,而且链表相关的操作相对而言比较简单,也适合考察写代码的能力。链表的操作也离不开指针,指针又很容易导致出错。综合多方面的原因,链表题目在面试中占据着很重要的地位。本文对链表相关的面试题做了较为全面的整理,希望能对找工作的同学有所帮助。

链表结点声明如下:

struct ListNode
{
    int m_nKey;
    ListNode * m_pNext;

};

题目列表:

1. 求单链表中结点的个数
2. 将单链表反转
3. 查找单链表中的倒数第K个结点(k > 0
4. 查找单链表的中间结点
5. 从尾到头打印单链表
6. 已知两个单链表pHead1 pHead2 各自有序,把它们合并成一个链表依然有序
7. 判断一个单链表中是否有环
8. 判断两个单链表是否相交
9. 求两个单链表相交的第一个节点
10. 已知一个单链表中存在环,求进入环中的第一个节点
11. 给出一单链表头指针pHead和一节点指针pToBeDeletedO(1)时间复杂度删除节点pToBeDeleted


详细解答

1. 求单链表中结点的个数

这是最最基本的了,应该能够迅速写出正确的代码,注意检查链表是否为空。时间复杂度为On)。参考代码如下:

 

[cpp] view plain copy 

  1. // 求单链表中结点的个数  
  2. unsigned int GetListLength(ListNode * pHead)  
  3. {  
  4.     if(pHead == NULL)  
  5.         return 0;  
  6.   
  7.     unsigned int nLength = 0;  
  8.     ListNode * pCurrent = pHead;  
  9.     while(pCurrent != NULL)  
  10.     {  
  11.         nLength++;  
  12.         pCurrent = pCurrent->m_pNext;  
  13.     }  
  14.     return nLength;  
  15. }  


2. 将单链表反转

从头到尾遍历原链表,每遍历一个结点,将其摘下放在新链表的最前端。注意链表为空和只有一个结点的情况。时间复杂度为On)。参考代码如下:

 

[cpp] view plain copy 

  1. // 反转单链表  
  2. ListNode * ReverseList(ListNode * pHead)  
  3. {  
  4.         // 如果链表为空或只有一个结点,无需反转,直接返回原链表头指针  
  5.     if(pHead == NULL || pHead->m_pNext == NULL)    
  6.         return pHead;  
  7.   
  8.     ListNode * pReversedHead = NULL; // 反转后的新链表头指针,初始为NULL  
  9.     ListNode * pCurrent = pHead;  
  10.     while(pCurrent != NULL)  
  11.     {  
  12.         ListNode * pTemp = pCurrent;  
  13.         pCurrent = pCurrent->m_pNext;  
  14.         pTemp->m_pNext = pReversedHead; // 将当前结点摘下,插入新链表的最前端  
  15.         pReversedHead = pTemp;  
  16.     }  
  17.     return pReversedHead;  
  18. }  


3. 查找单链表中的倒数第K个结点(k > 0 

最普遍的方法是,先统计单链表中结点的个数,然后再找到第(n-k)个结点。注意链表为空,k0k1k大于链表中节点个数时的情况。时间复杂度为On)。代码略。

这里主要讲一下另一个思路,这种思路在其他题目中也会有应用。

主要思路就是使用两个指针,先让前面的指针走到正向第k个结点,这样前后两个指针的距离差是k-1,之后前后两个指针一起向前走,前面的指针走到最后一个结点时,后面指针所指结点就是倒数第k个结点。

参考代码如下:

 

[cpp] view plain copy 

  1. // 查找单链表中倒数第K个结点  
  2. ListNode * RGetKthNode(ListNode * pHead, unsigned int k) // 函数名前面的R代表反向  
  3. {  
  4.     if(k == 0 || pHead == NULL) // 这里k的计数是从1开始的,若k0或链表为空返回NULL  
  5.         return NULL;  
  6.   
  7.     ListNode * pAhead = pHead;  
  8.     ListNode * pBehind = pHead;  
  9.     while(k > 1 && pAhead != NULL) // 前面的指针先走到正向第k个结点  
  10.     {  
  11.         pAhead = pAhead->m_pNext;  
  12.         k--;  
  13.     }  
  14.     if(k > 1 || pAhead == NULL)     // 结点个数小于k,返回NULL  
  15.         return NULL;  
  16.     while(pAhead->m_pNext != NULL)  // 前后两个指针一起向前走,直到前面的指针指向最后一个结点  
  17.     {  
  18.         pBehind = pBehind->m_pNext;  
  19.         pAhead = pAhead->m_pNext;  
  20.     }  
  21.     return pBehind;  // 后面的指针所指结点就是倒数第k个结点  
  22. }  


4. 查找单链表的中间结点 

此题可应用于上一题类似的思想。也是设置两个指针,只不过这里是,两个指针同时向前走,前面的指针每次走两步,后面的指针每次走一步,前面的指针走到最后一个结点时,后面的指针所指结点就是中间结点,即第(n/2+1)个结点。注意链表为空,链表结点个数为12的情况。时间复杂度On)。参考代码如下:

 

[cpp] view plain copy 

  1. // 获取单链表中间结点,若链表长度为n(n>0),则返回第n/2+1个结点  
  2. ListNode * GetMiddleNode(ListNode * pHead)  
  3. {  
  4.     if(pHead == NULL || pHead->m_pNext == NULL) // 链表为空或只有一个结点,返回头指针  
  5.         return pHead;  
  6.   
  7.     ListNode * pAhead = pHead;  
  8.     ListNode * pBehind = pHead;  
  9.     while(pAhead->m_pNext != NULL) // 前面指针每次走两步,直到指向最后一个结点,后面指针每次走一步  
  10.     {  
  11.         pAhead = pAhead->m_pNext;  
  12.         pBehind = pBehind->m_pNext;  
  13.         if(pAhead->m_pNext != NULL)  
  14.             pAhead = pAhead->m_pNext;  
  15.     }  
  16.     return pBehind; // 后面的指针所指结点即为中间结点  
  17. }  


5. 从尾到头打印单链表

对于这种颠倒顺序的问题,我们应该就会想到栈,后进先出。所以,这一题要么自己使用栈,要么让系统使用栈,也就是递归。注意链表为空的情况。时间复杂度为On)。参考代码如下:

自己使用栈:

 

[cpp] view plain copy 

  1. // 从尾到头打印链表,使用栈  
  2. void RPrintList(ListNode * pHead)  
  3. {  
  4.     std::stack<ListNode *> s;  
  5.     ListNode * pNode = pHead;  
  6.     while(pNode != NULL)  
  7.     {  
  8.         s.push(pNode);  
  9.         pNode = pNode->m_pNext;  
  10.     }  
  11.     while(!s.empty())  
  12.     {  
  13.         pNode = s.top();  
  14.         printf("%d\t", pNode->m_nKey);  
  15.         s.pop();  
  16.     }  
  17. }  

 

使用递归函数:

 

[cpp] view plain copy 

  1. // 从尾到头打印链表,使用递归  
  2. void RPrintList(ListNode * pHead)  
  3. {  
  4.     if(pHead == NULL)  
  5.     {  
  6.         return;  
  7.     }  
  8.     else  
  9.     {  
  10.         RPrintList(pHead->m_pNext);  
  11.         printf("%d\t", pHead->m_nKey);  
  12.     }  
  13. }  

 


6. 已知两个单链表pHead1 pHead2 各自有序,把它们合并成一个链表依然有序

这个类似归并排序。尤其注意两个链表都为空,和其中一个为空时的情况。只需要O1)的空间。时间复杂度为Omax(len1, len2))。参考代码如下:

 

[cpp] view plain copy 

  1. // 合并两个有序链表  
  2. ListNode * MergeSortedList(ListNode * pHead1, ListNode * pHead2)  
  3. {  
  4.     if(pHead1 == NULL)  
  5.         return pHead2;  
  6.     if(pHead2 == NULL)  
  7.         return pHead1;  
  8.     ListNode * pHeadMerged = NULL;  
  9.     if(pHead1->m_nKey < pHead2->m_nKey)  
  10.     {  
  11.         pHeadMerged = pHead1;  
  12.         pHeadMerged->m_pNext = NULL;  
  13.         pHead1 = pHead1->m_pNext;  
  14.     }  
  15.     else  
  16.     {  
  17.         pHeadMerged = pHead2;  
  18.         pHeadMerged->m_pNext = NULL;  
  19.         pHead2 = pHead2->m_pNext;  
  20.     }  
  21.     ListNode * pTemp = pHeadMerged;  
  22.     while(pHead1 != NULL && pHead2 != NULL)  
  23.     {  
  24.         if(pHead1->m_nKey < pHead2->m_nKey)  
  25.         {  
  26.             pTemp->m_pNext = pHead1;  
  27.             pHead1 = pHead1->m_pNext;  
  28.             pTemp = pTemp->m_pNext;  
  29.             pTemp->m_pNext = NULL;  
  30.         }  
  31.         else  
  32.         {  
  33.             pTemp->m_pNext = pHead2;  
  34.             pHead2 = pHead2->m_pNext;  
  35.             pTemp = pTemp->m_pNext;  
  36.             pTemp->m_pNext = NULL;  
  37.         }  
  38.     }  
  39.     if(pHead1 != NULL)  
  40.         pTemp->m_pNext = pHead1;  
  41.     else if(pHead2 != NULL)  
  42.         pTemp->m_pNext = pHead2;  
  43.     return pHeadMerged;  
  44. }  

 

也有如下递归解法:

 

[cpp] view plain copy 

  1. ListNode * MergeSortedList(ListNode * pHead1, ListNode * pHead2)  
  2. {  
  3.     if(pHead1 == NULL)  
  4.         return pHead2;  
  5.     if(pHead2 == NULL)  
  6.         return pHead1;  
  7.     ListNode * pHeadMerged = NULL;  
  8.     if(pHead1->m_nKey < pHead2->m_nKey)  
  9.     {  
  10.         pHeadMerged = pHead1;  
  11.         pHeadMerged->m_pNext = MergeSortedList(pHead1->m_pNext, pHead2);  
  12.     }  
  13.     else  
  14.     {  
  15.         pHeadMerged = pHead2;  
  16.         pHeadMerged->m_pNext = MergeSortedList(pHead1, pHead2->m_pNext);  
  17.     }  
  18.     return pHeadMerged;  
  19. }  


7. 判断一个单链表中是否有环

这里也是用到两个指针。如果一个链表中有环,也就是说用一个指针去遍历,是永远走不到头的。因此,我们可以用两个指针去遍历,一个指针一次走两步,一个指针一次走一步,如果有环,两个指针肯定会在环中相遇。时间复杂度为On)。参考代码如下:

 

[cpp] view plain copy 

  1. bool HasCircle(ListNode * pHead)  
  2. {  
  3.     ListNode * pFast = pHead; // 快指针每次前进两步  
  4.     ListNode * pSlow = pHead; // 慢指针每次前进一步  
  5.     while(pFast != NULL && pFast->m_pNext != NULL)  
  6.     {  
  7.         pFast = pFast->m_pNext->m_pNext;  
  8.         pSlow = pSlow->m_pNext;  
  9.         if(pSlow == pFast) // 相遇,存在环  
  10.             return true;  
  11.     }  
  12.     return false;  
  13. }  


8. 判断两个单链表是否相交

如果两个链表相交于某一节点,那么在这个相交节点之后的所有节点都是两个链表所共有的。也就是说,如果两个链表相交,那么最后一个节点肯定是共有的。先遍历第一个链表,记住最后一个节点,然后遍历第二个链表,到最后一个节点时和第一个链表的最后一个节点做比较,如果相同,则相交,否则不相交。时间复杂度为O(len1+len2),因为只需要一个额外指针保存最后一个节点地址,空间复杂度为O(1)。参考代码如下:

 

[cpp] view plain copy 

  1. bool IsIntersected(ListNode * pHead1, ListNode * pHead2)  
  2. {  
  3.         if(pHead1 == NULL || pHead2 == NULL)  
  4.                 return false;  
  5.   
  6.     ListNode * pTail1 = pHead1;  
  7.     while(pTail1->m_pNext != NULL)  
  8.         pTail1 = pTail1->m_pNext;  
  9.   
  10.     ListNode * pTail2 = pHead2;  
  11.     while(pTail2->m_pNext != NULL)  
  12.         pTail2 = pTail2->m_pNext;  
  13.     return pTail1 == pTail2;  
  14. }  


9. 求两个单链表相交的第一个节点
对第一个链表遍历,计算长度len1,同时保存最后一个节点的地址。
对第二个链表遍历,计算长度len2,同时检查最后一个节点是否和第一个链表的最后一个节点相同,若不相同,不相交,结束。
两个链表均从头节点开始,假设len1大于len2,那么将第一个链表先遍历len1-len2个节点,此时两个链表当前节点到第一个相交节点的距离就相等了,然后一起向后遍历,知道两个节点的地址相同。

时间复杂度,O(len1+len2)。参考代码如下:

 

[cpp] view plain copy 

  1. ListNode* GetFirstCommonNode(ListNode * pHead1, ListNode * pHead2)  
  2. {  
  3.     if(pHead1 == NULL || pHead2 == NULL)  
  4.         return NULL;  
  5.   
  6.     int len1 = 1;  
  7.     ListNode * pTail1 = pHead1;  
  8.     while(pTail1->m_pNext != NULL)  
  9.     {  
  10.         pTail1 = pTail1->m_pNext;  
  11.         len1++;  
  12.     }  
  13.   
  14.     int len2 = 1;  
  15.     ListNode * pTail2 = pHead2;  
  16.     while(pTail2->m_pNext != NULL)  
  17.     {  
  18.         pTail2 = pTail2->m_pNext;  
  19.         len2++;  
  20.     }  
  21.   
  22.     if(pTail1 != pTail2) // 不相交直接返回NULL  
  23.         return NULL;  
  24.   
  25.     ListNode * pNode1 = pHead1;  
  26.     ListNode * pNode2 = pHead2;  
  27.         // 先对齐两个链表的当前结点,使之到尾节点的距离相等  
  28.     if(len1 > len2)  
  29.     {  
  30.         int k = len1 - len2;  
  31.         while(k--)  
  32.             pNode1 = pNode1->m_pNext;  
  33.     }  
  34.     else  
  35.     {  
  36.         int k = len2 - len1;  
  37.         while(k--)  
  38.             pNode2 = pNode2->m_pNext;  
  39.     }  
  40.     while(pNode1 != pNode2)  
  41.     {  
  42.         pNode1 = pNode1->m_pNext;  
  43.         pNode2 = pNode2->m_pNext;  
  44.     }  
  45.         return pNode1;  
  46. }  


10. 已知一个单链表中存在环,求进入环中的第一个节点

首先判断是否存在环,若不存在结束。在环中的一个节点处断开(当然函数结束时不能破坏原链表),这样就形成了两个相交的单链表,求进入环中的第一个节点也就转换成了求两个单链表相交的第一个节点。参考代码如下:

 

[cpp] view plain copy 

  1. ListNode* GetFirstNodeInCircle(ListNode * pHead)  
  2. {  
  3.     if(pHead == NULL || pHead->m_pNext == NULL)  
  4.         return NULL;  
  5.   
  6.     ListNode * pFast = pHead;  
  7.     ListNode * pSlow = pHead;  
  8.     while(pFast != NULL && pFast->m_pNext != NULL)  
  9.     {  
  10.         pSlow = pSlow->m_pNext;  
  11.         pFast = pFast->m_pNext->m_pNext;  
  12.         if(pSlow == pFast)  
  13.             break;  
  14.     }  
  15.     if(pFast == NULL || pFast->m_pNext == NULL)  
  16.         return NULL;  
  17.   
  18.     // 将环中的此节点作为假设的尾节点,将它变成两个单链表相交问题  
  19.     ListNode * pAssumedTail = pSlow;   
  20.     ListNode * pHead1 = pHead;  
  21.     ListNode * pHead2 = pAssumedTail->m_pNext;  
  22.   
  23.     ListNode * pNode1, * pNode2;  
  24.     int len1 = 1;  
  25.     ListNode * pNode1 = pHead1;  
  26.     while(pNode1 != pAssumedTail)  
  27.     {  
  28.         pNode1 = pNode1->m_pNext;  
  29.         len1++;  
  30.     }  
  31.       
  32.     int len2 = 1;  
  33.     ListNode * pNode2 = pHead2;  
  34.     while(pNode2 != pAssumedTail)  
  35.     {  
  36.         pNode2 = pNode2->m_pNext;  
  37.         len2++;  
  38.     }  
  39.   
  40.     pNode1 = pHead1;  
  41.     pNode2 = pHead2;  
  42.     // 先对齐两个链表的当前结点,使之到尾节点的距离相等  
  43.     if(len1 > len2)  
  44.     {  
  45.         int k = len1 - len2;  
  46.         while(k--)  
  47.             pNode1 = pNode1->m_pNext;  
  48.     }  
  49.     else  
  50.     {  
  51.         int k = len2 - len1;  
  52.         while(k--)  
  53.             pNode2 = pNode2->m_pNext;  
  54.     }  
  55.     while(pNode1 != pNode2)  
  56.     {  
  57.         pNode1 = pNode1->m_pNext;  
  58.         pNode2 = pNode2->m_pNext;  
  59.     }  
  60.     return pNode1;  
  61. }  


11. 给出一单链表头指针pHead和一节点指针pToBeDeletedO(1)时间复杂度删除节点pToBeDeleted

 

 

对于删除节点,我们普通的思路就是让该节点的前一个节点指向该节点的下一个节点,这种情况需要遍历找到该节点的前一个节点,时间复杂度为O(n)。对于链表,链表中的每个节点结构都是一样的,所以我们可以把该节点的下一个节点的数据复制到该节点,然后删除下一个节点即可。要注意最后一个节点的情况,这个时候只能用常见的方法来操作,先找到前一个节点,但总体的平均时间复杂度还是O(1)。参考代码如下:

 

[cpp] view plain copy 

  1. void Delete(ListNode * pHead, ListNode * pToBeDeleted)  
  2. {  
  3.     if(pToBeDeleted == NULL)  
  4.         return;  
  5.     if(pToBeDeleted->m_pNext != NULL)  
  6.     {  
  7.         pToBeDeleted->m_nKey = pToBeDeleted->m_pNext->m_nKey; // 将下一个节点的数据复制到本节点,然后删除下一个节点  
  8.         ListNode * temp = pToBeDeleted->m_pNext;  
  9.         pToBeDeleted->m_pNext = pToBeDeleted->m_pNext->m_pNext;  
  10.         delete temp;  
  11.     }  
  12.     else // 要删除的是最后一个节点  
  13.     {  
  14.         if(pHead == pToBeDeleted) // 链表中只有一个节点的情况  
  15.         {  
  16.             pHead = NULL;  
  17.             delete pToBeDeleted;  
  18.         }  
  19.         else  
  20.         {  
  21.             ListNode * pNode = pHead;  
  22.             while(pNode->m_pNext != pToBeDeleted) // 找到倒数第二个节点  
  23.                 pNode = pNode->m_pNext;  
  24.             pNode->m_pNext = NULL;  
  25.             delete pToBeDeleted;  
  26.         }     
  27.     }  
  28. }  

2.算法&coding:

1)判断一棵树是不是完全二叉树,不记得什么是完全二叉树;

2)找出无序数组的中位数,不会;

3)单链表反转,单链表不记得;

4)二分查找能完整写出来吗?写不出来;

最后问对什么比较熟悉,能完整写出什么程序,就说不多,也没具体说出来,基础太差,直接送走了。

面试过程:

1.自我介绍:对之前的项目介绍比较清楚

2.redis过期机制:有过了解,但有些点回答的不对

3.hashmap:有过较深入的了解

4.职责链模式:不太了解

5.filter:对javaweb不太了解

6.threadpool:了解其基本原理

7.算法:打印出数组内指定个数元素的组合:没有思路,提示后还是没有,降低难度,找出2个数的排列组合,还是有些含糊

优势:工作年限长

劣势:态度恶劣,技术水平低,与工作年限严重不匹配

金融公司 离职待遇低 外包 不稳定

现在是否还负责具体开发工作?一直负责

画出最近的项目的架构图,跟进架构图进行分析提问

项目QPS多少,是否做过全链路压测,性能瓶颈在哪?怎么解决的?QPS很低,并未做过压测

项目架构中使用HSF,为什么使用HSF?解耦 未回答出其他方面

Dubbo和HSF相比,HSF做了哪些改进和优化?不知道

如果自己设计一个RPC框架怎么做:注册中心  通信协议 序列化反序列化

注册中心使用的技术或是框架了解吗?(用什么技术做?)不知道,不了解

是否了解过zookeeper:看过,忘了 使用场景:数据库集群中间件:一主多从读写分离(回答不正确),并未回答出其他场景

总结:候选人对于项目架构中技术的选用、选用技术的原理并不了解,并且对于分布式常用技术不了解,与其工作经验严重不匹配,并且态度恶劣,一面不通过

优势:

1.编程能力不错

2.基础不错

劣势:

1.项目中监控方面了解较少

面试过程:

1.Coding:准确无误的写出快排,了解各种排序的时间复杂度;一个文件中找出出现次数最多的前10个ip,描述出堆排序思路,如果文件较大,把文件分为10个小文件,没个文件中找出出现次数最多的一个ip;

2.语言相关:能够解释java jvm原理和依赖注入,控制反转;

3.操作系统:java程序虚拟内存分配情况比较清楚,正确回答出进程和线程的区别;

4.网络相关:页面加载过程中使用的协议,tcp和udp的区别都回答正确;

5.数据库:知道慢查询日志,有慢查询优化思路;

6.其他:平时自己用到的技术,不会去深入再看源码学习,但一些java工具,会看怎么实现的,比如hashmap,是使用数组加链表。

综上,本科毕业工作2年,有java编程经验,编程能力不错,基础不错,可以继续再深入考察。

面试轮次:二面

面试结果:待定

      java语言相关:  A.  spring 容器,注入的使用:                  能够清晰的描述出注入的使用; 并能了解它在程序运行过程中的加载运行过程;同时能够回答出实现类的解藕。

                                B.   异常的处理                                           清楚try catch throw finally的使用。并能够清楚异常是否在函数内处理,还是throw出去;并能够清楚不同架构层次的异常需要重新的包装。

                                C.   java多线程相关                                    使用过lock 和 synchronized; 对他们的差别描述得不是很清楚。  其他的同步组件没有描述。

       设计能力:        设计一个可扩展的序列化与反序列化协议格式,需要考虑什么?     候选人在效率,多语言 和 统计接口语言IDL给出了描述;

      编程能力:       排序后的数组,旋转了一下,查找其中的一个数字。  类似  在数组中100,112,134,145,3,  12,  45, 67,89,查找出12。 在提示后也没有写出来。

优势:

1.coding能力不错

2.数据库表设计能力不错,思维开阔,灵活

3.java经验和优化经验丰富

劣势:

1.mysql索引了解不多

面试过程:

1.coding:快排,能够快速无误地写出程序;

2.java:jvm工作原理和java虚拟内存分配比较了解,平时主要使用java开发;

3.数据库表设计:设计商品分类和商品分类下的商品排序,单独设计排序表,为了防止排序字段批量更新,想到排序列存放浮点数和不连续数,思路清晰,表述清楚;

4.排序表优化:使用redis的sortedset存储,并且描述出存储结构;

5.mysql:如果根据上述设计中的浮点数排序,mysql order by性能怎么样,这个不太清楚,对mysql索引了解不多。

综上,除了对mysql索引了解不多,coding,java,数据库表设计和业务优化都表现不错,一面通过。

优势:

1.有比较强的系统设计与架构能力

劣势:

1.计算机基础和语言的能力一般

面试过程:

1. 系统架构与设计: 能够架构和设计高并发的后台server,系统的架构与分层都是合理的,但在自动扩容和在线分库 分表上的实践比较少:         结论:设计能力不错,但还有提升的空间

2. 编程能力:   旋转数组的二分查找,在提示下没有写出完全正确的代码,但代码的组织还可以;                                                                            结论:算法一般,程序设计能力还可以。

 3.计算机基础:在并发,异步,同步,多进程,多线程方面的理解一般;                                                                                                                   结论:计算机的基础一般

4.沟通能力:     项目的描述与理解提问题的意图方面都不错。                                                                                                                                     结论:不错

优势:

1.分布式方面有不错的经验:负载均衡、容错

2.对自己做得业务熟悉:业务边界划分、基础业务沉淀都有自己想法

3.沟通表达好、思维活跃

4.有大型互联网工作经验

劣势:

1.缺乏系统方面数据的了解

2.对自己负责之外组件了解浅显,无深入度

面试过程:

1.自我介绍

问到游戏行业和互联网行业有很大的区别,为什么想转互联网。主要是职业规划,还是想让自己的技术全面一些,另一方面原因是项目组波动较大。

2.算法&coding

归并排序? 实现了,程序不是很简洁,边界条件考虑不周全,经提示后解决。

寻找字符串数组的最长公共字串? 想到了一种思路,并且实现了算法,有一点瑕疵,经提示后解决。

寻找无序数组的中位数?能想到快排,能想到算法的思路,程序实现上有些问题。

3.网络协议

tcp和udp有什么区别,回答较好,进一步问到在线视频用到什么协议,回复不知道

tcp三次握手,了解。

4.java基础

hashmap数据结构相关,以及衍生的hashtable和concurrentHashMap,回答得较好。

java锁机制,有一定了解。

综合以上:面试候选人基础还可以,但是游戏行业和互联网行业差异较大,可能有一个调整期。弱通过。

面试轮次:二面

面试结果:不通过

优点:

缺点:

         基本技能很弱

         缺少自我驱动的精神,学习能力不强

  1. 沟通表达:             沟通表达不太好,对项目的介绍一起使用到的技术都没有很好的总结和梳理。
  2. java 基本技能:     对读写锁的使用不熟悉,通过对程序中使用的多线程技术,感觉编程经验很欠缺。
  3. 项目经验:            项目中使用到的技术都不是特别了解,如配置文件的在线加载, 网络包的协议实现;程序的发布与维护等等都很欠缺
  4. 学习,自驱能力: 工作中越到的很多技术问题都没有深入了解,比如配置文件的热加载;产品的调用量和承载量。java多线程锁的实现。

劣势:

算法一般

coding一般

java应用一般

面试过程:

1.自我介绍

2.算法:找数组的中位数,只想到排序,对冒泡排序的时间复杂度不了解;找出有序数组中距离某个数最近的10个数,思路是首先找到这个数,然后在这个数前10个数和后10个数的范围内,求出差值,把差值排序,提示数组已经有序,没有用到数组已经有序的条件,没想到其他方法。算法只能想到比较简单的直接的方式,在提示下也想不到更优的方式。

3.coding:coding一般,写码时间较久,知道思路也写不出代码,边界条件也欠考虑。java单例模式写的不完全正确。

4.java应用:怎样防止java多线程并发,多线程并发可能会引发数据不一致,这种问题怎么避免?完全没有提到锁,提到消息机制和重试,重试回答不正确,其他也没回答全面。

5.数据库:乐观锁和悲观锁回答的模棱两可,加锁的例子也没回答出来。

面试轮次:一面

面试结果:不通过

优势:  对于开源系统的使用都比较熟悉,能够快速的搭建一个满足几百并发量的系统。

缺点:  对于系统的底层技术了解太少,基础不够扎实。

  1. 编程能力: 
              排序后的数组,旋转了一下,查找其中的一个数字。  类似  在数组中100,112,134,145,3,  12,  45, 67,89,查找出12。     结论:在提示后也没有写出一行代码。
  2. 基础知识:
             项目使用中的pb扩展性的原理,描述pb的可扩展性是依赖于字段生命的顺序;                                                                 结论:回答错误
             对使用中的一致性hash不熟悉,不能正确的描述出算法的名字;  
             项目中使用了codis。          对于codis的容错, 下机器的表述是不错的。   让他自己设计codis的容灾策略,没有想法。  结论:回答没有信息

面试轮次:一面

面试结果:弱通过

优势:

1.算法&coding还可以,但coding有些慢

2.思维还算灵活

劣势:

1.由于以前做游戏的,对于业务的数据库设计等不是很熟

2.语言表达能力一般

面试过程:

1.自我介绍:做游戏做久了,想换个方向,扩宽下自己的眼界。

2.算法&coding:

1)查找无序数组的中位数,最直接的方式想到了排序,并在排序基础上想到了优化方法,能正确写出程序,对时间复杂度也了解;

2)查找有序数组中距离某个数最近的10个数,使用二分查找到某个数没问题,找出最近的10个数思路有些问题,这块coding花的时间比较久;

3)2个栈实现1个队列,能很快想出方法,也能做一定优化,思路比较清晰。

3.设计题:商品多维度排序存储,想到了字符串序列存储,能说出优点,在提示这种方案缺点的情况下,思考有没有其他方案,还想到了整数序列存储,缺点改动较大,数据库存储没想到更优的方案了,但是程序的话还想到了链表存储。

综上,候选人算法和coding还可以,但coding有些慢,思维还算灵活,可以进一步考察看看。

面试轮次:二面

面试结果:不通过

  1. 沟通表达能力:  比较弱;很难描述自己的内心诉求;也不能流畅,清晰的表达出自己的优势。逻辑思维和总结能力都比较弱。
  2. 开发语言:         工作前四年工作中基本使用脚本;并且没有开发出在线上使用的产品;  程序设计能能力变弱。
  3. 程序设计:         旋转有序数组的二分查找;  能够找出最简单的方法,但不能做出一些优化。 
                               在很明确提示后,都不能给出有效的思考; 
  4. 学习能力:         为了找互联网的工作,自学了java spring,  mybatis。 但都极其初级; 对自己的职业没有规划,比较盲目。

面试轮次:一面

面试结果:不通过

优势:

实习经验丰富

劣势:

算法较弱

作为应届生,专业课基础不好

面试过程:

1.简历相关

先后在乐视、金山、百度实习过,但是掌握的知识点较为零碎;

2.算法&coding

查找无序数组的中位数? 首先想到的是冒泡排序;提示有没有效率更高的方式,想到了了快排;要求实现快排,有错误,经提示后修正;进一步问到有没有必要完全排序,经提示后表示理解,但是实现程序的时候仍然错了。

查找无序数组第二大的数? 想到了两次遍历的方式,提示有没有优化的空间比方说遍历一次就够了,没有实现。

3.计算机基础

tcp和udp的区别? 以及在线视频基于什么协议?   表示tcp需要三次握手,传输效率低,但是回复说在线视频是基于tcp协议,因为需要握手。

tcp三次握手以及为什么需要三次握手?  了解三次握手。没有回答出why

进程和线程的区别? 表示进程是资源分配的单位,线程是程序执行的最小单位。

综合以上,该候选人是应届生,实习经验丰富,表明比较积极主动,但是专业课基础和算法能力相对弱一些,一面不通过。

面试轮次:一面 (电话面试)

面试结果:不通过

优势:

1.数据结构基础还可以

2.态度不错

3.思维和表达比较顺畅

劣势:

1.java基础较差

2.工程能力较差

3.jvm体系结构较差

4.工程素质偏差

面试过程:

1.自我介绍

2.算法&coding:

1)二叉树寻找任意两个节点的父节点,给出思路,比较好

2)斐波那契数列的几种实现方式,能给出思路和优缺点

   

3.java相关

1)java多线程实现方式:

     知道Thread、runnable,不了解concurrent包的内容

2)sychronize和Lock锁机制

     不了解锁机制

3)Hashmap底层数据结构、优缺点

     了解,不了扩容机制和concurrentHashMap的底层数据结构

4.数据库

1)不了解事务隔离级别,但是行共享锁、排他锁、表锁这些完全不了解,不知道乐观锁和悲观锁的区别

2)大概了解B+树和散列的数据结构,但是不了解具体的优缺点

5.工程能力,缺乏些系统性的思考

1)常用设计模式

     设计能力较差,没写出基本设计模式的简单代码

综上,候选人算法和coding能力还可以,应届硕士毕业生,在工程能力上缺乏系统性的考虑,考虑到是硕士毕业生,java基础偏差,经与二面面试官刘凤玉沟通,一面不通过。

场景题:

  1. 不用分布式缓存,不用DB,互联网用户进入后固定看到1000中的3个客服 (考察互联网思维)
  2. 一个在线客服能够服务多个用户,用户是排队依次进入,怎么计算客服的工作时长,刨除用户间的累加时间(考察逻辑思维)
  3. 访问某个网站,比如www.meituan.com,从request到response 的数据流?(负载,大型网站架构)
  4. url的key,value解析,比如http://xxx.xxx.com?a=b&c=d&e=f&...怎么快速的得到c的value(url 尝试和正则能力)
  5. 数据库数据量大了的的时候怎么处理?水平和垂直拆分,一致性hash的含义?
  6. 分布式数据一致性的处理?调用多个接口,一个接口挂了?


    技术:
  7. Spring MVC 的实现原理,http 请求 怎么分配到 具体controller 
  8. listen ,servlet,filter的启动顺序
  9. filter和spring 拦截器的区别
  10. mysql 索引的作用,具体sql的书写?
  11. jvm 相关的问题 见 北京侧面试题
  12. java 基础 见 北京侧面试题

2GetPost区别?

  GET POST

后退按钮/刷新 无害 数据会被重新提交(浏览器应该告知用户数据会被重新提交)。 

书签 可收藏为书签 不可收藏为书签

缓存 能被缓存 不能缓存

编码类型 application/x-www-form-urlencoded application/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码。

历史 参数保留在浏览器历史中。 参数不会保存在浏览器历史中。 

对数据长度的限制 是的。当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。 无限制。

对数据类型的限制 只允许 ASCII 字符。 没有限制。也允许二进制数据。 

安全性 与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。

在发送密码或其他敏感信息时绝不要使用 GET ! POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。

可见性 数据在 URL 中对所有人都是可见的。 数据不会显示在 URL 中。

3、描述一下一次HTTP请求从请求到返回的过程,越详细越深入越好。 (或者,访问一个url 都经历过了哪些事情,越详细越好。)

1)把URL分割成几个部分:协议、网络地址、资源路径。

1)把URL分割成几个部分:协议、网络地址、资源路径。 其中网络地址指示该连接网络上哪一台计算机,可以是域名或者IP地址,可以包括端口号; 协议是从该计算机获取资源的方式,常见的是HTTP、FTP,不同协议有不同的通讯内容格式;资源路径指示从服务器上获取哪一项资源。 例如:http://www.guokr.com/question/554991/
协议部分:http
网络地址:www.guokr.com
资源路径:/question/554991/
2)如果地址不是一个IP地址,通过DNS(域名系统)将该地址解析成IP地址。 IP地址对应着网络上一台计算机,DNS服务器本身也有IP,你的网络设置包含DNS服务器的IP。
例如:www.guokr.com 不是一个IP,向DNS询问请求www.guokr.com 对应的IP,获得IP: 111.13.57.142。 这个过程里,你的电脑直接询问的DNS服务器可能没有www.guokr.com 对应的IP,就会向它的上级服务器询问, 上级服务器同样可能没有,就依此一层层向上找,最高可达根节点,找到或者全部找不到为止。 (DNS缓存和解析过程是一个考察点,有些面试者能叙述出完整的过程,有些只能给出笼统的结果,以下是DNS缓存策略)

浏览器缓存 – 浏览器会缓存DNS记录一段时间。 有趣的是,操作系统没有告诉浏览器储存DNS记录的时间,这样不同浏览器会储存个自固定的一个时间(2分钟到30分钟不等)。
系统缓存 – 如果在浏览器缓存里没有找到需要的记录,浏览器会做一个系统调用(windows里是gethostbyname)。这样便可获得系统缓存中的记录。 路由器缓存 – 接着,前面的查询请求发向路由器,它一般会有自己的DNS缓存。
ISP DNS 缓存 – 接下来要check的就是ISP缓存DNS的服务器。在这一般都能找到相应的缓存记录。
递归搜索 – 你的ISP的DNS服务器从跟域名服务器开始进行递归搜索,从.com顶级域名服务器到Facebook的域名服务器。一般DNS服务器的缓存中会有.com 域名服务器中的域名,所以到顶级服务器的匹配过程不是那么必要了。

3)如果地址不包含端口号,根据协议的默认端口号确定一个。

端口号之于计算机就像窗口号之于银行,一家银行有多个窗口,每个窗口都有个号码,不同窗口可以负责不同的服务。 

端口只是一个逻辑概念,和计算机硬件没有关系。 

例如:www.guokr.com 不包含端口号,http协议默认端口号是80。

如果你输入的url是http://www.guokr.com:8080/ ,那表示不使用默认的端口号,而使用指定的端口号8080。

4)向2和3确定的IP和端口号发起网络连接。 例如:向111.13.57.142的80端口发起连接

5)根据http协议要求,组织一个请求的数据包,里面包含大量请求信息,包括请求的资源路径、你的身份 例如:用自然语言来表达这个数据包,大概就是:请求 /question/554991/ ,我的身份是xxxxxxx。

6)服务器响应请求,将数据返回给浏览器。数据可能是根据HTML协议组织的网页,里面包含页面的布局、文字。数据也可能是图片、脚本程序等 。现在你可以用浏览器的“查看源代码”功能,感受一下服务器返回的是什么东东。如果资源路径指示的资源不存在,服务器就会返回著名的404 错误。

7)如果(6)返回的是一个页面,根据页面里一些外链的URL,例如图片的地址,按照(1)-(6)再次获取。

8)开始根据资源的类型,将资源组织成屏幕上显示的图像,这个过程叫渲染,网页渲染是浏览器最复杂、最核心的功能。

9)将渲染好的页面图像显示出来,并开始响应用户的操作。

以上只是最基本的步骤,实际不可能就这么简单,一些可选的步骤例如网页缓存、连接池、加载策略、加密解密、代理中转等等都没有提及。 

即使基本步骤本身也有很复杂的子步骤,TCP/IP、DNS、HTTP、HTML:每一个都可以展开成庞大的课题,而浏览器的基础——操作系统、编译 器、硬件等更是一个比一个复杂。

这道题说难不难,说容易不容易,不同层次不同水平的面试者可能会有不同的表现和见解,上面仅是答题要点,面试人员的表现和他的理解层次需 要面试官酌情判定。 

1)把URL分割成几个部分:协议、网络地址、资源路径。

1)把URL分割成几个部分:协议、网络地址、资源路径。 其中网络地址指示该连接网络上哪一台计算机,可以是域名或者IP地址,可以包括端口号; 协议是从该计算机获取资源的方式,常见的是HTTP、FTP,不同协议有不同的通讯内容格式;资源路径指示从服务器上获取哪一项资源。 例如:http://www.guokr.com/question/554991/
协议部分:http
网络地址:www.guokr.com
资源路径:/question/554991/
2)如果地址不是一个IP地址,通过DNS(域名系统)将该地址解析成IP地址。 IP地址对应着网络上一台计算机,DNS服务器本身也有IP,你的网络设置包含DNS服务器的IP。
例如:www.guokr.com 不是一个IP,向DNS询问请求www.guokr.com 对应的IP,获得IP: 111.13.57.142。 这个过程里,你的电脑直接询问的DNS服务器可能没有www.guokr.com 对应的IP,就会向它的上级服务器询问, 上级服务器同样可能没有,就依此一层层向上找,最高可达根节点,找到或者全部找不到为止。 (DNS缓存和解析过程是一个考察点,有些面试者能叙述出完整的过程,有些只能给出笼统的结果,以下是DNS缓存策略)

浏览器缓存 – 浏览器会缓存DNS记录一段时间。 有趣的是,操作系统没有告诉浏览器储存DNS记录的时间,这样不同浏览器会储存个自固定的一个时间(2分钟到30分钟不等)。
系统缓存 – 如果在浏览器缓存里没有找到需要的记录,浏览器会做一个系统调用(windows里是gethostbyname)。这样便可获得系统缓存中的记录。 路由器缓存 – 接着,前面的查询请求发向路由器,它一般会有自己的DNS缓存。
ISP DNS 缓存 – 接下来要check的就是ISP缓存DNS的服务器。在这一般都能找到相应的缓存记录。
递归搜索 – 你的ISP的DNS服务器从跟域名服务器开始进行递归搜索,从.com顶级域名服务器到Facebook的域名服务器。一般DNS服务器的缓存中会有.com 域名服务器中的域名,所以到顶级服务器的匹配过程不是那么必要了。

3)如果地址不包含端口号,根据协议的默认端口号确定一个。

端口号之于计算机就像窗口号之于银行,一家银行有多个窗口,每个窗口都有个号码,不同窗口可以负责不同的服务。 

端口只是一个逻辑概念,和计算机硬件没有关系。 

例如:www.guokr.com 不包含端口号,http协议默认端口号是80。

如果你输入的url是http://www.guokr.com:8080/ ,那表示不使用默认的端口号,而使用指定的端口号8080。

4)向2和3确定的IP和端口号发起网络连接。 例如:向111.13.57.142的80端口发起连接

5)根据http协议要求,组织一个请求的数据包,里面包含大量请求信息,包括请求的资源路径、你的身份 例如:用自然语言来表达这个数据包,大概就是:请求 /question/554991/ ,我的身份是xxxxxxx。

6)服务器响应请求,将数据返回给浏览器。数据可能是根据HTML协议组织的网页,里面包含页面的布局、文字。数据也可能是图片、脚本程序等 。现在你可以用浏览器的“查看源代码”功能,感受一下服务器返回的是什么东东。如果资源路径指示的资源不存在,服务器就会返回著名的404 错误。

7)如果(6)返回的是一个页面,根据页面里一些外链的URL,例如图片的地址,按照(1)-(6)再次获取。

8)开始根据资源的类型,将资源组织成屏幕上显示的图像,这个过程叫渲染,网页渲染是浏览器最复杂、最核心的功能。

9)将渲染好的页面图像显示出来,并开始响应用户的操作。

以上只是最基本的步骤,实际不可能就这么简单,一些可选的步骤例如网页缓存、连接池、加载策略、加密解密、代理中转等等都没有提及。 

即使基本步骤本身也有很复杂的子步骤,TCP/IP、DNS、HTTP、HTML:每一个都可以展开成庞大的课题,而浏览器的基础——操作系统、编译 器、硬件等更是一个比一个复杂。

这道题说难不难,说容易不容易,不同层次不同水平的面试者可能会有不同的表现和见解,上面仅是答题要点,面试人员的表现和他的理解层次需 要面试官酌情判定。 

1)把URL分割成几个部分:协议、网络地址、资源路径。

1)把URL分割成几个部分:协议、网络地址、资源路径。 其中网络地址指示该连接网络上哪一台计算机,可以是域名或者IP地址,可以包括端口号; 协议是从该计算机获取资源的方式,常见的是HTTP、FTP,不同协议有不同的通讯内容格式;资源路径指示从服务器上获取哪一项资源。 例如:http://www.guokr.com/question/554991/
协议部分:http
网络地址:www.guokr.com
资源路径:/question/554991/
2)如果地址不是一个IP地址,通过DNS(域名系统)将该地址解析成IP地址。 IP地址对应着网络上一台计算机,DNS服务器本身也有IP,你的网络设置包含DNS服务器的IP。
例如:www.guokr.com 不是一个IP,向DNS询问请求www.guokr.com 对应的IP,获得IP: 111.13.57.142。 这个过程里,你的电脑直接询问的DNS服务器可能没有www.guokr.com 对应的IP,就会向它的上级服务器询问, 上级服务器同样可能没有,就依此一层层向上找,最高可达根节点,找到或者全部找不到为止。 (DNS缓存和解析过程是一个考察点,有些面试者能叙述出完整的过程,有些只能给出笼统的结果,以下是DNS缓存策略)

浏览器缓存 – 浏览器会缓存DNS记录一段时间。 有趣的是,操作系统没有告诉浏览器储存DNS记录的时间,这样不同浏览器会储存个自固定的一个时间(2分钟到30分钟不等)。
系统缓存 – 如果在浏览器缓存里没有找到需要的记录,浏览器会做一个系统调用(windows里是gethostbyname)。这样便可获得系统缓存中的记录。 路由器缓存 – 接着,前面的查询请求发向路由器,它一般会有自己的DNS缓存。
ISP DNS 缓存 – 接下来要check的就是ISP缓存DNS的服务器。在这一般都能找到相应的缓存记录。
递归搜索 – 你的ISP的DNS服务器从跟域名服务器开始进行递归搜索,从.com顶级域名服务器到Facebook的域名服务器。一般DNS服务器的缓存中会有.com 域名服务器中的域名,所以到顶级服务器的匹配过程不是那么必要了。

3)如果地址不包含端口号,根据协议的默认端口号确定一个。

端口号之于计算机就像窗口号之于银行,一家银行有多个窗口,每个窗口都有个号码,不同窗口可以负责不同的服务。 

端口只是一个逻辑概念,和计算机硬件没有关系。 

例如:www.guokr.com 不包含端口号,http协议默认端口号是80。

如果你输入的url是http://www.guokr.com:8080/ ,那表示不使用默认的端口号,而使用指定的端口号8080。

4)向2和3确定的IP和端口号发起网络连接。 例如:向111.13.57.142的80端口发起连接

5)根据http协议要求,组织一个请求的数据包,里面包含大量请求信息,包括请求的资源路径、你的身份 例如:用自然语言来表达这个数据包,大概就是:请求 /question/554991/ ,我的身份是xxxxxxx。

6)服务器响应请求,将数据返回给浏览器。数据可能是根据HTML协议组织的网页,里面包含页面的布局、文字。数据也可能是图片、脚本程序等 。现在你可以用浏览器的“查看源代码”功能,感受一下服务器返回的是什么东东。如果资源路径指示的资源不存在,服务器就会返回著名的404 错误。

7)如果(6)返回的是一个页面,根据页面里一些外链的URL,例如图片的地址,按照(1)-(6)再次获取。

8)开始根据资源的类型,将资源组织成屏幕上显示的图像,这个过程叫渲染,网页渲染是浏览器最复杂、最核心的功能。

9)将渲染好的页面图像显示出来,并开始响应用户的操作。

以上只是最基本的步骤,实际不可能就这么简单,一些可选的步骤例如网页缓存、连接池、加载策略、加密解密、代理中转等等都没有提及。 

即使基本步骤本身也有很复杂的子步骤,TCP/IP、DNS、HTTP、HTML:每一个都可以展开成庞大的课题,而浏览器的基础——操作系统、编译 器、硬件等更是一个比一个复杂。

这道题说难不难,说容易不容易,不同层次不同水平的面试者可能会有不同的表现和见解,上面仅是答题要点,面试人员的表现和他的理解层次需 要面试官酌情判定。 

4、举出6http的状态码,502 504有什么区别。

状态码范围 作用

100-199 用于指定客户端应相应的某些动作。 

200-299 用于表示请求成功。

300-399 用于已经移动的文件并且常被包含在定位头信息中指定新的地址信息。 

400-499 用于指出客户端的错误。

500-599 用于支持服务器错误。

  TCP UDP

是否连接 面向连接 面向非连接

传输可靠性 可靠 不可靠

应用场合 传输大量数据 少量数据

速度 慢 快

参考答案:

大类区分见下表

具体每个码的含义见右边的链接->HTTP状态码大全
502 Bad Gateway:作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。

504 Gateway Time-out:作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LD AP)或者辅助服务器(例如DNS)收到响应。

502 Bad Gateway:Tomcat没有启动起来
504 Gateway Time-out: Nginx报出来的错误,一般是Nginx做为反向代理服务器的时候,所连接的应用服务器譬如Tomcat无相应导致的 解题思路:基础知识
考察点:HTTP的基础知识,要求能记住工作中常见的几个错误码
分类:网络应用层,HTTP,基础知识{社招}
难度分级:P5

5UDP,TCP是网络七层协议中哪一层的协议,区别是什么,分别适用于什么场景?
参考答案:

传输层。 在TCP/IP模型中,传输层的功能是使源端主机和目标端主机上的对等实体可以进行会话。

在传输层定义了两种服务质量不同的协议。即:传输控制协议TCP(transmission control protocol)和用户数据报协议UDP(user datagram protocol)。

TCP协议是一个面向连接的、可靠的协议。它将一台主机发出的字节流无差错地发往互联网上的其他主机。 需要三次握手建立连接,才能进行数据传输。在发送端,它负责把上层传送下来的字节流分成报文段并传递给下层。 在接收端,它负责把收到的报文进行重组后递交给上层。TCP协议还要处理端到端的流量控制,以避免缓慢接收的接收方没有足够的缓冲区接收发 送方发送的大量数据。 UDP协议是一个不可靠的、无连接协议,不与对方建立连接,而是直接就把数据包发送过去。主要适用于不需要对报文进行排序和流量控制的 场合。 UDP适用于一次只传送少量数据、对可靠性要求不高的应用环境。比如,我们经常使用“ping”命令来测试两台主机之间TCP/IP通信是否正常, 其 实“ping”命令的原理就是向对方主机发送UDP数据包,然后对方主机确认收到数据包,如果数据包是否到达的消息及时反馈回来,那么网络就是 通的。

解题思路:基础知识,从面向连接、可靠性、应用场合上进行分析对比 考察点:七层协议中传输层的基础知识,着重从TCP vs UDP的区别上考察 分类:七层协议,基础知识,网络,{校招,社招都可以用} 难度分级:P4,P5

6、互联网服务的默认端口是多少?

参考答案:

HTTP 80

HTTP 80 SMTP 25 POP3 110 FTP 21 20 TELNET 23

解题思路:
考察点:网络协议,端口
分类:网络应用层,基础知识{校招,社招都可以用}
难度分级:P5

7tcp的三次握手,如何用java实现tcp的广播,如果发现网段内的所有集群节点?

1.3、操作系统

1.4linux

1Linux Top有哪些重要参数值得关注,这些参数有什么具体含义?

参考答案:

Linux的top命令详解见http://www.2cto.com/os/201209/157960.html 解题思路:不同水平的面试人员有不同层次的理解,面试官应视其回答情况酌情给分 考察点:Linux运行情况的查看、top命令的使用熟练程度 分类:Linux基本操作{校招,社招都可以用}

难度分级:P4

2Linux上用什么命令看在线日志?

参考答案:

Linux 日志都以明文形式存储,所以用户不需要特殊的工具就可以搜索和阅读它们。 还可以编写脚本,来扫描这些日志,并基于它们的内容去自动执行某些功能。
Linux 日志存储在 /var/log 目录中。这里有几个由系统维护的日志文件,但其他服务和程序也可能会把它们的日志放在这里。 大多数日志只有root账户才可以读,不过修改文件的访问权限就可以让其他人可读。

可以用cat、head、tail等查看,用grep搜索过滤,用cut取字段(列数据),更高级的可以用awk和sed重排日志。

可以用cat、head、tail等查看,用grep搜索过滤,用cut取字段(列数据),更高级的可以用awk和sed重排日志。 解题思路:日志文件的格式多是文本文件,从文本文件的处理方式的考虑 考察点:日志的存储,Linux查看、搜索文本文件的方式,坑在直接用VI看,如果稍有经验的人这么做,那么基本可以送走了 分类:Linux基本操作{校招,社招都可以用}

难度分级:P4

3、如何输出时间到time.txt文件?

参考答案:

解题思路:重定向的应用
考察点: Linux命令输出重定向、简单的Linux命令 分类:Linux基本操作{校招,社招都可以用} 难度分级:P4

4、有一个文本文件source.txt,每行有个字符串,请使用shell命令查找包含“beijing”的行,并将结果保存到文件result.txt 

参考答案:

grep -i beijing source.txt > result.txt 解题思路:用grep来对文本文件搜索,注意-i选项用来忽略大小写 考察点: Linux命令输出重定向、grep简单应用 分类:Linux基本操作{校招,社招都可以用}

难度分级:P4

5、查看当前TCP/IP连接的状态和对应的个数?

参考答案:

 netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' 

解题思路:用netstat来查看连接和端口,用awk进行统计
考察点: netstat和awk的应用 分类:Linux组合操作{校招,社招都可以用}
难度分级:P5

7、分析apache访问日志,找出访问页面的次数排名前100ip?

 awk '{print $1}' localhost_access_log.txt | sort | uniq -c | sort -n -k 1 -r | head -n 100 

解题思路:用awk或者cut来取文本中的第一列,再用sort排序,uniq去重,数字排序,最后输出前100名 考察点: awk、sort、head等文本处理工具组合的应用
分类:Linux组合操作{社招}

8、符号链接(symbolic link)和硬链接的区别?

参考答案:

date >> time.txt 

硬链接(hard links): 为文件创建了额外的条目。使用时,与文件没有区别;删除时,只会删除链接,不会删除文件;

硬链接(hard links): 为文件创建了额外的条目。使用时,与文件没有区别;删除时,只会删除链接,不会删除文件; 硬链接的局限性: 1. 不能引用自身文件系统以外的文件,即不能引用其他分区的文件;2. 无法引用目录;
操作: ln file link, 只能link文件;

符号链接(symbolic links): 克服硬链接的局限性,类似于快捷方式,使用与硬链接相同. 如果先删除文件,则会成为坏链接(broken),ls会以不同颜色(Ubuntu, 红色)显示; 操作: ln -s item link,可以link文件和目录;

解题思路:hard link和soft link的区别,结合i-node的知识 考察点: i-node,文件链接 分类:Linux文件系统基本概念{校招,社招}

1.5web

1.6、安全

1.7、设计模式

1.8、数据库

1InnoDB 默认什么隔离级别,为什么选用这种级别。选其他的可以么? 

参考答案:

http://www.cnblogs.com/vinchen/archive/2012/11/19/2777919.html

解题思路:数据库事务

考察点:数据库事务

分类:数据库事务{校招,社招}

难度分级:P4

2RR级别下,都有哪些锁?有遇到过死锁么,什么情况下发生的死锁?

参考答案:

http://hedengcheng.com/?p=771

解题思路:数据库事务
考察点:数据库事务
分类:数据库事务{校招,社招}
难度分级:P4

3、数据服务端的一些命令(show processlist等等)

a. show tables或show tables from database_name; -- 显示当前数据库中所有表的名称
b. show databases; -- 显示mysql中所有数据库的名称
c. show columns from table_name from database_name; 或show columns from database_name.table_name; -- 显示表中列名称
d. show grants for user_name; -- 显示一个用户的权限,显示结果类似于grant 命令
e. show index from table_name; -- 显示表的索引
f. show status; -- 显示一些系统特定资源的信息,例如,正在运行的线程数量
g. show variables; -- 显示系统变量的名称和值
h. show processlist; -- 显示系统中正在运行的所有进程,也就是当前正在执行的查询。大多数用户可以查看他们自己的进程,但是如果他们拥有process权限,就可以查 看所有人的进程,包括密码。
i. show table status; -- 显示当前使用或者指定的database中的每个表的信息。信息包括表类型和表的最新更新时间
j. show privileges; -- 显示服务器所支持的不同权限
k. show create database database_name; -- 显示create database 语句是否能够创建指定的数据库
l. show create table table_name; -- 显示create database 语句是否能够创建指定的数据库
m. show engies; -- 显示安装以后可用的存储引擎和默认引擎。
n. show innodb status; -- 显示innoDB存储引擎的状态
o. show logs; -- 显示BDB存储引擎的日志
p. show warnings; -- 显示最后一个执行的语句所产生的错误、警告和通知
q. show errors; -- 只显示最后一个执行语句所产生的错误
r. show [storage] engines; --显示安装后的可用存储引擎和默认引擎
s. show procedure status --显示数据库中所有存储的存储过程基本信息,包括所属数据库,存储过 程名称,创建时间等

t. show create procedure sp_name --显示某一个存储过程的详细信息 解题思路:

考察点: mysql 分类:数据库,硬技能{校招,社招} 难度分级:P4、P5

4、为什么MySQL的索引要使用B+树而不是其它树形结构?为什么不用B 

参考答案:

为什么不用B树?:因为B树的所有节点都是包含键和值的,这就导致了每个几点可以存储的内容就变少了,出度就少了,树的高度会增高,查询的 时候磁盘I/O会增多,影响性能。由于B+Tree内节点去掉了data域,因此可以拥有更大的出度,拥有更好的性能。

解题思路:Mysql 索引数据结构
考察点: Mysql索引数据结构,B+树 B-树 分类:Mysql、数据结构{校招,社招} 难度分级:P4,P5

5、为什么InnoDB中表的主键最好要自增?

InnoDB使用聚集索引,数据记录本身被存于主索引(一颗B+Tree)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的 各条数据记录按主键顺序存放,因此每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(Inno DB默认为15/16),则开辟一个新的页(节点)。如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置, 当一页写满,就会自动开辟一个新的页。这样就会形成一个紧凑的索引结构,近似顺序填满。由于每次插入时也不需要移动已有数据,因此效率很 高,也不会增加很多开销在维护索引上。

如果使用非自增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置,此 时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增 加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。

因此,只要可以,请尽量在InnoDB上采用自增字段做主键。 解题思路:InnoDB 主键选择
考察点:InnoDB 索引数据结构,Mysql应用技能 分类:Mysql{校招,社招}

难度分级:P4,P5

6、数据库为什么要使用MVCC,使用MVCC有什么缺点?

参考答案:

Multi-Version Concurrency Control 多版本并发控制,因为锁机制是一种预防性的,读会阻塞写,写也会阻塞读,当锁定粒度较大,时间较长时并发性能就不会太好;而MVCC是一种 后验性的,读不阻塞写,写也不阻塞读,等到提交的时候才检验是否有冲突,由于没有锁,所以读写不会相互阻塞,从而大大提升了并发性能。

缺点:通过MVCC机制,虽然让数据变得可重复读,但我们读到的数据可能是历史数据,是不及时的数据,不是数据库当前的数据!这在一些对于 数据的时效特别敏感的业务中,就很可能出问题。

解题思路:MVCC
考察点: mysql 锁机制与MVCC 分类:Mysql、锁机制、MVCC{校招,社招} 难度分级:P5

7、如何分析慢查询,慢查询的分析步骤? 

参考答案:

慢查询优化基本步骤

0.先运行看看是否真的很慢,注意设置SQL_NO_CACHE 1.where条件单表查,锁定最小返回记录表。这句话的意思是把查询语句的where都应用到表中返回的记录数最小的表开始查起,单表每个字段分 别查询,看哪个字段的区分度最高
2.explain查看执行计划,是否与1预期一致(从锁定记录较少的表开始查询)

3.order by limit 形式的sql语句让排序的表优先查

3.order by limit 形式的sql语句让排序的表优先查 4.了解业务方使用场景 5.加索引时参照建索引的几大原则 6.观察结果,不符合预期继续从0分析

参考:http://tech.meituan.com/mysql-index.html 解题思路:
考察点:mySql查询优化 分类:数据库,硬技能{校招,社招}

8MySQL索引默认实现是用的什么数据结构,为什么采用这种? 

B+树。

索引也是磁盘上的,磁盘的I/O存取的消耗是比内存高出几个数量级的,索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数,所以要尽量降 低树的高度。要降低树的高度,因此用多分支的树,并且要树的每层的节点尽量的多,B+树将一个节点的大小设为等于一个页,这样每个节点只需 要一次I/O就可以完全载入,由于B+Tree内节点去掉了data域,因此可以拥有更大的出度,拥有更好的性能。

参考:http://www.marksaas.com/2014/04/mysql%E7%B4%A2%E5%BC%95%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86.html 解题思路:Mysql 索引数据结构
考察点: Mysql索引数据结构,B+树 B-树
分类:Mysql、数据结构{校招,社招}

难度分级:P4,P5

9MySQL联合索引使用是有什么规则?如果对A,B,C做索引,那么SQL语句写成where C=X and B=X and A=X,是否还能用到该索引?如果SQL语句写成where A=X and B>X and C=X是否还能用到该索引?

参考答案:

联合索引有最左前缀匹配原则。 

where C=X and B=X and A=X能用到该索引,因为=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式。

where A=X and B>X and C=X可以用到该索引,但C是用不到索引的,因为mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配。

解题思路:联合索引最左前缀匹配原则

考察点: 是否对联合索引的匹配原则,以及所以的数据结构有过了解

分类:Mysql索引基础知识{校招,社招}

难度分级:P4,P5

10MySQL引擎MyISAM,InnoDB有什么区别,各有什么特点?

参考答案:

MySQL有多种存储引擎,MyISAM和InnoDB是其中常用的两种。这里介绍关于这两种引擎的一些基本概念(非深入介绍)。

MyISAM是MySQL的默认存储引擎,基于传统的ISAM类型,支持全文搜索,但不是事务安全的,而且不支持外键。每张MyISAM表存放在三个文 件中:frm 文件存放表格定义;数据文件是MYD (MYData);索引文件是MYI (MYIndex)。

InnoDB是事务型引擎,支持回滚、崩溃恢复能力、多版本并发控制、ACID事务,支持行级锁定(InnoDB表的行锁不是绝对的,如果在执行一个S QL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表,如like操作时的SQL语句),以及提供与Oracle类型一致的不加锁读取方式。I nnoDB存储它的表和索引在一个表空间中,表空间可以包含数个文件。

主要区别:
MyISAM是非事务安全型的,而InnoDB是事务安全型的。 MyISAM锁的粒度是表级,而InnoDB支持行级锁定。 MyISAM支持全文类型索引,而InnoDB不支持全文索引。 MyISAM相对简单,所以在效率上要优于InnoDB,小型应用可以考虑使用MyISAM。

MyISAM表是保存成文件的形式,在跨平台的数据转移中使用MyISAM存储会省去不少的麻烦。

MyISAM表是保存成文件的形式,在跨平台的数据转移中使用MyISAM存储会省去不少的麻烦。

InnoDB表比MyISAM表更安全,可以在保证数据不会丢失的情况下,切换非事务表到事务表(alter table tablename type=innodb)。

应用场景:

MyISAM管理非事务表。它提供高速存储和检索,以及全文搜索能力。如果应用中需要执行大量的SELECT查询,那么MyISAM是更好的选择。

InnoDB用于事务处理应用程序,具有众多特性,包括ACID事务支持。如果应用中需要执行大量的INSERT或UPDATE操作,则应该使用InnoDB, 这样可以提高多用户并发操作的性能。

解题思路:MyISAM和InnoDB引擎区别
考察点: MyISAM和InnoDB引擎的了解
分类:Mysql
难度分级:P5

11、从性能上考虑,MySQL InnoDB 表主键如何选择,为什么?

自增主键

InnoDB使用聚集索引,数据记录本身被存于主索引(一颗B+Tree)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的 各条数据记录按主键顺序存放,因此每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(Inno DB默认为15/16),则开辟一个新的页(节点)。如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置, 当一页写满,就会自动开辟一个新的页。这样就会形成一个紧凑的索引结构,近似顺序填满。由于每次插入时也不需要移动已有数据,因此效率很 高,也不会增加很多开销在维护索引上。

如果使用非自增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置,此 时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增 加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。

因此,只要可以,请尽量在InnoDB上采用自增字段做主键。 解题思路:InnoDB 主键选择
考察点:InnoDB 索引数据结构,Mysql应用技能 分类:Mysql

12MySQL InnoDB默认的事务隔离级别是什么?

参考答案:
Repeatable Read(可重复读)
解题思路:Repeatable Read(可重复读)
考察点: 数据库事务了解
分类:Mysql、事务
难度分级:P4,P5

13、应用中怎么做到对数据库的读写分离,如何避免主从延迟造成的影响?

解题思路:
考察点:
分类:
难度分级:P5

14、如何处理组织机构树的联合查询问题?

树形结构来表征组织机构的关联关系,具体实现参考 

http://blog.csdn.net/monkey_d_meng/article/details/6647488 http://blog.csdn.net/biplusplus/article/details/7433625 解题思路:

考察点:

分类: 难度分级:P5

15MySQL Explain分析,给面试者一段具体的SQL Explain

参考答案:

http://wiki.sankuai.com/x/-JMRBQ

解题思路: 考察点:

分类:
难度分级:P5

16、如何删除一个表的重复数据 

参考答案:

CREATE TABLE `poi_menu_test` ( `id` bigint(30) NOT NULL AUTO_INCREMENT COMMENT 'ID', `poi_id` bigint(20) NOT NULL DEFAULT '0' COMMENT 'id', `name` varchar(64) NOT NULL DEFAULT '' COMMENT '', PRIMARY KEY (`id`) 

) ENGINE=InnoDB AUTO_INCREMENT=17621402 DEFAULT CHARSET=utf8 COMMENT='poi'; 

delete pmt from poi_menu_test pmt inner join ( select id,poi_id,name from poi_menu_test group by poi_id,name having count(*) > 1 )tmp on tmp.poi_id = pmt.poi_id and tmp.name = pmt.name and tmp.id <> pmt.id; 

解题思路:
考察点:
分类:社招
难度分级:P5

17、数据库事物隔离级别,每种的特点;SPRING事物传播与隔离级别的关系,如果配置的。

数据事务的四种隔离级别

在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别。我们的数据库锁,也是为了构建这些隔离级别存在的。 

隔离级别

未提交读(Read uncommitted) 已提交读(Read committed) 可重复读(Repeatable read) 可串行化(Serializable )

脏读(Dirty Read)

可能 不可能 不可能 不可能

不可重复读(NonRepeatable Read)

可能 可能 不可能 不可能

幻读(Phantom Read)

可能 可能 可能 不可能

未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据 提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)

可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存 在幻象读

串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

spring的事务隔离级别

ISOLATION_DEFAULT:使用数据库默认的隔离级别。 ISOLATION_READ_UNCOMMITTED:允许读取改变了的还未提交的数据,可能导致脏读、不可重复读和幻读。
ISOLATION_READ COMMITTED:允许并发事务提交之后读取,可以避免脏读,可能导致重复读和幻读。 ISOLATION_REPEATABLE_READ:对相同字段的多次读取结果一致,可导致幻读。 ISOLATION_SERIALIZABLE:完全服从ACID的原则,确保不发生脏读、不可重复读和幻读。 可以根据自己的系统对数据的要求采取适应的隔离级别,因为隔离牵涉到锁定数据库中的记录,对数据正性要求越严格,并发的性能也越差。 spring的事务传播行为
spring事务的传播行为说的是当一个方法调用另一个方法时,事务该如何操作。 PROPAGATION_MANDATORY:该方法必须运行在一个事务中。如果当前事务不存在则抛出异常。 PROPAGATION_NESTED:如果当前存在一个事务,则该方法运行在一个嵌套的事务中。被嵌套的事务可以从当前事务中单独的提交和回滚。如 果当前不存在事务,则开始一个新的事务。各厂商对这种传播行为的支持参差不齐,使用时需注意。 PROPAGATION_NEVER:当前方法不应该运行在一个事务中。如果当前存在一个事务,则抛出异常。 PROPAGATION_NOT_SUPPORTED:当前方法不应该运行在一个事务中。如果一个事务正在运行,它将在该方法的运行期间挂起。 PROPAGATION_REQUIRED:该方法必须运行在一个事务中。如果一个事务正在运行,该方法将运行在这个事务中。否则,就开始一个新的事务 。

PROPAGATION_REQUIRES_NEW:该方法必须运行在自己的事务中。它将启动一个新的事务。如果一个现有的事务正在运行,将在这个方法的运

PROPAGATION_REQUIRES_NEW:该方法必须运行在自己的事务中。它将启动一个新的事务。如果一个现有的事务正在运行,将在这个方法的运 行期间挂起。 PROPAGATION_SUPPORTS:当前方法不需要事务处理环境,但如果一个事务已经在运行的话,这个方法也可以在这个事务里运行。

配置方法:

<property name="transactionAttributes"> <props> <prop key="save*">PROPAGATION_REQUIRED</prop> <prop key="update*">PROPAGATION_REQUIRED</prop> <prop key="delete*">PROPAGATION_REQUIRED</prop> <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="find*">PROPAGATION_REQUIRED,ISOLATION_READ_UNCOMMITTED</prop> </props> 

解题思路: 考察点:

分类: 数据库,spring 难度分级:P5

18、如何优化查询语句,explain每个字段的含义,如果优化OR语句,IN 会用到索引吗?创建索引的顺序 

参考答案:
explain每个字段含义:Mysql explain学习总结 or语句:where语句里如果带有or条件,是可以用到索引,前提是有针对or条件所有字段的单独索引 in会用到索引
优化or语句:or条件建立单独索引,用union替代

解题思路:
考察点: mysql 索引,优化 分类:mysql
难度分级:P5

19、每个表的数据大小是否有限制,数据过大会对性能造成影响吗?常见的一些分库分表策略 

参考答案: mysql单表大小限制可以参考这篇文章:http://database.51cto.com/art/201011/234308.htm

这里引用一个问题为什么要分库分表呢?MySQL处理不了大的表吗? 其实是可以处理的大表的.我所经历的项目中单表物理上文件大小在80G多,单表记录数在5亿以上,而且这个表 属于一个非常核用的表:朋友关系表.

但这种方式可以说不是一个最佳方式. 因为面临文件系统如Ext3文件系统对大于大文件处理上也有许多问题. 这个层面可以用xfs文件系统进行替换.但MySQL单表太大后有一个问题是不好解决: 表结构调整相关的操作基 本不在可能.所以大项在使用中都会面监着分库分表的应用.

从Innodb本身来讲数据文件的Btree上只有两个锁, 叶子节点锁和子节点锁,可以想而知道,当发生页拆分或是添加 新叶时都会造成表里不能写入数据.

关于分表分库策略:

http://my.oschina.net/cmcm/blog/175104

解题思路:
考察点: mysql
分类:mysql
难度分级:P5 P6

20、如何实现主从分离,如何解决主从不一致带来的问题?

参考:数据库读写分离相关调研 解题思路:
考察点: MySQL

分类:MySQL 难度分级:P5 P6

21、数据库锁,如何防止覆盖更新,如何用数据库模拟队列?

参考答案:

覆盖更新可以用for update和 where 要更新的字段=更新之前的状态,判断影响记录数来实现。模拟队列需要考虑类型,优先级字段,同时用锁来避免重复同一条记录

解题思路:
考察点: MySQL,数据库
分类:数据库
难度分级:P5 P6

22、什么是乐观锁与悲观锁,如何实现乐观锁? 

悲观锁

正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中 ,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即 使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。 

乐观锁

相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之 而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。 

而乐观锁机制在一定程度上解决了这个问题。乐观锁,大多是基于数据版本( Version )记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个 “version” 字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本 信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。

--补充, 当主键采用数据库表生成时(GenerationType.TABLE),采用乐观锁好还是采用悲观锁好? 这个要考虑决具体的策略?

一般来讲,我们会根据数据生长速度(考察点,需要考虑)来申请一定数量的主键ID,比如100个,这样可以最大限度的增加主键生成的效率,减少不必要的 数据库交互

这样即使在集群环境下,表访问的竞争压力并不大,因此采用悲观锁就可以;而且乐观锁并不一定能够防止数据的"脏写",会导致主键重复的情况发生。 要说明的是,MVCC的实现没有固定的规范,每个数据库都会有不同的实现方式,这里讨论的是InnoDB的MVCC。

参考:Innodb中的事务隔离级别和锁的关系 解题思路:
考察点: 悲观锁 乐观锁
分类: 数据库

难度分级:P5

23、数据库连接池有哪些重要配置参数,分别起到什么作用?

标准答案:

C3P0 拥有比 DBCP 更丰富的配置属性,通过这些属性,可以对数据源进行各种有效的控制: acquireIncrement :当连接池中的连接用完时, C3P0 一次性创建新连接的数目; acquireRetryAttempts :定义在从数据库获取新连接失败后重复尝试获取的次数,默认为 30 ; acquireRetryDelay :两次连接中间隔时间,单位毫秒,默认为 1000 ;

autoCommitOnClose :连接关闭时默认将所有未提交的操作回滚。默认为 false ;
automaticTestTable : C3P0 将建一张名为 Test 的空表,并使用其自带的查询语句进行测试。如果定义了这个参数,那么属性 preferredTestQuery 将被忽略。你 不能在这张 Test 表上进行任何操作,它将中为 C3P0 测试所用,默认为 null ;
breakAfterAcquireFailure :获取连接失败将会引起所有等待获取连接的线程抛出异常。但是数据源仍有效保留,并在下次调 用 getConnection() 的时候继续尝试获取连接。如果设为 true ,那么在尝试获取连接失败后该数据源将申明已断开并永久关闭。默认为 false ;
checkoutTimeout :当连接池用完时客户端调用 getConnection() 后等待获取新连接的时间,超时后将抛出 SQLException ,如设为 0 则无限期等待。单位毫秒,默认为 0 ;
connectionTesterClassName : 通过实现 ConnectionTester 或 QueryConnectionTester 的类来测试连接,类名需设置为全限定名。默认为 com.mchange.v2.C3P0.impl.DefaultConnectionTester ;
idleConnectionTestPeriod :隔多少秒检查所有连接池中的空闲连接,默认为 0 表示不检查;
initialPoolSize :初始化时创建的连接数,应在 minPoolSize 与 maxPoolSize 之间取值。默认为 3 ;

maxIdleTime :最大空闲时间,超过空闲时间的连接将被丢弃。为 0 或负数则永不丢弃。默认为 0 ;

var flag=false; function checkForm(){

if (flag==true){ return false;

 } flag=true; document.form1.submit(); 

}

maxIdleTime :最大空闲时间,超过空闲时间的连接将被丢弃。为 0 或负数则永不丢弃。默认为 0 ;
maxPoolSize :连接池中保留的最大连接数。默认为 15 ;
maxStatements : JDBC 的标准参数,用以控制数据源内加载的 PreparedStatement 数量。但由于预缓存的 Statement 属 于单个 Connection 而不是整个连接池。所以设置这个参数需要考虑到多方面的因素,如果 maxStatements 与 maxStatementsPerConnection 均为 0 ,则缓存被关闭。默认为 0 ;
maxStatementsPerConnection :连接池内单个连接所拥有的最大缓存 Statement 数。默认为 0 ;
numHelperThreads : C3P0 是异步操作的,缓慢的 JDBC 操作通过帮助进程完成。扩展这些操作可以有效的提升性能,通过多线程实现多个操作同时被执行。默认为 3 ;
preferredTestQuery :定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个参数能显著提高测试速度。测试的表必须在初始数据源的时候就存在。默认 为 null ;
propertyCycle : 用户修改系统配置参数执行前最多等待的秒数。默认为 300 ;
testConnectionOnCheckout :因性能消耗大请只在需要的时候使用它。如果设为 true 那么在每个 connection 提交的时候都 将校验其有效性。建议使用 idleConnectionTestPeriod 或 automaticTestTable
等方法来提升连接测试的性能。默认为 false ;
testConnectionOnCheckin :如果设为 true 那么在取得连接的同时将校验连接的有效性。默认为 false 。

解题思路:同答案
考察点: 数据库连接池 分类:Spring,Mysql {社招} 难度分级:P5,P6 

二、Java相关

2.1Java基础知识 

1、为什么重载了equals方法之后需要去重载hashCode方法?

A:Hash的时候需要保证equals的对象映射到同一个位置

2、重载和覆盖的区别 

3static关键字的用法

静态方法和静态代码块

static和非static的区别,一般什么情况下会使用,怎么去用;

什么时候执行;

加分 —— 实例变量,静态变量,构造函数、父类相对变量的执行过程。

4final finalize finally 关键字都是干什么的?

5String StringBuffer StringBuilder 区别

StringBuffer和StringBuilder是线程安全问题,String和StringBuilder是效率以及内存分配问题。

加分1: String和StringBuilder在编译优化之后结果基本一致;

加分2: String在循环中操作,回导致声明很多的StringBuilder,因此禁止这种操作;

6HashMap的实现原理

基本:底层数据结构,冲突解决(Hash值映射到同一个位置——List,再次Hash)

加分:链表解决冲突的情况下如何优化速度?List长度超过一个值,B Tree。

加分:ConcurrentHashMap的实现——Segment。

加分:ConcurrentModificationException异常发生的原因

7waitsleep的区别

前者要求必须先获得锁才能调用,后者不需要。前者调用后会释放锁(进入等待池),后者不存在释放问题。

8synchronized关键字修饰静态方法和实例方法的区别

加锁对象不一样。

加分:和volatile关键字的区别?:volatile只管可见性,synchronized同时保证互斥性

9、死锁的四个条件

1) 互斥条件:一个资源每次只能被一个进程使用。(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

10notifynotifyAll的区别

除唤醒线程外,前者调用后其余线程还在等待池,后者其余线程进入锁池(可以主动竞争锁)

11Java 泛型的实现原理是什么

基本:概念用法,T ? extends

加分:泛型擦除,如下:编译报错还是运行报错

public void test(List<Integer> li){ } 

public void test(List<String> ls){ } 

12、浅克隆和深克隆?深克隆的方法

http://www.itzhai.com/java-based-notebook-the-object-of-deep-and-shallow-copy-copy-copy-implement-the-cloneable-interface-serializing-deep-deep-copy.html

13Integer缓存?Integer比较大小注意问题。==equals的区别考察 

Integer是有缓冲池的,java.lang.Integer.valueOf(int)方法默认情况下如果参数在-128到127之间,则返回缓存中的对象,否则返回new Integer(int)。java使用该机制是为了达到最小化数据输入和输出的目的,这是一种优化措施,提高效率

其他的包装器:
Boolean: (全部缓存) Byte: (全部缓存) Character ( <=127 缓存)

Short
Long
Float
Doulbe (没有缓存)

(-128~127 缓存) (-128~127 缓存)

(没有缓存)

可以设置系统属性 java.lang.Integer.IntegerCache.high 修改缓冲区上限,默认为127。参数内容应为大于127的十进制数形式的字符串,否则将被忽略。取值范围为127-Long.MAX_VALUE,但是用时将 强转为int。当系统中大量使用Integer时,增大缓存上限可以节省小量内存。

区别“==”和equals():“==”是比较两个对象是不是引用自同一个对象。 “equals()”是比较两个对象的内容。 

14、装箱和解箱机制?

http://developer.51cto.com/art/201203/325314.htm

15java的类加载器体系结构和双亲委托机制

http://blog.csdn.net/lovingprince/article/details/4317069 

加分:jetty or tomcat的类加载机制

16、简述一下java的异常体系,什么是受检异常?什么是运行时异常?封装一个API的时候什么情况下抛出异常?

17string常量池的考核 

String s1 = new String("hello");

String s2 = "hello";

区别

http://blog.sina.com.cn/s/blog_5203f6ce0100tiux.html

18Hash冲突,有哪几种常见的解决方法,JavaHashMap用的是哪一种?

参考答案:
(1)开放定址法; (2)拉链法;http://www.cnblogs.com/jillzhang/archive/2006/11/03/548671.html Java中HashMap使用的是拉链法。
解题思路:基础知识
考察点:Hash冲突,HashMap的底层数据结构实现
分类:数据结构,Java集合框架
难度分级:P4

19Java HashMap,已知整个生命周期内不会放入超过100个元素,那么占用内存大小最优且设置完初始值后无需自动扩容,该初始值应该设置为多少?

参考答案:

如果默认使用H ashMap内置的负载因子loadFactor为0.75。鉴于HashMap初始化设置大小为2的n次方,则100/0.75=133. 大于133的最小2的n次方为256个。
解题思路:基础知识
考察点: 考察HashMap的负载因子以及构造函数的理解

分类:Java集合框架{校招,社招} 难度分级:P4

20Java HashMap在高并发情况下不当使用,可能会导致什么样极端情况,为什么?

在并发的多线程使用场景中,在resize扩容的时候,使得HashMap形成环链,造成死循环,CPU飙升至100%。可以举例子说明。

参考链接:http://wiki.sankuai.com/x/oUl9BQ 解题思路:
考察点:HashMap的并发性 分类:{校招,社招}

21HashMap/ConcurrentHashMap的数据结构实现,扩容机制,HashMap hash的冲突处理。

答案参考前面。 补充:扩容机制考察扩容时机,扩容容量变化机制,扩容具体实现步骤-源码resize() 函数。 解题思路:
考察点:HashMap/ConcurrentHashMap的底层实现
分类:{校招,社招}
难度分级:P4,P5

22LinkedHashMap 数据结构实现 

参考答案:

首先搞清楚HashMap得实现;然后重点考察和HashMap的区别。 LinkedHashMap实现与HashMap的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序可 以是插入顺序或者是访问顺序。最好画个图解释下。Entry对象在HashMap的时候包含key,value,hash值,以及一个next;而在LinkedHashM

ap中新增了before和after。

ap中新增了before和after。
解题思路:基础知识 考察点:HashMap和LinkedHashMap 的数据结构的区别 分类:{校招,社招}
难度分级:P4,P5

23ArrayListLinkedList的区别,数据结构实现,扩容机制 

参考答案:

(1) ArrayList是实现了基于动态数组的数据结构,LinkedList基于双向循环链表的数据结构。 (2) 对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 (3) 对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。 (4) 查找操作indexOf,lastIndexOf,contains等,两者差不多。

(5) 随机查找指定节点的操作get,ArrayList速度要快于LinkedList. 当操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能;当你的操作是在 一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。
扩容: 针对ArrayList,在新增的时候,容量不够就需要扩容,2倍。
解题思路:基础知识
考察点:ArrayList和LinkedList的区别,ArrayList的扩容
分类:{校招,社招}
难度分级:P4

24、哈希函数的构造方法常见的有哪几种? 

参考答案:

(1)直接寻址法:取关键字或关键字的某个线性函数值为散列地址。即H(key)=key或H(key) = a·key + b为散列函数。若其中H(key)中已经有值了,就往下一个找,直到H(key)中没有值了,就放进去。 (2) 数字分析法:就是找出数字的规律,尽可能利用这些数据来构造冲突几率较低的散列地址。 (3)平方取中法:取关键字平方后的中间几位作为散列地址。

(4) 折叠法:将关键字分割成位数相同的几部分,最后一部分位数可以不同,然后取这几部分的叠加和(去除进位)作为散列地址。 (5)随机数法:选择一随机函数,取关键字的随机值作为散列地址,通常用于关键字长度不同的场合。 (6)除留余数法:取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即 H(key) = key MOD p,p<=m。不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p的选择很重要,一般取素数或m,若p选的不好,容易产生同 义词。

解题思路:基础知识 考察点:哈希函数的构造方法 分类:数据结构 难度分级:P4

25HashMap的实现原理(内部数据结构,null key,rehash);为什么说hashMap不是线程安全的。 

参考答案:

(1)内部数据结构实现:数组+链表 (最好画个图能解释清楚) (2)key值不能重复,只能put一个key为null的键值对。可以更深层次考察对put(null,value)以及get(null)的 理解。 (3)HashMap在put时,经过了两次hash,一个是JDK自带的对对象key的hash,然后再对结果使用HashMap内部函数hash(int h);hash(int h)方法根据key的hashCode重新计算一次散列。可以更深入考察对hash(int h)以及indexFor(int h, int length)两个函数的理解。 (4)在put时如果空间不够就需要扩容resize(),考察扩容过程--重新计算复制。 (5)在并发的多线程使用场景中,使用HashMap形成环链,造成死循环,CPU飙升至100%。例子见链接。 http://wiki.sankuai.com/pages/viewpage.action?pageId=89609604
解题思路:基础知识
考察点: 考察HashMap的底层实现远离
分类:Java集合框架{校招,社招}
难度分级:P4

26List有哪些实现,实现原理,如何选择实现;是否比较过性能差异?contains方法是怎么比较对象的?

参考答案:

(1)List的直接实现是两个抽象类,AbstactList和AbstractSequentialList.其中,AbstractList为随即访问(如数组)实现方案提供尽可能的封装 ,AbstractSequentialList为连续访问(如链表)实现方案提供了尽可能的封装。ArrayList,直接父类是AbstractList,数据结构是大小可变的数组, 它不是同步的。LinkedList,直接父类是AbstractSquentialList,数据结构是双向链表,它不是同步的,它同时实现了Deque(双向队列)和Queue(队 列)接口。同时它还提供了push和pop这两个堆栈操作的接口。Vector,直接父类是AbstractList,特性和ArrayList一样,只是它是线程同步的。Stack ,直接父类是Vector,实现堆栈这种数据结构。

(2)通过对象的equals方法。 解题思路:基础知识 考察点:考察对List的理解和运用以及equals的理解 分类:Java集合框架{校招,社招}

难度分级:P4

27、如何拷贝数组,怎样效率最高?为什么?

参考答案:

(1)使用循环结构 这种方法最灵活。唯一不足的地方可能就是代码较多 (2)使用Object类的clone()方法,

这种方法最简单,得到原数组的一个副本。灵活形也最差。效率最差,尤其是在数组元素很大或者复制对象数组时。 

这种方法最简单,得到原数组的一个副本。灵活形也最差。效率最差,尤其是在数组元素很大或者复制对象数组时。
(3) 使用Systems的arraycopy这种方法被告之速度最快,并且灵活性也较好,可以指定原数组名称、以及元素的开始位置、复 制的元素的个数,目标数组名称、目标数组的位置。
浅拷贝和深拷贝得理解:定义一个数组int[] a={3,1,4,2,5}; int[] b=a; 数组b只是对数组a的又一个引用,即浅拷贝。 如果改变数组b中元素的值,其实是改变了数组a的元素的值,要实现深度复制,可以用clone或者System.arrayCopy clone和System.arrayCopy都是对一维数组的深度复制;因为java中没有二维数组的概念,只有数组的数组。所以二维数组a中存储的实际上是两 个一维数组的引用。当调用clone函数时,是对这两个引用进行了复制。
解题思路:基础知识
考察点:数组拷贝,浅拷贝和深拷贝的区别
分类:{校招,社招}
难度分级:P4,P5 

2.2JVM

1 Jvm堆内存区,有两个S区有什么作用?

参考答案

S区即Survivor区,位于年轻代。年轻代分三个区。一个Eden 区,两个Survivor 区。大部分对象在Eden 区中生成。当Eden 区满时,还存活的对象将被复制到Survivor 区(两个中的一个),当这个Survivor 区满时,此区的存活对象将被复制到另外一个Survivor 区,当这个Survivor 去也满了的时候,从第一个Survivor 区复制过来的并且此时还存活的对象,将被复制年老区(Tenured)。需要注意,Survivor 的两个区是对称的,没先后关系,所以同一个区中可能同时存在从Eden 复制过来对象,和从前一个Survivor 复制过来的对象,而复制到年老区的只有从第一个Survivor 去过来的对象。而且,Survivor 区总有一个是空的。
解题思路:基础知识
考察点:JVM 内存结构
分类:JVM GC {校招,社招}
难度分级:P4

2、有遇到过OOM么,什么情况,怎么发现的,怎么查原因的?

参考答案:

http://outofmemory.cn/c/java-outOfMemoryError(OOM分类) http://www.51testing.com/html/92/77492-203728.html(jstat使用) http://my.oschina.net/shaorongjie/blog/161385(MAT使用)

解题思路:基础知识 考察点:jstat mat工具 jvm 分类:JVM GC {校招,社招} 难度分级:P4,P5

3、内存分配策略 

参考答案:

1)对象优先在Eden分配;2)大对象直接进入老年代;3)长期存活的对象将进入老年代;4)动态对象年龄判定

参考文献:http://www.cnblogs.com/liangzh/archive/2012/07/03/2575252.html

解题思路:基础知识 考察点: jvm
分类:JVM GC {校招,社招} 难度分级:P4,P5

4、线程内存和主内存是如何交互的? 

参考答案:

假设某条线程执行一个synchronized代码段,其间对某变量进行操作,JVM会依次执行如下动作: (1) 获取同步对象monitor (lock)
(2) 从主存复制变量到当前工作内存 (read and load)
(3) 执行代码,改变共享变量值 (use and assign)

(4) 用工作内存数据刷新主存相关内容 (store and write) (5) 释放同步对象锁 (unlock)

解题思路:基础知识 考察点: jvm
分类:JVM GC {校招,社招} 难度分级:P4,P5

5、线上环境JVM参数Xms Xmx是如何设置的, 如果大小是一至,为什么这样设置?

参考答案:

Xmx设置JVM 的最大可用内存,Xms 设置JVM实际使用内存,一般Xmx和Xms相同,这是因为当Xmx内存空间不够用时,将进行扩容导致Full GC。将Xmx和Xms设置成相同的值,避免因Xms偏小导致频繁重新分配内存,影响应用使用。

解题思路:基础知识 考察点: jvm
分类:JVM GC {校招,社招} 难度分级:P4,P5

6、如何定位一个CPU Load过高的Java线程?

参考答案:
1、jps -v列出所有的java进程 , top找出cpu占用过高的对应的java 进程pid
2、使用top -H -p PID 命令查看对应进程里的哪个线程占用CPU过高,取该线程pid
3、将线程的pid 转成16进制
4、jstack [进程pid]|grep -A 100 [线程pid的16进制] dump出jvm该线程的后100行,或者整个输出到文件 jstack -l pid > xxxfile 参考文献:Crm线上机器发布时load过高案例分析阶段总结以及监控工具介绍

解题思路:基础知识 考察点: jvm 分类:JVM GC {社招} 难度分级:P5

7JmapDump的文件大小和MAT分析工具里显示的大小不一致一般是什么原因导致的?

参考答案:

JmapDump的文件一般比MAT工具大。创建索引期间,MAT会删除部分垃圾收集算法遗留下的不可达的object,因为回收这些较小的object代价 较大,一般这些object占比不超过4%。另外不能正确的写JmapDump的文件。尤其在较老的jvm(1.4,1.5)并且使用jmap命令获取JmapDump 的文件的时候。

解题思路:基础知识 考察点: jvm 分类:JVM GC {社招} 难度分级:P5

8、如何在Jmap未响应的情况下Dump出内存?

参考答案:

加-F参数

解题思路:基础知识 考察点: jvm 分类:JVM GC {社招} 难度分级:P5

9、说出5JVM的参数以及含义,怎么样配置这样参数?

参考答案:

JVM参数设置

解题思路:基础知识 考察点: jvm
分类:JVM GC {校招,社招} 难度分级:P4,P5

10JVM的一些健康指标和经验值,如何配置最优?

参考答案: 这个是比较开发性试题,偏社招,考察面试者对系统的掌控力,一般都会从垃圾回收的角度来解释,比如用jstat或者gc日志来看ygc的单次时间和 频繁程度,full gc的单次时间和频繁程度;ygc的经验时间100ms以下,3秒一次;full gc 1秒以下 1小时一次,每次回收的比率70%等等,也会用jstack和jmap看系统是否有太多的线程和不必要的内存等等。关于如何才能让配置最优,有一些理 论支撑,比如高吞吐和延迟低的垃圾收集器选择,比如高并发对象存活时间不长,可以适当加大yong区;但是有经验的面试者会调整一些参数测试 来印证自己的想法。

解题思路:基础知识 考察点: jvm

分类:JVM GC {校招,社招}

分类:JVM GC {校招,社招} 难度分级:P4,P5

11、对象存活算法,常见的有哪几种,JAVA采用的是哪种?

参考答案:

(1)引用计数算法

原理:给对象添加一个引用计数器,每当有一个地方引用它时,计数器加1;引用失效时,计数器减1;计数器为0说明可被回收。 缺点:很难解决对象相互循环引用的问题(对象相互循环引用,但其实他们都已经没有用了。

(2)可达性分析算法

原理:通过一些列称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。在java语言中,可作为GC Roots的对象包括下面几种:虚拟机栈(栈帧中的本地变量表)中引用的对象、方法区类静态属性引用的对象、方法区中常量引用的对象、本地方法 栈中JNI引用的对象、

参考文献:http://blog.csdn.net/chaofanwei/article/details/19541421

解题思路:基础知识 考察点:JVM GC 分类:JVM GC {校招,社招} 难度分级:P4,P5

12JVM新生代ParNew用的是什么垃圾收集算法?

参考答案:复制 解题思路:基础知识

考察点:JVM GC 分类:JVM GC {校招,社招} 难度分级:P4,P5

13JVM垃圾收集复制算法中,Eden:Form:To,为什么是8:1:1,而不是1:1:1?

参考答案:

一般情况下,新生代中的对象大多生命周期很短,也就是说当进行垃圾收集时,大部分对象都是垃圾,只有一小部分对象会存活下来,所以只要保 留一小部分内存保存存活下来的对象就行了。在新生代中一般将内存划分为三个部分:一个较大的Eden空间和两个较小的Survior空间(一样大小 ),每次使用Eden和一个Survior的内存,进行垃圾收集时将Eden和使用的Survior中的存活的对象复制到另一个Survior空间中,然后清除这两个 空间的内存,下次使用Eden和另一个Survior,HotSpot中默认将这三个空间的比例划分为8:1:1,这样被浪费掉的空间就只有总内存的1/10了。 参考文献:http://www.cnblogs.com/angeldevil/p/3803969.html

解题思路:基础知识 考察点:JVM GC 分类:JVM GC {校招,社招} 难度分级:P4,P5

14JVM老年代CMS用的是什么垃圾收集算法?

参考答案:

CMS以获取最短回收停顿时间为目标的收集器,使用“标记-清除”算法,分为以下6个步骤

1.STW initial mark:第一次暂停,初始化标记,从root标记old space存活对象(the set of objects reachable from roots (application code))

2.Concurrent marking:运行时标记,从上一步得到的集合出发,遍历old space,标记存活对象 (all live objects that are transitively reachable from previous set)

3.Concurrent precleaning:并发的标记前一阶段被修改的对象(card table)

4.STW remark:第二次暂停,检查,标记,检查脏页的对象,标记前一阶段被修改的对象 (revisiting any objects that were modified during the concurrent marking phase)

5.Concurrent sweeping:运行过程中清理,扫描old space,释放不可到达对象占用的空间

6.Concurrent reset:此次CMS结束后,重设CMS状态等待下次CMS的触发 或者4个大步骤:

1,initial mark 2,concurrent mark 3,remark 4,concurrent sweep 解题思路:基础知识

考察点:JVM GC 分类:JVM GC {校招,社招} 难度分级:P4,P5

15young gcfull gc触发条件 

young gc :eden空间不足
full gc :显示调用System.GC、旧生代空间不足、Permanet Generation空间满、CMS GC时出现promotion failed和concurrent mode failure、 RMI等的定时触发、YGC时的悲观策略、dump live的内存信息时
参考文献:http://blog.csdn.net/vernonzheng/article/details/8460128
http://blog.sina.com.cn/s/blog_7581a4c301019hsc.html
解题思路:基础知识
考察点:JVM GC
分类:JVM GC {校招,社招}
难度分级:P4,P5

16、垃圾回收器种类,垃圾回收扫描算法(root扫描),回收算法(复制,标记清除,标记整理)

参考答案:

垃圾回收器种类:
Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS(ConCurrent Mark Sweep)、G1(Garbage First)

垃圾回收扫描算法:

垃圾检测通过建立一个根对象的集合(局部变量、栈桢中的操作数,在本地方法中引用的对象,常量池等)并检查从这些根对象开始的可触及性来 实现。根对象总是可访问的,如果存在根对象到一个对象的引用路径,那么称这个对象是可触及的或活动对象,否则是不可触及的,不可触及的对 象就是垃圾对象。 

回收算法:

标记清除

分为标记和清除两个阶段,在标记阶段,垃圾收集器跟踪从根对象的引用,在追踪的过程中对遇到的对象打一个标记,最终未被标记的对象就是垃 圾对象,在清除阶段,回收垃圾对象占用的内存。可以在对象本身添加跟踪标记,也可以用一个独立的位图来设置标记。标记清除法是基础的收集 

 算法,其他算法大多时针对这个算法缺点的改进。存在效率和碎片问题。 复制算法 

将内存划分为大小相等的两个区域,每次只使用其中的一个区域,当这个区域的内存用完了,就将可触及的对象直接复制到新的区域并连续存放以 消除内存碎片,当可触及对象复制完后,清除旧内存区域,修改引用的值。这种算法明显缺点是浪费内存,故实际使用中常将新生代划分成8:1:1三

个区。 标记整理

标记整理算法中标记的过程同标记清理一样,但整理部分不是直接清除掉垃圾对象,而是将活动对象统一移动一内存的一端,然后清除边界外的内 存区域,这样就避免了内存碎片。也不会浪费内存,不需要其他内存进行担保 

分代收集

大多数程序中创建的大部分对象生命周期都很短,而且会有一小部分生命周期长的对象,为了克服复制收集器中每次垃圾收集都要拷贝所有的活动 对象 

的缺点,将内存划分为不同的区域,更多地收集短生命周期所在的内存区域,当对象经历一定次数的垃圾收集存活时,提升它的存在的区域。一般 是划 分为新生代和老年代。新生代又划分为Eden区,From Survior区和To Survior区

自适应收集器 监听堆中的情形,并且对应地调用合适的垃圾收集技术。 

参考文献:http://www.cnblogs.com/angeldevil/p/3803969.html

解题思路:基础知识 考察点:JVM GC 分类:JVM GC {校招,社招} 难度分级:P4,P5

17 cms回收器的标记过程,内存碎片问题

参考答案:

cms回收器的标记过程:

1.STW initial mark:第一次暂停,初始化标记,从root标记old space存活对象(the set of objects reachable from roots (application code))

2.Concurrent marking:运行时标记,从上一步得到的集合出发,遍历old space,标记存活对象 (all live objects that are transitively reachable from previous set)

3.Concurrent precleaning:并发的标记前一阶段被修改的对象(card table)

4.STW remark:第二次暂停,检查,标记,检查脏页的对象,标记前一阶段被修改的对象 (revisiting any objects that were modified during the concurrent marking phase)

内存碎片问题:

CMS基于“标记-清除”算法,进行垃圾回收后会存在内存碎片,当申请大的连续内存时可能内存不足,此时需要进行一次Full GC,可以通过参数指定进行Full GC后或进行多少次Full GC后进行一次内存压缩来整理内存碎片。

解题思路:基础知识 考察点:JVM GC 分类:JVM GC {校招,社招} 难度分级:P4,P5

18GC Log分析,给面试者一段具体GC Log

参考 jvm gc介绍和日志说明 19、画一下JVM内存结构图,各块分别有什么的作用?-- by 刘柳

参考答案:

各模块作用:
程序技术器:是一块很小的内存区域,主要作用是记录当前线程所执行的字节码的行号。 虚拟机栈:是线程私有的,存放当前线程中局部基本类型的变量、部分的返回结果以及Stack Frame,非基本类型的对象的引用。Sun JDK的实现中JVM栈的空间是在物理内存上分配的,而不是从堆上分配。
堆:存储对象实例和数组区域 方法区域:是全局共享的,存放了所加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义为final类型的常量、类中的Field信息、类中 的方法信息。
本地方法堆栈:支持native方法的执行,存储每个native方法调用的状态。
解题思路:基础知识
考察点:JVM
分类:JVM {校招,社招}
难度分级:P4,P5

20JVM垃圾收集在ParNew+CMS条件下,哪些情况下会让JVM认为产生了一次FULL GC?

参考答案:

JVM认为在老年代或者永久区发生的gc行为就是Full GC,在ParNew+CMS条件下,发生Full GC的原因通常为: a) 永久区达到一定比例。
b) 老年代达到一定比例。
c) 悲观策略。

d) System.gc(), jmap -dump:live, jmap -histo:live 等主动触发的。 解题思路:
考察点:GC收集器 Full GC
分类:JVM GC {校招,社招}

难度分级:P4,P5

21、如何查看StringPool大小? 

通过java -XX:+PrintStringTableStatistics命令查看,Number of buckets显示的就是StringPool的默认大小,在jdk7 u40版本以前,它的默认大小是1009,之后便调整为60013。

解题思路:JVM基础知识 考察点:StringPool 分类:JVM GC {校招,社招} 难度分级:P4,P5

22JmapDump的文件中是否包括StringPool?

参考答案:

StringPool在jdk6中是在永久区,dump heap时,无法输出。在jdk7中,stringpool移到heap中,可以输出。

解题思路:JVM基础知识 考察点:StringPool 分类:JVM GC {校招,社招} 难度分级:P4,P5 

2.3、 多线程

1Java线程有哪些状态?并画出状态转换图

2、举例Java线程安全的实现方法,原理、区别?

参考答案:

互斥同步:synchronized关键字 , Lock ReentrantLock,volatile 非阻塞同步:原子变量 atomicLong 原理:sun.misc.Unsafe类,CAS指令

解题思路:基础知识 考察点:java 线程

分类:java 线程 {校招,社招}

分类:java 线程 {校招,社招} 难度分级:P4,P5

3、多次调用线程的start方法会怎么样?

参考答案:

线程的start()只能被调用一次,否则会报java.lang.IllegalThreadStateException

Thread类的start()方法

public synchronized void start() { if (threadStatus != 0) 

 throw new IllegalThreadStateException(); ...... 

}

解题思路:基础知识 考察点:java 线程 分类:java 线程 {校招,社招} 难度分级:P4,P5

4、线程sleep()和yield()的区别是什么?

参考答案:

sleep()使当前线程进入停滞状态,所以执行sleep()的线程在指定的时间内肯定不会执行;yield()只是使当前线程重新回到可执行状态,所以执行yi eld()的线程有可能在进入到可执行状态后马上又被执行。 sleep()可使优先级低的线程得到执行的机会,当然也可以让同优先级和高优先级的线程有执行的机会;yield()只能使同优先级的线程有执行的机会 。

解题思路:基础知识 考察点:java 线程 分类:java 线程 {校招,社招} 难度分级:P4,P5

5、线程同步问题

参考答案:

1) 在需要同步的方法的方法签名中加入synchronized关键字。 2)使用synchronized块对需要进行同步的代码段进行同步。 3)使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象。 4)锁的粒度:类级别和对象级别 5)读写锁,CountDownLatch等的使用

6) Lock与synchronized 的区别

http://houlinyan.iteye.com/blog/1112535

解题思路:基础知识 考察点:java 线程 分类:java 线程 {校招,社招} 难度分级:P4,P5

6wait()和notify(),waitsleep的区别 

参考答案:

wait()和notify()的区别:
http://blog.csdn.net/oracle_microsoft/article/details/6863662
wait和sleep的区别:
(1)sleep是Thread类的方法,是线程用来 控制自身流程的,比如有一个要报时的线程,每一秒中打印出一个时间,那么我就需要在print方法前面加上一个sleep让自己每隔一秒执行一次。 就像个闹钟一样。 wait是Object类的方法,用来线程间的通信,这个方法会使当前拥有该对象锁的进程等待知道其他线程调用notify方法时再醒来,不过你也可以给 他指定一个时间,自动醒来。这个方法主要是用走不同线程之间的调度的。
(2)关于锁的释放 ,在这里假设大家已经知道了锁的概念及其意义。调用sleep方法不会释放锁(自己的感觉是sleep方法本来就是和锁没有关系的,因为他是一个线 程用于管理自己的方法,不涉及线程通信)
(3)使用区域
由于wait函数的特殊意义,所以他是应该放在同步语句块中的,这样才有意义 。
注意:两个方法都需要抛出异常
解题思路:基础知识

考察点:

考察点: 分类:{校招,社招} 难度分级:P4

7IO密集型和CPU密集型与线程池大小的关系

参考答案:

任务性质不同的任务可以用不同规模的线程池分开处理。CPU密集型任务配置尽可能小的线程,如配置Ncpu+1个线程的线程池。IO密集型任务则 由于线程并不是一直在执行任务,则配置尽可能多的线程,如2*Ncpu。混合型的任务,如果可以拆分,则将其拆分成一个CPU密集型任务和一个I O密集型任务,只要这两个任务执行的时间相差不是太大,那么分解后执行的吞吐率要高于串行执行的吞吐率,如果这两个任务执行时间相差太大 ,则没必要进行分解。我们可以通过Runtime.getRuntime().availableProcessors()方法获得当前设备的CPU个数。 参考资料:http://www.infoq.com/cn/articles/java-threadPool

解题思路:基础知识 考察点: 分类:{校招,社招} 难度分级:P4,P5

8ThreadLocal 作用和实现机制

参考答案: http://wowlinda80.iteye.com/blog/228600

解题思路:基础知识 考察点: 分类:{校招,社招} 难度分级:P4,P5

9java线程池corePoolSize,maxPoolSize,queueCapacity这些参数的意义,如何考虑这些参数的设置

参考答案:

corePoolSize(线程池的基本大小):核心线程数,核心线程会一直存活,即使没有任务需要处理。当线程数小于核心线程数时,即使现有的线程 空闲,线程池也会优先创建新线程来处理任务,而不是直接交给现有的线程处理。 maximumPoolSize(线程池最大大小):当线程数大于或等于核心线程,且任务队列已满时,线程池会创建新的线程,直到线程数量达到maxPo olSize。如果线程数已等于maxPoolSize,且任务队列已满,则已超出线程池的处理能力,线程池会拒绝处理任务而抛出异常。 queueCapacity(任务队列容量):从maxPoolSize的描述上可以看出,任务队列的容量会影响到线程的变化,因此任务队列的长度也需要恰当的设 置。

参数的设置参考http://blog.csdn.net/zhouhl_cn/article/details/7392607

解题思路:最好搞清楚线程池的主要处理流程。 考察点:线程池的理解与使用 分类:{校招,社招}
难度分级:P4,P5

10ThreadLocal是什么,有什么典型的应用场景?

参考答案:

http://wowlinda80.iteye.com/blog/228600

解题思路:最好搞清楚线程池的主要处理流程。 考察点:线程池的理解与使用 分类:{校招,社招}
难度分级:P4,P5

11、考虑设计一个计数器程序,场景一,一个线程写,多个线程读;场景二,多个线程写,多个线程读。分别应对这2种场景设计一个计数器程序 ,要保证线程安全

参考答案:
一写多读的情况主要需要考虑读到最新的数据,所以加volatile关键字即可

多写多读的情况就需要考虑原子操作,可以利用CAS原理 解题思路:基础知识
考察点:多线程,异步
分类:{校招,社招}

难度分级:P4,P5

12、多线程的使用场景,为了解决什么样的问题。不适用于什么场景

参考答案:

这几点阐述的不完全正确
多线程优势 1.发挥多核处理器的强大能力,如果没有多核处理器,用多线程也只是形式而已,提升处理速度,常见的是一个任务用多线程跑比单线程跑快 2.建模简单,可以把一系列的复杂交互,变成简单的同步编程模型;比如我们在写controller时不用在考虑线程创建、销毁、调度优先级等;如果用 单线程模型会变得非常复杂。
3.异步事件的简化处理,参见NIO的实现
多线程的风险
1.线程安全性
2.活跃性(死锁)问题

3.性能问题,频繁切换上下文,调度

3.性能问题,频繁切换上下文,调度 想要同时处理多件事:单线程处理不了的,必须使用多线程。(类似于分身术) 多个线程分解大任务:用单线程可以做,但是使用多线程可以更快。(类似于左右开弓) 可以引申到异步和多线程的区别上。
解题思路:基础知识
考察点:多线程,异步
分类:{校招,社招都可以用}
难度分级:P4,P5

13、线程池的实现原理 

参考答案:

线程池的作用是有效的降低频繁创建销毁线程所带来的额外开销。一般来说,线程池都是采用预创建的技术,在应用启动之初便预先创建一定数目 的线程。应用在运行的过程中,需要时可以从这些线程所组成的线程池里申请分配一个空闲的线程,来执行一定的任务,任务完成后,并不是将线 程销毁,而是将它返还给线程池,由线程池自行管理。如果线程池中预先分配的线程已经全部分配完毕,但此时又有新的任务请求,则线程池会动 态的创建新的线程去适应这个请求。当然,有可能,某些时段应用并不需要执行很多的任务,导致了线程池中的线程大多处于空闲的状态,为了节 省系统资源,线程池就需要动态的销毁其中的一部分空闲线程。因此,线程池都需要一个管理者,按照一定的要求去动态的维护其中线程的数目。 线程池将频繁创建和销毁线程所带来的开销分摊到了每个具体执行的任务上,执行的次数越多,则分摊到每个任务上的开销就越小。当然,如果线 程创建销毁所带来的开销与线程执行任务的开销相比微不足道,可以忽略不计,则线程池并没有使用的必要。 

这个例子不错:

多线程就是通过线程调用线程实现的;打个比方来说就像“摆渡”,河的一岸有很多的人,他们想过河,过河的过程做什么就是他们自己的逻辑, 只要他符合我的要求我就送你过河(线程池的要求就是实现Runnable或继承Thread类),然后我开了几条船去送人,只要河的这一岸有满足的人 ,我就送你过河。这个例子中河一岸的人就是我们要执行的任务,是一个集合,船就是线程池中的线程,由我们自己控制,过河这个动作就是要执 行的逻辑,我们只负责把船调给你,怎么划桨怎么过河就是程序自己的逻辑了。

解题思路:基础知识 考察点:线程池 分类:{校招,社招都可以用} 难度分级:P4,P5

14、常见的线程工具(同步器、线程安全集合类、原子类),什么场景下使用 

参考答案:

【java】【分享】java多线程

解题思路:基础知识 考察点:Java线程状态 分类:{校招,社招} 难度分级:P4

15、常见的线程状态,以及相互转换图;WAITINGBLOCK的区别

参考答案:

线程状态以及相互转换图已有答案。 blocked是内部对象锁阻塞,另外blocked激活需要线程调度器允许其持有对象,waiting是等待其他线程通知线程调度器一个条件; BLOCK产生的原因:I/O等待阻塞,suspend挂起等
WAITING产生原因:Thread.sleep,Object.wait等
解题思路:基础知识
考察点:Java线程状态
分类:{校招,社招}
难度分级:P4

16、常见的同步方式 synchronized lock 如何选择 

参考答案:

参考:http://houlinyan.iteye.com/blog/1112535 解题思路:基础知识
考察点:线程同步方式
分类:{校招,社招}

难度分级:P4

17、死锁的几种场景,如何避免死锁 

参考答案: 参考http://www.cnblogs.com/cxd4321/archive/2012/05/28/2521542.html 解题思路:基础知识
考察点:死锁
分类:{校招,社招}
难度分级:P4

18、利用缓存机制优化一个复杂计算程序 

public class Memoizer<A, V> implements Computable<A, V> { private final ConcurrentMap<A, Future<V>> cache 

 = new ConcurrentHashMap<A, Future<V>>(); private final Computable<A, V> c; 

 public Memoizer(Computable<A, V> c) { this.c = c; } 

 public V compute(final A arg) throws InterruptedException { while (true) { 

} }}

Future<V> f = cache.get(arg); if (f == null) { 

 Callable<V> eval = new Callable<V>() { public V call() throws InterruptedException { 

 return c.compute(arg); } 

 }; FutureTask<V> ft = new FutureTask<V>(eval); f = cache.putIfAbsent(arg, ft); if (f == null) { f = ft; ft.run(); } 

} try {

 return f.get(); } catch (CancellationException e) { 

 cache.remove(arg, f); } catch (ExecutionException e) { 

 throw launderThrowable(e.getCause()); } 

19Java方法体中用到了多线程,使用了ThreadPool,但是方法体内程序员没有显式调用ShutDown关闭线程池,那么该方法执行结束后,JVM 是否能自动的关闭线程池,销毁线程?

标准答案:
答案是JVM不能自动关闭线程池,销毁线程。 可以参考海丰的CRM每天第一次发布导致cpu load过高报警的问题 解题思路:基础知识
考察点:线程池
分类:{校招,社招都可以用}
难度分级:P4,P5

20ThreadPool中线程是如何做到重用的?

参考答案: 线程池在执行execute方法的时候,会根据初始化参数的大小以及线程池已有的线程数,来创建核心线程或者把task塞入任务队列;其中创建的核 心线程创建后会启动,run方法内会执行一个runWork函数,此函数会不断地从任务队列中获取task执行。 解题思路:线程池的工作原理和工作流程。
考察点:线程池
分类:{校招,社招都可以用}
难度分级:P4,P5 

2.4、框架组件

三、Android相关

四、IOS相关

五、算法题

1、最短摘要生成

https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/%E6%9C%80%E7%9F%AD%E6%91%98%E8%A6%81%E7%9A%84%E7%94%9F%E6%88%90.md

六、逻辑题

1、捡肥皂

from:INF校招面试题目征集

有N(N>2)个同学站成一直排,裁判员一声令下,所有同学同时随机向左转或者向右转(包括队头队尾的也是随机),如果有两个同学面对面,那么就可以愉快地去捡肥皂了,请问剩下来的人数的期望值是多少?(建议考试的时候将捡肥皂改为找朋友)

  1. 分析:如果N=2,捡肥皂成功的概率是1/2 * 1/2 = 1/4;如果N=K+1,总的捡肥皂成功的pair数 = 前K个人成功的pair数+第K个人捡肥皂成功的概率,而第K个人成功的概率是1/4。所以N个人中总共预期有(N-1)/4对,也就是成功的人数是(N-1)/2,剩下的人数是(N+1)/2。
    考查要点:(1)基本的分析能力;(2)对复杂问题先从简单入手的能力,希望候选人先列举N=2, N=3, N=4...等几个简单的例子,然后从中发现规律。
发布了224 篇原创文章 · 获赞 100 · 访问量 53万+

猜你喜欢

转载自blog.csdn.net/chenpeng19910926/article/details/86526881