Skip to content

Instantly share code, notes, and snippets.

@junnplus
Last active April 3, 2016 05:38
Show Gist options
  • Save junnplus/0243fc387f8aa32dbe0fd99133e70e4f to your computer and use it in GitHub Desktop.
Save junnplus/0243fc387f8aa32dbe0fd99133e70e4f to your computer and use it in GitHub Desktop.

session/cookie

cookie 是客户端保持状态的方案

session 是服务器端保持状态的方案

都是用来跟踪会话,cookie还可以用来记录用户的偏好设置

cookie不安全,之所以出现session,主要是为了安全

session机制要借助cookie机制来达到保存标识到目的,也可以有其他选择

cookie机制

cookie是通过扩展HTTP协议来实现

服务器通过在HTTP的响应头中加上一行特殊的指示来提示客户端保存cookie

cookie会被自动发到服务器上

cookie 名字,值,过期时间,路径和域(路径和域组成作用范围)

session机制

散列表

cookie禁用可以通过URL重写或表单隐藏字段实现

flask中的session默认是client side session,通过secret key加密之后返回给客户端

rest和非rest区别

数据库瓶颈优化/调优

  1. 索引优化(查询优化)
  2. sql优化
  3. 缓存优化
  4. 读写数据库分离 or 分库分表查询

sql中建索引

where 和 order by 子句列建立索引 尽量避免全表扫描,有些sql语句即使在建立索引的情况下也会全表扫描 索引是为了提高select效率,但同时降低了insert 和 update 的效率,因为要重建索引 一个表的索引不要超过6个

mongo优化

flask上下文

HTTP

TCP/IP三次握手

控制标记 SYN ACK FIN 等 序列号 确认号:为从对方计算机接收到的最后一个序列号,用于确认已接收到的数据分段,其值是接收计算机即将接收的下一个序列号。

  1. 客户端发送一个SYN=1的请求包,主动打开连接,包的序列号为随机A
  2. 服务器端为合理的SYN包返回一个SYN/ACK包,确认号为A+1,序列号为随机B
  3. 客户端发送一个ACK=1的响应包,确认号为B+1,序列号为A+1

常见网络模型

mysql数据库引擎区别

mysql 中的锁

锁是在执行多线程时用于强行限制资源访问的同步机制,用于在并发控制中保证对互斥要求的满足

行级锁

行级锁是Mysql中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突。其加锁粒度最小,但加锁的开销也最大。行级锁分为 共享锁排他锁

开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

表级锁

表级锁是MySQL中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分MySQL引擎支持。最常使用的MYISAM与INNODB都支持表级锁定。表级锁定分为表共享读锁(共享锁)与表独占写锁(排他锁)。

开销小,加锁快;不会出现死锁;锁定粒度大,发出锁冲突的概率最高,并发度最低。

页级锁

页级锁是MySQL中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。BDB支持页级锁

开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般

MyISAM和MEMORY采用表级锁(table-level locking)

BDB采用页面锁(page-level locking)或表级锁,默认为页面锁

InnoDB支持行级锁(row-level locking)和表级锁,默认为行级锁

python中的可变变量和不可变变量

lambda函数

lambda 就是匿名函数

好处:可以动态生成一个函数对象,不用给这个对象命名,污染名字空间

另外python在函数式编程方面提供了些什么函数和语法?

函数:map()/filter()

语法:可以函数内部定义函数,闭包支持

线程和进程和协程

进程好比一个项目组,线程就是项目组成员,一个项目组(进程)必须有一个成员(线程)

进程是一个程序执行时的状态

线程由进程创建,进程可以通过创建多个线程来更好的利用多核心机器。

每个线程一个执行流,线程的调度由OS负责,程序员不可控

多线程程序在编写要注意内存中跨线程共享的数据的读写加速

协程是线程内的概念,一个线程可以通过保存调用栈和恢复调用栈来复用线程的执行流,提供多个执行流的抽象

每个协程为单独一个执行流,调度由程序员来控制

yield协程

并行和并发

并行和并发都是处理多任务的概念

并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔发生。

并发和并行的区别就是一个处理器同时处理多个任务和多个处理器或者是多核的处理器同时处理多个不同的任务。

一个处理器肯定没法同时处理多个任务,所以并发是逻辑上的同时发生,并行是物理上的同时发生。

Python是如何进行内存管理的?

虚拟机提供一个处理循环引用导致无法通过引用技术为0的自动垃圾回收机制

Python GC主要使用引用计数(reference counting)来跟踪和回收垃圾。

每个python对象都是有引用计数的,引用计数一旦为0,虚拟机自动释放对象,回收内存

在引用计数的基础上,通过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用问题,通过“分代回收”(generation collection)以空间换时间的方法提高垃圾回收效率

标记-清除

基本思路是先按需分配,等到没有空闲内存的时候从寄存器和程序栈上的引用出发,遍历以对象为节点、以引用为边构成的图,把所有可以访问到的对象打上标记,然后清扫一遍内存空间,把所有没标记的对象释放。

  • Python也会内存泄露,Python本身的垃圾回收机制无法回收重写了__del__的循环引用的对象
  • 程序员管理好每个python对象的引用,尽量在不需要使用对象的时候,断开所有引用

尽量少通过循环引用组织数据,可以改用weakref做弱引用或者用id之类的句柄访问对象

通过gc模块的接口可以检查出每次垃圾回收有哪些对象不能自动处理,再逐个逐个处理

docker与VM的区别

##并发和并行的区别,应用场景

解释GIL

线程间数据一致性和状态同步的困难

GIL 是全局解释锁,并不是Python 的特性,而是Cpython引入的

GIL是一个互斥锁,为了防止多个本地线程并行执行字节码,也就是说一个解释器在一个时间点只能有一个线程。

GIL保证了python内部对象是线程安全的。无需在实现时考虑额外的内存锁和同步操作

在解释器解释执行任何 Python 代码时,都需要先获得这把锁才行,在遇到 I/O 操作时会释放这把锁

如果是纯计算的程序,没有 I/O 操作,解释器会每隔 100 次操作就释放这把锁,让别的线程有机会执行

虽然 CPython 的线程库封装了操作系统的原生线程,但却因为 GIL 的存在导致多线程不能利用多个 CPU 内核的计算能力。好在可以利用多进程。

装饰器原理(运用场景)

快速排序

dict排序

字符串反转

python庫

csrf等web安全

关于python程序的运行性能方面,有什么手段能提升性能?

  • cpu:
  • 写C lib或Cython,将python的运算转移到C层去做
  • 改用PyPy类JIT解释器提高解释器性能
  • 使用多进程组织python程序,充分利用机器多个核心
  • network io:
  • 使用nonblock io,不使用block io,避免io操作阻塞当前执行流
  • 采用异步写法,比如使用Twisted
  • 采用同步写法,比如使用gevent

输入某年某月某日,判断这一天是这一年的第几天?(可以用python标准库)

from datetime import datetime
def day_of_year(year, month, day):
    return (datetime(year, month, day) - datetime(year, 1, 1)).days + 1

详细说说tuple、list、dict的用法,它们的特点;

  • tuple 固定长度的子项不可变的顺序型容器,一般用来做常量(策划配表)或者表示少量属性的对象(比如pos)表示
  • list 可变长度的子项可变的顺序型容器,一般用来实现队列/栈之类只需要用数字索引/分片分段访问的容器
  • dict 可变长度的hash字典容器,key是多种类型
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment