剑指offer

Posted venicid

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer相关的知识,希望对你有一定的参考价值。

一、Python基础

1、什么是python?使用python有什么好处?

python是一种编程语言,它有对象、模块、线程、异常处理和自动内存管理。它简洁,简单、方便、容易扩展、有许多自带的数据结果,而且它开源

Python是一种解释性语言,它的源代码可以直接运行,Python解释器会将源代码转换成中间语言,之后再翻译成机器码再执行

2、可变类型与不可变类型

可变类型:list、dict、可变集合set

不可变类型:数字,str,tuple元组,frozenset

内存中的那块内容(value)是否可变

可直接在原来的地址,修改

不可变的类型都可以被hash哈希

3、深浅copy

对不可变类型进行copy的话,都是深copy

对于可变类型进行copy的话,一般都是浅copy

浅拷贝只是增加了一个指针指向所复制的对象,共用一块内存

深拷贝是增加一个指针并且开辟了新的内存,这个增加的指针指向这个新的内存,

In [42]: li = [1,2,3,[4,5]]
In [43]: li2 = copy.copy(li)
In [44]: li3 = copy.deepcopy(li)


In [45]: li[-1][-1] = "222"
    
In [46]: li
Out[46]: [1, 2, 3, [4, '222']]

In [47]: li2
Out[47]: [1, 2, 3, [4, '222']]

In [48]: li3
Out[48]: [1, 2, 3, [4, 5]]

简单来说,如果有嵌套的话,浅copy只复制第一层,深copy会复制所有的

4、range-and-xrange

    py2:
        range() 生成的是列表
        xrange() 生成的是一个生成器 
    py3:
        range() 就是一个生成器
        xrange() 没了

5、闭包

def func():
    
    def inner():
        print('aaaa')  
        
    return inner

func()()  # aaaa 

内部函数对外部函数作用域里变量的引用(非全局变量),则称内部函数为闭包。

闭包的意义:返回函数对象+一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域

6、装饰器

调用装饰器其实是一个闭包函数,

不修改函数的代码与修饰方式,为其他函数添加附加功能

比如:插入日志、性能测试、事物处理、缓存、权限验证等

# 装饰器
import time
def login(func):
    def inner():
        start_time = time.time()
        func()
        end_time = time.time()
        print("fun 执行时间",end_time-start_time)
    return inner

@login
def test():
    for i in range(10000):
        for j in range(10000):
            pass
    print('test函数执行')

test()
# test函数执行
# fun 执行时间 2.0163347721099854

7、生成器

延迟操作,需要的时候才产生结果,而不是立即产生结果

在每次调用next()的时候执行,遇到yield语句返回

创建生成器的两种方式:

li = [i for i in range(100)]、yield方法

8、迭代器

for循环的数据类型:集合数据类型+生成器

list,tuple,dict,set,str + generator

不是一次性把数据加载到内存,而是被next()函数调用,不断返回下一个数据

9、*args与**kwargs

*args:位置参数 (‘alex‘,18)

**kwargs:关键字参数 {‘name‘=‘alex‘,‘age‘=18} 关键字参数一定要放在最后面

二、面向对象

1、经典类、新式类

经典类:深度优先,python2中

新式类:广度优先,Python3中

2、继承、多态、封装

(1)继承:类与类之间关系,Cat类是动物类,解决代码重用问题

重用 父类的属性与方法

def __init__(self, name, life_value, aggresivity, weapon):
        super().__init__(name, life_value, aggresivity,)        # python3格式
        self.weapon = weapon

 def attack(self, enemy):
       super().attack(enemy)

(2)多态:同一类事物多种形态

一个接口,多种形态

不应关注对象的类型本身,而是它如何使用的

鸭子类型:如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子’

(3)封装

私有化的属性,私有化的方法,封装起来,外部无法调用 双下划线__foo

3、classmethod,staticmethod,property

(1)property:特性 (统一访问 原则)

    @property
    def bmi(self):
        return self.weight / (self.height ** 2)

把类的方法转换为属性,直接 alex.bmi 调用

(2)staticmethod 静态方法 (普通函数 ) 绑定到对象上

类内的函数实例化---> 普通函数 。 (类和对象都可以使用)

    @classmethod
    def from_conf(cls):
        obj = settings.name,
        return obj

(3)classmethod 类方法 (def foo(cls)) 绑定到类上

将cls 类本身当做参数传入,直接用类来调用函数,而不用借助类实例

优雅地实现某个类的实例的构造

4、 new.init区别,如何实现单例模式

创建一个新实例时调用new new()在 init()之前被调用

初始化一个实例时调用init

单例模式设计的类只能实例化1个对象

# 方式1 python模板自带单例模式
# admin.py

class Admin(object):
    def register(self):
        pass

site = Admin()

# test.py
from admin import site
site.register()

# 方式2  __new__  _instance
class Single(object):
    _instance = None
    def __new__(cls,*args,**kwargs):
        if not cls._instance:
            cls._instance = super(Single,cls).__new__(cls,*args,**kwargs)
            
        return cls._instance

5、反射

“字符串”形式,操作对象的相关属性或方法。

hasattr, getattr, setattr, delattr

ret = getattr(obj,'get_file')()       # 反射  obj是实例对象,name是方法 

三、并发

1、线程、进程的区别

(1)进程:程序的运行过程, os 资源调度、分配的基本单位 os的并发

(2)线程:进程的实体, cpu 调度、分派的基本单位 进程内部的并发

区别

1、进程有独立的内存空间, 线程 共享 本进程 的内存空间

2、进程有独立的系统资源 ,线程只有(程序计数器,一组寄存器,栈) 共享本进程的资源(内存,I/O,cpu)

3、独立性:进程崩溃,不会影响其他的(健壮) 线程崩溃,本进程的全部线程死掉

4、开销:进程切换与创建 开销大于 线程的

5、线程不能独立执行 进程可以

联系

都可并发、一个进程由1or多个线程 组成、一个进程中的所有线程共享该进程全部资源

2、协程、GIL

GIL:全局解释器锁(cpython解释器), 同一时刻,在cpu只能有一个线程执行

协程:轻量级的线程,用户控制调度的

单线程下(的并发), 遇到I/O阻塞,多个任务,自动切换

3、进程同步方式

1、Event事件 。 通知操作

2、互斥量。 加锁

3、信号量。 生产者消费者模型 阻塞队列Queue

4、临界区 。保护区域

同步问题:生产者消费者模型,作者读者问题,哲学家进餐问题

4、通信方式

管道,系统IPC(消息队列,信号量,信号,共享内存),套接字,远程过程调用rpc

5、死锁

多个进程运行,争夺资源,一种僵局;没有外力,进程,无法继续执行

导致死锁的原因:循环等待、不可抢占、占有且等待、互斥

死锁处理:

1、预防 :破坏4个条件

2、避免:银行家算法

3、检测:算法检测,清除死锁

4、解除: 检测到,撤销进程or剥夺资源

6、select、poll和epoll (I/O多路复用)

可以监视多个描述符

一个描述符就绪,通知应用程序,执行读or写操作

(1)select :

把文件描述符 fd 集合maxSize=1024,用户态copy到内核态 开销大,在内核,遍历所有fd

(2)poll:

改善了连接数,不断轮询,fd集合 每次都copy到内核态

(3)epoll:

linux下的多路复用I/O接口, 只copy一次,只告知 ,刚变为就绪状态的fd

四、mysql数据库

1、索引

B+数:二叉树-->平衡二叉树-->B数

一个排序好,数据结构 (协助快速查询data) 范围查询

create index ix_age on t1(age);
create index 索引名1,索引名2 on 表名('字段1','字段2')

(1)什么时候用?

经常 select查询、表记录超多

经常需要搜索的列、主键列、连接的列(外键)、范围查找 age in [20,40]、排序的列 salary、where上的列

(2)什么时候不用?

经常update,delete,insert 表记录少

不经常使用的列 addr,数据值很少的列 blog,文本,image,bit 修改>查询的

2、存储过程

相当于 函数,封装了,一系列,可执行的sql语句,存放在mysql中

直接调用它的名称

create procedure p1()
BEGIN
    select * from blog;
    INSERT into blog(name,sub_time) values("xxx",now());
END

优点:网络传输量小,程序与slq解耦

缺点:程序猿拓展功能不方便

3、数据库引擎

INNODB 支持事务,外键,行锁, 查表总行数,全表扫描

MYISAM不支持事务,不支持外键,表锁(插入data,锁定这个表),查表总行数,不需要全表扫描

4、redis

key-value数据库 ,经常用的data放在redis

性能极高,支持多种数据类型 ,放在内存中 (必要时可以写入硬盘)

五、网络

1、http常用的状态码

200:请求成功 OK

202:服务器接受请求,尚未处理

302:重定向

304??:上次的文档,已被缓存, 还可继续使用

400:客户端请求语法or参数错误

403:服务器收到请求,拒绝提供服务,找不到cookie

404:客户端请求的资源url不存在

500: 服务器的程序出现错误

503:服务器当前时间不能处理客户端的请求,一段时间后恢复

2、HTTP请求方式

HTTP1.0 GET/HEAD/POST

HTTP1.1 PUT/DELETE/CONNECT/OPTIONS/TRACE

3.GET/POST区别

(1)get提交的数据放在url后 /?name=alex&age=18 http请求头

     post的数据放在http报请求体

(2)GET的数据大小有限制,POST没有限制

(3)GET方式会带来安全问题,在url出现信息,可能获得username password

(4)在服务端 获取请求数据方式不同

4、http请求头,请求体

协议版本,状态码,状态码原因 HTTP /1.1 200 OK

Cookie:

Content-Language

Content-Type 文本类型

Content-Length 请求体长度

User-Agent: 浏览器的身份标识,类型,手机端or电脑端

Date:时间

请求体

5、TCP/UDP区别 (运输层)

1、TCP 传输控制协议,面向连接的,可靠的,数据流传输 ,注重data安全性,传输慢,面向字节流

2、UDP用户数据报文协议,非面向连接的,不可靠,数据流传输, data传输快,安全性一般,面向报文

以上是关于剑指offer的主要内容,如果未能解决你的问题,请参考以下文章

剑指 Offer(第 2 版)完整题解笔记 & C++代码实现(LeetCode版)

LeetCode(剑指 Offer)- 14- I. 剪绳子

LeetCode(剑指 Offer)- 14- I. 剪绳子

剑指offer——第二十九天(动态规划“困难”)

剑指 Offer 45. 把数组排成最小的数 剑指 Offer 61. 扑克牌中的顺子 剑指 Offer 40. 最小的k个数

剑指 offer 刷题记录