1、有序数组排序,二分,复杂度
2、快排的时间复杂度,冒泡时间复杂度,快排是否稳定,快排的过程
3、有N个节点的满二叉树的高度。1+logN
4、朋友之间的点对点关系用图维护,怎么判断两人是否是朋友,并查集,时间复杂度,过程。
5、单元点最短路的方法,时间复杂度
6、如何实现关键字输入提示,使用字典树,复杂度多少,有没有其他方案,答哈希,如果是中文呢,分词后建立字典树?
7、hashmap的实现讲一下吧,讲的很详细了。讲一下红黑树的结构,查询性能等。
8、Java中的垃圾回收讲一下,讲了分代,gc算法,gc root可达性分析等
9、讲一下两个项目你都做了什么吧。
10、除了代码之外你还学习了什么技术,框架。
11、死锁是怎么产生的
12、线程和进程的区别
13、进程的通信方式
14、CPU的执行方式
15、代码中遇到进程阻塞,进程僵死,内存泄漏等情况怎么排查。通过ps查询状态,分析dump文件等方式排查。
16、Linux了解么,查看进程状态ps,查看cpu状态 top。查看占用端口的进程号netstat grep
17、10g文件,只有2g内存,怎么查找文件中指定的字符串出现位置。MapReduce分割文件处理

18、100w个数,怎么找到前1000个最大的,堆排序,怎么构造,怎么调整,时间复杂度。

19、一个矩阵,从左上角到右下角,每个位置有一个权值。可以上下左右走,到达右下角的路径权值最小怎么走。
20、四辆小车,每辆车加满油可以走一公里,问怎么能让一辆小车走最远。说了好几种方案,面试官引导我优化了一下,但是还是不满意,最后他说跳过。
21、秒杀系统的架构设计
22、MySQL的索引,B+树性质。
23、Linux的cpu 100怎么排查,top jstack,日志,gui工具
24、Linux大文件怎么查某一行的内容。
25、Redis内存数据库的内存指的是共享内存么
26、Redis的持久化方式
27、hashmap的实现,hashtable,concurrenthashmap实现。

28、hashMap和ConcurrentHashMap的区别
29、hashMap内部具体如何实现的
30、如果hashMap的key是一个自定义的类,怎么办
31、为什么重写equals还要重写hashcode
32、ArrayList和LinkedList的区别,如果一直在list的尾部添加元素,用哪个效率高?
33、介绍一下Syncronized锁。如果用这个关键字修饰一个静态方法,锁住了什么?如果修饰成员方法,锁住了什么?
34、介绍一下volatile
35、多线程中的i++线程安全吗?为什么?
36、如何线程安全的实现一个计数器?
37、讲一下TCP的连接和释放连接。
38、讲一下浏览器从接收到一个URL到最后展示出页面,经历了哪些过程。
39、TCP和UDP的区别,具体使用场景呢。
40、TCP四次挥手讲一下过程,最后一次ack如果客户端没收到怎么办。
41、对于socket编程,accept方法是干什么的,在三次握手中属于第几次,可以猜一下,为什么这么觉得
42、Redis和MySQL有什么区别,用于什么场景

43、JDK 和 JRE 有什么区别?

44、== 和 equals 的区别是什么?

45、两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?

46、final 在 java 中有什么作用?

47、接口和抽象类有什么区别?

48、BIO、NIO、AIO 有什么区别?

49、如何决定使用 HashMap 还是 TreeMap?

47、线程和进程的区别?

48、创建线程有哪几种方式?

49、线程有哪些状态?

50、sleep() 和 wait() 有什么区别?

51、notify()和 notifyAll()有什么区别?

52、创建线程池有哪几种方式?

53、什么是死锁?怎么防止死锁?

54、如何避免 sql 注入?

55、什么是 XSS 攻击,如何避免?

1、多线程

java里线程的5种基本状态?
新建状态(new): 当线程对象创建后,即进入新建状态
就绪状态(Runnable): 当调用线程对象的start()方法,线程进入就绪状态,处于就绪状态的线程并不一定会立即就被执行,只是说明此线程已经做好了准备,随时等待cpu的调度执行
运行状态(Running): 当cpu开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态.
阻塞状态(Blocked): 处于运行状态中的线程由于某种原因,暂时放弃对cpu的使用权,停止执行,此时进入阻塞状态,直到其恢复到就绪状态,才有机会再次被cpu调度以进入到运行状态.
根据阻塞产生的原因不同,阻塞状态又可以分为3种:
等待阻塞: 运行状态中的线程执行了wait()方法,使本线程进入等待阻塞状态
同步阻塞: 线程在获取synchronized同步锁失败(因为锁被其他线程占用),它会进入同步阻塞状态
其他阻塞: 通过调用线程的sleep()或join()或发出i/o请求,线程会进入到阻塞状态,当sleep()状态超时、join()等待线程终止或超时、或者i/o处理完毕,
线程会重新恢复到就绪状态.
死亡状态(Dead): 线程执行完毕或者因为异常退出了run()方法,该线程结束生命周期.
-------------------------------------------------------------------------
线程池的作用:
有5个核心的属性:最大线程数量,核心线程数量,等待队列,任务队列,拒绝策略;

1): 线程复用,减少对象创建销毁的系统资源开销

2): 可有效的控制最大并发线程数,提高系统资源的使用率,同事避免过多资源竞争,避免阻塞

3): 管理线程(提供定时执行、定期执行、单线程、并发数控制等功能)
-----------------------------------------------------------------------------
线程池的区别,使用场景? juc.Excutors

1):Executors.newFixedThreadPool

通俗:创建可容纳固定数量线程的池子,每个线程的存活时间是无限的,当池子满了就不再添加线程了;如果池中的所有线程均在繁忙状态,对于新任务会进入阻塞队列中(无界的阻塞队列);
适用:执行长期的任务,性能好很多;

2):Executors.newSingleThreadExecutor

通俗:创建只有一个线程的线程池,且线程的存活时间是无限的;当该线程正繁忙时,对于新任务会进入阻塞队列中(无界的阻塞队列);
适用:一个任务一个任务执行的场景;

3):Executors.newCachedThreadPool

通俗:当有新任务到来,则插入到SynchronousQueue中,由于SynchronousQueue是同步队列,因此会在池中寻找可用线程来执行,
若有可以线程则执行,若没有可用线程则创建一个线程来执行该任务;若池中线程空闲时间超过指定大小,则该线程会被销毁;
适用:执行很多短期异步的小程序或者负载较轻的服务器;

4):Executors.newScheduledThreadPool

通俗:创建一个固定大小的线程池,线程池内线程存活时间无限制,线程池可以支持定时及周期性任务执行,如果所有线程均处于繁忙状态,
对于新任务会进入DelayedWorkQueue队列中,这是一种按照超时时间排序的队列结构;
适用:周期性执行任务的场景;
------------------------------------
juc常用的并发工具类:
CountDownLatch
CyclicBarrier
Semaphore
Exchanger
-----------------------------------
可重入锁ReentrantLock的局限性?
防止线程A在写数据、线程B在读数据造成的数据不一致,但这样,如果线程C、线程D也在读数据,读数据是不会改变数据的,没必要加锁,但是还是加锁了,降低了性能.
由此抛出 读写锁 ReadWriteLock(interface) ReentrantReadWriteLock implements ReadWriteLock.

ReadWriteLock 是什么?
实现读写锁的分离,读锁是共享式,写锁是独占式. 读和读之间不会互斥,写和读、写和写之间才互斥,提升了读写的性能.


2、ES
es的倒排索引是什么?
通过分词策略,形成词和文章的映射关系表,这种词典+映射表(倒排表)即为倒排索引,有了倒排索引,就能O(1)时间复杂度来检索文章了,极大提高效率。
倒排索引底层实现是基于 FST(Finite State Transducer)数据结构. FST的优点: 占用空间小(通过对词典中单次的前缀、后缀的重复利用,压缩存储空间)、查询速度快
--------------------------------------------------------------------------------------------------------------------------------------
es游标查询Scroll用法?
GET /old_index/_search?scroll=1m
{
"query": { "match_all": {}},
"sort" : ["_doc"],
"size": 1000
}
保持游标查询窗口一分钟。
关键字 _doc 是最有效的排序顺序。
游标查询每次返回一个新字段 _scroll_id(base64编码的字符串),每次我们做下一次游标查询,我们必须把前一次查询返回的字段 _scroll_id 传递进去,
当没有更多的结果返回的时候,我们就处理完所有匹配的文档了。


3、消息队列 (kafka)
Consumer是推(push)模式还是拉(pull)模式?
拉模式,即consumer从broker拉取消息

拉模式和推模式 各自的利弊?
拉模式:
利:consumer可以自主决定是否批量从broker拉取消息, 可以根据自己的消费能力来决定消费策略.
弊:如果broker没有可供消费的消息,会导致consumer不断在循环中轮询,直到有新消息到达broker.
kafka为了避免这点,有个参数可以让consumer阻塞直到新消息到达.

推模式:
利:由broker决定消息推送的速率. 致力于让consumer以最大的速率最快速的消费消息.
弊:
(1)、对于不同消费速率的consumer就不太好处理了,当broker推送的速率远大于consumer消费的速率时,consumer就可能要崩溃了.
(2)、必须在不知道下游consumer消费能力和消费策略的情况下决定是立即推送还是缓存之后批量推送,如果为了避免consumer崩溃而采用较低的推送速率,将可能导致一次只推送较少的消息而造成浪费.
--------------------------------------------------------------------------------
为什么要使用MQ, MQ的应用场景?
解耦: 生产端和消费端不需要相互依赖
流量削峰: 在访问量剧增的情况下,应用仍需要继续发挥作用,但是这样突发的巨大流量不是常见的,使用消息队列能关使关键组件顶住突发的访问压力,使系统不会因为突发的超负荷的请求儿崩溃不可用.
异步: 生产端不需要等待消费端响应,直接返回,提高了响应时间和吞吐量

4、redis
redis 用过pipline(管道)么?有什么用?
可以将要执行的多个redis命令添加到pipline中,发起一次.pipline()调用,请求一次redis完成批量命令执行.

redis 可以保证数据的强一致性么?
不可以,所以redis集群可能会有丢失写操作.


-------------------------------------
5、零拷贝
一个i/o场景: 调用read读取文件,转成字节数组,然后调用write方法,将字节流写到socket。这个过程中os底层发生了几次拷贝过程?
read调用 用户态->内核态 一次变化,第一次拷贝开始,引擎从磁盘读取文件,并将数据放到内核缓冲区.
将内核缓冲区的数据拷贝到用户缓冲区,发生第二次数据拷贝。同时,内核态->用户态.
调用write方法,发生第三次拷贝,系统将用户缓冲区的数据拷贝到socket缓冲区. 此时又发生一次用户态->内核态的上下文切换.
第四次拷贝,数据异步的从socket缓冲区使用DMA引擎拷贝到网络协议引擎.
所以一共发生四次拷贝,3次上下文切换.

优化->零拷贝(减少上下文切换次数,减少拷贝次数)
mmap优化:
sendFile优化:


常用的零拷贝有 mmap 和 sendFile.
mmap适合小数据量读写,sendFile适合大文件传输
mmap需要4次上下文切换,3次数据拷贝; sendFile需要3次上下文切换,最少2次数据拷贝.
rocketMQ在消费消息时,使用了mmap. kafka使用了 sendFile. (kafka在客户端和broker进行数据传输时,会使用transferTo和transferFrom方法,对应linux的sendFile)

 

算法逻辑题:
有20瓶药丸,其中19瓶装有1克/粒的药丸,余下一瓶装有1.1克/粒的药丸。给你一台称重精准的天平,怎么找出比较重的那瓶药丸?天平只能用一次。
solution: 对每个药瓶进行编号,药瓶#1,药瓶#2....药瓶#20,然后每个药瓶取出各自编号粒药丸,进行称重,即#1取一粒,#2取两粒....#20取20粒.
如果都是1g,则总重是210g, (实际重量 - 210) / 0.1 得到的结果即为较重药瓶的编号.

posted on 2019-10-08 09:40  初来乍到的小菜鸟  阅读(537)  评论(0编辑  收藏  举报