快手面试题目

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/caoxiaohong1005/article/details/83022858

快手面试总结

  • 一面
    • 算法
      跳台阶问题
    • 稳定且有上限的带宽条件下,超大文件从server传输到client端,选择一个tcp连接快,还是构建多个tcp连接
      考察点:tcp连接的滑动窗口+带宽受限
      • 局域网内,带宽受限时,每秒钟传输的信息量大小被限制,就算是多个tcp连接,也只是多个tcp传输的信息量和=单个tcp连接传输的信息量。
      • 公网上,可能由于tcp被阻塞断开连接,此时多条tcp连接要比单tcp连接更保险,所以此时多tcp连接可能效率更高。
    • 线程和进程的区别
    • 线程模型、线程状态切换
      从就绪、运行、阻塞到内核态和用户态的切换,几个方面自己讲了讲。
      • 分类:用户级线程、内核级线程
      • 用户级线程
        • 当线程在用户空间下实现时,OS对线程的存在一无所知,OS只能看到进程
        • 当一个线程完成了其工作或等待需要被阻塞时,其调用系统过程阻塞自身,然后将CPU交由其它线程
        • 这种模式的好处
          • 在用户空间下进行进程切换的速度 远快于 在操作系统内核中
          • 用户空间下实现线程使得程序员可以实现自己的线程调度算法
          • 由于操作系统不需要知道线程的存在,所以在任何操作系统上都能应用
        • 这种模式的缺点
          • 由于操作系统不知道线程的存在,因此当一个进程中的某一个线程进行系统调用时,比如缺页中断而导致线程阻塞,此时操作系统会阻塞整个进程
          • 造成编程困难,我们在写程序的时候必须仔细斟酌在什么时候应该让出CPU给别的线程使用
          • 假如进程中一个线程长时间不释放CPU,因为用户空间并没有时钟中断机制,会导致此进程中的其它线程得不到CPU而持续等待
      • 内核级线程
        • 这种模式下,操作系统知道线程的存在

        • 实现线程造成阻塞的运行时调用(System runtime call)成本会高出很多

        • 当一个线程阻塞时,操作系统可以选择将CPU交给同一进程中的其它线程,或是其它进程中的线程。而在用户空间下实现线程时,调度只能在本进程中执行,直到操作系统剥夺了当前进程的CPU

        • 这种模式的优点

          • 用户编程简单,用户程序员在编程的时候无需关心线程的调度,即无需担心线程什么时候会执行,什么时候会挂起
          • 如果一个线程执行阻塞操作,操作系统可以从容地调度另外一个线程执行。因为操作系统能监控所有线程。
        • 这种模式的缺点

          • 效率较低。因为线程在内核态实现,每次线程切换都需要陷入到内核,由操作系统来进行调度
          • 占用内核稀缺的内存资源
      • 混合模式-现在OS的实现方式
        • 用户态的执行系统负责进程内部线程在非阻塞时的切换
        • 内核态的操作系统负责阻塞线程的切换
        • 每个内核态线程可以服务一个或多个用户态线程
        • 在这种模式下,操作系统只能看到内核线程
    • mysql架构+这样设计的原因
    • redis项目中怎么用的
    • redis为什么设计成单线程的
    • mysql的事务,acid特性 ,宕机时正在处理的事务会如何?
      • 针对突然宕机的问题
        不会自动继续执行,不会自动直接回滚,但是可以人工手动选择继续执行或者直接回滚,依据是事务日志。
        事务开启时,事务中的操作,都会先写入存储引擎的日志缓冲中,在事务提交之前,这些缓冲的日志都需要提前刷新到磁盘上持久化,这就是人们口中常说的“日志先行”(Write-Ahead Logging)
      • 日志分为2种
        • redo log
          • 保障的是事务的持久性和一致性
          • 在系统启动的时候,就已经为redo log分配了一块连续的存储空间,以顺序追加的方式记录redo log,通过顺序io来改善性能
          • 所有的事务共享redo log的存储空间,它们的redo log按语句的执行顺序,依次交替的记录在一起
          • 如果数据库崩溃或者宕机,那么当系统重启进行恢复时,就可以根据redo log中记录的日志,把数据库恢复到崩溃前的一个状态。未完成的事务,可以继续提交,也可以选择回滚,这基于恢复的策略而定。
        • undo log
          • 保障了事务的原子性
          • 主要为事务的回滚服务
          • undo log记录了数据在每个操作前的状态,如果事务执行过程中需要回滚,就可以根据undo log进行回滚操作
      • redo log和undo log的过程分析
        • eg : 假设有2个数值,分别为A和B,值为1,2
          1 start transaction;
          2 记录 A=1 到undo log;
          3 update A = 3;
          4 记录 A=3 到redo log;
          5 记录 B=2 到undo log;
          6 update B = 4;
          7 记录B = 4 到redo log;
          8 将redo log刷新到磁盘
          9 commit
        • 在1-8的任意一步系统宕机,事务未提交,该事务就不会对磁盘上的数据做任何影响.
        • 如果在8-9之间宕机,恢复之后可以选择回滚,也可以选择继续完成事务提交,因为此时redo log已经持久化
        • 若在9之后系统宕机,内存映射中变更的数据还来不及刷回磁盘,那么系统恢复之后,可以根据redo log把数据刷回磁盘
    • 智力题
      两个同体积的糖罐和盐罐,里面分别装满了糖和盐。现在拿一个勺子从糖罐挖走一勺糖放到盐罐里,再从盐罐里挖走同样大小的一勺糖罐里面的东西(可以糖盐混合,不定)。问最终糖罐的盐质量百分比和盐罐的糖质量百分比谁大谁小?
      answer:一样。
  • 二面
    • 层序遍历变种,每层从右到左打印,空节点打印特殊字符
    • 悲观锁、乐观锁
      • 乐观锁
        • 乐观锁是指操作数据库时(更新操作),想法很乐观,认为这次的操作不会导致冲突,在操作数据时,并不进行任何其他的特殊处理(也就是不加锁),而在进行更新后,再去判断是否有冲突了.
        • innodb对乐观锁的实现是MVCC机制
        • 用于并发控制
      • 悲观锁
        • 在操作数据时,认为此操作会出现数据冲突,所以在进行每次操作时都要通过获取锁才能进行对相同数据的操作,这点跟java中的synchronized很相似.
        • 悲观锁需要耗费较多的时间
        • 两种实现
          • 排他锁(写锁)
            • 对于多个不同的事务,对同一个资源只能有一把锁
            • update、insert、delete语句会自动加排它锁
          • 共享锁(读锁)
            指的就是对于多个不同的事务,对同一个资源共享同一个锁
      • 行锁
      • 表锁
    • session和cookie的区别,如果浏览器禁用了cookie,怎么解决
      https://blog.csdn.net/caoxiaohong1005/article/details/79633849
    • JVM都了解什么内容
    • 并发和并行的区别
    • get post 的区别
      • get
        • 请注意,查询字符串(名称/值对)是在 GET 请求的 URL 中发送的
        • GET 请求可被缓存
        • GET 请求保留在浏览器历史记录中
        • GET 请求可被收藏为书签
        • GET 请求应在处理敏感数据时使用
        • GET 请求有长度限制 ,大多数浏览器通常都会限制url长度在2K个字节
        • GET 请求只应当用于取回数据
        • 只接受ASCII字符的参数的数据类型
        • get效率高
      • post
        • 查询字符串(名称/值对)是在 POST 请求的 HTTP 消息主体中发送的
        • POST 请求不会被缓存
        • POST 请求不会保留在浏览器历史记录中
        • POST 不能被收藏为书签
        • POST 请求对数据长度没有要求
        • POST支持多种编码方式
      • 为什么get比post效率高
        • **[最重要原因]**post在真正接受数据之前会先将请求头发送给服务器进行确认,然后才真正发送数据
          • post 请求过程
            1.浏览器请求tcp连接(第一次握手)
            2.服务器答应进行tcp连接(第二次握手)
            3.浏览器确认,并发送post请求头(第三次握手,这个报文比较小,所以http会在此时进行第一次数据发送)
            4.服务器返回100 continue响应
            5.浏览器开始发送数据
            6.服务器返回200 ok响应
          • get 请求过程
            1.浏览器请求tcp连接(第一次握手)
            2.服务器答应进行tcp连接(第二次握手)
            3.浏览器确认,并发送get请求头和数据(第三次握手,这个报文比较小,所以http会在此时进行第一次数据发送)
            4.服务器返回200 ok响应
        • get会将数据缓存起来,而post不会。
          ps:chrome下和firefox下如果检测到get请求的是静态资源,则会缓存,如果是数据,则不缓存,但是IE这个傻X啥都会缓存起来
        • post请求包含更多的请求头
        • post不能进行管道化传输
    • 智力题
      5L桶和3L桶,如何量出4L的水?
      写成程序怎么写?

猜你喜欢

转载自blog.csdn.net/caoxiaohong1005/article/details/83022858