java/后端面试常见问题

操作系统

1. 进程和线程的区别?

  1. 进程是资源分配的基本单位,线程是调度的基本单位。
  2. 进程切换开销大,线程切换开销小。
  3. 线程共享进程资源,进程通信要IPC。

2. 什么是协程?

编程语言级别的线程,全程处于用户态

3. 进程同步的方法?

  1. 信号量机制和管程。

  2. 管程封装了条件变量和wai、signal操作,能更利于进程同步,一个时刻只有一个进程能使用管程。

4. 进程通信的方法?

  1. 共享存储,最快的IPC,信号量来实现同步。
  2. 管道,半双工通信。
  3. 命名管道,去除了管道只能在父子进程中使用的限制。
  4. 消息队列,不需要自己进行同步管理。
  5. 套接字。
  6. 信号量。

5. 用户态内核态?

  1. 内核程序管理硬件资源并向用户态提供系统调用。
  2. 用户程序可以通过陷入调用内核程序。

6. 同步异步

  1. 同步:顺序执行,必须等待到一个结果才会继续做下一件事
  2. 异步:遇到耗时操作可先做其他事情,其他事情做完了再处理耗时操作的结果

7. 五种IO模型

  1. 同步IO

    1. BIO

      进入系统调用,一直阻塞到内核把数据准备好,之后再把内核数据写到用户数据。(一个线程维护一个IO,不适合高并发)

    2. NIO

      内核在没有准备好数据时会返回错误码,准备好了才会处理,调用程序不会休眠,会不断轮询(用户态轮询),缺点是cpu消耗太高。

    3. select、poll、epoll

      1. select,是一个阻塞函数, 将文件描述符收集过来,交给内核,让内核帮我们判断哪一个fd有数据,有数据时select返回,遍历fd。。缺点fdset不可重用,用户到内核拷贝有时间消耗

      2. poll

        pollfd数组解决bitmap1024大小限制,置位revents使得FD可以重用

      3. epoll

        用户内核态共享,解决用户内核态拷贝开销,遍历复杂的O(1)

  2. 异步IO

    异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。

8. 共享内存需要注意什么?

​ 用信号量来实现同步互斥。

系统设计

1. 限流

  1. 令牌桶算法

    token流入速度确定,请求处理速度不确定。(可以处理突发流量)

  2. 漏桶算法

    请求流入速度不确定,处理速度是确定的。(可以平滑网络流量)

2. 一致性hash

//todo

3. JWT

//todo

计算机网络

1.TCP/IP分为几层?tcp属于哪一层?http属于哪一层?http基于tcp还是udp?

四层,传输层,应用层,tcp

2. TCP/UDP区别

TCP是面向连接的可靠的有流量控制拥塞控制的提供全双工通信,面向字节流的,每一条tcp连接只能是点对点的。

UDP是无连接的,尽最大努力交付的,面向报文,没有拥塞控制。

3. 三次握手、四次挥手

  1. 握手

    第一次:SYN=1,ACK=0,seq=x; 进入syn-sent状态

    第二次:SYN=1,ACK=1,ack=x+1,seq=y;进入syn-rcvd状态

    第三次:ACK=1,ack=y+1,seq=x+1;发出后客户端进入连接建立状态,服务端收到后进入连接建立状态。

    之所以三次握手,是要发送双方都知道对方的发送和接收能力都正常,还可以这样考虑,客户端发出第一次请求的报文延时,于是又发一次,后来受到确认如果这时建立连接传完数据并释放连接。这时第一次延时的报文到了服务端,服务端回确认,建立连接,但客户端不会发送数据,浪费资源。

    半连接队列:服务端回了确认之后就是syn-rcvd状态,回确认之后等第三次握手,等不到就重发一次,超时了就将该链接删除。

    初始化序号不唯一:一是可以防止在网络中被延迟的分钟又发送,导致错误的判断,还可以防止被猜到利用。

    第一二次握手不携带数据:疯狂发syn报文可以搞瘫服务器。

    SYN攻击:伪造IP发SYN包,服务器回复确认包不断重发,占用半连接队列资源。可以增加半连接数,缩短超时时间。

  2. 挥手

    第一次:FIN=1,seq=u 进入FIN-WAIT1状态。

    第二次:ACK = 1,seq=v,ack=u+1,进入CLOSE-WAIT,客户端受到后进入FIN-WAIT2状态。

    第三次:FIN=1。。服务端进入LAST-ACK状态,客户端收到后进入TIME-WAIT状态。

    第四次:ACK=1

    之所以四次握手,服务端收到FIN报文后可能还要发一些报文,只能先回一个确认,等所有报文发完后再发FIN。

    2MLS:如果只等一个MLS,ACK丢失,服务端重发FIN是收不到的所以要2个,ACK丢失,服务端重发FIN,客户端重置2MLS。还有一个原因,防止已失效的连接请求报文段出现在新的连接中。

4. http状态码有哪几类?

有五种类型,1~5

1xx 到目前为止都很正常,客户端可以继续发送请求,或者忽略这个响应。

2xx 成功

200 ok

204 no content 处理成功但返回无实体部分

206 partial content 范围实体内容

3xx 重定向

301 永久性重定向

304 not modified 请求资源未更新,可以使用缓存

4xx 客户端错误

403 请求被拒绝

404 not found

5xx 服务器错误

500 internal server error 服务器正在执行请求时发生错误

503 service unavaiable 服务器暂时处于超负载或正在停机维护,无法处理请求。

JAVA

1. HashMap和currentHashMap?

1. hashMap,entry数组,拉链法解决hash冲突,链表长度超过8会转换成红黑树
2. currentHashMap,并发安全,用分段锁,jdk1.8之后用CAS操作,失败时用synchronized。

2. 锁升级

//todo

3. 垃圾收集算法

  1. 标记清除
  2. 标记整理
  3. 复制

4. static、volatile

//todo

数据库

1. 慢sql是什么?

2. 索引

1. 聚簇索引:按照表的主键构建索引,索引文件和数据文件为一个文件,叶子节点存放数据,每张表只能有一个聚簇索引,若没有主键,innoDB会选非空的唯一索引替代,否则会创建隐式索引。聚簇索引将索引和数据在同一个B+树中,所以查找快。插入满,依赖插入顺序,所以会定义自增的主键。主键更新代价高。
2. 联合索引,a有序的条件下b有序,若没有a,b不会有序,索引会失效。

3. mysql引擎

  1. innodb 支持事务,行级锁
  2. myisam 不支持事务,表级锁

4. 事务是什么,有哪些操作,隔离级别默认是啥?

一组操作要么全部完成,要么全部失败,开启事务,设置保存点,回到保存点,默认隔离级别是read committed。

5. 可重复读解决了幻读吗?

不行。可以串行化或者MVCC+next-key locks可以解决。

6. redis的理解,应用场景?

内存型数据库,很快支持string、set、zset、hash、list这几种数据类型。

应用场景:todo

保证缓存与数据库一致性的方案:todo

7. hash、zset的实现?

Redis 的字典 dict 中包含两个哈希表 dictht,这是为了方便进行 rehash 操作。在扩容时,将其中一个 dictht 上的键值对 rehash 到另一个 dictht 上面,完成之后释放空间并交换两个 dictht 的角色。

zset是一个跳跃表。实现简单,插入快,因为不需要旋转来维护平衡。支持无锁操作。

7. bitmap

int a[] = {13, 8, 1, 34, 23, 56, 78, 91, 3, 0, 45, 87, 95};
int length = sizeof(a) / sizeof(int);

//将bitmap所有位设置为0
for (int i = 0; i < N; ++i) {
    clean(i);
}

//bitmap中将待排序数组中值所在的位设置为1
for (int i = 0; i < length; i++)
    set(a[i]);

//输出排序后的结果
for (int i = 0; i < N; ++i) {
    if (contain(i))
        printf("%d  ", i);
}

排序的算法思想:首先在byte[]中设置这个值的bit位为1,进而顺序遍历0 - N 查找这个值是否存在,那么就达到了排序的目的。另外需要注意的是Bitmap算法只能操作非重复数字的排序

上一篇:android Webview 实现js调用java代码实现Activity跳转


下一篇:C++ Primer Plus【复习笔记】-【分支语句和逻辑运算符】