IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> python后端知识点的自我复习 -> 正文阅读

[Python知识库]python后端知识点的自我复习

python知识点

python特点

(1)python是动态强类型语言,强语言不会发生隐式的类型转换

(2)胶水语言,轮子多,应用广泛

(3)性能问题,代码维护问题,python2、3兼容问题

(4)python中一切皆对象

python2/3之间的差异

(1)print改为函数,python2中是一个关键字

(2)编码,python3不再有unicode对象,默认str就是unicode

(3)除法,python3返回浮点数

(4)3中可以用super()直接调用父类函数

(5)高级解包,*args、**kwargs,分别返回tuple、dict

(6)新增,yield产生生成器,内置库asyncio、enum、mock、ipaddress、concurrent.futures等

python函数传递

(1)传递可变类型参数

def do_ls(l):
    l.append(0)
    print(l)

l = []
# 执行结果
do_ls(l) # [0]
do_ls(l) # [0,0]
do_ls(l) # [0,0,0]

(2)传递不可变类型参数

def do_str(s):
    s += "a"
    print(s)

s = "hh"
# 执行结果
do_str(s) # hha
do_str(s) # hha

?因为在python中,对一个变量赋值,只是将对象的引用赋给变量,比如:a=1,本质上是1这个对象的引用赋予了a。回到上面的解析,传递可变参数给函数的时候,本质上将可变参数的引用传入函数,所以在函数内使用的变量引用和外部的是一样的,又因为是参数是可变类型,所以在函数内部发生修改时,外部的变量也一样发生改变。不可变类型的参数,之所以没有变化,是因为引用指向了其他对象。

def do_str(s):
    print("这是刚刚传入的s,id为:", id(s)) # 这是刚刚传入的s,id为: 140338339314032
    s += "a"
    print("这是发生改变后的s, id为:", id(s)) # 这是发生改变后的s, id为: 140338338859376
    print(s)

s = "hh"
print("这是外部s, id为:", id(s)) # 这是外部s, id为: 140338339314032
# 执行结果
do_str(s) # hha
def do_ls(s):
    print("这是刚刚传入的s,id为:", id(s)) # 这是刚刚传入的s,id为: 139688067340160
    s += "a"
    print("这是发生改变后的s, id为:", id(s)) # 这是发生改变后的s, id为: 139688067340160
    print(s)

s = []
print("这是外部s, id为:", id(s)) # 这是外部s, id为: 139688067340160
# 执行结果
do_ls(s) # ["a"]

?(3)注意点:函数中,默认参数只计算一次

def do_ls(l = [1]):
    l.append(1)
    print(l)


do_ls() # [1,1]
do_ls() # [1,1,1]

python中异常处理

try:
    # 无异常执行
except:
    # 发生异常执行
else:
    # 异常没有发生,即执行
finally:
    # 无论是否发生异常都执行

注意:可以研究raise库,出现异常的时候,可以自带自定义的错误信息

python中的GIL锁:

(1)影响:

? ? ? ? a、同一时间只能有一个线程执行字节码

? ? ? ? b、CPU密集计算,难用到多核优势

? ? ? ? c、IO期间会释放GIL,对IO密集程序影响不大

(2)避免GIL影响的方式:

? ? ? ? a、CPU密集可以使用多线程+进程池

? ? ? ? b、IO密集使用多线程/协程

? ? ? ? c、cython扩展

(3)有GIL锁也要关注线程安全,因为非原子操作存在,在IO的时候,GIL锁会释放,其他线程开始执行,有可能会出现线程不安全

服务端性能优化措施:

(1)web应用一般语言不会成为瓶颈,数据结构与算法优化

(2)数据库:索引优化、慢查询消除、批量操作减少IO,NoSQL

(3)网络IO:批量操作、pipeline操作减少IO

(4)缓存:内存数据库redis、memcached

(5)异步:asyncio、celery

(6)并发:gevent、多线程

生成器与迭代器:

(1)生成器:
????????生成器本质上就是一个函数,它记住了上一次返回时在函数体中的位置。对生成器函数的第二次(或第n次)调用,跳转到函数上一次挂起的位置。而且记录了程序执行的上下文。生成器不仅“记住”了它的数据状态,生成还记住了程序执行的位置。

(2)迭代器:

????????迭代器是一种支持next()操作的对象。它包含了一组元素,当执行next()操作时,返回其中一个元素。当所有元素都被返回后,再执行next()报异常—StopIteration生成器一定是可迭代的,也一定是迭代器对象

(3)区别:
????????a、生成器是生成元素的,迭代器是访问集合元素的一中方式
????????b、迭代输出生成器的内容
????????c、迭代器是一种支持next()操作的对象
????????d、迭代器(iterator):其中iterator对象表示的是一个数据流,可以把它看做一个有序序列,但我们不能提前知道序列的长度,只有通过nex()函数实现需要计算的下一个数据。可以看做生成器的一个子集。

python面向对象:

(1)创建一个对象的时候,会先调用__new__方法,再调用__init__进行初始化

(2)类变量:可以通过类或实例直接访问的变量,可以修改

class Person:

    Country = 'China'

    def __init__(self, name):
        self.name = name

    def print_name(self):
        print(self.name)


wjf = Person("wjf")
wjf.print_name()  # wjf
print(wjf.Country)  # China
print(Person.Country)  # China

Person.Country = "CHINA"

print(wjf.Country)  # CHINA
print(Person.Country)  # CHINA

(3)classmethod和staticmethod的区别

? ? ? ? a、都可以class.method()的方式使用

? ? ? ? b、classmethod第一个参数是cls,可以引用类变量

? ? ? ? c、staticmethod用法和普通函数一样,只是放到类里面组织

class Person:

    Country = 'China'

    def __init__(self, name):
        self.name = name

    @classmethod
    def print_country(cls):
        print(cls.Country)

    @staticmethod
    def join_name(first_name, last_name):
        print(first_name + last_name)


Person.print_country() # China
Person.join_name("vick", "·vi") # vick·vi

(4)__call__函数:将对象变成函数的使用方式,例如:可用于用户改变状态的场景

class Person:
        
    def __call__(self,name):
        print("my name is ", name)

wjf = Person()
wjf("wjf") # my name is  wjf

python装饰器decorator:

(1)python中一切皆对象,函数也可以作为参数传递

(2)装饰器是接受函数作为参数,添加功能后返回一个新函数的函数(类)

(3)@语法糖的方式使用装饰器

(4)注意装饰器的调用顺序:装饰顺序,就近原则;执行顺序,就远原则;执行结束:就近原则。也可以理解为,就近入栈,执行时按出栈顺序入栈,结束时按顺序出栈,最终才结束函数调用。

def test1(func):
    print("test1被调用")
    def test1_1(*args, **kwargs):
        print("test1_1被调用")
        res = func(*args, **kwargs)
        print("test1_1被调用-end")
        return res
    return test1_1


def test2(func):
    print("test2被调用")
    def test2_2(*args, **kwargs):
        print("test2_2被调用")
        res = func(*args, **kwargs)
        print("test2_2被调用-end")
        return res
    return test2_2

@test1
@test2
def test():
    print("test被调用")
    return "结束"

print(test())

"""
test2被调用
test1被调用
test1_1被调用
test2_2被调用
test被调用
test2_2被调用-end
test1_1被调用-end
结束
"""

(5)带参数的装饰器

def test2(x):
    print("test2被调用")
    def test1(func):
        print("test1被调用")
        def test1_1(*args, **kwargs):
            print(x+1)
            res = func(*args, **kwargs)
            print("test1_1被调用-end")
            return res
        return test1_1
    return test1


@test2(1)
def test():
    print("test被调用")
    return "结束"

print(test())

"""
test2被调用
test1被调用
2
test被调用
test1_1被调用-end
结束
"""

(6)类装饰器

class test:

    def __init__(self, use_int=False) -> None:
        self.use_int = use_int

    def __call__(self, func):
        def _log(*args, **kwargs):
            if self.use_int:
                print("打开")
            else:
                print("不打开")
            res = func(*args, **kwargs)

            return res
        return _log


@test(True)
def mydo():
    print("mydo执行了")
    return "结束"

print(mydo())

"""
打开
mydo执行了
结束
"""

python的设计模式:

(1)工厂模式:解决对象创建问题

(2)构造模式:控制复杂对象的创建(比如组装电脑,这个模式允许自定义电脑的配置),创建和表示分离

(3)原型模式:通过原型的克隆创建新的实例

(4)单例模式:一个类只能创建同一个对象(容易被问到,甚至实现,比如说python的模块)

class Singleton:
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            _instance = super().__new__(cls, *args, **kwargs)
            cls._instance = _instance
        return cls._instance

class MyClass(Singleton):
    pass

c1 = MyClass()
c2 = MyClass()

print(c1 is c2) # true

# is 和 == 的区别:is判断引用是否一样;==判断值是否一样

(5)对象池模式:预先分配同一个类型的一组实例

(6)惰性计算模式:延迟计算(python的property)

多线程threading模块:?

(1)threading.Thread类用来创建线程;

(2)start()方法启动线程;

(3)可以用join()等待线程结束。

python多进程:

(1)multiprocessing多进程模块;

(2)Multiprocessing.Process类实现多进程;

(3)一般在cpu密集程序里,可以使用,提高程序效率。

python的垃圾回收机制:

(1)引用计数为主(缺点:循环引用无法解决);

(2)引入标记清除和分代回收解决引用技术的问题。


数据结构

常用内置库数据结构和算法:
(1) 线性结构:语言内置,list、tuple;内置库:array、collections.namedtuple

(2)链式结构:内置库,collections.deque(双端队列)

(3)字典结构:语言内置,dict;内置,collections.Counter(计数器)、collections.OrderedDict(有序字典)

(4)集合:语言内置,set、frozenset(不可变)

(5)排序算法:语言内置,sorted

(6)二分算法:内置库,bisect

(7)堆算法:heapq模块

collections模块用法:

(1)Counter:字典的子类,提供了可哈希对象的计数功能

(2)defaultdict:字典的子类,提供了一个工厂函数,为字典查询提供了默认值

(3)OrderedDict:字典的子类,保留了他们被添加的顺序

(4)namedtuple:创建命名元组子类的工厂函数

(5)deque:类似列表容器,实现了在两端快速添加(append)和弹出(pop)

dict底层使用的哈希表:

(1)为了支持快速查找,使用了哈希表作为底层

(2)哈希表平均查找时间复杂度O(1)

(3)使用二次探查法解决哈希冲突问题

其他部分有关算法会重新更新。


Linux操作系统

日常开发用到命令:

根据进程名查看进程号:ps -ef | grep 进程名

根据进程号查看占用的端口:netstat -apn | grep 进程号 -m 显示多少条

根据端口号查看使用的进程:lsof -i:端口号

实时抓取某个文件的内容:tail -f 文件名

Ubuntu的定时任务:crontab -l:显示定时任务有哪些;crontab -e进入编辑

进程与线程的区别:

(1) 进程是对运行时程序的封装,是系统资源调度和分配的基本单位;

(2)线程是进程的子任务,cpu调度和分配的基本单位,实现进程内的并发;

(3)一个进程可以包含多个线程,线程依赖进程存在,并共享进程内存。

线程同步的方式:

(1)互斥量(锁):通过互斥机制防止多个线程同时访问公共资源;

(2)信号量:控制同一时刻多个线程访问同一个资源的线程数;

(3)事件(信号):通过通知的方式保持多个线程同步。

进程间通信的方式:

(1)管道/匿名管道/有名管道(pipe)

(2)信号:比如用户使用ctrl+c产生SIGINT程序终止信号;

(3)消息队列(Message);

(4)共享内存;

(5)信号量;

(6)套接字(socket):最常用的方式,我们的web应用都是这种方式。

分页机制:逻辑地址和物理地址分离的内存分配管理方案

(1)程序的逻辑地址划分为固定大小的页;

(2)物理地址划分为同样大小的帧;

(3)通过页表对应逻辑地址和物理地址;

分段机制:为了满足代码的一些逻辑需求

(1)数据共享,数据保护,动态链接等;

(2)通过段表实现逻辑地址和物理地址的映射;

(3)每个段内部是连续内存分配,段和段之间是离散分配的

分段和分页的区别:

(1) 页是出于内存利用率的角度提出的离散分配机制;

(2)段是出于用户角度,用于数据保护、数据隔离等用途的管理机制;

(3)页的大小是固定的,操作系统决定的;段大小不确定,用户程序决定。

虚拟内存:把一些暂时不用的内存信息放到硬盘上

(1)局部性原理,程序运行时只有部分必要的信息装入内存;

(2)内存中暂时不需要的内容放到硬盘上;

(3)系统好像提供了比实际内存大得多的容量,为虚拟内存。

内存抖动:

(1)频繁的页调度,进程不断产生缺页中段;

(2)置换一个页,又不断再次需要这个页;

(3)运行程序太多;页面替换策略不好;

(4)解决方案,终止进程或者增加物理内存。

死锁:一组进程中,每个进程都无限等待被该组进程中另一进程所占有的资源,因而永远无法得到的资源,这种现象称为进程死锁,这一组进程就称为死锁进程

(1)互斥使用(资源独占):一个资源每次只能给一个进程使用;

(2)占有且等待(请求和保持,部分分配):进程在申请新的资源的同时保持对原有资源的占有;

(3)不可抢占(不可剥夺):资源申请者不能强行的从资源占有者手中夺取资源,资源只能由占有者自愿释放;

(4)循环等待:存在一个进程等待队列 {P1 , P2 , … , Pn},其中P1等待P2占有的资源,P2等待P3占有的资源,…,Pn等待P1占有的资源,形成一个进程等待环路。

当死锁产生的时候一定会有这四个条件,有一个条件不成立都不会造成死锁。


计算机网络

浏览器输入一个url中间经历的过程:

(1)DNS查询(域名解析)

(2)TCP握手(3次握手)

(3)HTTP请求

(4)反向代理Nginx(负载均衡)

(5)uwsgi/gunicom

(6)web app响应

(7)TCP挥手(4次挥手)

TCP 和 UDP的区别:

(1)tcp,面向连接、可靠的、基于字节流

(2)无连接、不可靠、面向报文

5中IO模型:

(1)Blocking IO(阻塞io)

(2)Nonblocking IO(非阻塞io)

(3)IO multiplexing(io多路复用)

(4)Signal Driven IO(信号驱动io)

(5)Asynchronous IO(异步io)

io多路复用:

(1)为了实现高并发需要一种机制并发处理多个socket

(2)Linux常见的是select/poll/epoll

(3)可以使用单线程单进程处理多个socket


mysql数据库

事务是什么:

(1)事务是数据库并发控制的基本单位;

(2)事务1可以看作是一系列sql语句的集合;

(3)事务必须要么全部执行成功,要么全部执行失败(回滚);

事务的4个特性ACID:

(1)原子性:一个事务中所有操作全部完成或失败;

(2)一致性:事务开始和结束之后数据完整新没被破坏;

(3)隔离性:允许多个事务同时对数据库修改和读写;

(4)持久性:事务结束之后,修改是永远的不会丢失。

事务并发会出现4种问题:

(1)幻读:一个事务第二次查出现第一次没有的结果;

(2)非重复读:一个事务重复读两次得到不同结果(获得结果不是最新的);

(3)脏读:一个事务读取到另一个事务没有提交的修改;

(4)丢失修改:并发写入造成其中一些修改丢失。

事务的4种隔离级别:

(1)读未提交:别的事务读到未提交的数据;

(2)读已提交:只能读取已经提交的数据;

(3)可重复读:同一个事务先后查询结果一页(默认);

(4)串行读:事务完成串行化的执行,隔离级别最高,执行效率最低。

防止高并发下插入重复值:

(1)使用数据库的唯一索引;

(2)使用队列异步写入;

(3)使用redis实现分布式锁;

乐观锁和悲观锁:

(1)悲观锁,先获取锁再进行操作。一锁二查三更新;

(2)乐观锁,先修改,更新的时候发现数据变了就回滚。

InnoDB和MyISAM引擎的区别:

(1)MyISAM不支持事务,InnoDB支持事务;

(2)MyISAM不支持外键,InnoDB支持外键;

(3)MyISAM只支持表锁,InnoDB支持行锁和表锁;

B-Tree:

(1)多路平衡查找树(每个节点最多m(m>=2)个孩子,称为m阶或者度);

(2)叶节点具有相同的深度;

(3)节点中的数据key从左到右是递增的。

B+Tree:

(1)mysql实际使用的B+Tree作为索引的数据结构;

(2)只在叶子节点带有指向记录的指针(可以增加树的度);

(3)叶子节点通过指针相连(实现范围查询)。

mysql索引的类型:

(1)普通索引(create index);

(2)唯一索引,索引列的值必须是唯一的(create unique index);

(3)多列索引;

(4)主键索引(primary key),一个表只能有一个;

(5)全文索引(fulltext index),InnDB不支持。

什么时候创建索引:

(1)经常用作查询条件的字段(where条件);

(2)经常用作表连接的字段;

(3)经常出现在order by,group by 之后的字段。

哪些字段适合当索引:

(1)非空字段;

(2)区分度高,离散度大,作为索引的字段值尽量不要有大量相同值;

(3)索引的长度不要太长(比较耗费时间);

索引失效:口诀:模糊匹配、类型隐转、最左匹配

(1)以%开头的like语句,模糊搜索;

(2)出现隐式类型转换(在python这种动态语言查询中需要注意);

(3)没有满足最左匹配原则;

比如:a, b, c为联合索引

如果:
where a b c;
where a b;
where a;
where b c; 这个会导致索引失效

?聚集索引和非聚集索引:

(1)聚集和非聚集:是B+Tree叶节点存的是指针还是数据记录;

(2)MyISAM索引和数据分离,使用的非聚集;

(3)InnoDB数据文件就是索引文件,主键索引就是聚集索引。

用该两表来探究mysql连接的区别

内连接:

?(1)将左表和右表关联起来的数据连接后返回;

(2)类似求两个表的交集

(3)select * from A inner join B on A.id=B.id;

?外连接:

(1)左连接返回左表中所有记录,即使右表中没有匹配的记录(left join);

?

(2)右连接返回右表中所有记录,即使左表中没有匹配的记录(right join)


缓存redis:内存数据库

redis的作用:

(1)缓解关系数据库(常见的是mysql)并发访问的压力:热点数据;

(2)减少响应时间:内存IO速度比磁盘快;

(3)提升吞吐量:redis等内存数据库单机就可以支撑很大的并发;

(4)redis和memcached主要区别,就是redis可以持久化。

redis的数据类型:

(1)String(字符串):用来实现简单的kv键值对存储,比如计数器;

(2)List(链表):实现双向链表,比如用户关注,粉丝列表;

(3)hash(哈希表):用来存储彼此相关的键值对;

(4)set(集合):存储不重复元素,比如用户的关注者;

(5)sorted set(有序集合):实时信息排行榜


web知识点

什么是WSGI:

(1)解决python web server乱象;

(2)描述了web server(Gunicorn/uWSGI)如何与web框架(Flask/Django)交互,web框架如何处理请求;

web框架对比:

(1)Djingo:大而全,内置ORM、Admin等组件,第三方插件比较多;

(2)Flask:微框架,插件机制,比较灵活;

(3)Tornado:异步支持的微框架和异步网络库。

MVC是什么:

(1)Model:负责业务对象和数据库的交互(ORM)

(2)View:负责与用户的交互展示;

(3)Controller:接收请求参数调用模型和视图完成请求。

常见的web安全问题:

(1)sql注入;

(2)xss(跨站脚本攻击);

(3)csrf(跨站请求伪造)。

sql注入:

(1)通过构造特殊的输入参数传入web应用,导致后端执行了恶意sql;

(2)通常由于程序员未对输入进行过滤,直接动态拼接sql产生;

(3)可以使用开源工具sqlmap、sqlninja检测。

如何防范sql注入:永远不要相信用户的任何输入

(1)对输入参数做好检查(类型和范围);过滤和转义特殊字符;

(2)不要直接拼接使用sql,使用ORM可以大大降低sql注入风险;

(3)数据库层:做好权限管理配置;不要明文存敏感信息。

xss攻击:

(1)恶意用户将代码植入到提供给其他用户使用的页面中,未经转义的恶意代码输出到其他用户的浏览器被执行;

(2)用户浏览页面的时候嵌入页面的脚本(js)会被执行,攻击用户;

(3)主要分未为:反射型(非持久型)、存储型(持久型)。

前后端分离是什么:

后端只负责提供数据接口,不再渲染模板,前端获取数据并呈现

前后端分离的优点:

(1)前后端解耦,接口复用(前端和客户端共用接口),减少并发量;

(2)各司其职,前后端同步开发,提升工作效率,定义号接口规范;

(3)更有利于调试(mock),测试和运维部署。

什么是RESTful:

(1)表现层状态转移,由于http协议的主要设计者提出;

(2)资源(resources),表现层(representation),状态转化(state transfer)

(3)是一种以资源为中心的web软件架构风格,可以用Ajax和RESTful web服务构建应用;

(4)Resources(资源):使用URI指向的一个实体;

(5)Representation(表现层):资源的表现形式,比如图片、html文本;

(6)State Transfer(状态转化):get、post、put、delete http动词来操作资源,实现资源状态的改变。

RESTful的准则:?

(1)所有事物抽象为资源(resource),资源对应唯一的标识(identifier);

(2)资源通过接口进行操作实现状态转移,操作本身是无状态的;

(3)对资源的操作不会改变资源的标识。

RESTful API:

(1)通过http get、post、put、delete 获取、新建、更新、删除 资源;

(2)一般使用json格式返回数据;

(3)一般web框架都有相应的插件支持RESTfu API。

?

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-12-10 11:01:17  更:2021-12-10 11:03:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 4:13:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码