zoukankan      html  css  js  c++  java
  • 2020年Shopee面试问题整理

    ------------恢复内容开始------------
    个人的一二面记录:https://www.cnblogs.com/Jun10ng/p/12616409.html

    本文md文件在:https://github.com/Jun10ng/Gache/blob/master/Shopee面试问题整理.md
    给个start吧

    Shopee面试问题整理

    三握手四挥手 及其状态

    Go操作redis

    github 上面的rediGo

    什么是平衡二叉树

    编程:实现反转链表

    MySQL复合索引

    set的使用场景 有序set的使用场景

    有序且去重的场景

    1、 排行榜:有序集合经典使用场景。例如视频网站需要对用户上传的视频做排行榜,榜单维护可能是多方面:按照时间、按照播放量、按照获得的赞数等。

    2、用Sorted Sets来做带权重的队列,比如普通消息的score为1,重要消息的score为2,然后工作线程可以选择按score的倒序来获取工作任务。让重要的任务优先执行。

    反射 反射的弊端

    优点:运行期类型的判断,动态类加载,动态代理使用反射。

    缺点:性能是一个问题,反射相当于一系列解释操作,通知jvm要做的事情,性能比直接的java代码要慢很多。

    进程调度算法

    先来先服务 时间片轮转算法 短作业优先 最短剩余时间 高响应比 优先级

    进程间怎么通信

    管道 有名管道 套接字 消息队列 信号量

    线程间通信

    主要分为共享内存和消息传递

    volatile关键字 wait/notify机制

    事务隔离级别

    隔离级别 脏读(Dirty Read) 不可重复读 幻读(Phantom Read)

    未提交读(Read uncommitted) 可能 可能 可能

    已提交读(Read committed) 不可能 可能 可能

    可重复读(Repeatable read) 不可能 不可能 可能

    可串行化(Serializable ) 不可能 不可能 不可能

    MyISAM和InnoDB差别

    MyISAM不支持事务,InnoDB支持。MyISAM不支持行锁,只支持表锁,InnoDB支持行锁。

    InnoDB没有保存具体的行数,所以在统计行数的时候回扫描全表,MyISAM有保存。

    myisam的索引以表名+.MYI文件分别保存。innodb的索引和数据一起保存在表空间里。

    LINUX kill命令

    在Linux/unix下,中止一个Java进程有两种方式,一种是kill -9 pid,一种是kill -15 pill(默认)。

    SIGNKILL(9) 的效果是立即杀死进程. 该信号不能被阻塞, 处理和忽略

    SIGNTERM(15) 的效果是正常退出进程,退出前可以被阻塞或回调处理。并且它是Linux缺省的程序中断信号(默认是15)。

    TCP四次挥手的TIME_WAIT

    在第三次挥手的时候,服务端发FIN给客户端,然后客户端再发ACK命令给客户端,然后进入TIME_WAIT状态,2MSL之后,进入CLOSED状态,从客户端的角度来说,第四次挥手是为了告诉服务端,我收到了你的FIN信号,一切正常,等待2MSL是为了确保服务端收到了ACK,如果因为网络波动导致服务端没收到ACK,那么服务端会重传FIN信号。从服务端的角度老说,第四次挥手能确保客户端收到FIN信号。

    TCP UDP

    TCP面向连接,UDP是无连接的,TCP能通过校验和,重传控制等,保证可靠传输,UDP不能保证可靠传输,但UDP实时性高且UDP对资源需要的少。

    TCP 如何保证数据传输的可靠性

    校验和 确认应答+序列号 超时重传 流量控制 拥塞控制

    TCP3次握手的过程,为什么要3次 ,SYN攻击

    大文件为什么越下载越快?

    滑动窗口,慢启动算法,越传越快。

    前面说过,还有一个ssthresh(slow start threshold),是一个上限,当cwnd >= ssthresh时,就会进入“拥塞避免算法”。一般来说ssthresh的值是65535,单位是字节,当cwnd达到这个值时后,算法如下:

    1)收到一个ACK时,cwnd = cwnd + 1/cwnd

    2)当每过一个RTT时,cwnd = cwnd + 1

    这样就可以避免增长过快导致网络拥塞,慢慢的增加调整到网络的最佳值。很明显,是一个线性上升的算法。

    Innodb 自增主键

    上文讨论过InnoDB的索引实现,InnoDB使用聚集索引,数据记录本身被存于主索引(一颗B+Tree)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放,因此每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(InnoDB默认为15/16),则开辟一个新的页(节点)。

    如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页。这样就会形成一个紧凑的索引结构,近似顺序填满。由于每次插入时也不需要移动已有数据,因此效率很高,也不会增加很多开销在维护索引上。

    HTTP 无状态 无连接

    无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。为请求时建连接、请求完释放连接,以尽快将资源释放出来服务其他客户端,可以加KeepAlive弥补无连接的问题

    无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。即我们给服务器发送 HTTP 请求之后,服务器根据请求,会给我们发送数据过来,但是,发送完,不会记录任何信息。 可以通过Cookie和Session来弥补这个问题。

    cookie 是一种发送到客户浏览器的文本串句柄,并保存在客户机硬盘上,可以用来在某个WEB站点会话间持久的保持数据。

    Session的本质上也是cookie,但是不同点是存在服务器上的。这就导致,你如果使用cookie,你关闭浏览器之后,就丢掉Cookie了,但是如果关掉浏览器,重新打开之后,发现还有相应的信息,那就说明用的是Session。因为cookie是存在本地的,所以也会有相应的安全问题,攻击者可以去伪造他,填写相应的字段名,就能登录你的账户,还有如果cookie的有效期很长的话,也不安全。

    session 由服务器产生,对于客户端,只存储session id在cookie中。

    LRU算法是如何实现的?

    双向链表加 哈希表

    数组中出现次数最高的K个数

    map+优先队列

    先用map统计每个数的出现次数,然后维护 一个大小为K的优先队列(堆)。

    volatile 内存屏障

    CPU有可能会把相应代码的CPU指令进行一次重排序,这虽然能提高运行的效率,但是也可能会影响一些数据的可见性,而volatile通过 内存屏障 这个指令,来保证了相应代码块的执行顺序。内存屏障还会强制更新一次CPU缓存。加载最新的内容。

    快排的优化

    快排有三个步骤:

    1. 选择基准
    2. 分割操作
    3. 递归地对两个序列快速排列,直到序列为空或只有一个元素。

    所以可以针对这三个方面做优化

    选择基准:最理想的基准就是,每次划分都能分成登长的两个子序列。最坏的情况 就是基准是最大最小值。

    可以选的基准有:固定位置,随机位置,三数取中。

    三数取中是指 取 最左 最右 中间元素 三个数的中间值。

    其他优化方式

    1. 当排序序列分割到一定大小的时候,可以使用插入排序
    2. 如果有key相等的元素,可以聚在一起,下次排序的时候,就不用对相等的元素再排序了
    3. 优化递归操作
    4. 多线程

    Mysql 的 redo undo

    Undo日志记录某数据被修改前的值,可以用来在事务失败时进行回滚;Redo日志记录某数据块被修改后的值,可以用来恢复未写入data file的已成功事务更新的数据。

    死锁的四个条件 和预防

    互斥,不可剥夺,循环等待,请求和保持

    预防,检测,避免死锁,接触死锁

    银行家算法

    多路IO模型 NIO

    在多路复用IO模型中,会有一个线程(Java中的Selector)不断去轮询多个socket的状态,只有当socket真正有读写事件时,才真正调用实际的IO读写操作。因为在多路复用IO模型中,只需要使用一个线程就可以管理多个socket,系统不需要建立新的进程或者线程,也不必维护这些线程和进程,并且只有在真正有socket读写事件进行时,才会使用IO资源,所以它大大减少了资源占用。

    五种网络IO模型

    阻塞IO 非阻塞IO 多路IO复用,信号驱动IO(不常用),异步IO,

    前四种都是同步IO

    像listen()、send()、recv()这些接口都是阻塞的,一问一答型的。这就给网络编程带来了一个问题,如果在调用send的时候,线程将被阻塞,在此期间,无法执行任何运算或相应任何的网络请求。于是有了多路IO模型,一个socket可以多次accept多次,比如Java中的selcetor 不断轮询多喝socket的状态,只有当socket真正有读写事件的时候,才会调用实际的IO读写操作,还有想Golang里的select+多个channel,这样只需要一个线程就可以管理多个socket,能减少大量资源占用。

    非阻塞IO模型

    在非阻塞IO模型中,用户进程不需要主动询问对方是否准备好数据与否,比如进程发出read操作,如果对方没有准备好,会返回一个error,这表示对方没有准备好,但是进程并不会阻塞在这一步,而是继续执行,等对方准备好数据后,再去调用它。

    异步IO

    异步IO是真正意义上的非阻塞IO,用户进程发起read操作后,立刻就可以开始做其他事,而另一方面,当他收到一个异步请求时,会立即返回一个值,所以不会对用户进程产生任何阻塞,等数据准备完后,再将数据拷贝到用户内存,当这一切都完成后,再给用户进程发送一个signal,告诉他read操作完成了。

    非阻塞IO和异步IO的区别

    虽然非阻塞IO在大多时间内不会被阻塞,但是它要求进程去主动监察对方数据是不是准备好了,一旦准备好了,会再次要求进程调用接收函数将数据拷贝过来。而异步IO完全不管这些,就像吧IO操作外包掉,等他人做完再发信号通知,这个期间内,进程不要检查也不用主动的去拷贝。

    Golang里的Sync包

    互斥锁:Mutex,读写锁:RWMutex. WaitGoup,Cond实现一个条件变量,Once 使对象只执行一次。

    Java线程的6种状态及切换

    初始:新建一个线程对象

    运行:调用了start后就是运行状态

    阻塞:线程被锁阻塞

    等待,进入该状态的线程需要等待其他线程做出一些动作(通知或者唤醒

    超时等待:

    终止:

    虚拟内存

    虚拟内存使得应用程序认为它拥有连续的可用内存,这样一来,就在逻辑层面上扩大了内存容量。但是实际上,只是把比较常用的内存片段取出来了而已,还有部分资源是放在磁盘存储器上的。需要的时候再进行数据交换。

    调度方式有,分页式,段式,段页式。比较流行方式是段页式,他结合了前两者的优点,以页为单位替换,以段为单位使用。

    常见的替换替换算法有4种,随机算法,先进先出算法,LRU算法,最优算法。 比较常使用的是LRU算法,他在redis里也有使用,当redis的内存满了的时候就是使用LRU算法替换掉旧内存。

    ------------恢复内容结束------------

  • 相关阅读:
    linux部署docker镜像
    SpringBoot 定时任务篇
    POST形式 soapUI调用WebService的restful接口,传入json参数,并且返回json
    Java操作FTP工具类(实例详解)
    MyBatis逆向工程:根据table生成Model、Mapper、Mapper.xml
    Netty完成网络通信(二)
    NIO完成网络通信(一)
    MySQL5.6数据库8小时内无请求自动断开连接
    Eclipse集成Tomcat插件(特别简单)
    程序从sqlserver2008搬家到MySQL5.6
  • 原文地址:https://www.cnblogs.com/Jun10ng/p/12616416.html
Copyright © 2011-2022 走看看