您的位置:首页 > 职场人生

互联网公司校招Java面试题总结及答案——微店、去哪儿、蘑菇街

2017-01-12 12:41 766 查看
部分重复的我已经去掉了,所以显得比较少,其他请参看我的系列文章:
互联网公司校招Java面试题总结及答案——招银科技
互联网公司校招Java面试题总结及答案——乐视、滴滴、华为
互联网公司校招Java面试题总结及答案——CVTE
互联网公司校招Java面试题总结及答案——美团
( 百度Java面经)互联网公司校招Java面试题总结及答案——百度(目前只是部分总结)
互联网公司校招Java面试题总结及答案——京东

------------------------------------微店------------------------------------
2.servlet和filter的区别。filter你在哪些地方用到过。

servlet是一种运行服务器端的java应用程序,具有独立于平台和协议的特性,并且可以动态的生成web页面,它工作在客户端请求与服务器响应的中间层。

1) 客户端发送请求至服务器端;

2) 服务器将请求信息发送至 Servlet;

3) Servlet 生成响应内容并将其传给服务器。响应内容动态生成,通常取决于客户端的请求;

4) 服务器将响应返回给客户端。

在 Web 应用程序中,一个 Servlet 在一个时刻可能被多个用户同时访问。这时 Web 容器将为每个用户创建一个线程来执行 Servlet。

filter是一个可以复用的代码片段,可以用来转换HTTP请求、响应和头信息。Filter不像Servlet,它不能产生一个请求或者响应,它只是修改对某一资源的请求,或者修改从某一的响应。只要你在web.xml文件配置好要拦截的客户端请求,它都会帮你拦截到请求,此时你就可以对请求或响应(Request、Response)统一设置编码,简化操作;同时还可进行逻辑判断,如用户是否已经登陆、有没有权限访问该页面等等工作。

Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。

创建一个Filter只需两个步骤:

建Filter处理类;

web.xml文件中配置Filter。

一定要实现javax.servlet包的Filter接口的三个方法init()、doFilter()、destroy().

listener:监听器,从字面上可以看出listener主要用来监听只用。通过listener可以监听web服务器中某一个执行动作,并根据其要求作出相应的响应。

interceptor:是在面向切面编程的,就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法,是基于JAVA的反射机制。比如动态代理就是拦截器的简单实现
3.堆与普通二叉树有什么区别。

堆是结点之间满足一定次序关系的完全二叉树(大多数情况下使用的是完全二叉树,但不一定必须是完全二叉树)。

具有n个结点的堆,其深度即为堆所对应的完全二叉树的深度log n 。

以小根堆为例,堆的特点是双亲结点的关键字必然小于等于孩子结点的关键字,而两个孩子结点的关键字没有次序规定。

堆存在的原因:

我们需要能得到一个集合的最小值,并且,在它被任意划分成为若干个子集的时候,这些子集的最小值我们也是知道的,这些子集不断的被划分,我们依然知道再次被划分出来的这些子集的最小值。

堆不止二叉堆,还有更复杂的二项堆,斐波那契堆,配对堆等等。

总之,堆是一种特殊的树。
4.linux如何查找文件

cat、vi、

find :find <指定目录> <指定条件> <指定动作>

使用locate搜索linux系统中的文件,它比find命令快。因为它查询的是数据库(/var/lib/locatedb),数据库包含本地所有的 文件信息。使用locate命令在根目录下搜索interfaces文件的命令为”locate interfaces“

使用”whereis“命令可以搜索linux系统中的所有可执行文件即二进制文件。使用whereis命令搜索grep二进制文件的命令为”whereis grep“。
--------------------------------------------------去哪儿--------------------------------------------
3.类加载机制

启动类加载器( Bootstrap ClassLoader)启动类加载器无法被 java 程序员直接引用, 这个类加载器负责把存放在<JAVA_HOME>\lib目录中的,
或者被-Xbootclasspath参数指定路径中的, 并且是被虚拟机识别的类库加载到虚拟机内存中.

扩展类加载器(Extension ClassLoader)负责加载在<JAVA_HOME>\lib\ext目录中的, 或者被java.ext.dirs系统变量所指定的路径中的所有类库。

应用程序类加载器( Application ClassLoader )这个类加载器是ClassLoader 中的 getSystemClassLoader()方法的返回值,
一般称其为系统类加载器, 它负责加载用户类路径( ClassPath )上所指定的类库
从 java 虚拟机的角度而降, 只存在两种不同的类加载器:

一个是启动类加载器( Bootstrap ClassLoader ), 这个类加载使用 C++ 语言实现, 是虚拟机自身的一部分;

另一种是其他所有的类加载器, 他们由 java 语言实现, 独立于虚拟机之外, 并且全部继承自java.lang.ClassLoader
加载类的寻找范围就是 JVM 默认路径加上Classpath,
类具体是使用哪个类加载器不确定。
4.类加载主要步骤

加载 把 class 文件的二进制字节流加载到 jvm 里面

验证 确保 class 文件的字节流包含的信息符合当前 jvm 的要求 有文件格式验证, 元数据验证, 字节码验证, 符号引用验证等

准备 正式为类变量分配内存并设置类变量初始值的阶段, 初始化为各数据类型的零值

解析 把常量值内的符号引用替换为直接引用的过程

初始化 执行类构造器<clinit>()方法

使用 根据相应的业务逻辑代码使用该类

卸载 类从方法区移除
5.双亲委派模型:
除了顶层的启动类加载器之外, 其余的类加载器都应当有自己的父类加载器, 父子关系这儿一般都是以组合来实现。
工作过程: 如果一个类加载器收到了类加载的请求, 它首先不会自己去尝试加载这个类, 而是把这个请求委派给父类加载器去完成, 最终所有的加载请求都会传送到顶层的启动类加载器中, 只有当父类加载器反馈自己无法完成这个请求时候, 才由子加载器来加载。
例如类Object,它放在rt.jar中,无论哪一个类加载器要加载这个类,最终都是委派给启动类加载器进行加载,因此Object类在程序的各种类加载器环境中都是同一个类。
对于任何一个类, 都需要由加载它的类加载器和这个类本身一同确定其在 java 虚拟机中的唯一性。
ClassLoader.loadClass()的代码如下,先检查是否已经被加载过,如果没有则parent.loadClass()调用父加载器的loadClass()方法,如果父加载器为空则默认使用启动类加载器作为父加载器。如果父类加载器加载失败,抛出ClassNotFoundException,再调用自己的findClass()方法进行加载。
另外,如果我们自己实现类加载器,一般是Override复写 findClass方法,而不是loadClass方法。



1.双亲委派模型

Java虚拟机类加载过程是把Class类文件加载到内存,并对Class文件中的数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的java类型的过程。

在加载阶段,java虚拟机需要完成以下3件事:

a.通过一个类的全限定名来获取定义此类的二进制字节流。

b.将定义类的二进制字节流所代表的静态存储结构转换为方法区的运行时数据结构

c.在java堆中生成一个代表该类的java.lang.Class对象,作为方法区数据的访问入口。



(1).BootStrap ClassLoader:启动类加载器,负责加载存放在%JAVA_HOME%\lib目录中的,或者通被-Xbootclasspath参数所指定的路 径中的,并且被java虚拟机识别的(仅按照文件名识别,如rt.jar,名字不符合的类库,即使放在指定路径中也不会被加载)类库到虚拟机的内存中,启 动类加载器无法被java程序直接引用。

(2).Extension ClassLoader:扩展类加载器,由sun.misc.Launcher$ExtClassLoader实现,负责加 载%JAVA_HOME%\lib\ext目录中的,或者被java.ext.dirs系统变量所指定的路径中的所有类库,开发者可以直接使用扩展类加载 器。

(3).Application ClassLoader:应用程序类加载器,由sun.misc.Launcher$AppClassLoader实现,负责加载用户类路径 classpath上所指定的类库,是类加载器ClassLoader中的getSystemClassLoader()方法的返回值,开发者可以直接使 用应用程序类加载器,如果程序中没有自定义过类加载器,该加载器就是程序中默认的类加载器。

java虚拟机规范推荐开发者使用双亲委派模式(ParentsDelegation Model)进行类加载,其加载过程如下:

(1).如果一个类加载器收到了类加载请求,它首先不会自己去尝试加载这个类,而是把类加载请求委派给父类加载器去完成。

(2).每一层的类加载器都把类加载请求委派给父类加载器,直到所有的类加载请求都应该传递给顶层的启动类加载器。

(3).如果顶层的启动类加载器无法完成加载请求,子类加载器尝试去加载,如果连最初发起类加载请求的类加载器也无法完成加载请求时,将会抛出ClassNotFoundException,而不再调用其子类加载器去进行类加载。

具体参看《深入理解Java虚拟机》第七章 虚拟机类加载机制。
2.单源最短路算法简述

 Dijkstra算法是解单源最短路径问题的贪心算法。

算法流程:

(a) 初始化:用起点v到该顶点w的直接边(弧)初始化最短路径,否则设为∞;

(b) 从未求得最短路径的终点中选择路径长度最小的终点u:即求得v到u的最短路径;

(c) 修改最短路径:计算u的邻接点的最短路径,若(v,…,u)+(u,w)<(v,…,w),则以(v,…,u,w)代替。

(d) 重复(b)-(c),直到求得v到其余所有顶点的最短路径。

算法基于:如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点。那么(Vi...Vk)也必定是从i到k的最短路径。

dist[j]=min{dist[j],dist[i]+matrix[i][j]}

单源最短路除了dijkstra算法之外,还有一种常用的算法叫做SPFA(shortest path faster algorithm)算法,不同于dijkstra的复杂度为o(n^2),SPFA算法的平均复杂度为o(kE),E为边数,且k通常不超过2。用bfs实现。

SPFA的核心思想如下:

最开始起点入队,然后考虑和起点相邻的点,更新dis数组,并将这些点入队;

当队列不为空时,每次取队首一个点,对这个点相邻的点进行松弛操作,即比较原先的dis和经过新加入的点的优化后的dis,如果松弛成功,且被松弛的点不在队列中,则将其加入队列,重复上述动作。

SPFA可以用来判断负环,我们开一个cnt数组记录每个点入队的次数,如果次数超过n说明出现负环。
3..有若干个点,给出哪些点是相连的,求第一个点到最后一个点是否联通,并求出经过几个点(实际还是最短路问题)
4.Mybatis和hibernate有什么区别

Hibernate和Mybatis都是orm对象关系映射框架,都是用于将数据持久化的框架技术。

Hiberante较深度的封装了jdbc,对开发者写sql的能力要求的不是那么的高,我们只要通过hql语句操作对象即可完成对数据持久化的操作了。

另外hibernate可移植性好,如一个项目开始使用的是mysql数据库,但是随着业务的发展,现mysql数据库已经无法满足当前的绣球了,现在决定使用Oracle数据库,虽然sql标准定义的数据库间的sql语句差距不大,但是不同的数据库sql标准还是有差距的,那么我们手动修改起来会存在很大的困难,使用hibernate只需改变一下数据库方言即可搞定。用hibernate框架,数据库的移植变的非常方便。

但是hibernate也存在着诸多的不足,比如在实际开发过程中会生成很多不必要的sql语句耗费程序资源,优化起来也不是很方便,且对存储过程支持的也不够强大。但是针对于hibernate它也提供了一些优化策略,比如说懒加载、缓存、策略模式等都是针对于它的优化方案。

Mybatis 也是对jdbc的封装,但是封装的没有hibernate那么深,我们可以再配置文件中写sql语句,可以根据需求定制sql语句,数据优化起来较hibernate容易很多。

Mybatis要求程序员写sql的能力要相对使用hibernate的开发人员要高的多,且可移植性也不是很好。

涉及到大数据的系统使用Mybatis比较好,因为优化较方便。涉及的数据量不是很大且对优化没有那么高,可以使用hibernate。

两者相同点

Hibernate与MyBatis都可以是通过SessionFactoryBuider由XML配置文件生成SessionFactory,然后由SessionFactory 生成Session,最后由Session来开启执行事务和SQL语句。其中SessionFactoryBuider,SessionFactory,Session的生命周期都是差不多的。

Hibernate和MyBatis都支持JDBC和JTA事务处理。
Mybatis优势

MyBatis可以进行更为细致的SQL优化,可以减少查询字段。

MyBatis容易掌握,而Hibernate门槛较高。
Hibernate优势

Hibernate的DAO层开发比MyBatis简单,Mybatis需要维护SQL和结果映射。

Hibernate对对象的维护和缓存要比MyBatis好,对增删改查的对象的维护要方便。

Hibernate数据库移植性很好,MyBatis的数据库移植性不好,不同的数据库需要写不同SQL。

Hibernate有更好的二级缓存机制,可以使用第三方缓存。MyBatis本身提供的缓存机制不佳。
他人总结

Hibernate功能强大,数据库无关性好,O/R映射能力强,如果你对Hibernate相当精通,而且对Hibernate进行了适当的封装,那么你的项目整个持久层代码会相当简单,需要写的代码很少,开发速度很快,非常爽。 

Hibernate的缺点就是学习门槛不低,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡取得平衡,以及怎样用好Hibernate方面需要你的经验和能力都很强才行。 

iBATIS入门简单,即学即用,提供了数据库查询的自动对象绑定功能,而且延续了很好的SQL使用经验,对于没有那么高的对象模型要求的项目来说,相当完美。 

iBATIS的缺点就是框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。

针对高级查询,Mybatis需要手动编写SQL语句,以及ResultMap。而Hibernate有良好的映射机制,开发者无需关心SQL的生成与结果映射,可以更专注于业务流程。
5.数据库索引优点和缺点?sql优化方案(见数据库总结)
6.滑动窗口算法
7.简单介绍下线程池的参数?你了解哪些线程池
(参看7.线程池的配置)
8.简述JVM,从类加载一直到运行时的内存区域
http://blog.csdn.net/d12345678a/article/details/53956334
9.Mybatis原理

MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手工设置参数以及抽取结果集。 MyBatis 使用简单的 XML 或注解来配置和映射基本体,将接口和 Java 的 POJOs(Plain Old Java Objects, 普通的 Java对象)映射成数据库中的记录。  

MyBatis应用程序根据XML配置文件创建 SqlSessionFactory,SqlSessionFactory在根据配置,配置来源于两个地方,一处是配置文件,一处是Java代码的注解, 获取一个SqlSession。SqlSession包含了执行sql所需要的所有方法,可以通过SqlSession实例直接运行映射的sql语句,完成对数据的增删改查和事务提交等,用完之后关闭SqlSession。

通过factory方法获取sqlsession----通过MapperProxy代理到dao--执行底层数据库操作

http://blog.csdn.net/d12345678a/article/details/53956485
10.说下CMS收集器,说下G1收集器(之前有总结了)
----------------------------------------------------蘑菇街---------------------------------------
1.Mysql和mongodb索引原理(说一下B+tree和B-tree区别,为什么一个用b+一个用b-,为什么索引用btree不用平衡二叉树)mysql两种存储引擎

B-树和B+树最重要的一个区别就是B+树只有叶节点存放数据,其余节点用来索引,而B-树是每个索引节点都会有Data域。

这就决定了B+树更适合用来存储外部数据,也就是所谓的磁盘数据。

从Mysql(Inoodb)的角度来看,B+树是用来充当索引的,一般来说索引非常大,尤其是关系性数据库这种数据量大的索引能达到亿级别,所以为了减少内存的占用,索引也会被存储在磁盘上。

那么Mysql如何衡量查询效率呢?磁盘IO次数,B-树(B类树)的特定就是每层节点数目非常多,层数很少,目的就是为了就少磁盘IO次数,当查询数据的时候,最好的情况就是很快找到目标索引,然后读取数据,使用B+树就能很好的完成这个目的,但是B-树的每个节点都有data域(指针),这无疑增大了节点大小,说白了增加了磁盘IO次数(磁盘IO一次读出的数据量大小是固定的,单个数据变大,每次读出的就少,IO次数增多,一次IO多耗时啊!),而B+树除了叶子节点其它节点并不存储数据,节点小,磁盘IO次数就少。这是优点之一。

另一个优点是什么,B+树所有的Data域在叶子节点,一般来说都会进行一个优化,就是将所有的叶子节点用指针串起来。这样遍历叶子节点就能获得全部数据,这样就能进行区间访问啦。

至于MongoDB为什么使用B-树而不是B+树,可以从它的设计角度来考虑,它并不是传统的关系性数据库,而是以Json格式作为存储的nosql,目的就是高性能,高可用,易扩展。首先它摆脱了关系模型,上面所述的优点2需求就没那么强烈了,其次Mysql由于使用B+树,数据都在叶节点上,每次查询都需要访问到叶节点,而MongoDB使用B-树,所有节点都有Data域,只要找到指定索引就可以进行访问,无疑单次查询平均快于Mysql(但侧面来看Mysql至少平均查询耗时差不多)。

总体来说,Mysql选用B+树和MongoDB选用B-树还是以自己的需求来选择的。
2.浮点型为什么不是精确值

十进制小数部分化二进制,常常化不尽。

如同无限循环小数,最后有截断误差

二进制无法精确表示十进制的十分之一。

使用BigDecimal来做精确运算
3.线程池原理,单核操作系统是否应该使用多线程,为什么

应该,不知道为什么。。。
4.有1万个左右的脏词,每次发帖要判断帖子里边是否包括有脏词,数据库应该如何设计

可以建立一个脏词字典表,写好函数判断帖子正文里面是否有脏词。然后再这个帖子正文字段上面建立check 约束。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: