美团一面测试开发岗   一、自我介绍   二、主要编程语言是python,问了一些python   1.装饰器简单介绍一下作用和怎么使用   2.元类了解吗,介绍一下怎么使用(答的不好)   3.python经典类和新式类区别是什么(答的不好)   4.python包和模块是什么?模块中必须有什么文件   三、计算机网络   1.TCP三次握手和四次握手介绍一下,区别是什么?   2.TCP三次握手,为什么不多一次,为什么不少一次?(回答不好)四、数据库   1.查询学生表中所有姓孟的同学   2.左连接右连接内连接和外连接   3.聚簇索引和非聚簇索引区别(忘记了)   聚簇索引:将数据存储与索引放到了一块,找到索引也就找到了数据   非聚簇索引:将数据存储于索引分开结构,索引结构的叶子节点指向了数据的对应行,myisam通过key_buffer把索引先缓存到内存中,当需要访问数据时(通过索引访问数据),在内存中直接搜索索引,然后通过索引找到磁盘相应数据,这也就是为什么索引不在key buffer命中时,速度慢的原因   4.数据库隔离级别   解释一下可重复读和幻读(我背的八股文,但是面试官觉得我解释不好)   五、HTTP:   get和post区别是什么?   1.逻辑题   A说:是B偷吃的,B说:是D偷吃的。C说;我没有偷吃。D说:B在撒谎! 其中有一人说了真话,谁偷吃了蛋糕?   逻辑题一开始我选c,面试官问我在想一想确定不,我就不坚定,bab说了遍,还是太不坚定了,被面试吓到了,太紧张了。   7.手写代码,我和面试官说不会nlogn,只会暴力,自己按照暴力来写。今天美团这个面试官有点严肃,把我搞紧张了,感觉他在做其他的事情       总结:可能因为面试官比较严肃,搞得我很紧张,说话说的太快了,我面试很大一个问题就是说话太快,然后可能就面试官听不清,下次面试一定要放松,说话语速放慢点,美团这次应该凉了       下面干货送给你们,面试之前整理的美高频率试题,我面不上,但是希望帮助到秋招的你们       美团高频面试题   一、redis缓存雪崩,穿透,击穿   缓存雪崩   缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重雪崩。   举个简单的例子:如果所有首页的Key失效时间都是12小时,中午12点刷新的,我零点有个秒杀活动大量用户涌入,假设当时每秒 6000 个请求,本来缓存在可以扛住每秒 5000 个请求,但是缓存当时所有的Key都失效了。此时 1 秒 6000 个请求全部落数据库,数据库必然扛不住,它会报一下警,真实情况可能DBA都没反应过来就直接挂了。此时,如果没用什么特别的方案来处理这个故障,DBA 很着急,重启数据库,但是数据库立马又被新的流量给打死了。这就是我理解的缓存雪崩   解决方法:   1.处理缓存雪崩简单,在批量往Redis存数据的时候,把每个Key的失效时间都加个随机值就好了,这样可以保证数据不会在同一时间大面积失效   2.如果Redis是集群部署,将热点数据均匀分布在不同的Redis库中也能避免全部失效的问题       缓存击穿   对于一些设置了过期时间的key,如果这些key可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。这个时候,需要考虑一个问题:缓存被“击穿”的问题,这个和缓存雪崩的区别在于这里针对某一key缓存,前者则是很多key。   缓存在某个时间点过期的时候,恰好在这个时间点对这个Key有大量的并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。   解决方法:   1.使用互斥锁   2.设置热点数据永不过期       缓存穿透   缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。在流量大时,可能DB就挂掉了,要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞。   解决方案:   1.采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。   2.在接口层增加校验,比如用户鉴权校验,参数做校验,不合法的参数直接代码Return,比如:id 做基础校验,id <=0的直接拦截等           二、布隆过滤器原理,应用缺点   原理:   将所有可能存在的数据采用多个哈希函数映射到一个足够大的bitmap中   应用:   1、网页爬虫对URL的去重,避免爬取相同的URL地址;   2、反垃圾邮件,从数十亿个垃圾邮件列表中判断某邮箱是否垃圾邮箱;   3、缓存击穿,将已存在的缓存放到布隆过滤器中,当黑客访问不存在的缓存时迅速返回避免缓存及DB挂掉。   缺点:   1.误算率是其中之一。随着存入的元素数量增加,误算率随之增加。   2.一般情况下不能从布隆过滤器中删除元素,如果需要删除,操作耗时且复杂       三、数据库隔离级别,怎么实现   事务的四大特性(ACID)   1. 原子性(atomicity): 事务的最小工作单元,要么全成功,要么全失败。   2. 一致性(consistency): 事务开始和结束后,数据库的完整性不会被破坏。   3. 隔离性(isolation): 不同事务之间互不影响,四种隔离级别为RU(读未提交)、RC(读已提交)、RR(可重复读)、SERIALIZABLE (串行化)。   4. 持久性(durability): 事务提交后,对数据的修改是永久性的,即使系统故障也不会丢失           事务的隔离级别   读未提交(Read UnCommitted/RU)   又称为脏读,一个事务可以读取到另一个事务未提交的数据。这种隔离级别岁最不安全的一种,因为未提交的事务是存在回滚的情况。       读已提交(Read Committed/RC)   又称为不可重复读,一个事务因为读取到另一个事务已提交的修改数据,导致在当前事务的不同时间读取同一条数据获取的结果不一致。       可重复读(Repeatable Read/RR)   又称为幻读,一个事物读可以读取到其他事务提交的数据,但是在RR隔离级别下,当前读取此条数据只可读取一次,在当前事务中,不论读取多少次,数据任然是第一次读取的值,不会因为在第一次读取之后,其他事务再修改提交此数据而产生改变。因此也成为幻读,因为读出来的数据并不一定就是最新的数据。       串行化(Serializable)   所有的数据库的读或者写操作都为串行执行,当前隔离级别下只支持单个请求同时执行,所有的操作都需要队列执行。所以种隔离级别下所有的数据是最稳定的,但是性能也是最差的。数据库的锁实现就是这种隔离级别的更小粒度版本。       MVCC 解决数据丢失   MVCC,多版本的并发控制,Multi-Version Concurrency Control。   使用版本来控制并发情况下的数据问题,在B事务开始修改账户且事务未提交时,当A事务需要读取账户余额时,此时会读取到B事务修改操作之前的账户余额的副本数据,但是如果A事务需要修改账户余额数据就必须要等待B事务提交事务。   MVCC使得数据库读不会对数据加锁,普通的SELECT请求不会加锁,提高了数据库的并发处理能力。借助MVCC,数据库可以实现读未提交可重复读等隔离级别,用户可以查看当前数据的前一个或者前几个历史版本,保证了ACID中的I特性(隔离性)。   四、左连接、右连接、内链接、外链接   基本定义:   left join (左连接):返回包括左表中的所有记录和右表中连接字段相等的记录。   right join (右连接):返回包括右表中的所有记录和左表中连接字段相等的记录。   inner join (等值连接或者叫内连接):只返回两个表中连接字段相等的行。   full join (全外连接):返回左右表中所有的记录和左右表中连接字段相等的记录       五、进程和线程区别   线程:   线程是CPU调度和分派的基本单位,它可以和同一进程下的其他线程共享全部资源   联系:   线程是进程中的一部分,一个进程可以有多个线程,但线程只能存在于一个进程中。   区别:   1. 根本区别:进程是操作系统资源调度的基本单位,线程是任务的调度执行的基本单位   2. 开销方面:进程都有自己的独立数据空间,程序之间的切换开销大;线程也有自己的运行栈和程序计数器,线程间的切换开销较小。   3. 共享空间:进程拥有各自独立的地址空间、资源,所以共享复杂,需要用IPC(Inter-Process Communication,进程间通信),但是同步简单。而线程共享所属进程的资源,因此共享简单,但是同步复杂,需要用加锁等措施。       六、测试用例设计方法有哪些   7种方法:等价类、边界值、场景设计法、判定表、因果图、正交法、错误猜测法   测试要从那些方面去思考问题:   功能测试:要实现些什么样的功能   界面测试:界面美观否兼容性如何   性能测试:压力测试,负载测试等等   安全测试:防止攻击,暴力破解,使用安全   易用性测试:是否好用,是否符合人体工程学   测试主要的四个阶段   1.测试计划设计阶段:产品立项之后,进行需求分析,需求评审,业务需求评级,绘制业务流程图。确定测试负责人,开始制定测试计划;   2.测试准备阶段:各成员编写测试用例、先小组内评审、后会议评审,测试样机和配件,测试工具。   3.测试执行阶段:负责人对测试任务分工,按计划执行测试过程,提测后,搭建QA环境,先执行冒烟测试,然后进行系统测试,提交bug,跟踪bug,直到被测软件达到测试需求要求,测试结束;   4.测试总结阶段:项目测试结束,负责人输出测试报告,对整个测试过程和版本质量做一个详细评估,确认是否可以上线;       七、python中元组和列表的区别   元组和列表的区别具体体现在以下几个方面:   1.列表属于可变序列,它的元素可以随时修改或删除;元素属于不可变序列,其中的元素不可以修改,除非将整个元组替换。   2.列表的list 类型提供了诸多方法,可帮助实现添加和修改列表元素,例如 append()、insert()、remove()等;而元组的 tuple 类型未提供类似的方法,无法修改或删除元素。   3.列表可以使用切换访问和修改列表中的元素;虽然元素支持使用切片,但只能用于访问元素,而不能对元素做修改;   虽然看起来,元组确实没有列表那么多功能,但是元组依旧是很重要的序列类型之一,元组的不可替代性体现在以下这些场景中:   1.元组作为很多内置函数和序列类型方法的返回值存在,也就是说,在使用某些函数或者方法时,它的返回值会元组类型,因此你必须对元组进行处理。   2.元组比列表的访问和处理速度更快,因此,当需要对指定元素进行访问,且不涉及修改元素的操作时,建议使用元组。   3.元组可以在映射(和集合的成员)中当做“键”使用,而列表不行           八、get和post区别,状态码   1、Get 是用来从服务器上获得数据,而 Post 是用来向服务器上传递数据。   2、GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。   3、对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据)。对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200。并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次   4、GET请求只能进行url编码,而POST支持多种编码方式   5、GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留   6、GET请求在URL中传送的参数是有长度限制的,而POST没有          九、cookies和session   Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器之后向同一服务器再次发起请求时被携带上,用于告知服务端两个请求是否来自同一浏览器。由于之后每次请求都会需要携带 Cookie 数据,因此会带来额外的性能开销(其是在移动环境下)    cookies用途   会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)   个性化设置(如用户自定义设置、主题等)   浏览器行为跟踪(如跟踪分析用户行为等)   session   除了可以将用户信息通过Cookie 存储在用户浏览器中,也可以利用 Session 存储在服务器端,存储在服务器端的信息更加安全。   Session 可以存储在服务器上的文件、数据库或者内存中。也可以将 Session 存储在 Redis 这种内存型数据库中,效率会更高   使用Session 维护用户登录状态的过程如下:   用户进行登录时,用户提交包含用户名和密码的表单,放入HTTP 请求报文中;   服务器验证该用户名和密码,如果正确则把用户信息存储到Redis 中,它在 Redis 中的 Key 称为 Session ID;   服务器返回的响应报文的Set-Cookie 首部字段包含了这个 Session ID,客户端收到响应报文之后将该 Cookie 值存入浏览器中;   客户端之后对同一个服务器进行请求时会包含该Cookie 值,服务器收到之后提取出 Session ID,从 Redis 中取出用户信息,继续之前的业务操作。            
点赞 6
评论 3
全部评论

相关推荐

纸鹰:对他说:“你好,我是百度JAVA。”
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务