Python 面试题大全系列(四)

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 今天继续分享 Python 相关的面试题,你已经准备好了吧!

综合篇(二),数据库和框架

1. 列举常见的数据库


关系型数据库:MySQL,Oracle,SQLServer,SQLite,DB2

非关系型数据库:MongoDB,Redis,HBase,Neo4j


2. 数据库设计三大范式


建立科学的,规范的的数据库是需要满足一些规范的,以此来优化数据数据存储方式,在关系型数据库中这些规范就可以称为范式。

第一范式:当关系模式 R 的所有属性都不能在分解为更基本的数据单位时,称 R 是满足第一范式的,简记为 1NF。

关系模式R的所有属性不能再分解

第二范式:如果关系模式 R 满足第一范式,并且 R 的所有非主属性都完全依赖于 R 的每一个候选关键属性,称 R 满足第二范式,简记为 2NF。

非主属性都要依赖于每一个关键属性

三范式:设 R 是一个满足第一范式条件的关系模式,X 是 R 的任意属性集,如果 X 非传递依赖于 R 的任意一个候选关键字,称 R 满足第三范式,简记为 3NF。

数据不能存在传递关系,即每个属性都跟主键有直接关系而不是间接关系


3. 什么是数据库事务


事务(Transaction)是并发控制的基本单位。所谓的事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。

在关系数据库中,一个事务可以是一条 SQL 语句、一组 SQL 语句或整个程序。

四个属性:原子性,一致性,隔离性和持久性。


4. MySQL 索引种类


MySQL 目前主要有以下几种索引类型:

  1. 普通索引
  2. 唯一索引
  3. 主键索引
  4. 组合索引
  5. 全文索引


5. 数据库设计中一对多和多对多的应用场景


一对一关系示例:

一个学生对应一个学生档案材料,或者每个人都有唯一的身份证编号。

一对多关系示例:

一个学生只属于一个班,但是一个班级有多名学生。

多对多关系示例:

一个学生可以选择多门课,一门课也有多名学生。


6. 简述触发器、函数、视图、存储过程


触发器:触发器是一个特殊的存储过程,它是数据库在 insert、update、delete 的时候自动执行的代码块。

函数:数据库中提供了许多内置函数,还可以自定义函数,实现 sql 逻辑。

视图:视图是由查询结果形成的一张虚拟表,是表通过某种运算得到的一个投影

存储过程:把一段代码封装起来,当要执行这一段代码的时候,可以通过调用该存储过程来实现(经过第一次编译后再次调用不需要再次编译,比一个个执行 sql 语句效率高)


7. 常用 SQL 语句


DML(数据操作语言)

  • SELECT - 从数据库表中获取数据
  • UPDATE - 更新数据库表中的数据
  • DELETE - 从数据库表中删除数据
  • INSERT INTO - 向数据库表中插入数据

DDL(数据定义语言)

  • CREATE DATABASE - 创建新数据库
  • ALTER DATABASE - 修改数据库
  • CREATE TABLE - 创建新表
  • ALTER TABLE - 变更(改变)数据库表
  • DROP TABLE - 删除表
  • CREATE INDEX - 创建索引(搜索键)
  • DROP INDEX - 删除索引


8. 主键和外键的区别


定义主键和外键主要是为了维护关系数据库的完整性

主键是能确定一条记录的唯一标识。不能重复,不允许为空。

外键用于与另一张表关联。是能确定另一张表记录的字段,用于保持数据的一致性。


主键 外键 索引
定义 唯一标识一条记录,不能重复,不允许为空 表的外键是另一表的主键,外键可以重复,可以是空值 该字段没有重复值,但可以有空值
作用 用来保证数据完整性 用来和其他表建立联系 提高查询排序的速度
个数 只能有一个 可有多个 可有多个


9. 如何开启 MySQL 慢日志查询


  1. 修改配置文件,然后重启服务生效
    在linux下,vim /etc/my.cnf,在[mysqld]内容项下增加:
    slow_query_log = ON
    long_query_time = 2  # 查询超过2秒的就会记录
  2. 命令行,但是重启服务后会失效
    SET GLOBAL slow_query_log = 'ON';
    SET GLOBAL long_query_time = 2;


10. MySQL 数据库备份命令


mysqldump -u 用户名 -p 数据库名 > 导出的文件名


11. char 和 varchar 的区别


char:存储定长数据很方便,CHAR 字段上的索引效率级高,必须在括号里定义长度,可以有默认值,比如定义 char(10)。

varchar:存储变长数据,但存储效率没有 CHAR 高,必须在括号里定义长度,可以有默认值。


12. 最左前缀原则


mysql 建立多列索引(联合索引)有最左前缀的原则,即最左优先,如:

如果有一个2列的索引(col1,col2),则已经对(col1)、(col1,col2)上建立了索引;

如果有一个3列索引(col1,col2,col3),则已经对(col1)、(col1,col2)、(col1,col2,col3)上建立了索引;


13. 无法命中索引的情况


  1. 使用or关键字会导致无法命中索引
  2. 左前导查询会导致无法命中索引,如 like '%a' 或者 like '%a%'
  3. 单列索引的索引列为 null 时全值匹配会使索引失效,组合索引全为 null 时索引失效
  4. 组合索引不符合左前缀原则的列无法命中索引,如我们有4个列 a、b、c、d,我们创建一个组合索引 INDEX(a,b,c,d),那么能命中索引的查询为 a,ab,abc,abcd,除此之外都无法命中索引
  5. 强制类型转换会导致索引失效
  6. 负向查询条件会导致无法使用索引,比如 NOT IN,NOT LIKE,!= 等
  7. 如果 mysql 估计使用全表扫描要比使用索引快,则不使用索引


14. 数据库读写分离


读写分离,就是将数据库分为了主从库,一个主库用于写数据,多个从库完成读数据的操作,主从库之间通过某种机制进行数据的同步,是一种常见的数据库架构。


15. 数据库分库分表


数据库水平切分,是一种常见的数据库架构,是一种通过算法,将数据库进行分割的架构。一个水平切分集群中的每个数据库,通常称为一个“分片”。每一个分片中的数据没有重合,所有分片中的数据并集组成全部数据。

水平切分分为库内分表和分库分表,是根据表内数据内在的逻辑关系,将同一个表按不同的条件分散到多个数据库或多个表中,每个表中只包含一部分数据,从而使得单个表的数据量变小,达到分布式的效果。


16. redis 和 memcached 比较


  • redis 和 memcached 都是将数据存放在内存中,都是内存数据库。不过 memcached 还可用于缓存其他东西,例如图片、视频等等。
  • redis 不仅仅支持简单的 k/v 类型的数据,同时还提供 list,set,hash 等数据结构的存储。
  • 分布式设定, 都可以做一主多从或一主一从 。
  • 存储数据安全,memcached 挂掉后,数据完全丢失;redis 可以定期保存到磁盘(持久化)。
  • 灾难恢复,memcached 挂掉后,数据不可恢复; redis 数据丢失后可以通过 aof 恢复。


17. redis中数据库默认是多少个 db 及作用


redis 默认有16个数据库,每个数据库中的数据都是隔离的,这样,在存储数据的时候,就可以指定把不同的数据存储到不同的数据库中。

且只有单机才有,如果是集群就没有数据库的概念。


18. redis 有哪几种持久化策略


RDB 持久化:是将 Reids 在内存中的数据库记录定时 dump 到磁盘上的持久化

AOF(append only file)持久化:将 Reids 的操作日志以追加的方式写入文件


19. redis 支持的过期策略


通用的三种过期策略

  1. 定时删除
    在设置 key 的过期时间的同时,为该 key 创建一个定时器,让定时器在 key 的过期时间来临时,对 key 进行删除
  2. 惰性删除
    key 过期的时候不删除,每次从数据库获取 key 的时候去检查是否过期,若过期,则删除,返回 null。
  3. 定期删除
    每隔一段时间执行一次删除过期 key 操作

redis 采用惰性删除+定期删除策略


20. 如何保证 redis 中的数据都是热点数据


限定 Redis 占用的内存,Redis 会根据自身数据淘汰策略,加载热数据到内存。

所以,计算一下所有热点数据大约占用的内存,然后设置一下 Redis 内存限制即可。


21. Python 操作 redis


使用 redis 第三方库来操作

import redis
# 创建一个 redis 连接池
def redis_conn_pool():
    pool = redis.ConnectionPool(host='redis-host', port=redis-port,
                                decode_responses=True, password='redis-pwd')
    r = redis.Redis(connection_pool=pool)
    return r


22. 基于 redis 实现发布和订阅


订阅者

if __name__ == "__main__":
     conn = redis.Redis(host='',
                        port=12143, password='')
     ps = conn.pubsub()
     ps.subscribe('chat')  # 从 chat 订阅消息
     for item in ps.listen():  # 监听状态:有消息发布了就拿过来
         if item['type'] == 'message':
             print(item)
            print(item['channel'])
            print(item['data'])

发布者

if __name__ == "__main__":
     number_list = ['300033', '300032', '300031', '300030']
     signal = ['1', '-1', '1', '-1']
     pool = redis.ConnectionPool(host='redis-12143.c8.us-east-1-3.ec2.cloud.redislabs.com', port=12143,
                                 decode_responses=True, password='pkAWNdYWfbLLfNOfxTJinm9SO16eSJFx')
    r = redis.Redis(connection_pool=pool)
     for i in range(len(number_list)):
         value_new = str(number_list[i]) + ' ' + str(signal[i])
         print(value_new)
        r.publish("chat", value_new)


23. 如何高效的找到 redis 中的某个 KEY


import redis
con = redis.Redis()
con.keys(pattern='key*') # *代表通配符


24. 基于 redis 实现先进先出、后进先出及优先级队列


class Zhan:
     def __init__(self,conn):
         self.conn = conn
     def push(self,val):
         self.conn.rpush('aaa',val)
     def pop(self):
        return self.conn.rpop('aaa')
 class Dui:
    def __init__(self,conn):
        self.conn = conn
    def push(self,val):
        self.conn.rpush('bbb',val)
    def get(self):
        return self.conn.lpop('bbb')
class Xu:
    def __init__(self,conn):
        self.conn = conn
    def push(self,val,count):
        self.conn.zadd('ccc',val,count)
    def get(self):
        a = self.conn.zrange('ccc', 0, 0)[0]
        self.conn.zrem('ccc', a)
        return a


25. redis 如何实现主从复制


在从服务器中配置 SLAVEOF 127.0.0.1 6380 # 主服务器 IP,端口


26. 循环获取 redis 中某个非常大的列表数据


def list_iter(name):
    """
   自定义redis列表增量迭代
    :param name: redis中的name,即:迭代name对应的列表
    :return: yield 返回 列表元素
    """
    list_count = r.llen(name)
    for index in xrange(list_count):
        yield r.lindex(name, index)


27. redis 中的 watch 的命令的作用


watch 用于在进行事务操作的最后一步也就是在执行 exec 之前对某个 key 进行监视,如果这个被监视的 key 被改动,那么事务就被取消,否则事务正常执行。


28. redis 分布式锁


为 redis 集群设计的锁,防止多个任务同时修改数据库,其本质就是为集群中的每个主机设置一个会超时的字符串,当集群中有一半多的机器设置成功后就认为加锁成功,直至锁过期或解锁不会有第二个任务加锁成功。


29. http 协议


超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。HTTP 是一个客户端和服务器端请求和应答的标准。客户端是终端用户,服务器端是网站。一般由 HTTP 客户端发起一个请求,建立一个到服务器指定端口(默认是80端口)的 TCP 连接,HTTP 服务器则在那个端口监听客户端发送过来的请求,并给与响应。


30. uwsgi,uWSGI 和 WSGI 的区别


WSGI:全称是 Web Server Gateway Interface,是一种描述 web server 如何与 web application 通信的规范。django,flask 等都遵循该协议。

uwsgi:是服务器和服务端应用程序的一种协议,规定了怎么把请求转发给应用程序和返回; uwsgi 是一种线路协议而不是通信协议,在此常用于在 uWSGI 服务器与其他网络服务器的数据通信。

uWSGI:是一个 Web 服务器,它实现了 WSGI 协议、uwsgi、http 等协议。Nginx 中 HttpUwsgiModule 的作用是与 uWSGI 服务器进行交换。


31. HTTP 状态码


1xx: 信息

2xx:成功

3xx:重定向

4xx:客户端错误

5xx:服务器错误


32. HTTP常见请求方式


GET,POST,PUT,DELETE,PATCH 等


33. 响应式布局


响应式布局是 Ethan Marcotte 在2010年5月份提出的一个概念,简而言之,就是一个网站能够兼容多个终端——而不是为每个终端做一个特定的版本。


34. 实现一个简单的 AJAX 请求


AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。

AJAX = 异步 JavaScript 和 XML

$(function(){
    $('#send').click(function(){
          $.ajax({
             type: "GET",
              url: "test.json",
              data: {username:$("#username").val(), content:$("#content").val()},
              dataType: "json",
              success: function(data){
                          $('#resText').empty();   //清空resText里面的所有内容
                         var html = ''; 
                         $.each(data, function(commentIndex, comment){
                               html += '<div class="comment"><h6>' + comment['username']
                                         + ':</h6><p class="para"' + comment['content']
                                        + '</p></div>';
                         });
                         $('#resText').html(html);
                      }
         });
    });
});


35. 同源策略


同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。

如果两个页面的协议,端口(如果有指定)和主机都相同,则两个页面具有相同的源。我们也可以把它称为“协议/主机/端口 tuple”,或简单地叫做“tuple". ("tuple" ,“元”,是指一些事物组合在一起形成一个整体,比如(1,2)叫二元,(1,2,3)叫三元)


36. 什么是 CORS


CORS 全称是跨域资源共享(Cross-Origin Resource Sharing),是一种 AJAX 跨域请求资源的方式,支持现代浏览器。


37. 什么是 CSRF


CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。


38. 前端实现轮询、长轮询


轮询

var xhr = new XMLHttpRequest();
    setInterval(function(){
        xhr.open('GET','/user');
        xhr.onreadystatechange = function(){
        };
        xhr.send();
    },1000)

长轮询

    function ajax(){
        var xhr = new XMLHttpRequest();
        xhr.open('GET','/user');
        xhr.onreadystatechange = function(){
              ajax();
        };
        xhr.send();
    }


39. 简述 MVC 和 MTV


所谓 MVC 就是把 web 应用分为模型(M),控制器(C),视图(V)三层,他们之间以一种插件似的,松耦合的方式连接在一起。

模型负责业务对象与数据库的对象(ORM),视图负责与用户的交互(页面),控制器(C)接受用户的输入调用模型和视图完成用户的请求。

Django 中的 MTV 模式:Model(模型):负责业务对象与数据库的对象(ORM),Template(模版):负责如何把页面展示给用户,View(视图):负责业务逻辑,并在适当的时候调用 Model 和 Template,本质上与 MVC 相同。


40. 接口的幂等性


接口幂等性就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。


41. Flask 框架的优势


简洁,轻巧,扩展性强,自由度高。


42. 什么是 ORM


ORM 的全称是 Object Relational Mapping,即对象关系映射。它的实现思想就是将关系数据库中表的数据映射成为对象,以对象的形式展现,这样开发人员就可以把对数据库的操作转化为对这些对象的操作。


43. PV、UV 的含义


PV:是(page view)访问量,页面浏览量或点击量,衡量网站用户访问的网页数量。在一定统计周期内用户每打开或刷新一个页面就记录1次,多次打开或刷新同一页面则浏览量累计。

UV:是(Unique Visitor)独立访客,统计一段时间内访问某站点的用户数(以cookie为依据)。


44. supervisor 的作用


supervisor 管理进程,是通过 fork/exec 的方式将这些被管理的进程当作 supervisor 的子进程来启动,所以我们只需要将要管理进程的可执行文件的路径添加到 supervisor 的配置文件中即可。


45. 使用 ORM 和原生 SQL 的优缺点


优点:

  • 方便的使用面向对象,语句清晰;
  • 有效的防止 SQL 注入;
  • 方便动态构造语句,对于不同的表的相同操作采用多态实现更优雅;
  • 一定程度上方便重构数据层
  • 方便设置设置钩子函数

缺点:

  • 不太容易处理复杂查询语句
  • 性能较直接用 SQL 差


46. 列举一些 django 的内置组件


  • Admin 组件:是对 model 中对应的数据表进行增删改查提供的组件
  • model 组件:负责操作数据库
  • form 组件:生成 HTML 代码;数据有效性校验;校验信息返回并展示
  • ModelForm 组件:用于数据库操作,也可用于用户请求的验证


47. 列举 Django 中执行原生 sql 的方法


  1. 使用 execute 执行自定义的 SQL
    直接执行 SQL 语句(类似于 pymysql 的用法)
from django.db import connection
cursor = connection.cursor()
cursor.execute("SELECT DATE_FORMAT(create_time, '%Y-%m') FROM blog_article;")
ret = cursor.fetchall()
print(ret)
  1. 使用 extra 方法:queryset.extra(select={"key": "原生的SQL语句"})
  2. 使用 raw 方法
  1. 执行原始 sql 并返回模型
  2. 依赖于 model 模型,多用于查询操作


48. cookie 和 session 的区别


cookie 是保存在浏览器端的键值对,可以用来做用户认证。

sesseion 是将用户的会话信息保存在服务端,key 值是随机产生的字符串,value 值是 session 的内容,依赖于 cookie 将每个用户的随机字符串保存到用户浏览器中。


49. beautifulsoup 模块的作用


BeautifulSoup 库是解析、遍历、维护“标签树”的功能库。

url = "http://www.baidu.com/"
request = requests.get(url)
html = request.content
soup = BeautifulSoup(html, "html.parser", from_encoding="utf-8")


50. Selenium 模块简述


Selenium 是模拟操作浏览器的库,可以根据我们的指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏,或者判断网站上某些动作是否发生等。

from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
print(browser.page_source) # browser.page_source 是获取网页的全部 html
browser.close()


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1天前
|
数据安全/隐私保护 Python
Python文件与目录操作:面试中的高频考点
【4月更文挑战第15天】本文介绍了Python文件和目录操作的面试重点,包括文件的读写、目录遍历及权限管理。强调了文件关闭、异常处理、特殊文件判断以及权限位和权限字符串的理解。提供了代码示例,如读写文件、遍历目录和更改文件权限,帮助读者在面试中表现出色。掌握这些技能将对编程求职之路大有裨益。
14 0
|
1天前
|
JSON 网络协议 API
Python网络编程面试题精讲
【4月更文挑战第15天】本文介绍了Python网络编程的面试重点,包括基础Socket编程、HTTP协议与requests库、异步编程与asyncio库。通过实例解析常见面试题,强调了非阻塞套接字、异常处理、HTTP状态码检查以及异步任务管理等关键点。提供代码示例帮助读者巩固概念,助力面试准备。
9 0
|
2天前
|
调度 Python
Python多线程、多进程与协程面试题解析
【4月更文挑战第14天】Python并发编程涉及多线程、多进程和协程。面试中,对这些概念的理解和应用是评估候选人的重要标准。本文介绍了它们的基础知识、常见问题和应对策略。多线程在同一进程中并发执行,多进程通过进程间通信实现并发,协程则使用`asyncio`进行轻量级线程控制。面试常遇到的问题包括并发并行混淆、GIL影响多线程性能、进程间通信不当和协程异步IO理解不清。要掌握并发模型,需明确其适用场景,理解GIL、进程间通信和协程调度机制。
18 0
|
2天前
|
API Python
Python模块化编程:面试题深度解析
【4月更文挑战第14天】了解Python模块化编程对于构建大型项目至关重要,它涉及代码组织、复用和维护。本文深入探讨了模块、包、导入机制、命名空间和作用域等基础概念,并列举了面试中常见的模块导入混乱、不适当星号导入等问题,强调了避免循环依赖、合理使用`__init__.py`以及理解模块作用域的重要性。掌握这些知识将有助于在面试中自信应对模块化编程的相关挑战。
17 0
|
2天前
|
UED Python
掌握Python异常处理:面试中的关键考点
【4月更文挑战第14天】本文探讨了Python异常处理在面试中的重要性,涵盖核心概念、常见问题和易错点。异常处理涉及异常、捕获、异常链、自定义异常、finally子句和raise语句。面试中应注意避免过于宽泛的异常捕获、忽视异常链、在finally中误用return、自定义异常设计不实用以及异常处理与业务逻辑混杂等问题。通过理解并解决这些问题,可提升代码健壮性和面试表现。
17 0
|
7天前
|
数据采集 机器学习/深度学习 数据可视化
数据科学面试准备:解决Python数据分析常见问答和挑战
【4月更文挑战第12天】本文介绍了Python数据分析面试中常见的问题和挑战,涉及Pandas、NumPy、Matplotlib等库的基础知识,以及数据预处理、探索性分析、可视化、回归分析和分类分析的方法。例如,使用Pandas处理缺失值和异常值,利用Matplotlib和Seaborn进行数据可视化,通过Scikit-learn进行回归和分类模型的构建。
|
1月前
|
Unix Java C++
最常见的 35 个 Python 面试题及答案(2018 版)
最常见的 35 个 Python 面试题及答案(2018 版)
52 0
|
1月前
|
存储 机器学习/深度学习 算法
python常用算法,新手必会,面试必出
python常用算法,新手必会,面试必出
37 0
|
3月前
|
存储 算法 Java
Python编程面试题及答案(20例)
Python编程面试题及答案(20例)
21 1
|
3月前
|
机器学习/深度学习 存储 人工智能
50道必备的Python面试题 (建议点赞)
50道必备的Python面试题 (建议点赞)
146 0