面经-字节跳动-web后端开发实习生(一面凉经)

一面:55min

  • 自我介绍
  • 爬虫项目:

1. http常见的状态码

(1)200 OK:请求已正常处理

(2)204 No Content:请求处理成功,但没有任何资源可以返回给客户端

(3)206 Partial Content:是对资源某一部分的请求

(4)301 Moved Permanently:资源的uri已更新,你也更新下你的书签引用吧,永久性重定向

(5)302 Found:资源的URI已临时定位到其他位置了,姑且算你已经知道了这个情况了,临时性重定向

(6)304 Not Modified:资源已找到,但未符合条件请求

(7)400 Bad Request:服务器端无法理解客户端发送的请求,请求报文中可能存在语法错误

(8)401 Unauthorized:该状态码表示发送的请求需要有通过HTTP认证(BASIC认证,DIGEST认证)的认证信息

(9)403 Forbidden:不允许访问那个资源,该状态码表明对请求资源的访问被服务器拒绝了

(10)404 Not Found:服务器上没有请求的资源,路径错误等

(11)500 Internal Server Error:貌似内部资源出故障了

(12)503 Service Unavailable:抱歉,我现在正在忙着 

2. requests库:

(1)GET:请求指定的页面信息,并返回实体主体

(2)HEAD: 只请求页面的首部

(3)POST: 请求服务器接受所指定的文档作为对所标识的URI的新的从属实体

(4)PUT: 从客户端向服务器传送的数据取代指定的文档的内容

(5)DELETE: 请求服务器删除指定的页面

(6)模拟浏览器访问:有些网站访问时必须带有浏览器等信息,如果不传入headers就会报错

(7)证书验证:urllib3.disable_warnings()这条命令主要用于消除警告信息,将verify设置位False即可

(8)代理设置:在进行爬虫爬取时,有时候爬虫会被服务器给屏蔽掉,这时采用的方法主要有降低访问时间,通过代理ip访问

(9)超时设置:访问有些网站时可能会超时,这时设置好timeout就可以解决这个问题

(10)认证设置:如果碰到需要认证的网站可以通过requests.auth模块实现

  •  Python

1. 解释装饰器、生成器、迭代器的概念

2. Python并发:Python的多线程因为GIL全局锁的存在,利用不了多核,但它在IO密集型场合下依旧是并发的,效率高于单线程。但是如果是CPU密集型,多线程效率会大幅度下降,需要采用多进程替换。

  • 数据库

1. 数据库索引

(1)B+树是数据库实现索引的首选数据结构呢?——评价一个数据结构作为索引的指标就是在查找时IO操作的次数

(2)B+树非叶子节点只存储key,只有叶子结点存储value,叶子结点包含了这棵树的所有键值,每个叶子结点有一个指向相邻叶子结点的指针,这样可以降低B树的高度。

(3)B+树相比于B树的优势:(1)B+树单一节点存储更多的元素,使得查询的IO次数更少(2)B+树所有查询都要查找到叶子节点,查询效率更加稳定(3)B+树所有叶子节点形成有序链表,便于范围查询,更有利于对数据库的扫描

(4)索引字段要尽量的小:IO次数取决于b+数的高度h,h=log(m+1)N,数据量N一定的情况下,每个磁盘块数据项的数量m越大h越小,m=磁盘块的大小/数据项的大小,前者固定,后者越小越好

(5)索引的最左匹配特性(即从左往右匹配)

2. mysql索引:

(1)普通索引index,加速查找

(2)唯一索引:主键索引primary key和唯一索引unique

(3)联合索引:前三者对(id,name)复合数据项产生索引时

(4)其他:全文索引fulltext和空间索引spatial

3. 乐观锁和悲观锁

(1)乐观锁,简单地说,就是从应用系统层面上做并发控制,去加锁。

(2)实现乐观锁常见的方式:版本号version。实现方式,在数据表中增加版本号字段,每次对一条数据做更新之前,先查出该条数据的版本号,每次更新数据都会对版本号进行更新。在更新时,把之前查出的版本号跟库中数据的版本号进行比对,如果相同,则说明该条数据没有被修改过,执行更新。如果比对的结果是不一致的,则说明该条数据已经被其他人修改过了,则不更新,客户端进行相应的操作提醒。

(3)悲观锁,简单地说,就是从数据库层面上做并发控制,去加锁。

(4)悲观锁的实现方式有两种:共享锁(读锁)和排它锁(写锁)

(5)通过对比,发现for update的加锁方式无非是比lock in share mode的方式多阻塞了select...lock in share mode的查询方式,并不会阻塞快照读

(6)mysql InnoDB引擎默认的修改数据语句:update,delete,insert都会自动给涉及到的数据加上排他锁,select语句默认不会加任何锁类型。在Java中,synchronized的思想也是悲观锁。

(7)像乐观锁适用于写比较少的情况下(多读场景),即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果是多写的情况,一般会经常产生冲突,这就会导致上层应用会不断的进行retry,这样反倒是降低了性能,所以一般多写的场景下用悲观锁就比较合适。

  • 数据结构

1. 如何避免Hash碰撞

(1)开放地址法:开放定址法就是一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将记录存入

(2)再哈希法:当哈希地址发生冲突用其他的函数计算另一个哈希函数地址,直到冲突不在产生为止

(3)链地址法:将哈希表的每个单元作为链表的头结点,所有哈希地址为 i 的元素构成一个同义词链表。即发生冲突时就把该关键字链在以该单元为头节点的链表的尾部

(4)建立公共溢出区:将哈希表分为基本表和溢出表两部分,发生冲突的元素都放在溢出表中

原文地址:https://www.cnblogs.com/zhenxinruoshui/p/14014903.html