百度贴吧的面试,还挺简单的

教育   2025-01-01 08:15   湖南  

欢迎点击下方👇关注我,记得星标哟~

文末会有重磅福利赠送

今天分享的是百度贴吧外包的面经,内容主要包括操作系统、go、计网、数据库以及缓存

1 自我介绍 ;2 项目难点

面试前一定要准备好回答这种问题的话术

3 进程与线程的概念与区别?协程是什么?

进程(Process)

定义:进程是操作系统进行资源分配和调度的基本单位,它包含了程序执行所需的一切信息,包括代码段、数据段、堆栈空间等。每个进程都有自己独立的地址空间,这意味着一个进程中的变量和其他资源对其他进程不可见。

特点

  • 独立性:每个进程都有自己的内存空间、文件描述符等资源。
  • 安全性:由于进程之间相互隔离,一个进程的崩溃不会影响到其他进程。
  • 开销较大:创建和销毁进程的代价相对较高,因为涉及到系统调用、内存分配等操作。
  • 通信复杂:进程间通信(IPC)需要通过特定机制实现,如管道、消息队列、共享内存等。

线程(Thread)

定义:线程是进程中更小的执行单元,它是 CPU 调度的基本单位。同一个进程内的多个线程共享该进程的资源,例如内存地址空间、文件描述符等,但每个线程有自己的栈和寄存器状态。

特点

  • 轻量级:相比进程,线程的创建和切换成本较低,因为它不需要像进程那样重新分配大量的资源。
  • 高效率:线程之间的通信更加直接高效,因为它们共享同一块内存区域。
  • 依赖于所属进程:线程不能脱离其所属的进程单独存在;如果进程结束,所有相关线程也会随之终止。
  • 并发性:多线程可以同时运行,提高应用程序的响应速度和吞吐量。

协程(Coroutine)

定义:协程是一种用户态下的轻量级线程,它允许开发者编写非阻塞的异步代码。与传统的线程不同,协程是由程序员显式控制其挂起和恢复的行为,而不是由操作系统调度。

特点

  • 协作式调度:协程之间的切换不是强制性的,而是基于程序逻辑,通常在一个协程主动让出控制权时才会发生切换。
  • 更低的开销:相比于线程,协程的创建和上下文切换更为廉价,因此可以在单个进程中创建成千上万个协程。
  • 简化编程模型:协程使得编写复杂的异步任务变得简单直观,特别是在处理 I/O 密集型工作时优势明显。
  • 语言支持:许多现代编程语言提供了原生或库级别的协程支持,如 Python 的 asyncio 和 Go 语言的 goroutines。

4 操作系统:查看进程占用端口的命令

  1. netstat (虽然逐渐被 ss 取代,但仍然广泛使用)

  • 查看所有监听端口及其对应的 PID:
    netstat -tulnpe | grep LISTEN
  • 查找特定端口的占用情况:
    netstat -tulnpe | grep :<port>
  • ss (推荐替代 netstat

    • 查看所有监听端口及其对应的 PID:
      ss -tulnp
    • 查找特定端口的占用情况:
      ss -tulnp | grep :<port>
  • lsof (List Open Files)

    • 查找特定端口的占用情况:
      lsof -i :<port>
    • 查找所有监听端口:
      lsof -i -P -n | grep LISTEN
  • fuser

    • 查找特定端口的占用情况:
      fuser <port>/tcp

    5 golang的调试工具常用哪些?

    1. Delve (dlv)

    • 概述:官方推荐的命令行调试器,支持断点、单步执行、变量检查等典型调试功能。
    • 特点:易于与 IDE 和编辑器集成(如 VSCode、GoLand),提供交互式调试体验。
  • fmt 和 log 包

    • 概述:通过打印日志信息来跟踪程序执行和变量状态。
    • 特点:简单直接,适合快速诊断问题;fmt 用于格式化输出,log 提供更高级的日志记录功能。
  • pprof

    • 概述:性能剖析工具,帮助分析 CPU 和内存使用情况。
    • 特点:内置支持,能够生成详细的性能报告,适用于性能调优和查找瓶颈。
  • trace

    • 概述:跟踪工具,用于可视化程序的执行流程,特别是 goroutine 的创建和调度。
    • 特点:有助于理解并发程序的行为,生成图形化的执行轨迹图。

    6 linux更改文档权限的命令

    更改权限:chmod

    • 数字模式:使用三位八进制数来设置权限。

      示例

      • 设置文件为所有者读写执行,组和其他人只读:
        chmod 744 文件名
      • 7 = 读+写+执行
      • 6 = 读+写
      • 5 = 读+执行
      • 4 = 只读
      • 2 = 只写
      • 1 = 只执行
      • 0 = 无权限
    • 符号模式:使用符号来增加或移除权限。

      操作符:

      示例

      • 给文件添加执行权限给所有者:
        chmod u+x 文件名
      • + = 添加权限
      • - = 移除权限
      • = = 设置权限
      • u = 用户(所有者)
      • g = 组
      • o = 其他
      • a = 所有(用户、组和其他)

    更改所有者:chown

    • 语法chown 新所有者[:新组] 文件名

      示例

      • 更改文件所有者为 user1
        sudo chown user1 文件名
      • 同时更改所有者和组:
        sudo chown user1:group1 文件名

    更改所属组:chgrp

    • 语法chgrp 新组 文件名

      示例

      • 更改文件所属组为 group1
        sudo chgrp group1 文件名

    递归应用:-R

    • 对目录及其内部文件和子目录递归地应用权限或所有权更改。

      示例

      • 递归更改目录及其内容的所有权:
        sudo chown -R user1 目录名

    7 http状态码有哪些?

    1xx:信息性

    • 表示请求已被接收,继续处理。

    2xx:成功

    • 200 OK:请求成功。
    • 201 Created:资源已创建。
    • 204 No Content:请求成功但无内容返回。

    3xx:重定向

    • 301 Moved Permanently:永久重定向。
    • 302 Found:临时重定向。
    • 304 Not Modified:资源未修改。

    4xx:客户端错误

    • 400 Bad Request:请求有误。
    • 401 Unauthorized:需要身份验证。
    • 403 Forbidden:禁止访问。
    • 404 Not Found:找不到资源。

    5xx:服务器错误

    • 500 Internal Server Error:服务器内部错误。
    • 502 Bad Gateway:无效响应从上游服务器。
    • 503 Service Unavailable:服务器暂时无法处理请求。
    • 504 Gateway Timeout:网关超时。

    8 tcl挥手与握手区别?

    握手 和 挥手 的主要区别在于它们的目的和发生的阶段:

    握手

    • 目的:建立连接。
    • 发生阶段:通信开始之前。
    • 过程:通过一系列消息交换确认双方准备好进行通信,并协商通信参数。例如,TCP 的三次握手确保了连接的可靠建立。

    挥手

    • 目的:断开连接并释放资源。
    • 发生阶段:通信结束之后。
    • 过程:通过一系列消息交换确保所有数据都已传输完毕,并安全地关闭连接。例如,TCP 的四次挥手确保了连接的优雅终止,并释放了占用的资源。

    总结

    • 握手 是为了建立可靠的连接,确保双方可以开始安全、有序的数据交换。
    • 挥手 是为了安全地关闭连接,确保所有数据都已正确传输,并且资源被适当释放。

    9 HTTP与HTTPS的区别?

    HTTP 和 HTTPS 的主要区别:

    1. 安全性

    • HTTP:数据以明文形式传输,这意味着任何在网络中截获的数据包都可以被读取,存在信息泄露的风险。
    • HTTPS:通过 SSL/TLS 加密技术确保数据的安全传输。所有通信都经过加密,防止中间人攻击(MITM),保护用户隐私和数据完整性。

    2. 端口

    • HTTP:默认使用端口 80 进行通信。
    • HTTPS:默认使用端口 443 进行通信。

    3. 加密机制

    • HTTP:没有内置的加密功能,所有数据直接在网络上传输。
    • HTTPS:使用 SSL(Secure Sockets Layer)或其后继者 TLS(Transport Layer Security)来加密客户端与服务器之间的通信。这包括:
      • 对称加密:用于快速加密大量数据。
      • 非对称加密:用于安全地交换对称加密所需的密钥。
      • 数字证书:验证服务器的身份,确保用户连接到的是合法的网站。

    4. 性能

    • HTTP:由于不需要加密和解密过程,理论上速度更快,但在现代网络环境中,这种差异通常不明显。
    • HTTPS:加密和解密操作会带来一定的计算开销,可能导致稍微慢一点的速度。然而,随着硬件加速和优化算法的发展,HTTPS 的性能影响已经大大减小。

    5. SEO 影响

    • HTTP:搜索引擎可能不会给纯 HTTP 网站同样的权重,因为缺乏安全性。
    • HTTPS:Google 等搜索引擎更倾向于推荐和支持 HTTPS 网站,认为它们提供了更好的用户体验和更高的安全性。

    总结

    • HTTP 适合于那些对安全性要求不高、仅提供静态内容或公开信息的简单网页。
    • HTTPS 是当今互联网的标准,广泛应用于电子商务、银行服务、社交媒体等各种涉及敏感数据传输的场合,确保了更高的安全性和用户信任。

    10 MVCC讲讲?

    多版本并发控制(MVCC)是一种用于数据库管理系统和事务内存的并发控制机制,其核心目标是提高并发性能,解决并发读写操作中的数据一致性问题。MVCC通过保存数据的历史版本来实现非阻塞读取,允许读写操作并行执行而不互相干扰。

    1. 隐藏列

    在MySQL的InnoDB存储引擎中,每一行记录都会隐式地包含以下几个字段:

    • DB_TRX_ID:最近修改这条记录的事务ID。
    • DB_ROLL_PTR:指向undo日志中的位置,用于回滚指针,可以找到该行之前的版本。
    • DB_ROW_ID:隐藏的主键,当表没有显式的主键时使用。

    2. Undo Log(回滚日志)

    • 当一个事务对某一行进行更新或删除时,并不会直接修改原始数据,而是创建一个新的版本并将旧版本的信息保存到undo日志中。
    • 这样做不仅支持了事务的回滚功能,还为MVCC提供了读取历史版本的能力。

    3. Read View(读视图)

    • 每个事务在开始时会生成一个Read View,它包含了当前系统中所有活跃事务的快照。
    • Read View主要用于确定哪些版本的数据是可以被当前事务看到的,哪些是不可见的。

    4. 可见性判断规则

    根据Read View中的信息,结合每行记录的DB_TRX_ID以及undo日志中的历史版本,按照如下规则判断某一版本是否对当前事务可见:

    • 如果记录的事务ID小于Read View中的最小活跃事务ID,则认为此版本是在当前事务之前提交的,因此是可见的。
    • 如果记录的事务ID大于等于Read View中的最大已分配事务ID,则认为此版本是在当前事务之后创建的,所以是不可见的。
    • 如果记录的事务ID位于上述两个范围之间,则需要检查该事务ID是否存在于Read View中的活跃事务列表中。如果存在,则表示这个版本是由尚未提交的事务产生的,因而不可见;否则就是已经提交的版本,可以看见。

    5. 版本链

    每当有新的更改发生时,都会产生新的版本,并通过DB_ROLL_PTR链接起来形成版本链。查询时,会从最新的版本开始沿链向下查找,直到找到满足可见性条件的第一个版本为止。

    11 理论上 索引可以加快查询,为什么不给全字段加上索引

    理论上,索引确实可以加快查询速度,但并不是所有字段都适合创建索引,也不应该为所有字段创建索引

    1. 性能影响

    • 写入性能下降:每当向表中插入、更新或删除数据时,数据库不仅需要更新实际的数据行,还需要更新相关的索引结构。这会增加额外的 I/O 操作和 CPU 开销,导致写入性能下降。

    • 索引维护成本:随着索引数量的增加,数据库在执行 DML(数据操作语言,如 INSERT, UPDATE, DELETE)语句时需要花费更多的时间来维护这些索引。

    2. 存储空间占用

    • 额外的磁盘空间:每个索引都会占用额外的磁盘空间。对于大表来说,过多的索引可能会显著增加存储需求,进而影响到备份、恢复等操作的成本和效率。

    3. 查询优化器复杂度

    • 选择最佳执行计划难度增加:当存在大量索引时,查询优化器需要考虑更多的选项来决定最优的查询路径。这可能导致查询优化过程变得更加复杂和耗时,并且有时反而会选择次优方案。

    12 索引失效场景

    索引失效是指在查询时,数据库引擎无法使用索引来加速查询,从而导致查询性能下降。以下是可能导致MySQL索引失效的一些常见场景:

    • 数据类型不匹配:当查询中的列与索引列的数据类型不一致时,可能会导致索引无法使用。
    • 函数操作:对索引列进行函数操作(如CONCATSUBSTRINGDATE_FORMAT等)会使索引失效。
    • 通配符前缀:使用通配符前缀(例如LIKE 'prefix%')可能会影响B-tree索引的有效性。
    • 使用OR条件:如果OR连接的子条件中至少有一个没有索引支持,则整个查询可能会导致索引失效。
    • 组合索引顺序不合理:查询中的列顺序应尽量与组合索引的列顺序相匹配,否则索引可能不会被有效利用。
    • 数据分布不均匀:若索引列的数据分布极不均匀,查询优化器可能会选择不使用索引以更快完成查询。
    • 隐式数据类型转换:查询中的数据类型与索引列的数据类型需要隐式转换时,可能导致索引失效。
    • 不满足最左匹配原则:对于多列组合索引,查询条件必须从索引最左边的列开始连续匹配,否则索引可能失效。
    • **使用SELECT ***:查询所有列的数据(非索引列)会降低索引的效率,因为非索引列不会走索引。

    13 讲讲缓存击穿、缓存穿透、缓存雪崩

    以下是这三个问题的概述:

    缓存穿透

    定义:缓存穿透指的是查询一个实际上不存在的数据。由于该数据既不在缓存中也不在数据库中,每次请求都会导致访问数据库,增加了数据库的负担。

    影响:如果大量不存在的数据被请求,将会导致大量的数据库查询,从而可能导致数据库性能下降甚至过载。

    解决方案

    • 对于确实不存在的数据,可以考虑将一个空结果或特定标志位(例如null)缓存一段时间,避免重复查询。
    • 采用布隆过滤器等数据结构,先判断数据是否存在再决定是否查询缓存或数据库。

    缓存击穿

    定义:缓存击穿是指某个热点key(高并发访问的数据)在某一时刻突然失效,此时所有的请求都会落到数据库上,造成瞬时的数据库压力骤增。

    影响:短时间内对数据库产生巨大压力,可能使数据库响应缓慢或直接宕机。

    解决方案

    • 使用带有过期时间的分布式锁,在获取锁之后再去加载数据并更新缓存,确保同一时间只有一个线程去加载数据。
    • 设置热点数据永不过期或者设置很长的过期时间,并通过定时任务主动刷新缓存。
    • 将缓存的过期时间随机化,防止多个缓存同时过期。

    缓存雪崩

    定义:缓存雪崩是指在某一个时间段内,缓存中的大量key集中过期,导致这些key对应的查询全部打到数据库上,造成数据库瞬间承受巨大压力。

    影响:数据库可能会因为突如其来的大量请求而无法正常工作,严重时会导致服务不可用。

    解决方案

    • 分散缓存的有效期,即给不同的缓存设置不同的有效期,避免所有缓存同时失效。
    • 建立多级缓存机制,如本地缓存+分布式缓存,以减轻单点故障带来的风险。
    • 提前预热缓存,在业务高峰期来临之前预先加载一些关键数据到缓存中。
    • 监控缓存命中率及数据库负载情况,及时预警和采取措施。

    早日上岸!

    我们搞了一个免费的面试真题共享群,互通有无,一起刷题进步。

    没准能让你能刷到自己意向公司的最新面试题呢。

    感兴趣的朋友们可以加我微信:wangzhongyang1993,备注:面试群。

    点击下方文章,看看他们是怎么找到好工作的!

    Go就业陪跑训练营,辅导到就业为止!

    Java就业陪跑训练营,辅导到就业为止!

    我们又出成绩啦!大厂Offer集锦!遥遥领先!

    王中阳
    公司技术总监,创办就业陪跑服务,辅导学员拿到600多个offer。专注程序员的就业辅导、简历优化、模拟面试等。
     最新文章