JAVA面试汇总

集锦一:

一、面试题基础总结
1、 JVM结构原理、GC工作机制详解

答:具体参照:JVM结构、GC工作机制详解 ,说到GC[垃圾回收机制(garbage collection)],记住两点:1、GC是负责回收所有无任何引用对象的内存空间。 注意:垃圾回收回收的是无任何引用的对象占据的内存空间而不是对象本身,2、GC回收机制的两种算法,a、引用计数法 b、可达性分析算法( 这里的可达性,大家可以看基础2 Java对象的什么周期),至于更详细的GC算法介绍,大家可以参考:Java GC机制算法

扩展:JVM结构、内存分配、垃圾回收算法、垃圾收集器。
JVM结构

  • 类加载器
  • 执行引擎
  • 内存区(方法区,java堆,java栈,程序计数器,本地方法栈)
  • 本地方法接口

内存分配

添加链接描述

  • Java的内存分配原理与C/C++不同,C/C++每次申请内存时都要malloc进行系统调用,而系统调用发生在内核空间,每次都要中断进行切换,这需要一定的开销,而Java虚拟机是先一次性分配一块较大的空间,然后每次new时都在该空间上进行分配和释放,减少了系统调用的次数,节省了一定的开销,这有点类似于内存池的概念;二是有了这块空间过后,如何进行分配和回收就跟GC机制有关了
  • java一般内存申请有两种:静态内存和动态内存。很容易理解,编译时就能够确定的内存就是静态内存,即内存是固定的,系统一次性分配,比如int类型变量;动态内存分配就是在程序执行时才知道要分配的存储空间大小,比如java对象的内存空间。根据上面我们知道,java栈、程序计数器、本地方法栈都是线程私有的,线程生就生,线程灭就灭,栈中的栈帧随着方法的结束也会撤销,内存自然就跟着回收了。所以这几个区域的内存分配与回收是确定的,我们不需要管的。但是java堆和方法区则不一样,我们只有在程序运行期间才知道会创建哪些对象,所以这部分内存的分配和回收都是动态的。一般我们所说的垃圾回收也是针对的这一部分

垃圾回收算法

2、Java对象的生命周期

答:创建阶段 、 应用阶段 、不可见阶段 、不可达阶段 、收集阶段 、终结阶段、 对象空间重新分配阶段等等,具体参照:Java 对象的生命周期

3、Map或者HashMap的存储原理

答:HashMap是由数组+链表的一个结构组成,具体参照:HashMap的实现原理
扩展:数据结构中通过数组和链表实现对数据的存储
数组:

  • 存储区间连续,占用内存严重,空间复杂度较大。但是数组的二分查找时间复杂度小时间复杂度O(1)。

  • 数组特点:寻址容易,插入和删除困难;

         链表:
    
  • 存储区域区间离散,占的内存比较宽松,空间复杂度很小,但是时间复杂度较大为O(N)。

  • 寻址困难

         哈希表为了结合两者特性,做出寻址容易,插入删除也容易的数据结构。去满足数据的查找方便,同时不占用内容空间。哈希表的展示形式:**拉链法**链表的数组
         ![在这里插入图片描述](https://img-blog.csdnimg.cn/2020080709354429.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI5NDIzMzg3,size_16,color_FFFFFF,t_70)
    

哈希表是由数组和链表组成,在长度为16的数组中,数组中存储的都是一个链表的头节点,元素存储都是通过hash(key)%len获得,比如上述哈希表中,12%16=12,28%16=12,108%16=12,140%16=12。所以12、28、108以及140都存储在数组下标为12的位置。

解决hash冲突的方法

  • 开发地址法
  • 再哈希法
  • 链地址法(java中的hashmap的解决办法就是采用链地址法)。
  • 建立一个公共溢出区域

4、当数据表中A、B字段做了组合索引,那么单独使用A或单独使用B会有索引效果吗?(使用like查询如何有索引效果)

答:看A、B两字段做组合索引的时候,谁在前面,谁在后面,如果A在前,那么单独使用A会有索引效果,单独使用B则没有,反之亦然。同理,使用like模糊查询时,如果只是使用前面%,那么有索引效果,如果使用双%号匹配,那么则无索引效果

5、数据库存储日期格式时,如何考虑时区转换问题?

答:使用TimeStamp , 原因参照:Java编程中遇到的时区转换问题

6、Java Object类中有哪些方法

答:Object是所有类的父类,任何类都默认集成Object方法 有哪些方法如下:

  • hashCode 返回对象的哈希码值
  • notify 唤醒在此对象监视器上等待的单个线程
  • notifyAll唤醒此对象监视器上等待的所有线程
  • toString 返回该对象的字符串表示
  • clone 保护方法,实现对象的浅复制
  • equals 在object与==是一样
  • getClass final方法,获得运行时类型
  • wait 当前线程等待改对象的锁,当前线程必须是该对象的拥有者。wait方法一直等待,直到获得锁或者被中断

7、HTTP协议,GET和POST 的区别

答:浅谈HTTP中GET和POST的区别
Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE。URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作。到这里,大家应该有个大概的了解了,GET一般用于获取/查询资源信息,而POST一般用于更新资源信息。

  1. GET请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据。POST把提交的数据则放置在是HTTP包的包体中
  2. GET方式提交的数据最多只能是1024字节,理论上POST没有限制,可传较大量的数据。
  3. POST的安全性要比GET的安全性高
  4. Get是向服务器发索取数据的一种请求,而Post是向服务器提交数据的一种请求

二、线程、设计模式、缓存方面
1、SimpleDataFormat是非线程安全的,如何更好的使用而避免风险呢

答:关于SimpleDateFormat安全的时间格式化线程安全问题
SimpleDateFormat 是 Java 中一个非常常用的类,该类用来对日期字符串进行解析和格式化输出,但如果使用不小心会导致非常微妙和难以调试的问题,因为 DateFormat 和 SimpleDateFormat 类不都是线程安全的,在多线程环境下调用 format() 和 parse() 方法应该使用同步代码来避免问题。
2、如何看待设计模式,并简单说说你对观察者模式的理解

答:1、设计模式有神马用

  • 是从许多优秀的软件系统中总结出的成功的、能够实现可维护性复用的设计方案,使用这些方案将可以让我们避免做一些重复性的工作。
  • 设计模式提供了一套通用的设计词汇和一种通用的形式来方便开发人员之间沟通和交流,使得设计方案更加通俗易懂。
  • 大部分设计模式都兼顾了系统的可重用性和可扩展性,这使得我们可以更好地重用一些已有的设计方案、功能模块甚至一个完整的软件系统,避免我们经常做一些重复的设计、编写一些重复的代码。
  • 合理使用设计模式并对设计模式的使用情况进行文档化,将有助于别人更快地理解系统
  • 学习设计模式将有助于初学者更加深入地理解面向对象思想,让你知道:如何将代码分散在几个不同的类中?为什么要有“接口”?何谓针对抽象编程?何时不应该使用继承?如果不修改源代码增加新功能?同时还让你能够更好地阅读和理解现有类库(如JDK)与其他系统中的源代码
    2、观察者模式类图及实现

3、集群环境中,session如何实现共享

答:

1、Java集群之session共享

2、session多服务器共享方案,还有一种方案就是使用一个固定的服务器专门保持session,其他服务器共享

4、分布式、集群环境中,缓存如何刷新,如何保持同步?

答:

A、缓存如何刷新? 1、定时刷新 2、主动刷新覆盖 ,每个缓存框架都有自带的刷新机制,或者说缓存失效机制,就拿Redis和 Ehcache举例, 他们都有自带的过期机制,另外主动刷新覆盖时,只需获取对应的key进行数据的覆盖即可

B、缓存如何保持同步? 这个redis有自带的集群同步机制,即复制功能,具体参考:基于Redis分布式缓存实现 ,Ehcache也有分布式缓存同步的配置,只需要配置不同服务器地址即可,参照:Ehcache分布式缓存同步

5、一条sql执行过长的时间,你如何优化,从哪些方面?

答:

1、查看sql是否涉及多表的联表或者子查询,如果有,看是否能进行业务拆分,相关字段冗余或者合并成临时表(业务和算法的优化)

2、涉及链表的查询,是否能进行分表查询,单表查询之后的结果进行字段整合

3、如果以上两种都不能操作,非要链表查询,那么考虑对相对应的查询条件做索引。加快查询速度

4、针对数量大的表进行历史表分离(如交易流水表)

5、数据库主从分离,读写分离,降低读写针对同一表同时的压力,至于主从同步,mysql有自带的binlog实现 主从同步

6、explain分析sql语句,查看执行计划,分析索引是否用上,分析扫描行数等等

7、查看mysql执行日志,看看是否有其他方面的问题

个人理解:从根本上来说,查询慢是占用mysql内存比较多,那么可以从这方面去酌手考虑

三、三大框架方面问题
1、Spring 事务的隔离性,并说说每个隔离性的区别
解答:Spring事务详解
2、Spring事务的传播行为,并说说每个传播行为的区别
解答:Spring事务详解
3、hibernate跟Mybatis/ ibatis 的区别,为什么选择?
解答:Hibernate与Mybatis的比较
在这里插入图片描述

4、Struts跟Spring mvc的优缺点,让你选会如何选
解答:Spring MVC 与 Struts的区别
在这里插入图片描述

5、简单说说Spring 事务机制
解答:Spring事务机制
6、Spring 4.0新特性
解答:Spring4新特性
四、负载均衡、集群相关
1、weblogic 负载均衡的原理和集群的配置
解答:a、WEBLOGIC负载均衡原理 b、负载均衡和集群的配置(参考)
2、Nginx+Tomcat+Redis实现负载均衡、资源分离、session共享
解答:配置参考
3、nginx配置文件详解——nginx.conf
解答:Nginx配置文件详细说明
五、项目优化相关
1、web如何项目优化
解答:这个我整理过一次,web项目性能优化(整理)

  • 压缩源码和图片
  • 选择合适的图片格式
  • 合并静态资源
  • 开启服务器端的Gzip压缩
  • 使用CDN
  • 延长静态资源缓存时间
  • 把css放在页面头部,把jsp放在页面底部,这样就不会有阻塞页面渲染,让页面出现长时间的空白。

2、单例模式有几种? 如何优化?
解答:单例模式的7中用法

  • 第一种(懒汉,线程不安全)
  • 第二种(懒汉,线程安全)
  • 第三种(饿汉)
  • 第四种(饿汉,变种)
  • 第五种(静态内部类)
  • 第六种(枚举)
  • 第七种(双重校验锁)

3、简单说说线程池的原理和实现
解答:线程原理及实现
六、并发和安全方面
1、项目并发如何处理?(我们是web项目)
解答:高并发量网站解决方案,另外,还有数据库乐观锁,数据库读写分离、使用消息队列、多用存储过程等等
2、简单说说功能权限存在的水平权限漏洞和垂直权限漏洞的场景和解决办法(因为我们目前权限级别就是功能权限)
解答:
A、水平权限漏洞,如下图

假设机构有 用户A和用户B 两个用户,其中A有1、2和3权限 , 用户B有 2 和3 的权限,这时候假设用户B 知道1,并给自己添加1的权限,这时候就是水平权限漏洞。
目前解决办法:1、限制入口,让用户B无法编辑自己的权限 2、对用户B无法进行向上扩展。最根本的解决办法是深入到数据权限
解答:水平权限漏洞和解决办法

B、垂直权限漏洞
解答:垂直权限漏洞案例和解决方案
3、平台上的图片如何防盗链
解答:http下载防盗链原理:http协议的字段referer记录来实现
4、如何区分上传的图片是不是木马?
解答:1、看上传的图片后缀 2、如何后缀是篡改的,那么每个文件有个魔术数字 文件上传-魔术数字
5、消息队列的原理和实现
解答:1、消息队列原理 2、深入浅出 消息队列 ActiveMQ
七、数据库方面
1、mysql查询字段区不区分大小写?
解答:不区分,哪怕值也不区分(我当时还反问了,区不区分大小的应用含义有哪些,面试官没说得出来)
2、简单说说数据库集群和负载均衡、分布式(我不懂这块)
解答:数据库负载均衡和集群参考 ,参考2
3、存储过程的结构和优点
解答:大概结构
存储过程的优缺点
4、触发器的原理和作用
解答:参考
八、Java底层基础题
1、SpringMVC的原理以及返回数据如何渲染到jsp/html上?

答:Spring MVC的核心就是 DispatcherServlet , 一个请求经过 DispatcherServlet ,转发给HandlerMapping ,然后经反射,对应 Controller及其里面方法的@RequestMapping地址,最后经ModelAndView和ViewResoler返回给对应视图 。 具体可参考:Spring MVC的工作原理

2、一个类对象属性发生改变时,如何让调用者知道?

答:Java event时间监听 ,即在set方法改变属性时,触发 ,这种模式也可以理解为观察者模式,具体查看:观察者模式简单案例和说明

3、重写equals为何要重写hashCode?

答:判断两个对象是否相等,比较的就是其hashCode, 如果你重载了equals,比如说是基于对象的内容实现的,而保留hashCode的实现不变,那么很可能某两个对象明明是“相等”,而hashCode却不一样。 hashcode不一样,就无法认定两个对象相等了

4、谈谈你对JVM的理解?

答: Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。Java编译器只要面向JVM,生成JVM能理解的代码或字节码文件。Java源文件经编译成字节码程序,通过JVM将每一条指令翻译成不同平台机器码,通过特定平台运行。

JVM执行程序的过程 :I.加载。class文件 ,II.管理并分配内存 ,III.执行垃圾收集

JRE(java运行时环境)由JVM构造的java程序的运行环境

具体详情:JVM原理和调优

5、Mysql的事物隔离级别?

答:Mysql的事物隔离级别 其实跟 Spring的事物隔离级别一样,都是1、Read Uncommitted(读取未提交内容), 2、Read Committed(读取提交内容),3、Repeatable Read(可重读),4、Serializable(可串行化) 具体参照:mysql事物隔离级别

6、Spring的原理

答:Spring的核心是IOC和AOP ,IOC是依赖注入和控制反转, 其注入方式可分为set注入、构造器注入、接口注入等等。IOC就是一个容器,负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。简单理解就是:JAVA每个业务逻辑处理至少需要两个或者以上的对象协作进行工作,但是每个对象在使用它的合作对象的时候,都需要频繁的new 对象来实现,你就会发现,对象间的耦合度高了。而IOC的思想是:Spring容器来管理这些,对象只需要处理本身业务关系就好了。至于什么是控制反转,就是获得依赖对象的方式反转了。
AOP呢,面向切面编程,最直接的体现就是Spring事物管理。至于Spring事物的相关资料,就不细说了,参考:Spring注解式事物管理

7、谈谈你对NIO的理解

答:IO是面向流,NIO是面向缓冲 ,这里不细讲了,具体参照:Java NIO和IO的区别

8、ArrayList和LinkedList、Vector的区别?

答:总得来说可以理解为:.

 1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 
 2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 
 3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据

Vector和ArrayList类似,但属于强同步类,即线程安全的,具体比较参照:比较ArrayList、LinkedList、Vector

9、随便说说几个单例模式,并选择一种线程安全的

答:单例的类别:懒汉、饿汉、枚举、静态内部类、双重校验锁 等等 , 选择线程安全我选最后一种,双重校验锁。 具体实现方式参照:Java:单例模式的七种写法

10、谈谈红黑树
在线数据结构测试网站
https://www.cs.usfca.edu/~galles/visualization/RedBlack.html

答:算法和数据结构一直是我薄弱之处,这方面说自己补吧,成效不大,这里我就推荐一个:红黑树

11、举例说说几个排序,并说明其排序原理

答:这里我就不细说了,大家自己看看 Java实现几种常见的排序算法

12、Mysql索引的原理

答:索引的作用大家都知道,就是加快查询速度,但是原理,我说不上来,这里直接看吧:Mysql索引工作原理

13、序列化的原理和作用

答:Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化deserialization是一种将这些字节重建成一个对象的过程,主要用于HTTP或者WebService接口传输过程中对象参数的传播,具体可参看:Java序列化机制和原理

九、并发及项目调优
1、说说线程安全的几种实现方式?

答:什么是线程安全? 我的理解是这样的,一个对象被多个线程同时访问,还能保持其内部属性的顺序性及同步性,则认定为线程安全。实现线程安全的三种方式:被volatile、synchronized等关键字修饰,或者使用java.util.concurrent下面的类库。 至于前两者的关系,参考:synchronized和volatile的用法区别

2、方法内部,如何实现更好的异步?

答:我们知道异步其实就是让另一个线程去跑,那么如何创建线程? 第一种直接new Thread ,第二种new 一个实现Runnable接口的实现类。 第三种,通过线程池来管理创建等 ,这里说到更好的实现异步,那就是说我们在方法内部避免频繁的new 线程,就可以考虑线程池了。 那么线程池如何创建? 这里可以new 一个线程池,但是需要考虑单例,或者在程序初始启东时,就创建一个线程池,让他跑着,然后在具体方法的时候,通过线程池来创建线程,实现异步

3、项目中为何要用缓存?如何理解nginx + tomcat + redis 集群缓存?

答1:最直接的表现就是减轻数据库的压力。避免因为数据读取频繁或过大而影响数据库性能,降低程序宕机的可能性

答2:nginx常用做静态内容服务和代理服务器,直面外来请求转发给后面的应用服务。nginx本身也能做缓存,比如静态页面的缓存什么的。而tomcat是应用服务器,处理JAVA WEB程序功能等等 。你也可以这么理解,假设把用户的请求当做是一条河流,那么nginx就相当于一个水利工程,tomcat相当于一条条分流的支流,而redis 相当于支流旁边的一个个水库。 当你洪水来了,nginx根据你每条支流的承受力度分发不同的水流量,在确保程序正常运行的情况下,分发给每条支流(tomcat)不同的水流量。而redis相当于一个个支流的水库,存储水源,降低压力,让后面的水量平稳。

4、日常项目中,如果你接手,你准备从哪些方面调优?

答:这个呢首先是了解哪些需要优化,需要优化肯定是项目性能遭遇瓶颈或者猜测即将遭遇了,我们才会去考虑优化。那么怎么优化?

a、扩容 ,扩容的理解,就是扩充服务器并行处理的能力,简单来说就是加服务器,增加处理请求的能力,例如增加nginx 、tomcat等应用服务器的个数,或者物理服务器的个数,还有加大服务器带宽等等,这里考虑的是硬件方面

b、调优 ,调优,包括系统调优和代码调优 。 系统调优就是说加快处理速度,比如我们所提到的CDN、ehcache、redis等缓存技术,消息队列等等,加快服务间的响应速度,增加系统吞吐量,避免并发,至于代码调优,这些就需要多积累了,比如重构、工厂等, 数据库调优的话这个我不是很懂,只知道索引和存储过程,具体参考:Mysql数据库调优21个最佳实践 ,其他数据库调优方面就各位自己找找吧

5、谈谈你对分布式的理解

答:个人理解:分布式就是把一个系统/业务 拆分成多个子系统/子业务 去协同处理,这个过程就叫分布式,具体的演变方式参考:Java分布式应用技术架构介绍

6、Redis实现消息队列

答:Redis实现消息队列 、参考2

7、另总结多线程相关面试题50道

8、分享一个调优工具和方案:如何利用 JConsole观察分析Java程序的运行,进行排错调优

十、手写代码题(包含sql题)
1、假设商户表A(id , city ) ,交易流水表B (aid, amount , time) 这里的time代表交易时间, 请用sql写出查询每个城市每个月的销售业绩(答案可在评论里回复)

2、假设有一个数组 A ,int[] A = { 1 , 3 , -1 ,0 , 2 , 1 , -4 , 2 , 0 ,1 … N}; 原来是需要查出大于0的数组,但是由于传参错误或者其他原因,导致查出0和负数了,现在要求在不使用新数组和新集合的情况下(即只使用这个A数组,因数组数据比较大,且只能用一次循环) 实现正数放到数组的前面,小于等于0的数放到数组的末尾(答案可在评论里回复)

十一、设计方案相关
面试还会问到一些关于设计方案相关的问题,比如

1、你的接口服务数据被人截包了,你如何防止数据恶意提交?

答:我们可以在接口传输参数里面设置一个业务编号,这个编号用来区分是否重复提交。这样即使数据被抓包了,对方也无法区分每个字段你的含义,这时,这个业务编号的作用就来了

2、假设服务器经常宕机,你从哪些方面去排查问题?

答:这个就留个各位看官补充了,可评论回复

集锦二:

一、Java基础

  1. String类为什么是final的。
    主要是为了效率安全性的缘故,若String允许被继承,由于它的高度被使用率,可能会降低程序的性能,所以String被定义为final。
  2. HashMap的源码,实现原理,底层结构。
    JDK1.8
Static final int hash(Object key){
   int h;
   //key.hashCode():返回散列值也是hashcode  ^ 按位异或  >>>无符号右移 
   return(key==null)?0:(h=key.hashCode())^(h>>>16);
 }

JDK1.7 HashMap的源码

static int hash(int h){
  h^=(h>>>20)^(h>>>4)
 }

在这里插入图片描述
在这里插入图片描述

  1. 说说你知道的几个Java集合类:list、set、queue、map实现类咯。。。
1.collection
  collection是最基本的集合接口。一个Collection代表一组Object的集合
  public interface Collection<E>extends Iterable<E>{}
  任何实现Collection接口的类,都必须实现iterator方法来提供遍历集合中的元素
  List中集合的遍历方式
  List<String>strings=Arrays.asList(array);
  while(iterator.hasNext()){
   System.out.println(iterator.next());
}

Collection是集合的接口,所有的集合类都实现该接口,Collectors是一个类,提供了sort方法对集合进行排序,Collectors.sort方法的使用

2.set 
   Set继承collection接口,不能包含重复元素 使用equals方法来判断两个集合是否相等 
   HashSet实现了Set的接口,由哈希表提供支持,不能保证Set的迭代顺序,允许有空值但是不允许元素有重复,因为hashSet的底层是使用HashMap来实现的,hashSet中的元素放在HashMap的key上。
   HashSet使用add方法添加元素,调用put方法插入元素
   linkedHashSet继承自HashSet,使用链表来维护元素的顺序,元素以插入的顺序访问,在性能上略低于HashSet,但是在迭代方法时候有很好的性能
   sortedSet 主要用于排序操作,实现此接口的都属于排序子类。
   TreeSet 基于SortedSet,底层实现通过二叉树。

3.list
  List代表元素有序,可重复的集合,集合中每个元素都有对应的顺序索引 允许加入重复元素,通过索引指定元素的位置,实现的有ArrayList,Vector,Queue.
  ArrayList是基于数组实现的,封装了一个动态增长,允许在分配的Object[]数组。
  vector  动态数组
  public class Vector<E> extends AbstractList<E> implements List<E>,RandomAccess,Cloeable,java.io.Serializable
  Vector是线程安全的,对集合元素的操作的时候都加了Synchronized,保证线程安全
  Stack(栈)实现vector类
  ListedList 实现List接口
  queue用于模拟队列数据结构,先进先出。
4 map 用于保存映射关系的数据结构 key用于存放具体的值 当value为null时候,map就是实现了set的数据结构
  hashmap
  LinkedHashMap
  HashTable
  SortedMap
  TreeMap的数据结构就是红黑树,TreeMap存储key-value时,根据key对节点进行排序,保证所有节点有序状态。
  1. 描述一下ArrayList和LinkedList各自实现和区别
    ArrayList,LinkedList,Vector三个类都实现了java.util.List接口,但是他们有各自不同的特性
    同步性
    ArrayList,linkedlist是不同步的,不要求线程安全,而vector是同步的,多线程的情况下不得不使用vector.
    数据增长
    ArrayList和vector都是使用object的数组形式来存储的,当你向这两种类型中增加元素的时候,元素数目超出了内部数组长度就需要扩展数组长度,vector会在缺省的情况下自动增长原来的一倍,ArrayList是原来的一半。
    检索,插入,删除对象的效率
    ArrayList和vector是数组,查找 插入和删除一个对象的时间是一样的,但是在集合位置上增加和移除元素花费的时间会线性增长。
    ListedList是链表,在插入删除的时候花费时间一样的,但是在索引的时候比较慢。

  2. Java中的队列都有哪些,有什么区别

  3. 在这里插入图片描述
    内置的不阻塞队列: PriorityQueue 和 ConcurrentLinkedQueue
    PriorityQueue 类实质上维护了一个有序列表
    ConcurrentLinkedQueue 是基于链接节点的、线程安全的队列。并发访问不需要同步。因为它在队列的尾部添加元素并从头部删除它们,所以只要不需要知道队列的大 小, 对公共集合的共享访问就可以工作得很好。收集关于队列大小的信息会很慢,需要遍历队列。
    实现阻塞接口:
    * ArrayBlockingQueue :一个由数组支持的有界队列。
      * LinkedBlockingQueue :一个由链接节点支持的可选有界队列。
      * PriorityBlockingQueue :一个由优先级堆支持的无界优先级队列。
      * DelayQueue :一个由优先级堆支持的、基于时间的调度队列。
      * SynchronousQueue :一个利用 BlockingQueue 接口的简单聚集(rendezvous)机制。

  4. 反射中,Class.forName和classLoader的区别

相同点是都可以对类进行加载。
不同点 class.forName将.class文件加载到jvm,还会对类进行解释,执行类中的static静态代码块。
classLoader就是.class文件加载到jvm,对内容进行解析。
8. Java7、Java8的新特性(baidu问的,好BT)

  1. Java数组和链表两种结构的操作效率,在哪些情况下(从开头开始,从结尾开始,从中间开始),哪些操作(插入,查找,删除)的效率高
    数组是按照元素按照一定的顺序排列的集合,数组的存储区域是连续的,占用内存比较大,空间复杂很大。数组的特点是:查询简单,增加和删除困难。
    链表是一种物理存储单元 空间是分散的,不需要连续,每个元素有两个属性,一个是指针,一个是地址,查找困难,插入和删除快,时间复杂度是o(1).

  2. Java内存泄露的问题调查定位:jmap,jstack的使用等等

  3. string、stringbuilder、stringbuffer区别
    在这里插入图片描述

  4. hashtable和hashmap的区别
    哈希表
    在这里插入图片描述
    紫色的部分代表哈希表,也称为哈希数组,数组每一个元素都是单链表的头节点,链表是用来解决冲突的,如果不同的key值映射到数组的同一个位置,就将其放入到单链表中。

HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长。
HashMap是非线程安全的,只是用于单线程环境下,多线程环境下可以采用concurrent并发包下的****concurrentHashMap
HashMap 实现了Serializable接口,因此它支持序列化,实现了Cloneable接口,能被克隆。
HashMap存数据的过程是:
HashMap内部维护了一个存储数据的Entry数组,HashMap采用链表解决冲突,每一个Entry本质上是一个单向链表。当准备添加一个key-value对时,首先通过hash(key)方法计算hash值,然后通过indexFor(hash,length)求该key-value对的存储位置,计算方法是先用hash&0x7FFFFFFF后,再对length取模,这就保证每一个key-value对都能存入HashMap中,当计算出的位置相同时,由于存入位置是一个链表,则把这个key-value对插入链表头。
HashMap中key和value都允许为null。key为null的键值对永远都放在以table[0]为头结点的链表中

Hashtable是基于哈希表实现的,内部通过单链表解决冲突
Hashtable是线程安全的,能过用于多线程
Hashtable同样实现了Serializable接口,它支持序列化,实现了Cloneable接口,能被克隆。

两者的区别
1.继承的父类不同
Hashtable继承来自Diectionary类,而HashMap继承来自AbstractMap类 但是两者实现map接口
2.线程安全性不同
Hashtable 线程安全很好理解,因为它每个方法中都加入了Synchronize
synchronized的三种应用方式:
一. 修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁。
二. 修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁。
三. 修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象。

Map m = Collections.synchronizedMap(new HashMap(...));

13 .异常的结构,运行时异常和非运行时异常,各举个例子

  1. String a= “abc” String b = “abc” String c = new String(“abc”) String d = “ab” + “c” .他们之间用 == 比较的结果

  2. String 类的常用方法

String.length();
String.charAt(4);//字符串的某一个位置
String.substring();//提取字串
String.compareTo();//字符串比较
String.equals();//字符串比较
string.concat(String str);//字符串连接 相当于加号
string.indexOf();//字符串中单个字符查找 
eg:
String str = "I am a good student";
int a = str.indexOf('a');//a = 2
int d = str.lastIndexOf("a");//d = 5

  • Java 的引用类型有哪几种
    java 分为基本数据类型和引用数据类型,其中引用数据类型在存储堆中需要引用对象进行引用,目前我们接触到的主要包括4种引用类型。

  • 强引用

  • 如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题

  • 软引用

  • 例如从网络上获取图片,然后将获取的图片显示的同时,通过软引用缓存起来。当下次再去网络上获取图片时,首先会检查要获取的图片缓存中是否存在,若存在,直接取出来,不需要再去网络上获取

  • 弱引用

  • 如果一个对象只具有弱引用,那么在垃圾回收器线程扫描的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

  • 虚引用

  • 虚引用是所有引用类型中最弱的一个。一个持有虚引用的对象,和没有引用几乎是一样的,随时都可能被垃圾回收器回收。当试图通过虚引用的get()方法取得强引用时,总是会失败

  1. 抽象类和接口的区别
    接口是对动作的抽象,而抽象类是对根源的抽象。
    对于抽象类而言,可以分为男人和女人两类,对于这两类我们可以设计一个更高级别的抽象类----人。
    对于接口而言,我们可以做着吃饭,也可以用筷子吃,用叉子吃,站着吃饭。那么我们可以把这些吃饭的动作抽象成一个接口–吃饭。
    所以一个类只能继承一个抽象类(因为你不可能是人又同时不是人),但是一个类可以实现多个接口,比如实现一个开车接口,滑冰接口,踢足球接口和游泳接口。
    总结:抽象类和接口不能被直接实例化,如果需要实例化,需要涉及多态。
    抽象类要被子类继承,接口要被子类实现。
    接口只能对方法声明,抽象类既可以对方法声明也可以对方法实现。
//定义接口,含有钻火圈的方法
public interface DrillFireCircle(){
    public abstract void drillFireCircle();
 }
 //定义抽象类狗类
 public abstract class Dog{
    public abstract void eat();
    public abstract void sleep();
  }
  //继承抽象类并且实现接口
  class 牧羊犬Dog extends Dog implements drillFireCircle{
      public void eat(){
      }
      public void sleep(){
      }
      public void drillFireCircle(){
       
       } 
   }
   //总结:继承是一个“是不是”的关系,而接口实现是“有没有”关系。如果一个类继承了某个抽象类,子类必定是抽象类的种类。接口实现则是不是则是有没有,具备不具备的关系。
  1. 面向对象的三大特点
    面向对象的三个基本特征:封装,继承,多态。
    在这里插入图片描述
    封装就是把客观事务封装成抽象的类,并且类可以把自己的数据和方法让可信的类或者对象操作,对不可信的类进行信息隐藏。
    继承是可以使用现有类的所有功能,并且在无需要重新编写原来类的情况下对这些功能扩展。在考虑使用继承时,有一点需要注意,那就是两个类之间的关系应该是“属于”关系。例如,Employee 是一个人,Manager 也是一个人,因此这两个类都可以继承 Person 类。但是 Leg 类却不能继承 Person 类,因为腿并不是一个人。
    多态就是允许你将父对象设置为一个或者更多的他的子对象相等的技术,允许将子类指针复制给父类类型的指针。
    实现多态的方法:覆盖和重载
    覆盖是指子类重新定义父类的虚函数的做法。
    重载是指允许存在多个同名函数,而这些函数的参数表不同。
重载的概念并不属于“面向对象编程”,重载的实现是:编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数(至少对于编译器来说是这样的)。如,有两个同名函数:function func(p:integer):integer;和function func(p:string):integer;。那么编译器做过修饰后的函数名称可能是这样的:int_func、str_func。对于这两个函数的调用,在编译器间就已经确定了,是静态的(记住:是静态)。也就是说,它们的地址在编译期就绑定了(早绑定),因此,重载和多态无关!真正和多态相关的是“覆盖”。当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态(记住:是动态!)的调用属于子类的该函数,这样的函数调用在编译期间是无法确定的(调用的子类的虚函数的地址无法给出)。因此,这样的函数地址是在运行期绑定的(晚邦定)。结论就是:重载只是一种语言特性,与多态无关,与面向对象也无关!引用一句Bruce Eckel的话:“不要犯傻,如果它不是晚邦定,它就不是多态。

总结:封装目的是隐藏细节,使得代码模块化;
继承可以拓展已经存在的代码模块,两着的目的是都是为了代码重用。
多态的目的是为了接口重用,多态的作用就是为了类在继承和派生的时候,保证家族中任一类的实例的某一属性的正确调用。
21. java的基础类型和字节大小。
总共有八个基础类型,六个数字类型(四个整数型(int),两个浮点型(doouble)),一种字符,一种布尔。
byte 256 -128-127 一个字节 8位 整数
short -32768~32767 两个字节 16位 整数
int -2,147,483,648~2,147,485,647 三个字节 32位 整型
long -9,223,372,036,854,775,808~9,223,372,036,854,775,807 四个字节 64位 整数
float -3.4E38- 3.4E38 四个字节 32位 单精度浮点
double 64位 双精度浮点
boolean true和false
char 最小值是’\u0000’(即为0) 最大值是’\uffff’(即为65,535) 可以当整数来用,它的每一个字符都对应一个数字

  1. Hashtable,HashMap,ConcurrentHashMap 底层实现原理与线程安全问题(建议熟悉 jdk 源码,才能从容应答)
    Hashtable 是底层数组+链表 key和value不能为null,线程安全,实现线程安全的方式是在修改数据的时候锁住了整个HashTable,扩容:newsize = olesize2+1。
    HashMap 是底层数据+链表实现,可以储存null键和null值,线程不安全,扩容:newsize = oldsize
    2,size一定为2的n次幂,每次扩容时,原来数组中的元素依次重新计算存放位置,并重新插入。Map中元素总数超过Entry数组的75%,触发扩容操作,为了减少链表长度,元素分配更均匀。
    ConcurrentHashMap底层采用分段的数组和链表,线程安全,先把整个map分割N个部分,提供相同的线程安全,hashtable的synchronized是针对整个hash表的,即每次锁住的整张表让线程独占,ConcurrentHashMap允许多个修改并发进行,关键技术使用了锁分离技术。
    hashmap和hashtable都实现了map接口,Hashtable的实现是基于Dictionary抽象类的
    hashmap基于哈希思想实现对数据的读写,当我们将键值传递给put方法时,调用hashCode()的方法来计算hashcode,然后找到bucket的位置来存储对象。

  2. 如果不让你用Java Jdk提供的工具,你自己实现一个Map,你怎么做。说了好久,说了HashMap源代码,如果我做,就会借鉴HashMap的原理,说了一通HashMap实现

  3. Hash冲突怎么办?哪些解决散列冲突的方法?

  4. HashMap冲突很厉害,最差性能,你会怎么解决?从O(n)提升到log(n)咯,用二叉排序树的思路说了一通

  5. rehash

  6. hashCode() 与 equals() 生成算法、方法怎么重写

二、Java IO

  1. 讲讲IO里面的常见类,字节流、字符流、接口、实现类、方法阻塞。

  2. 讲讲NIO。

  3. String 编码UTF-8 和GBK的区别?

  4. 什么时候使用字节流、什么时候使用字符流?

  5. 递归读取文件夹下的文件,代码怎么实现

三、Java Web

  1. session和cookie的区别和联系,session的生命周期,多个服务部署时session管理。

  2. servlet的一些相关问题

  3. webservice相关问题

  4. jdbc连接,forname方式的步骤,怎么声明使用一个事务。举例并具体代码

  5. 无框架下配置web.xml的主要配置内容

  6. jsp和servlet的区别

四、JVM

  1. Java的内存模型以及GC算法

  2. jvm性能调优都做了什么

  3. 介绍JVM中7个区域,然后把每个区域可能造成内存的溢出的情况说明

  4. 介绍GC 和GC Root不正常引用。

  5. 自己从classload 加载方式,加载机制说开去,从程序运行时数据区,讲到内存分配,讲到String常量池,讲到JVM垃圾回收机制,算法,hotspot。反正就是各种扩展

  6. jvm 如何分配直接内存, new 对象如何不分配在堆而是栈上,常量池解析

  7. 数组多大放在 JVM 老年代(不只是设置 PretenureSizeThreshold ,问通常多大,没做过一问便知)

  8. 老年代中数组的访问方式

  9. GC 算法,永久代对象如何 GC , GC 有环怎么处理

  10. 谁会被 GC ,什么时候 GC

  11. 如果想不被 GC 怎么办

  12. 如果想在 GC 中生存 1 次怎么办

五、开源框架

  1. hibernate和ibatis的区别

  2. 讲讲mybatis的连接池。

  3. spring框架中需要引用哪些jar包,以及这些jar包的用途

  4. springMVC的原理

  5. springMVC注解的意思

  6. spring中beanFactory和ApplicationContext的联系和区别

  7. spring注入的几种方式(循环注入)

  8. spring如何实现事物管理的

  9. springIOC

  10. spring AOP的原理

  11. hibernate中的1级和2级缓存的使用方式以及区别原理(Lazy-Load的理解)

  12. Hibernate的原理体系架构,五大核心接口,Hibernate对象的三种状态转换,事务管理。

六、多线程

  1. Java创建线程之后,直接调用start()方法和run()的区别

  2. 常用的线程池模式以及不同线程池的使用场景

  3. newFixedThreadPool此种线程池如果线程数达到最大值后会怎么办,底层原理。

  4. 多线程之间通信的同步问题,synchronized锁的是对象,衍伸出和synchronized相关很多的具体问题,例如同一个类不同方法都有synchronized锁,一个对象是否可以同时访问。或者一个类的static构造方法加上synchronized之后的锁的影响。

  5. 了解可重入锁的含义,以及ReentrantLock 和synchronized的区别

  6. 同步的数据结构,例如concurrentHashMap的源码理解以及内部实现原理,为什么他是同步的且效率高

  7. atomicinteger和Volatile等线程安全操作的关键字的理解和使用

  8. 线程间通信,wait和notify

  9. 定时线程的使用

  10. 场景:在一个主线程中,要求有大量(很多很多)子线程执行完之后,主线程才执行完成。多种方式,考虑效率。

  11. 进程和线程的区别

  12. 什么叫线程安全?举例说明

  13. 线程的几种状态

  14. 并发、同步的接口或方法

  15. HashMap 是否线程安全,为何不安全。 ConcurrentHashMap,线程安全,为何安全。底层实现是怎么样的。

  16. J.U.C下的常见类的使用。 ThreadPool的深入考察; BlockingQueue的使用。(take,poll的区别,put,offer的区别);原子类的实现。

  17. 简单介绍下多线程的情况,从建立一个线程开始。然后怎么控制同步过程,多线程常用的方法和结构

  18. volatile的理解

  19. 实现多线程有几种方式,多线程同步怎么做,说说几个线程里常用的方法

七、网络通信

  1. http是无状态通信,http的请求方式有哪些,可以自己定义新的请求方式么。

  2. socket通信,以及长连接,分包,连接异常断开的处理。

  3. socket通信模型的使用,AIO和NIO。

  4. socket框架netty的使用,以及NIO的实现原理,为什么是异步非阻塞。

  5. 同步和异步,阻塞和非阻塞。

  6. OSI七层模型,包括TCP,IP的一些基本知识

  7. http中,get post的区别

  8. 说说http,tcp,udp之间关系和区别。

  9. 说说浏览器访问www.taobao.com,经历了怎样的过程。

  10. HTTP协议、 HTTPS协议,SSL协议及完整交互过程;

  11. tcp的拥塞,快回传,ip的报文丢弃

  12. https处理的一个过程,对称加密和非对称加密

  13. head各个特点和区别

  14. 说说浏览器访问www.taobao.com,经历了怎样的过程。

八、数据库MySql

  1. MySql的存储引擎的不同

  2. 单个索引、联合索引、主键索引

  3. Mysql怎么分表,以及分表后如果想按条件分页查询怎么办(如果不是按分表字段来查询的话,几乎效率低下,无解)

  4. 分表之后想让一个id多个表是自增的,效率实现

  5. MySql的主从实时备份同步的配置,以及原理(从库读主库的binlog),读写分离

  6. 写SQL语句。。。

  7. 索引的数据结构,B+树

  8. 事务的四个特性,以及各自的特点(原子、隔离)等等,项目怎么解决这些问题

  9. 数据库的锁:行锁,表锁;乐观锁,悲观锁

  10. 数据库事务的几种粒度;

  11. 关系型和非关系型数据库区别

九、设计模式

  1. 单例模式:饱汉、饿汉。以及饿汉中的延迟加载,双重检查

  2. 工厂模式、装饰者模式、观察者模式。

  3. 工厂方法模式的优点(低耦合、高内聚,开放封闭原则)

十、算法

  1. 使用随机算法产生一个数,要求把1-1000W之间这些数全部生成。(考察高效率,解决产生冲突的问题)

  2. 两个有序数组的合并排序

  3. 一个数组的倒序

  4. 计算一个正整数的正平方根

  5. 说白了就是常见的那些查找、排序算法以及各自的时间复杂度

  6. 二叉树的遍历算法

  7. DFS,BFS算法

  8. 比较重要的数据结构,如链表,队列,栈的基本理解及大致实现。

  9. 排序算法与时空复杂度(快排为什么不稳定,为什么你的项目还在用)

  10. 逆波兰计算器

  11. Hoffman 编码

  12. 查找树与红黑树

十一、并发与性能调优

  1. 有个每秒钟5k个请求,查询手机号所属地的笔试题(记得不完整,没列出),如何设计算法?请求再多,比如5w,如何设计整个系统?

  2. 高并发情况下,我们系统是如何支撑大量的请求的

  3. 集群如何同步会话状态

  4. 负载均衡的原理

5 .如果有一个特别大的访问量,到数据库上,怎么做优化(DB设计,DBIO,SQL优化,Java优化)

  1. 如果出现大面积并发,在不增加服务器的基础上,如何解决服务器响应不及时问题“。

  2. 假如你的项目出现性能瓶颈了,你觉得可能会是哪些方面,怎么解决问题。

  3. 如何查找 造成 性能瓶颈出现的位置,是哪个位置照成性能瓶颈。

  4. 你的项目中使用过缓存机制吗?有没用用户非本地缓存

十二、其他

1.常用的linux下的命令

转载出处

携程一面:
1-Object下都有什么方法?
见以上
2-面向对象的特点
封装 可以隐藏实现细节 使得代码模块化
继承 可以扩展已经存在的代码模块 目的是实现代码重用
多态
3-如何实现多态?并以面向对象的思想设计一个猫吃鱼的例子(写代码)
多态就是一种事务的多种形态,就是在同一符号或者名字下有不同的解释现象,多态就是同一个行为具有不同的表现形式,多态就是同一个接口使用不同的实例而执行不同操作。

class Animal{
      public void eat(){
         System.out.println("吃饭");
       }
 }
 class Dog extends Animal{
         public void eat(){
            System.out.println("狗吃肉");
          }
          public void watchHome(){
              System.out.println("狗看家");
            }
     class Cat extends Animal{
          public void eat(){
             System.out.println("猫吃鱼");
           }
           public void playGame(){
              System.out.println("猫捉秘藏");
            }
      }
  }
class DouTaiTest{
   public static void main(String[] args){
    //定义成狗
    Animal a=new Dog();
    a.eat();
    System.out.println("----------");
    //还原成狗
    Dog d=(Dog)a;
    d.eat();
    d.watchHome();
    System.out.println("----------");
    //变成猫
    a=new Cat();
    a.eat();
    System.out.println("------------");
    Cat c=(Cat) a;
    c.eat();
    c.playGame();
    }
 }

4-如何避免线程死锁
死锁是由于多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放,由于线程被无限期的阻塞,因此线程被无限期阻塞,因此线程不能正常运行。
导致死锁的根源在于不适当的运用“synchronized”关键词来管理线程对特定对象的访问。synchronized关键字的作用是确保在某个时刻只有一个线程被允许执行特定的代码块。
死锁发生的必要条件

  • 互斥条件:一个资源内次只能被一个进程使用。
  • 请求和保持条件:一个进程因请求资源而阻塞是,对已获得的资源保持不放。
  • 不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。
  • 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

死锁的解决办法有三个:设置加锁顺序,设置加锁时限,开启死锁检测。
加锁顺序
当多个线程需要相同的一些锁,按照不同的顺序加锁,死锁就很容易发现。如果确保所有的线程都是按照相同的顺序获得锁,那么死锁就不会发生,线程只有获得了从顺序上排在前面的锁后,才能获得后面的锁。
加锁时限
在尝试了获的时候加了一个超时时间,就是在尝试获得锁的过程中如果超过了这个时限该线程则放弃对锁的请求。如果一个线程没有在给定的时限内成功获得所有需要的锁,则会进行回退并释放所有已经获得锁,然后在等待一段随机的时间在重试。
死锁检测

5-synchronized关键字加在静态方法和非静态方法上有何区别

  • Synchronized修饰非静态方法,实际上对调用该方法的对象加锁,俗称 对象锁
  • Synchronized修饰静态方法,实际上是对该类对象加锁,类锁。

6-线程有哪些基本状态,状态切换图画出来
每个线程包括新生,就绪,运行,阻塞和死亡五种状态。
在这里插入图片描述

  • 1.new 创建方法 调用start,线程进入就绪状态。
  • 2.运行状态的线程遇到sleep,线程进入睡眠状态。
  • 3运行的状态可能在等待IO,也可能进入挂起状态,IO完成,转化成就绪状态
  • 4处于运行状态的线程yield,线程转为就绪状态。(yield只让给权限比自己高的)
  • 5处于运行状态的线程遇到wait,线程处于等待状态,需要notify()/notifyALL来唤醒线程,唤醒后的线程处于锁定状态,获取了“同步锁”,之后,线程才转为就绪状态。处于运行的线程synchronized,加上后 变成同步操作。处于锁定状态,获取了“同步锁”,之后,线程才转为就绪状态。

7-解释一下IO阻塞
阻塞IO
最传统的一种IO模型,在读写数据过程中会发生阻塞现象,当用户线程发生IO请求之后,内核区查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处在阻塞状态,用户线程交出CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并且返回结果给用户线程,用户线程才接触block状态。
非阻塞IO
多路复用IO
信号驱动IO
异步IO

8-用过哪些集合?
List ArrayList LinkedList

  • Array数组是基于索引(index)的数据结构,在数组中读取搜索数据是很快的,但是删除数据的开销很大,需要重拍数组中的所有数据(删除治好后,需要把后面所有的数据前移动),ArrayList可以看作是能够自动增长容量的数组
  • LinkList是一个双链表,在添加和删除元素的时候有更好的性能,适合数据量较大或者操作频繁。

Set HashSet TreeSet

  • hashset不能保证元素的排列顺序,顺序可能发生改变。不是同步的,集合元素可以是null,但是只能放入一个null。hashset使用hashCode()方法或者该对象的值,然后根据hashCode的值来决定该对象在hashSet中的存储位置
  • TreeSet是SortedSet接口的实现类,TreeSet可以确保集合元素处于排序状态
  • TreeSet是二叉树实现的,TreeSet中的数据是自动拍好序的,不允许放空值。
  • HashSets是哈希表实现的,表中的数据是无序的,可以放入null,但是两者中的值不能是重复的

使用场景:
HashSet:哈希表是通过散列法的机制来存储信息,元素并没有以某种特定的顺序来存放
TreeSet:提供一个使用树结构存储Set接口的实现(红黑树算法),对象以升序存储,访问和遍历时间很快

Map HashMap TreeMap
9-ArrayList和LinkedList的区别?
见之上
10-HashMap的底层原理? 在key相同的情况下怎么处理?
数组加链表 拉链法解决冲突
11-HashMap线程安全吗?与ConcurrentHashMap的区别?分段锁在Java8后有什么变化?
hashmap的实现里没有锁的机制,因此它的线程是不安全的。最大的区别就是ConcurrentHashMap是线程安全的,因为ConcurrentHashMap引入了一个分段锁的概念,底层采用分段的数组+链表实现,线程安全,具体可以一个大的map拆分成N个小的HashTable,根据key.hashCode()来决定把key放到哪个HashTable中。java8舍弃分段锁是因为减少内存开销,获得JVM的支持
12-TCP如何保证可靠传输

  • 确认和重传:接受放收到报文就会确认,发送方发送一段时间之后没有收到确认就重传。
  • 数据校验
  • 数据合理分片和排序
  • 流量控制:当接受方来不及处理发送方的数据,能提示方法方减低发送的速率,防止包丢失。
  • 拥塞控制:网络拥塞是,减少数据的发送。

13-TCP两次握手不行吗?
两次握手只能保证单向连接是通畅的,只有经过第三次握手才可以双向都可以接收到对方的发送的数据
Step1 A -> B : 你好,B。
Step2 A <- B : 收到。你好,A。
Step3 A -> B : 收到,B。
14-TCP断连呢?为什么需要4次挥手?
三次握手是保证建立连接
四次挥手是关闭连接
建立连接的时,ACK和SYN可以放在一个报文中来发送,而关闭连接的时,被动关闭方需要发送一些数据后,在发送FIN报文表示同意现在可以关闭连接,所以他这里的ACK报文和FIN报文多数情况下是分来发送的。

15-TCP建立连接后,服务端出现故障,怎么处理?
16-TCP流量控制、拥塞控制?
17-解释一下SQL注入
18-事务的特性是什么?
19-事务隔离级别有哪些?
20-MySQL存储引擎是什么
21-关系型数据库与非关系型数据库的区别?非关系型数据库在什么场景下使用?
22-索引的优点是什么?什么场景下使用索引、什么场景下不使用?
23-B+树原理是什么?
24-算法题:n皇后

数据库索引技术
说白了 索引问题就是查找问题
数据库索引是数据库管理系统中的一个排序的数据结构,以协助快速查询,更新数据库表中的数据。索引的实现通常是使用B树及其变种B+树。数据库系统还维护者满足特定查找算法的数据结构,索引就是通过某种方式指向数据,这样就可以在数据结构上实现高级查找算法。
建立索引也是需要付出代价的.1是增加了数据库的存储结构,2是在插入和修改数据时花费较多的时间
在这里插入图片描述
上图是一种可能的索引方式,左边是数据表,最左边是物理地址。为了加快col2的查找,可以生成右边所示的二叉查找树,每个节点分别包含索引键值和一个指向数据记录的物理地址的指针,这样就可以运用二叉查找在O(log2n)时间复杂度内获得相应的数据。

创建索引可以大大提升系统性能。
第一,创建索引,可以保证数据表中每一行数据的唯一性。
第二,可以大大加快数据检索的速度。
第三,加速表和表之间的连接
第四,使用分组和排序时候,减少查询中分组和排序的时间
第五,通过索引,在查询中使用优化隐藏器,提升系统性能。

索引缺点
第一 创建索引和维护索引需要花费时间
第二 索引需要占据物理空间
第三 数据增删查的时候,索引也需要维护

数据库使用数据结构的方法本质上就是查找,所以我先把树的查找方式搞定
红黑树查找

二叉查找树是一颗二叉树,每个节点都有可比较的键值(特点是节点值都大于左子树,小于右子树)
在这里插入图片描述
二叉查找树是查找一个键是递归算法:
如果树是空的,则查找未命中。如果被查找的键和根结点的键相等,查找命中。否则我们就在适当的子树中继续查找。如果被查找的键较小就选择左子树,较大就选择右子树。随着我们查找不断向下,当前节点表示的子树的大小也在减小。
二叉查找树的情况:
在这里插入图片描述
二叉查找树和快速排序就是双胞胎,树的根节点就是快速排序中的第一个切分的元素,左侧小右侧大。这个和快速排序中对应的子数组的递归完全一样。

平衡查找树
在一棵含有N个节点的树中,我们希望树高度为lgN,这样保证所有的查找就可以在lgN内结束,可以转化为二分查找。
2-3查找树
在这里插入图片描述
一颗完美的平衡的2-3查找树所有的空连接到根节点的距离都是相同的。
https://blog.youkuaiyun.com/yang_yulei/article/details/26066409

SQL demo用法
在这里插入图片描述

插入
INSERT INTO stu (id, name, second) VALUES (‘1’, ‘houyi’, ‘99’);
INSERT INTO stu (id, name, second) VALUES (‘1’, ‘houyi’, ‘99’),(‘1’, ‘zhang’, ‘98’),(‘1’, ‘li’, ‘97’),(‘1’, ‘sun’, ‘96’);
sql语句求某列的和、平均值、最大值、最小值、行数,主要用到sum,avg,max,min,count函数
求和:
SELECT sum(second) FROM stu
求平均值:
SELECT avg(second) FROM stu
求取最小值
SELECT MIN(second) FROM stu
求取最大值
SELECT max(second) FROM stu
求取某列的行数
SELECT count(second) FROM stu

查找算法:
暴力算法:遍历for 就是不停的遍历
二分查找:有序
哈希:最高效 O(1)。hash冲突,JDK1.8里面的HashMap:链表+红黑树(处理Hash冲突)
索引:搜索索引
bfs and dfs
平衡树
B+树
B-树

  • 红黑树的时候,你一次只能得到一个键值的信息,而用B树,可以得到最多M-1个键值的信息

  • 红黑树的阶数更大,B树更短

  • B树的设计思想是,将相关数据尽量集中在一起,以便一次读取多个数据,减少硬盘操作次数
    相对学术一点的B树的定义:

  • 根节点至少有两个子节点

  • 每个节点有M-1个key,并且以升序排列(M阶 就是有几个分叉)

  • 位于M-1和M key的子节点的值位于M-1 和M key对应的Value之间

  • 其它节点至少有M/2个子节点

  • 所有叶子节点都在同一层
    在这里插入图片描述
    1到22 阶数是3,就是满足一个节点中的值满足是3的时候,就把字节中之间那个数组提上去成为父节点即可。
    红黑树 (因为有时候二叉查找树特殊情况下会转化成一条链表,为了解决这种情况,解决平衡问题,我们引入了红黑树的概念)
    红黑树规则:

  • 每个节点都有红色或者黑色

  • 树的根节点始终是黑色

  • 没有两个相邻的节点是红色(红色节点不能有红色父节点或者红色子节点

  • 从节点到其他任何后代为null节点(叶子节点)的每条路径都有相同数量的黑色节点

  • 在这里插入图片描述

红黑树的两大操作:

  • recolor(重新标记黑色或红色)
  • rotation(旋转,树达到平衡)

jdk 1.8 HashMap 中有使用到红黑树,你知道触发条件是什么吗?有读过源码是如何 put 和 remove 的吗?
这里讲的是红黑树的 insert,delete 又是什么规则呢?
哪些场景可以应用红黑树?
你了解各种树的时间复杂度吗?
留个小作业,应用工具将 [10 70 32 34 13 56 32 56 21 3 62 4 ] 逐个插入到树中,理解红黑树 recolor 和 rotation 的转换规则
红黑树转化的过程就是平衡二叉树的调节过程,只不过我们需要不断注意树的颜色。
在这里插入图片描述
https://www.cs.usfca.edu/~galles/visualization/RedBlack.html
二叉搜索树:
二叉查找树如图:
在这里插入图片描述

任务调度程序Gearman
Gearman是一个简单的分发任务的程序框架,和Hadoop相比,gearman更偏向于任务分发功能,只需要脚本就可以完成
在这里插入图片描述
gearman分布式任务实现原理只需要两个字段,任务名称(function name)和执行任务所需要的自定义内容(data)
gearman分布式架构中的三个角色
client:请求的发起者,工作的需求方。
job Server:请求的调者,需要负责将client的请求转发给相应的worker(gearmand服务进程的创建)
worker:请求的处理着

gearman支持的特性:

  • 高可用
  • 负载均衡
  • 可扩展
  • 分布式
  • 队列机制
  • 高性能
    京东一面总结
    数据库索引
    数据库的索引的目的是为了提高查询速度的。
  • 普通索引
  • ALTER mytable ADD INDEX[indexName] ON(username(length))
  • 唯一索引 索引列必须唯一,允许空值
  • CREATE UNIQUE INDEX indexName ON mytable(username(length))
  • 主键索引 特殊的唯一索引,但是不允许有空值
  • CREATE TABLE mytable( ID INI NOT NULL,username VARCHAR(16) NOT NULL,PRIMARY KEY(ID));
  • 组合索引 对表添加多个字段
  • CREATE TABLE mytable( ID INT NOT NULL,username VARCHAR(16)NOT NULL, city VARCHAR(50) NOT NULL,age INT NOT NULL);
  • 为了进一步提升mysql效率,就要建
  • 立组合索引,将name city age 建立到一个索引中
    什么时候建立索引???????在WHERE和JOIN中出现的列需要建立索引
SELECT t.Name
FROM mytable t LEFT JQIN mytable m
ON t.Name=m.username WHERE m.age=20 AND m.city="郑州"

此时需要对city和age建立索引。
索引的缺点:1.提高查询速度,但是会降低更新表的速度,因为更新表的时候不光需要保存数据,还需要保存索引文件。
2.建立索引会占用磁盘的索引文件。

索引的原理:
原理就是平衡树
缓存
1.数据交换的缓冲区(cache),数据的读取可以从硬盘和缓存,缓存的数据读取快,缓存的作用就是帮硬件运行的更快。
2.常见的缓存策略(redis

  • 基于访问的时间,此类算法根据缓存被访问的时间来组织缓存队列,LRU
  • 基于访问频率 LFU LRU2
  • 访问时间和频率兼顾的
  • 基于访问模式
    3 数据不一致性产生的原因:先操作缓存,在写数据库成功之前,如果有读请求发生,可能导致旧数据进入缓存,引发数据不一致。
    4 缓存穿透,缓存击穿,缓存雪崩和缓存刷新。

线程池
线程:进程中负责程序执行的执行单元。一个线程中至少有一个线程。
多线程:解决多任务同时执行的需求,合理的使用CPU资源。多线程的运行是根据CPU切换完成,如何切换由CPU决定,因此多线程具有不确定性。
线程池:基本的思想是一种对象池的思想,开辟了一块内存空间,里面存放着众多线程(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务的时候,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象带来的性能开销。
java8新特性
hashmap线程不安全
消息队列

jdk体系结构
在这里插入图片描述
java 跨平台使用
在这里插入图片描述
在这里插入图片描述

数据分析师
MapReduce
Hadoop
Spark

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值