阿里Python后端1w+薪资面试真题!(附带准答案)offer
2019-10-23 本文已影响0人
PathonDiss
1. 列举 创建索引但是无法命中索引的8种情况
/*
小编是一名python开发工程师,这里有我自己整理了一套最新的python系统学习教程,
包括从基础的python脚本到web开发、爬虫、数据分析、数据可视化、机器学习等。
想要这些资料的可以关注小编。且我这有个学习Python基地,里面有很多学习资料,
感兴趣的+Q群:895817687
*/
- like '%xx'
select * from tb1 where name like '%cn';
- 使用函数
select * from tb1 where reverse(name) = 'wupeiqi';
- or
select * from tb1 where nid = 1 or email = 'seven@live.com';
特别的:当or条件中有未建立索引的列才失效,以下会走索引
select * from tb1 where nid = 1 or name = 'seven';
select * from tb1 where nid = 1 or email = 'seven@live.com' and name = 'alex'
- 类型不一致
如果列是字符串类型,传入条件是必须用引号引起来,不然...
select * from tb1 where name = 999;
- !=
select * from tb1 where name != 'alex'
特别的:如果是主键,则还是会走索引
select * from tb1 where nid != 123
- >
select * from tb1 where name > 'alex'
特别的:如果是主键或索引是整数类型,则还是会走索引
select * from tb1 where nid > 123
select * from tb1 where num > 123
- order by
select email from tb1 order by name desc;
当根据索引排序时候,选择的映射如果不是索引,则不走索引
特别的:如果对主键排序,则还是走索引:
select * from tb1 order by nid desc;
2. 数据库优化方案?
1. 避免全表扫描,首先应考虑在 where 及 orderby 涉及的列上建立索引。
2. 避免在 where 子句中对字段进行 null 值判断,导致引擎放弃使用索引而进行全表扫描
3. 避免在 where 子句中使用 != 或>操作符,引擎将放弃使用索引而进行全表扫描。
4. 避免在 where 子句中使用or 来连接条件
5. 慎用in 和 not, 可以用 exists 代替 in
6. 慎用 like 'XXX%',要提高效率,可以全文检索。
7. 应尽量避免在 where 子句中对字段进行表达式操作,如:
select id from t where num/2=100
应改为select id from t where num=100*2
8. 避免在where子句中对字段进行函数操作
select id from t where substring(name,1,3)='abc'
改为:
select id from t where name like 'abc%'
9. 在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。(索引的最左前缀原则)
10. 并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。
11. 索引不是越多越好,索引可以提高select 的效率,同时也降低 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引。
12. 任何地方都不要使用 select * from t ,用具体的字段列表代替“*”
13. 避免频繁创建和删除临时表,以减少系统表资源的消耗。
14. 在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。
15. 尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。
数据库中的数据在未进行分库分表的情况下,随着时间和业务的发展,库中的表会越来越多,表中的数据量也会越来越大,相应地,数据操作,增删改查的开销也会越来越大
16. 读写分离。通过数据库配置设置, mysql复制时,产生了多个数据副本(备库),为减少服务器压力,备库用于处理读操作,主库可同时处理读写。备库的复制是异步的,无法实时同步,读写分离的主要难点也在于备库上的脏数据。通常如果使用备库进行读,一般对数据的实时性要求不能太高。
17. 分库、分表。
分库:当数据库中的表太多,可以考虑将表分到不同的数据库
分表
水平分表:将一些列分到另一张表
垂直分表:将历史信息分到另一张表中,很久之前的记录少有查询
18. 利用缓存存储经常被查询的数据。利用redis、memcache
3. 1000w条数据,使用limit offset 分页时,为什么越往后翻越慢?如何解决?
答案一:
先查主键,在分页。
select * from tb where id in (
select id from tb where limit 10 offset 30
)
答案二:
按照也无需求是否可以设置只让用户看200页
答案三:
记录当前页 数据ID最大值和最小值
在翻页时,根据条件先进行筛选;筛选完毕之后,再根据limit offset 查询。
select * from (select * from tb where id > 22222222) as B limit 10 offset 0
如果用户自己修改页码,也可能导致慢;此时对url种的页码进行加密(rest framework )
4. redis中数据库默认是多少个db 及作用?
Redis默认支持16个数据库(可以通过配置文件支持更多,无上限),可以通过配置databases来修改这一数字。客户端与Redis建立连接后会自动选择0号数据库,不过可以随时使用SELECT命令更换数据库
Redis支持多个数据库,并且每个数据库的数据是隔离的不能共享,并且基于单机才有,如果是集群就没有数据库的概念。
5. 如果redis中的某个列表中的数据量非常大,如果实现循环显示每一个值?
通过scan_iter分片取,减少内存压力
scan_iter(match=None, count=None)增量式迭代获取redis里匹配的的值
# match,匹配指定key
# count,每次分片最少获取个数
r = redis.Redis(connection_pool=pool)
for key in r.scan_iter(match='PREFIX_*', count=100000):
print(key)