那技术人究竟都须要修炼哪些“内功”呢?我以为,无外乎就是大学里的那些基础课程,操做系统、计算机网络、编译原理等等,固然还有数据结构和算法
做为业务开发,咱们会用到各类框架、中间件和底层系统,好比 Spring、RPC 框架、消息中间件、Redis 等等。在这些基础框架中,通常都揉和了不少基础数据结构和算法的设计思想
这里面有 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树;10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法。java
时间复杂度
大 O 时间复杂度实际上并不具体表示代码真正的执行时间,而是表示代码执行时间随数据规模增加的变化趋势,因此,也叫做渐时间复杂度mysql
时间复杂度分析方法
一、只关注循环执行次数最多的一段代码(n的量级就是要分析的时间复杂度)
二、总的时间复杂度就等于量级最大的那段代码的时间复杂度(常量不算)
三、乘法法则:嵌套代码的复杂度等于嵌套内外代码复杂度的乘积linux
时间复杂度分类
粗略分为多项式量级和非多项式量级
非多项式:当数据规模 n 愈来愈大时,非多项式量级算法的执行时间会急剧增长,求解问题的执行时间会无限增加。因此,非多项式时间复杂度的算法实际上是很是低效的算法
指数阶(2的n次方)、阶乘阶O(n!)
多项式:
常量阶O(1):常量级时间复杂度的一种表示方法。只要代码的执行时间不随 n 的增大而增加,这样代码的时间复杂度咱们都记做 O(1)。或者说,通常状况下,只要算法中不存在循环语句、递归语句,即便有成千上万行的代码,其时间复杂度也是Ο(1)。
对数阶O(logn)
线性阶O(n)
线性对数阶O(nlogn)
平方阶O(n的平方),O(n的三次方).....O(n的k次方)nginx
空间复杂度
空间复杂度全称就是渐进空间复杂度,表示算法的存储空间与数据规模之间的增加关系(常见的空间复杂度就是 O(1)、O(n)、O(n的2次方)),通常分析起来比较简单面试
最好状况时间复杂度就是,在最理想的状况下,执行这段代码的时间复杂度
最坏状况时间复杂度就是,在最糟糕的状况下,执行这段代码的时间复杂度
平均状况时间复杂度
只有同一块代码在不一样的状况下,时间复杂度有量级的差距,咱们才须要分析最好、最好和平均时间复杂度
均摊时间复杂度(一种特殊的平均)
对一个数据结构进行一组连续操做中,大部分状况下时间复杂度都很低,只有个别状况下时间复杂度比较高,并且这些操做之间存在先后连贯的时序关系,这个时候,咱们就能够将这一组操做放在一起分析,看是否能将较高时间复杂度那次操做的耗时,平摊到其余那些时间复杂度比较低的操做上。并且,在可以应用均摊时间复杂度分析的场合,通常均摊时间复杂度就等于最好状况时间复杂度redis
数组
数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具备相同类型的数据。对内存的要求比较高
随机访快,删除和插入惭怍低效,由于要保证连续来作数据搬移
数组和链表的区别:“链表适合插入、删除,时间复杂度 O(1);数组适合查找,根据下标随机访问的时间复杂度为 O(1)”
数组插入优化:若是数组数据有序,则须要插入到k位置,k及之后的都要日后移动,若是数组数据无序,只需将数组k位置的数据移动至数组末尾,k位置放入新数据,时间复杂度从O(n)降为了O(1)
数组删除优化:若是要删除好几个数据,能够把要删除的数据都记下来,当数组没有存储空间后,把标记的数据真正的都删掉,再总体移动数据,(JVM中标记清除垃圾回收算法)
若是事先能肯定须要存储的数据大小,最好在建立 ArrayList 的时候事先指定数据大小
ArrayList和数组区别:ArrayList不能存储基本数据类型(int,long),而 Autoboxing、Unboxing 则有必定的性能消耗,因此若是特别关注性能,或者但愿使用基本类型,就能够选用数组;若是数据大小事先已知,而且对数据的操做很是简单,用不到 ArrayList 提供的大部分方法,也能够直接使用数组。
线性表就是数据排成像一条线同样的结构。每一个线性表上的数据最多只有前和后两个方向。其实除了数组,链表、队列、栈等也是线性表结构。非线性表,好比二叉树、堆、图等。之因此叫非线性,是由于,在非线性表中,数据之间并非简单的先后关系。算法
链表
链表不须要一块连续的内存空间,它经过“指针”将一组零散的内存块串联起来使用,每一个内存空间叫作”节点“,每一个节点有”后继指针“记录下个节点的地址,第一个节点叫作头结点,最后一个节点叫作尾节点。spring
单链表
头结点用来记录链表的基地址,而尾结点特殊的地方是:指针不是指向下一个结点,而是指向一个空地址 NULL,表示这是链表上最后一个结点。
链表删除和插入时间复杂度O(1),查找k元素时间复杂度O(n)sql
循环链表
循环链表是一种特殊的单链表,而循环链表的尾结点指针是指向链表的头结点
环形结构能够用循环链表实现(例如:约瑟夫问题)mongodb
双向链表
它支持两个方向,每一个结点不止有一个后继指针 next 指向后面的结点,还有一个前驱指针 prev 指向前面的结点。
优势:和单项链表比,双向链表能够支持 O(1) 时间复杂度的状况下找到前驱结点,
缺点:和单向链表比,双向链表每一个节点多了一个前驱指针,因此耗费空间多
双向链表比单向应用更普遍(例如:LinkedHashMap)
缘由:一、删除或插入一个节点k时,单向须要找前驱节点,双向找到k后能够直接删除或插入
二、针对有序链表,在查找上双向链表效率更高,由于查找k能够经过已知位置q和k比较,双向能够往前或者日后找一半数据
4.如何选择?
数组简单易用,在实现上使用连续的内存空间,能够借助CPU的缓冲机制预读数组中的数据,因此访问效率更高,而链表在内存中并非连续存储,因此对CPU缓存不友好,没办法预读。
若是代码对内存的使用很是苛刻,那数组就更适合,由于链表会多占用一个指针的空间,内存消耗会翻倍,对链表进行频繁的插入、删除操做,还会致使频繁的内存申请和释放,容易形成内存碎片,若是是 Java 语言,就有可能会致使频繁GC.
数组的缺点是大小固定,一经声明就要占用整块连续内存空间,声明过大可能没有那么大连续内存,太小需申请更大的空间,把数组拷贝到新数组中,数据拷贝很耗时。链表自己没有大小限制,支持自然动态扩容
栈
后进者先出,先进者后出,这就是典型的“栈”结构。栈是一种“操做受限”的线性表,只容许在一端插入和删除数据
实际上,栈既能够用数组来实现,也能够用链表来实现。用数组实现的栈,咱们叫做顺序栈,用链表实现的栈,咱们叫做链式栈
栈:浏览器的前进后退,计算器的运算,判断括号是否匹配
队列
先进者先出,这就是典型的“队列”。
咱们知道,栈只支持两个基本操做:入栈 push()和出栈 pop()。队列跟栈很是类似,支持的操做也颇有限,最基本的操做也是两个:入队 enqueue(),放一个数据到队列尾部;出队 dequeue(),从队列头部取一个元素
队列跟栈同样,也是一种操做受限的线性表数据结构。
用数组实现的队列叫做顺序队列,用链表实现的队列叫做链式队列。
队列:普通队列,循环队列,阻塞队列
阻塞队列其实就是在队列基础上增长了阻塞操做。简单来讲,就是在队列为空的时候,从队头取数据会被阻塞。尚未数据可取,直到队列中有了数据才能返回;若是队列已经满了,那么插入数据的操做就会被阻塞,直到队列中有空闲位置后再插入数据,而后再返回。
前面咱们讲了阻塞队列,在多线程状况下,会有多个线程同时操做队列,这个时候就会存在线程安全问题,那如何实现一个线程安全的队列呢?
线程安全的队列咱们叫做并发队列。最简单直接的实现方式是直接在 enqueue()、dequeue()方法上加锁,可是锁粒度大并发度会比较低,同一时刻仅容许一个存或者取操做。实际上,基于数组的循环队列,利用 CAS 原子操做,能够实现很是高效的并发队列。这也是循环队列比链式队列应用更加普遍的缘由。在实战篇讲 Disruptor 的时候,我会再详细讲并发队列的应用。
实际上,对于大部分资源有限的场景,当没有空闲资源时,基本上均可以经过“队列”这种数据结构来实现请求排队。
好比高性能队列 Disruptor、Linux 环形缓存,都用到了循环并发队列;Java concurrent 并发包利用 ArrayBlockingQueue 来实现公平锁等。
关于如何实现无锁并发队列
可使用 cas + 数组的方式实现。
队列的其余应用
分布式消息队列,如 kafka 也是一种队列。
散列表
散列表用的是数组支持按照下标随机访问数据的特性,因此散列表其实就是数组的一种扩展,由数组演化而来。能够说,若是没有数组,就没有散列表。
散列表三个重要因素,散列key(关键字)、散列函数(hash(key)),计算出来的值是散列值
散列函数的三个要求
一、计算出来的散列值是非负整数
二、若是 key1 = key2,那 hash(key1)== hash(key2);
三、若是 key1 ≠ key2,那 hash(key1) ≠ hash(key2)。
要求合理,可是第三点很难作到,也没法彻底避免这种散列冲突。并且,由于数组的存储空间有限,也会加大散列冲突的几率
散列冲突
解决散列冲突的方法,有两类,开放寻址法(open addressing)和链表法(chaining)
一、开放寻址方法
开放寻址法的核心思想是,若是出现了散列冲突,咱们就从新探测一个空闲位置,将其插入
探测的方法
线性探测:线性探测法其实存在很大问题。当散列表中插入的数据愈来愈多时,散列冲突发生的可能性就会愈来愈大
二次探测(Quadratic probing)和双重散列(Double hashing)。
双重散列:咱们先用第一个散列函数,若是计算获得的存储位置已经被占用,再用第二个散列函数,依次类推,直到找到空闲的存储位置。
无论是哪一种探测方法,当散列表中位置很少的时候,散列冲突会大大的增长,因此会提供一个装载因子(load factor)来表示空位的多少
链表法是一种更加经常使用的散列冲突解决办法,相比开放寻址法,它要简单不少。咱们来看这个图,在散列表中,每一个“桶(bucket)”或者“槽(slot)”会对应一条链表,全部散列值相同的元素咱们都放到相同槽位对应的链表中。
散列表两个核心问题是散列函数设计和散列冲突解决
Java 中 LinkedHashMap 就采用了链表法解决冲突,ThreadLocalMap 是经过线性探测的开放寻址法来解决冲突
我总结一下,当数据量比较小、装载因子小的时候,适合采用开放寻址法。这也是 Java 中的ThreadLocalMap使用开放寻址法解决散列冲突的缘由。
我总结一下,基于链表的散列冲突处理方法比较适合存储大对象、大数据量的散列表,并且,比起开放寻址法,它更加灵活,支持更多的优化策略,好比用红黑树代替链表。
哈希函数
将任意长度的二进制值串映射为固定长度的二进制值串,这个映射的规则就是哈希算法,而经过原始数据映射以后获得的二进制值串就是哈希值
三种哈希算法在分布式系统中的应用,它们分别是:负载均衡、数据分片、分布式存储。
在负载均衡应用中,利用哈希算法替代映射表,能够实现一个会话粘滞的负载均衡策略。在数据分片应用中,经过哈希算法对处理的海量数据进行分片,多机分布式处理,能够突破单机资源的限制。在分布式存储应用中,利用一致性哈希算法,能够解决缓存等分布式系统的扩容、缩容致使数据大量搬移的难题。
一个优秀的散列表
散列函数的设计不能太复杂。过于复杂的散列函数,势必会消耗不少计算时间,也就间接的影响到散列表的性能
散列函数生成的值要尽量随机而且均匀分布,这样才能避免或者最小化散列冲突
索引的出现其实就是为了提升数据查询的效率,就像书的目录同样
能够提升读写速度的数据结构:哈希表、有序数组和搜索树
哈希表这种结构适用于只有等值查询的场景,查询区间就要遍历全表
有序数组在等值查询和范围查询场景中的性能就都很是优秀,查找能够二分查找,单看查询效率有序数组很棒,可是插入和删除须要移动数组,成本过高
因此,有序数组索引只适用于静态存储引擎,好比城市人口信息,不会更改的数据
二叉搜索树的特色是:每一个节点的左儿子小于父节点,父节点又小于右儿子
二叉树是搜索效率最高的,可是实际上大多数的数据库存储却并不使用二叉树。其缘由是,索引不止存在内存中,还要写到磁盘上。二叉树数据量大的时候树比较高,访问磁盘过多
N 叉树因为在读写上的性能优势,以及适配磁盘的访问模式,已经被普遍应用在数据库引擎中了。
不一样存储引擎索引实现不同,由于索引是在存储引擎层实现的
InnoDB 的索引模型
在 InnoDB 中,表都是根据主键顺序以索引的形式存放的,这种存储方式的表称为索引组织表
InnoDB 使用了 B+ 树索引模型,因此数据都是存储在在 B+ 树中的。每个索引在 InnoDB 里面对应一棵 B+ 树。
InnoDB用B+树的缘由:B+ 树可以很好地配合磁盘的读写特性,减小单次查询的磁盘访问。
主键索引的叶子节点存的是整行数据。在 InnoDB 里,主键索引也被称为聚簇索引(clustered index)。
非主键索引叶子节点内容是主键的值。在 InnoDB 里,非主键索引也被称为二级索引(secondary index)。
基于主键索引和普通索引的查询有什么区别?
主键查询方式,只须要搜索ID这棵B+树
普通索引查询方式,则须要先搜索 k 索引树,获得 ID 的值,再到 ID 索引树搜索一次。这个过程称为回表。
因此更推荐主键索引,少查一次树
从性能和存储空间方面考量,自增主键每每比业务逻辑字段作主键更好
缘由:
性能:自增主键有序,业务字段无序,每次插入中间须要挪动位置,插入若是页满了,会引发页3分裂,删除数据,可能有页合并
存储:主键长度越小,普通索引的叶子节点就越小,普通索引占用的空间也就越小,
若是只有一个索引这种状况,用业务字段做为主键比较好,由于能够少查一次树
覆盖索引:因为覆盖索引能够减小树的搜索次数,显著提高查询性能,因此使用覆盖索引是一个经常使用的性能优化手段。例如:select ID from T where k between 3 and 5 代替 select * 减小了回表
B+ 树这种索引结构,能够利用索引的“最左前缀”,来定位记录
前缀索引:能够看到,不仅是索引的所有定义,只要知足最左前缀,就能够利用索引来加速检索。这个最左前缀能够是联合索引的最左 N 个字段,也能够是字符串索引的最左 M 个字符。
第一原则是,若是经过调整顺序,能够少维护一个索引,那么这个顺序每每就是须要优先考虑采用的
索引下推:而 MySQL 5.6 引入的索引下推优化(index condition pushdown), 能够在索引遍历过程当中,对索引中包含的字段先作判断,直接过滤掉不知足条件的记录,减小回表次数。
分布式(distributed)是指多台不一样的服务器部署不通的服务模块,经过远程调用协议协同工做,对外提供服务
分布式思想,经过把意见大的事情,拆分红多个小事情,分别交给不一样的人作
集群(cluster)是指在多台不一样的服务器中部署相同应用或服务模块,构成一个集群,经过负载均衡设备对外提供服务
rpc是指计算机A上的进程,调用另一台计算机B上进程,其中A上的调用进程呗挂起,而B上的被调用进程开始执行,当值返回给A时,A进程继续执行,调用方能够经过使用使用参数讲信息传送给被调用方,然后能够经过传回的结果获得信息
RPC框架主要三个角色,Provider、Consumer,Registry,服务提供者启动后会主动向注册中心注册机器ip,port以及提供的服务列表,服务消费者启动时向注册中心获取服务提供地址列表,可实现软负载均衡和Failover
rpc设计技术
动态代理技术:java原生,CgLib,javassist
序列化
java原生序列化,效率低,开源的,protobuf,Thrift,hession,Kryo,Msgpack
NIO
RPC框架都直接基于netty这一IO通讯框架,好比HSF,dubbo,Hadoop Avro,推荐使用Netty做为底层通讯框架
服务注册中心
可选技术:Redis,Zookooper,Consul,Etcd
RPC开源框架
Dubbo 阿里
Motan 新浪微博
gRPC Google开发的高性能、通用的开源RPC框架,主要面向移动端,基于HTTP/2协议标准,基于ProtoBuf序列化协议开发,支持众多开发语言,自己不是分布式的,须要实现框架爱功能
thrift Apache的一个跨语言的高性能服务框架
一、介绍一下mysql索引?为何用B+树
索引(Index)是帮助MySQL高效获取数据的数据结构
MYsql经常使用索引有,主键索引、惟一索引、普通索引、全文索引、组合索引
不能创建过多索引,可能会致使磁盘和内存占用太高,从而影响总体性能
mysql经常使用的INnoDB数据库使用B+tree实现的
数据增大,索引自己增大,不能所有存在内存中,索引已索引文件存储在磁盘上,这样索引查找会产生磁盘i/O消耗,相对于内存存取,I/O存取消耗要高不少个数量级,若是数据量上百万的节点二叉树深度很深,这么深度的二叉树,每读取一个节点,须要一次I/O,总体消耗很高,减小存取次数,减小树的深度,把二叉树变成多路索引树
B+Tree就是一种多路索引数,mysql将节点大小设置为页的整数倍,利用了磁盘预读原理,
二、Java类加载机制,双亲委派模型的好处
通常来讲,咱们把 Java 的类加载过程分为三个主要步骤:加载、连接、初始化
首先是加载阶段(Loading),它是 Java 将字节码数据从不一样的数据源读取到 JVM 中,并映射为 JVM 承认的的数据结构(Class 对象),这里的数据源多是各类各样的形态,如 jar 文件、class 文件,甚至是网络数据源等;若是输入数据不是 ClassFile 的结构,则会抛出 ClassFormatError。
加载阶段是用户参与的阶段,咱们能够自定义类加载器,去实现本身的类加载过程。
第二阶段是连接(Linking),这是核心的步骤,简单说是把原始的类定义信息平滑地转化入 JVM 运行的过程当中。这里可进一步细分为三个步骤:
验证(Verification),这是虚拟机安全的重要保障,JVM 须要核验字节信息是符合 Java 虚拟机规范的,不然就被认为是 VerifyError,这样就防止了恶意信息或者不合规的信息危害 JVM 的运行,验证阶段有可能触发更多 class 的加载。
准备(Preparation),建立类或接口中的静态变量,并初始化静态变量的初始值。但这里的“初始化”和下面的显式初始阶段是有区别的,侧重点在于分配所须要的内存空间,不会去执行更进一步的 JVM 指令。
解析(Resolution),在这一步会将常量池中的符号引用(symbolic reference)替换为直接引用。在Java 虚拟机规范中,详细介绍了类、接口、方法和字段等各个方面的解析。
最后是初始化阶段(initialization),这一步真正去执行类初始化的代码逻辑,包括静态字段赋值的动做,以及执行类定义中的静态初始化块内的逻辑,编译器在编译阶段就会把这部分逻辑整理好,父类型的初始化逻辑优先于当前类型的逻辑。
再来谈谈双亲委派模型,简单说就是当类加载器((Class-Loader)试图加载某个类型的时候,除非父加载器找不到相应类型,不然尽可能将这个任务代理给当前加载器的父加载器去作。使用委派模型的目的是避免重复加载 Java 类型
三、java线程启动的几种方式?线程池使用,拒绝策略
三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。
(1)与锁相比,使用比较交换(下文简称CAS)会使程序看起来更加复杂一些。但因为其非阻塞性,它对死锁问题天生免疫,而且,线程间的相互影响也远远比基于锁的方式要小。更为重要的是,使用无锁的方式彻底没有锁竞争带来的系统开销,也没有线程间频繁调度带来的开销,所以,它要比基于锁的方式拥有更优越的性能。
(2)无锁的好处:
第一,在高并发的状况下,它比有锁的程序拥有更好的性能;
第二,它天生就是死锁免疫的。
CAS(Compare And Swap):指的是CPU所支持的一种特殊指令,该指令对内存中的共享数据作原子性的读写操做,也叫作“比较交换”
四、Spring bean的生命周期?默认建立的模式是什么?不想单例怎么办?
五、HashMap和HashTable以及CocurrentHashMap详细说明
六、java线程变量怎么实现?内存模型?
七、说一下aop
八、java里的锁了解哪些?说了Lock和synchronized
可重入锁:在执行对象中全部同步方法不用再次得到锁
可中断锁:在等待获取锁过程当中可中断
公平锁: 按等待获取锁的线程的等待时间进行获取,等待时间长的具备优先获取锁权利
读写锁:对资源读取和写入的时候拆分为2部分处理,读的时候能够多线程一块儿读,写的时候必须同步地写
九、java栈何时会发生内存溢出?Java堆呢
十、写代码模拟,50我的,2个窗口排队买票
11,无序数列中求第k大的数
al
一面
一、自我介绍和项目
二、java的内存分区
三、java对象的回收方式,回收算法
四、CMS和G1了解吗,CMS解决了什么问题,说一下回收的过程
五、CMS回收停顿了几回,为何要停顿两次
六、java栈何时回发生内存溢出,java堆呢,说一种场景,我说集合类持有对象
七、那集合类如何解决这个问题呢,我说用软引用和弱引用,那你讲讲这两个引用的区别吧
八、java锁了解哪些,说了Lock和synchronized
九、他们的使用的方式和实现原理有什么区别呢
十、synchronized锁升级的过程,说了偏向锁到轻量级再到重量级锁,而后为我他们分别是怎么实现的,解决得我是哪些问题,何时回发生锁升级
十一、Tomcat了解吗,说一下类加载器结构吧
12说了Spring,问我Spring中如何让A和b两个b顺序加载
1三、10亿个数去重,我说用了hash分片作,他说可能不均匀,而后我说了bitmap,他说那数字量更多怎么办,我说那就两个bitmap吧,他说下一题吧
二面
一、讲一下项目
二、作的主要是java对吧,讲一下多线程吧,用到哪些写一下
三、写了thread和runnable,而后写了线程池,又问了线程池由哪些组件组成,有哪些线程池,分别怎么用,以及拒绝策略有哪些
四、何时多线程会发生死锁,写一个例子吧,而后我写了 两个线程,两个锁,分别持有一个,请求另外一个死锁的实例
五、集合熟悉吧,写一个题目,一个字符串集合,找出pdd而且删除
六、而后说一下redis,是单线程仍是多线程,redis的分布式怎么作
七、rpc了解吗,我说了主要是协议栈+数据格式+序列化方式,而后须要有服务注册中心管理生产者和消费者
九、tcp三次握手的过程,若是没有第三次握手有什么问题
三面
一、自我介绍
二、cap了解吗,分别指什么,base呢,强一致性和弱一致性有什么方法来作,apc了解吗,说一下大体过程
三、负载均衡怎么作到的呢,为何这么作
四、了解集群雪崩吗
五、mysql的主从复制怎么作的,具体原理是什么有什么优缺点
六、redis有哪些线程模式,各自的区别
七、项目用到了多线程,若是线程数不少怎么办
八、分布式了解哪些东西,消息队列了解吗,用在什么场景
说了消峰,限流和异步,说了kafka,问我怎么保证数据不丢失,以及怎么确保消息不会被重复消费,还问了消息送达确认是怎么作到的。
九、讲一下项目的主要架构,你再里面作了什么
十、有什么比较复杂的业务逻辑讲一下
十一、最大的难点是什么,收获是什么
一面
一面偏架构方面
一、介绍一下本身,讲讲项目经历
二、大家项目中微服务是怎么划分的,划分粒度怎么肯定?
三、那在实践微服务架构中,有遇到什么问题么?
四、大家在关于微服务间数据一致性问题,是如何解决的?
五、大家为何不用其余的MQ,最终选择了RokcetMQ?
六、为何RocketMQ没有选择ZooKeeper,而是本身实现了一个NameServer集群?
七、嗯,理解的不错,Zookeeper在选举的过程当中,还能对外提供服务么?
八、对Paxos算法了解多少?
九、若是让你来设计一个春晚抢红包架构,你会怎么设计?
十、有什么想问个人?
大概聊了40分钟左右~
二面
二面有点偏底层和算法
一、扯了下项目、讲一下项目经历
二、大家用了redis,redis的底层数据结构了解多少?
三、知道动态字符串sds的优缺点么?
注:sds为redis底层数据结构之一
四、redis的单线程特性有什么优缺点?
五、用过 Redis 的哪些数据结构, 分别用在什么场景?
六、大家怎么解决缓存击穿问题的?
注:估计答了Hytrix
七、Hytrix的隔离机制有哪些?Hytrix常见配置是哪些?
八、本身作过哪些调优?JVM调优、数据库调优都行!
九、给了个场景,问你怎么调
十、一道算法题,具体题目忘了,在给出的连接中做答~
三面
一、讲讲本身基础掌握状况,以及项目经历
二、平时会用到哪些数据结构?
三、链表和数组的优缺点?
四、解决hash冲突的方法有哪些?
五、讲讲本身对HashMap的理解,以及和Weakhashmap的区别?
六、你刚才讲的是JDK1.7版本的实现,知道JDK1.8作了哪些改动么?
七、大家在微服务中用RPC通讯仍是REST?
八、RPC和HTTP的关系是什么?
九、知道HTTP1.0和1.1的区别么?
十、谈谈什么是HTTP的长链接和短链接?
十一、TCP的三次握手和四次挥手,以及为何要三次握手,而不是二次?
十二、TCP 有哪些状态,相应状态的含义
1三、让你评价一下你本身?
而后问了下面试官还有几轮,面试官说不必定!
四面
一、依然是介绍本身
二、大家数据库的高可用架构是怎么样的?
三、如何保证数据库主从一致性?
四、知道mysql的索引算法么?
五、为何mongodb的索引用了B树,而mysql用B+树?
六、用mysql过程当中,有遇到什么问题么?
七、大家生产用的是哪一种事务隔离级别,为何?
八、谈一谈你对微服务架构的理解
九、你用过哪些RPC框架,讲讲他们优缺点
十、用过docker么,对容器了解多少
十一、有什么问个人?
HR面
问经历,问离职缘由,问职业规划,问待遇。
惟一比较奇葩的一个,竟然不问你指望薪水~~
初级开发而言,须要让面试官感受出以下的要点。
1. 熟悉SSM架构,至少在项目里作过。
这个的说法是,介绍项目时,用一个业务流程来讲spring mvc如何作的。
2. 知道Spring MVC中的细节,好比@Autowired的用法,如何把url映射到Controller上,ModelAndView对象返回的方式等。
3. 最好结合项目的用法,说下你是怎么用AOP,拦截器的,好比说能够经过拦截器拦截非法请求,怎么用 AOP输出日志等。
4. 关于ORM方面,不限用过哪一种,但得知道一对一,一多多,多对多等的用法,以及cascade和inverse的用法。
5. 最好知道声明式事务的作法。
若是你要应聘高级开发,那在上述基础上,最好了解以下的知识点:
Spring Bean的周期
最好能经过阅读源代码,说下IOC,AOP以及Spring MVC的工做流程
最好能结合反射,说下IOC等的实现原理
Spring Boot和Spring Cloud的一些知识点
四. 数据库方面须要准备的点
很多候选人会看不少SQL的技巧,好比select该怎么写,insert又该怎么写,但仅限于此,不会再准备其它的。
这样就很吃亏,由于面试官会认为,哪怕是初级开发,SQL语句也该会写,因此这块不会多问,而会问以下方面的问题。
1. 索引怎么建的,怎么用的?好比我建好了一个索引,在where 语句里写 name like '123%'会不会走索引,怎么状况下不应建索引,哪些语句不会走索引。
2. 除了索引以外,你有过哪些SQL优化方面的经验,好比分库分表,或经过执行计划查看SQL的优化点。这最好是能结合你作的项目实际来说。
这里,我面试下来,大概有70%的候选人只知道基本SQL的写法,因此哪怕你是只有理论经验,会说一些优化点,也是很是有利的。
这块对于高级开发而言,更得了解优化方面的技能。
五. Java Core方面须要准备的点
这块是基础,其实不少问的问题,候选人必定会在项目里用到,但不多能说好说全。
这块主要会从集合,多线程,异常处理流程以及JVM虚拟机这些方面来问。
集合方面:
1. hashcode有没有重写过?在什么场景下须要重写。若是能够,结合hash表的算法,说下hashmap的实现原理。
对于高级开发而言,最好经过ConcurrentHashMap来讲明下并发方面的底层实现代码。
2. ArrayList,LinkedList的差异,好比一个基于数组,一个基于链表,它们均是线程不安全的,ArrayList的扩容作法等。
对于高级而言,最好看下底层的代码。
3. Set如何实现防重的,好比TreeSet和HashSet等。
4. Collection的一些方法,好比比较方法,包装成线程安全的方法等。
5. 可能有些面试官会问,如何经过ArrayList实现队列或堆栈,这个能够准备下。
多线程方面,其实在项目里不怎么会用到,但会问以下的问题:
1. synchronized和可重入锁的差异,而后可能会顺便问下信号量等防并发的机制。
2. 在线程里该如何返回值,其实就是callable runnable 区别。
3. 必定得经过ThreadLocal或volatile关键字,来讲明线程的内存模型。
4. 线程池方面,会用,了解些经常使用参数
线程方面,可能问得比较多的就是并发机制,若是是高级开发,可能会问得深些。
虚拟机方面
1. 结构图和流程能够大体说下。
2. 必定得了解针对堆的垃圾回收机制,具体而言,能够画个图,说下年轻代年老代等。
3. 说下垃圾回收的流程,而后针对性地说下如何在代码中优化内存性能。
4. 最好说下若是出现了OOM异常,该怎么排查?如何看Dump文件。
5. GC的一些概念,好比强弱软引用,finalize方法等,这些能够准备下。
架构方面
1. 能证实本身能够干活(这不难),同时能结合底层代码说出IOC,AOP或Spring MVC的流程,只要能说出一个便可。或者能说出拦截器,Controller等的高级用法。
2. 能证实本身有Spring Boot或Spring Cloud的经验,好比能说出些Spring Cloud组件的用法。
3. 若是能证实本身有分布式开发的经验,那最好了,其实这不难证实,好比能说出服务的包是放在多台机器上(大多数公司其实都这样),并且能说出如何部署,如何经过nginx等作到负载均衡。
数据库方面,其实讲清楚一个问题便可:如何进行SQL调优,好比经过索引,看执行计划便可,若是有其它的优化点,说清楚便可。
Java Core方面,这里给出些诀窍:
1. 能结合ConcurrentHashMap的源代码,说出final,volatile,transient的用法,以及在其中如何用Lock对象防止写并发。
2. 结合一个项目实际,说下设计模式的实践。
3. 多线程方面,能说出Lock或volatile等高级知识点的用法。
4. 这块最取巧:说下GC的流程,以及如何经过日志和Dump文件排查OOM异常,若是再高级些的话,说下如何在代码中优化内存代码。
记忆比较深入的有:BIO NIO AIO
spring的aop怎么实现
jdk和cglib的动态代理
jdk的动态代理与cglib代理
hashmap底层是啥
arraylist和vector的区别
是如何扩容的
若是想要使用hashmap又想线程安全怎么办
而后问我哪一个数据库最熟
我说mysql 问 最经常使用的两种存储引擎
答 myisam 还有innodb
他们的区别在哪里
一、两个栈怎么实现队列
二、不用递归遍历二叉树
三、实现一个树,深度层级差不超过1
四、ConcurrentMap原理
五、aop原理,实现接口是动态代理,不实现接口是xxlib
六、java8的新特性
七、等待队列的几种,怎么实现的
八、redis是单线程仍是多线程,怎么保证事务的一致性
如何实现分布式锁
悲观锁乐观锁应用原理
多线程(我以前就问通常多线程写在哪)
session共享如何实现
上海也有问数据库优化,还有一些深的索引,你用的技术底层原理
工厂模式什么的
还有jdk你用的几,8的话为啥是他,有什么不同和以前的比
leetcode和剑指offer刷完,牛客面试题刷完,bat确定稳的(什么鬼)
牛客面试题刷完offer就能爆破你的邮箱了
会不会分布式框架
spring运行流程
spring 原理
网易(刘)(2017.05)
先让写了个linux
统计一个日志里的ip的个数排
写了两种单例
写了个工厂模式
写了个冒泡和快排
还有个交换a和b的值,不用第三个变量
问了问redis,spring的aop和ioc
问了问map
数组那块
王 (2017.05)
好多呢,开始时作dsp的一些,魅族,小广告公司
有公司问过期间复杂度的问题
算法通常问怎么实现的
jvm、垃圾回收什么的
设计模式的具体实现什么的
优酷 (2017.05)
写一个队列
问我引擎的总体架构(画出来)
问我elk怎么优化的,难点是什么
jvm的内存结构,gc算法
他问我写过spring注解吗
懂原理吗。问我知道redis消息队列德原理吗
云杉 (2017.05)
Mapreduce
闭包
Java 8新特性
Iterable
什么java8提高了哪些功能
说什么百万的用户id,而后让我实现什么找到排名前十的
问我除了java还会什么语言,还有grep sed awk 是干什么的,
还有问我jvm内存模型,和gc ,为何要分代
还有hashmap arraylist linkedlist 的实现
最后出了一道题,让我不断优化啥的,还有范型
array list、toarray
除了java还会什么语言
京东商城 (2017.05)
一
为何离职
spring事物管理,或者说一说数据库的事务管理四个特性,传播和隔离
问我哪一个项目最熟悉、最近作的项目、访问量是多少,有多少实例,解决过超时这些问题什么的吗,让我具体说一说其中一个功能
redis和memchache的区别,memchache能存对象吗
java里面集合,和特性
多线程状态转换,生产者消费者写一个,用在哪了
经常使用的设计模式,让我说了说模板方法模式
用shell写一个问题,一个累加的问题
有什么问题须要问
二
为何离职
cookiemapping的实现,设计整个cookiemapping服务
联盟有哪些
引擎的框架
实现一个多个线程同时加加或减减
走的是rtb规范吗
dmp的问题
elk优化过吗
问我最熟悉的模块
同步模块的设计什么的
有什么问题须要问
hr
如今薪资多少,
指望薪资多少,
若是发offer能够介绍如今公司的来吗
在如今公司将来1-3年的发展
自我介绍
以为本身凭什么要那么多工资
有什么问题须要问
饿了么
一面
1,自我介绍,
2,说一下我画其中一个项目的架构,好比依赖什么,
3,问我这个是一个系统作的仍是好几个系统一块儿作的,而后说其中一个项目定时拉取数据怎么实现的,
4,问我用过的mq,
5,zk了解吗,怎么实现锁一致性仍是啥玩意的,
6,问我redis怎么实现访问的,怎么保证锁一致的,
7,synccronrie 内部怎么实现的,让我写了一个单例模式,而后说怎么内部优化的,
8,redis用到的结构,
9,问我dubbo 怎么实现两个系统通信的
10.还问了我aop用过吗,原理是啥
十一、单例模式写一个,为何用volitire。。。
展心展粒
问我关于项目里面红包的设计,还有问我有多少种排序,快拍的原理,知道的几种数据结构
他说我快拍的原理说的不对,而后说我红包的设计有点问题
没能解决超卖的问题
而后问了我大概在公司作啥
红包系统的难点
问我分布式里面数据一致性的问题,说我这个红包设计师有问题的
问我快排的复杂度,归并的复杂度,问我排序里面哪些比较快
他问我redis为啥可以多个用户同时访问还很快,分布式锁两个同时去执行,会怎么样
字节跳动
一、怎么设计一个udp的重传机制
二、m长的线段分红n段有多少种分法(算法)再不会的状况下,写leetcode第一题(链表翻转)
三、hashmap和hashcode的区别,红黑树的时间复杂度
四、设计一秒杀系统,每一层具体能过滤多少流量
五、elk里面作了什么,日志里面的字段和es怎么对应,keyword为何比long快,long的存储结构
六、客户投诉你的系统太慢了怎么办,(主要考察系统怎么慢,以及怎么解决。。。)
七、
刘杰面试:
二分查找
线程轮换打印奇偶数
线程池的参数都有啥
线程安全的概念
怎么实现
lock类里唤醒线程的方法
主要围绕多线程
我说validate关键字顺带说了内存模型
项目遇到的难点
先说mq特性,而后问到再说呗
Mq最多问的:问的最多就是mq的时序和事物,幂等
时间同步技术 ntp
主动更新,数据库字段更新后发消息更新缓存,这个须要用到一个组件阿里叫metaq就是就是数据库字段更新会产生一条消息
在 URL 中用逗号隔开,服务端会有一个组件解析这个 URL是阿里版Nginx的一个插件
不太明白你问啥意思,是说压测工具吗? Apache ab就很好
系统静态化改造
合并部署
一致性hash算法
算法和数据结构:各类排序,遍历,查找。时间复杂度,树,二叉树,平衡二叉树,红黑树,栈,队列。链表
Java 集合,static,final,集合原理。文件。匿名类,泛型,反射
26种设计模式
网络:http,https,tcpip 套接字
Spring springmvc 读源码
业务,整个广告的流程,计费,还有高级设置,频次控制什么的是怎么实现的
Maven整个项目的结构
Redis和memcache
Nginx的基本配置
Jvm
性能调优
分布式
数据库,数据库的优化,sql,去重,各类sql
设计模式项目同步模块配置Spark 和mapreduce 的关系计费Redis 队列的实现和memcache 的关系Mysql 调优频次控制得实现什么的并发301和302重点是能不能把一个不懂这个项目得人讲明白各类包Spring 事物Mybaties 是用jdbc 连接数据库吗数据库里面的范式Java 8新特性自动拆装箱静态类和非静态类得区别Hashmap 的实现。各类集合的区别Spring 事物Spring 单实例的实现单例模式