python面试基础之知识点总结

回顾

可迭代对象、迭代器和生成器

  • 可迭代对象
1、定义 :可通过for循环迭代读取数据供我们使用的对象
2、本质 :可迭代对象通过__iter__()方法向我们提供一个迭代器
3、示例
name_list = ['紫衫龙王','金毛狮王','白眉鹰王','青翼蝠王']
name_iterator = name_list.__iter__() # 提供该可迭代对象(names_list)的迭代器
for name in name_iterator:
    print(name)
    
4、__iter__()函数与__next()__函数的作用是什么?
  1、__iter()__函数: 获取可迭代对象的迭代器
  2、__next()__函数:对迭代器不断使用__next()__函数来获取下一条数据,完成之后再次调用会抛出StopIteration异常
  • 迭代器
一个实现了__iter__()方法和__next__()方法的对象,就是迭代器
  • 生成器
1、函数中有yield关键字,就称为生成器
2yield作用
  1、保存当前运行状态(断点),然后暂停执行,即将生成器(函数)挂起
  2、将yield关键字后面表达式的值作为返回值返回,此时可以理解为起到了return的作用
3、如何启动生成器
  next():单纯的获取生成器中的一个值
4、示例
def f1():
    for i in range(3):
        yield i
g = f1()
print(next(g))

并发和并行

# 1. 并发
同时处理多个任务,内核在任务间不断地切换,达到好像多个任务同时被执行的效果,实际上每一时刻只有1个任务在占有CPU

# 2. 并行
一起执行,多个任务利用计算机的多核资源同时执行,此时多个任务之间是并行关系
# 3. 示例
在计算机系统中,并行和并发是同时存在的
计算机 :2核
任务   :QQ、微信、爱奇艺、英雄联盟、Chrome
并发   :这5个任务间存在着并发关系
并行   :第1(QQ)、第2(微信)

进程、线程、协程

# 1. 进程(运用场景:计算密集型)
程序的运行过程,是CPU分配资源的最小单位.(通信方式:管道,消息队列,共享内存,信号量,套接字等)

# 2. 线程(IO密集型)
最小执行单位,是系统分配内核的最小单位,由所属进程管理,一个进程可有多个线程.(通信方式:全局变量等)

# 3. 协程(yield是实现协程的关键字)
1、定义 :微线程,协程允许在不同的位置暂停或者开始执行,简单来说,协程就是可以暂停执行的函数
2、原理 :记录一个函数栈的上下文,进行协程的切换调度,当一个函数暂停执行时,会将上下文栈帧保存起来
3、本质 :单线程,资源消耗小,无须线程间切换的开销,无需加互斥锁
4、协程模块 :greenlet、gevent、... ...

基于协程的多任务并发?

import gevent

from gevent import monkey

# 修改阻塞行为
monkey.patch_socket()
from socket import socket


# 创建套接字

def server():
    server = socket()
    server.bind(("0.0.0.0", 8888))
    server.listen(5)
    print("等待客户端连接...")

    while True:
        # 等待客户端连接
        client, addr = server.accept()
        print(addr, "连接成功!")
        # 处理客户端请求
        # handle(client)
        #协程处理多并发,接收多个客户端连接
        gevent.spawn(handle,client)



def handle(client):
    while True:
        data = client.recv(1024)
        if not data:
            break
        print(data.decode())
        client.send("服务端收到消息!".encode())



if __name__ == '__main__':
    server()
from socket import socket

client=socket()
#连接服务器

client.connect(("172.88.2.175",8001))

while True:
    #发消息
    data=input("输入消息:")
    client.send(data.encode())
    #收消息
    reserver=client.recv(1024)
    print(reserver.decode())

Python中的那些锁

  • GIL锁

    # 1. GIL是什么? - CPython
    全局解释器锁,限制多线程同时执行,保证同一时间内只有一个线程在执行
    
    # 2. 作用
    同一进程中线程是数据共享,当各个线程访问数据资源时会出现竞争状态,即数据可能会同时被多个线程占用,造成数据混乱,这就是线程的不安全。而解决多线程之间数据完整性和状态同步最简单的方式就是加锁。GIL能限制多线程同时执行,保证同一时间内只有一个线程在执行
    
    # 3. 影响
    影响多线程效率
    
    # 4. 如何避免?
    1、用多进程 代替 多线程
    2、更换解释器
    
  • 互斥锁

    # 1. 问题原因
    多个线程共享数据时,如果数据不进行保护,则可能出现数据不一致现象
    # 2. 解决方案
    使用一把锁把代码保护起来,以牺牲性能换取代码的安全性
    # 3. 示例
    
  • 死锁

    多个进程/线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都无法进行下去,此时称系统处于死锁状态
    

产生死锁

"""
死锁
    1.线程1等待锁2
    2.线程2等待锁1
    3.产生死锁
"""
import time
from threading import Thread, Lock

lock1 = Lock()
lock2 = Lock()


# 线程1的事件
def f1():
    # lock1加锁
    lock1.acquire()

    print("线程1锁住了lock1")
    time.sleep(0.1)
    lock2.acquire()   #产生死锁,线程锁只能使用一次
    print("线程1锁住了lock2")
    lock2.release()

    lock1.release()

def f2():
    # lock2加锁
    lock2.acquire()

    print("线程2锁住了lock2")
    time.sleep(0.1)
    lock1.acquire()
    print("线程2锁住了lock1")
    lock1.release()

    lock2.release()


t1 = Thread(target=f1)
t2 = Thread(target=f2)
t1.start()
t2.start()
t1.join()
t2.join()

避免死锁

"""
死锁:
    1.线程1等待锁2
    2.线程2等待锁1
    3.产生死锁
    4.解决死锁
"""
import time
from threading import Thread, Lock

lock1 = Lock()
lock2 = Lock()


# 线程1的事件
def f1():
    # lock1加锁
    lock1.acquire()

    print("线程1锁住了lock1")
    time.sleep(0.1)
    while True:
        # 产生死锁,线程锁只能使用一次,导致阻塞
        if lock2.acquire(timeout=1):
            # 解决:设置超时时间,若在1秒内执行成功返回false,否则返回True
            print("线程1锁住了lock2")
            lock2.release()
            break
        else:
            lock1.release()


def f2():
    # lock2加锁
    lock2.acquire()

    print("线程2锁住了lock2")
    time.sleep(0.1)
    lock1.acquire()
    print("线程2锁住了lock1")
    lock1.release()

    lock2.release()


t1 = Thread(target=f1)
t2 = Thread(target=f2)
t1.start()
t2.start()
t1.join()
t2.join()

MySQL数据库

  • 数据库的三范式

    # 1. 三范式
      1NF:字段不可分
      2NF:有主键,非主键字段依赖主键
      3NF:非主键字段不能相互依赖
    
    # 2. 解释 
      1NF:原子性 字段不可再分,否则就不是关系数据库
      2NF:唯一性 一个表只说明一个事物
      3NF:每列都与主键有直接关系,不存在传递依赖
        
    # 3. 解释
    1NF:
      符合1NF:   用户ID  用户名  密码   姓名  电话
      不符合1NF:用户ID  用户名  密码   用户信息(包含姓名和电话)
    
    2NF:
      第二范式是在第一范式的基础之上建立起来的,满足第二范式前提必须满足第一范式,要求数据库表中的每个实例或行都能被唯一区分,建立主键
    
    3NF:
      1、满足第三范式必须先满足第二范式
      2、要求:属性不依赖于其他非主属性,简而言之为如果表的信息能被推导出来,就不能单独设计一个字段来存放
      3、如果一个实体中出现其他实体的非主属性,可以将这两个实体用外键关联,而不是将另一张表的非主属性直接写在当前表中
      
    表1:
    商品名称  价格  描述   有效期    分类     分类描述
    雪碧       32020   酒水饮料   碳酸饮料
    
    重新设计后:1:商品信息表(product)2:分类信息表(product_type)
    商品ID 商品名称 价格 描述 有效期   分类ID  分类     分类描述
      1     雪碧    32020     1   酒水饮料  碳酸饮料
     
    表3:中间表(product_type) - 做外键关联
    商品ID  分类ID
      1       1
    
  • 关联查询

    1、内连接(inner join)
    2、左外连接(left join):以左表为主显示查询结果
    3、右外连接(right join):以右表为主显示查询结果
    select xxx from 表1 inner|left|right join from 表2 on 条件;
    4、问题: 
        查询商品的名称(name)、价格(price)以及所属分类(type)???
        1.写出两条创建外键关联的语句
        创建商品表
        create table product(id int,name varchar(20),price decimal(6,2),comments varchar(50), time date)charset=utf8;
        创建类型表
        create table type(id int,type varchar(20),comments varchar(50))charset=utf8;
        中间表
        create table middle(pid int,tid int,foreign key(pid) references product(id) on delete cascade on update cascade,foreign key(tid)references type(id) on delete cascade on update cascade)charset=utf8;
    	插入数据
         insert into product values(1,"雪碧",3.29,"甜","2019-10-1"),(2,"可乐",6.73,"甜","2019-11-1"),(3,"威龙",8.96,"辣","2019-12-1");
        insert into type values(1,"酒水饮料","碳酸饮料"),(2,"零食","辣条");
        insert into middle values(1,1),(2,1),(3,2);
        2.查询商品名称以及所属类别
        select product.name,type.type from product inner join middle on product.id=middle.pid inner join type on middle.tid=type.id;
        3.查询所有的酒水饮料的商品
    select product.name,type.type from product inner join middle on product.id=middle.pid inner join type on middle.tid=type.id where type.type="酒水饮料";
    
  • 子查询

    把外层命令的查询结果作为内层查询的查询条件,就是一条查询语句中又嵌套了查询语句
    
  • 索引的优缺点及建立原则

    # 1. 优点
    1、提高检索速度
    2、唯一性索引可保证数据库表中每一行数据的唯一性
    3、使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间
    
    # 2.缺点
    1、创建索引和维护索引需要耗费时间;
    2、索引需要占用物理空间
    3、当对表进行增、删、改、的时候索引也要动态维护,这样就降低了数据的维护速度
    
    # 3. 建立原则
    1、频繁用来查询的字段上建立索引
    2、需要排序的字段上建立索引
    3、频繁使用条件判断的字段建立索引
    
    # 4.索引类型
    	普通索引,唯一索引,外键,主键
        组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并
    	全文索引:对文本的内容进行分词,进行搜索
    
  • 常用存储引擎及特点

    1、InnoDB:行级锁
    2、MyISAM:表级锁
    3、MEMORY:基于内存存储
    
  • MySQL数据库的优化

    1、存储引擎优化
    	1.读操作多:MYISAM
        2.写操作多:InnoDB
        3.临时表:MEMORY
    2、索引优化
    	经常查询,排序,条件判断的字段建立索引
    3、SQL语句优化
    	避免进行全表扫描
        查询指定字段:union all,between and
    
  • MySQL锁

    1、锁类型分类: 读锁、写锁    都属于悲观锁  
        读锁(共享锁):别人能读不能写
        写锁(排他锁):不能读也不能写
    2、锁粒度分类(自动加锁和释放锁,无需手动操作): 表级锁(锁对应表)、行级锁(锁对应表记录)
    
  • MySQL数据库重置密码

1、sudo -i
2/etc/init.d/mysql stop  #停止mysql服务
3、cd /etc/mysql/mysql.conf.d  #修改配置文件
4、vi mysqld.cnf  在 [mysqld]下添加如下语句后保存退出
   skip-grant-tables     #跳过授权表
5/etc/init.d/mysql start #启动mysql服务
6、命令行:mysql
7、切换库:use mysql
8、重置密码:
    update user set authentication_string=password('新密码') where user='root';
9、去掉配置文件中刚添加的 skip-grant-tables
10、重启mysql服务登录 /etc/init.d/mysql restart

基础面试题

  • Python2和Python3的区别

    # 1、编码格式区别
    python2: 默认编码格式是ascii,如果代码中使用中文需加如下声明:
    #!coding=utf-8 或者 #!-*- coding=utf-8 -*-
    python3: 默认编码为utf-8,并且引入了字节串
      
    # 2、函数区别
    1print
       python2中是关键字,print "hello world"
       python3中是函数,print()
    2input
       python2中有input()数值和raw_input()字符串
       python3中只有input()   都是字符串
    3range
       python2中range得到列表,xrange得到迭代器
       python3中只有range,得到迭代器
        
    # 3、运算修改
    python2中: 3/2=1  3.0/2=1.5
    python3中: 3/2=1.5 3.0/2=1.5
    python2中用浮点数相除得到浮点数,用整数相除得到整数.
    python3没有这些规则.
      
    # 4、数据类型
    python3中引入字节串,python3废弃python2的long类型,只有int
    python3中引用字节串,只有int类型长度无上限,只要内存够大
    # 5、语法变化
    1、异常: python2中异常和异常对象用逗号隔开
       except Exception,e
    2、python3中更加严格的缩进规则,在python2中tab和对应数量空格等同,python3中则不可以
    
  • 深拷贝和浅拷贝

    # 1、浅拷贝定义及特点
    1、定义: 对另外一个变量的内存地址引用的拷贝,这两个变量指向同一个内存地址的变量值
    2、特点: 
      公用一个值
      这两个变量的内存地址一样
      对其中一个变量值改变,另一个变量的值也会改变
    # 2、深拷贝定义及特点
    1、定义: 一个变量对另外一个变量的值拷贝
    2、特点:
      两个变量的内存地址不同
      两个变量各有自己的值,且互不影响 
      对其任意一个变量的值的改变不会影响另外一个
      
    # 3、python中如何实现?
    浅拷贝: copy.copy()
    深拷贝: copy.deepcopy()
      
    # 简单总结
    1、拷贝使用Python标准库模块 copy 实现
    2、copy.copy()内部拷贝了可变类型当时的引用,而copy.deepcopy()所有元素都拷贝
    
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值