另一个
Python的5个标准库
os 操作系统
sys 命令行,运行环境
random 随机
math 数学常数和数学函数
datetime 时间
with的优势 异常处理(不论哪种异常都会关闭文件),代码优化
Python的装饰器本质上是一个嵌套函数,它接受被装饰的函数(func)作为参数,并返回一个包装过的函数。这样我们可以在不改变被装饰函数的代码的情况下给被装饰函数或程序添加新的功能。Python的装饰器广泛应用于缓存、权限校验(如django中的@login_required和@permission_required装饰器)、性能测试(比如统计一段程序的运行时间)和插入日志等应用场景。有了装饰器,我们就可以抽离出大量与函数功能本身无关的代码,增加一个函数的重用性。
set的去重原理: set 的去重是通过两个函数hash和eq结合实现的。当两个对象的哈希值不相同时,就认为这两个对象是不同的; 当两个对象的哈希值一样时,调用eq方法,当返回值为 True 时认为这两个对象是重复的,应该去除一个。返回 FALSE 时,认为这两个对象不是重复的,所以不去重。
列出几种魔法方法
__new__ 创建实例对象,在对象创建之前被调用
__inti__ 初始化实例对象,在对象创建之后被调用
__str__ 返回值str, 输出实例对象时会自动调用该方法
__getattr__ 当用户试图获取一个不存在的属性时被调用
__getattribute__ 当该类的属性(不管存不存在)被访问时
__setattr__ 当一个属性被设置时被调用
__delattr__ 当一个属性被删除时被调用
__iter__ 定义获取迭代器时的行为
__next__ 定义获取迭代器对应的下一个元素时的行为
class Tree():
def __init__(self):
self.name = '大树'
def __getattribute__(self, item):
print('no no no ')
super().__getattribute__(item)
def __getattr__(self, item):
print('{}不存在'.format(item))
aa = Tree()
aa.it
# no no no
# it不存在
# 注释 super函数行代码 输出 no no no
# 注释__getattribute__函数 输出 it不存在
赋值、浅拷贝 copy.copy()、深拷贝 copy.deepcopy()的区别
import copy
a = [1, 2, 'hello', [1, 2]]
b1 = a
# 浅拷贝只会拷贝不可变的数据元素,对可变元素不拷贝
b2 = copy.copy(a) # 等同于 b2 = a.copy()
# 深拷贝是全部拷贝,与原来的变量再没有什么关系
b3 = copy.deepcopy(a)
a[0] = 2
a[-1].append(0)
print('b1 ', b1)
print('b2 ', b2)
print('b3 ', b3)
b1 [2, 2, 'hello', [1, 2, 0]]
b2 [1, 2, 'hello', [1, 2, 0]]
b3 [1, 2, 'hello', [1, 2]]
a 内存地址 41614152
a[-1] 内存地址 41612616
b1 内存地址 41614152
b1[-1] 内存地址 41612616
b2 内存地址 41693064
b2[-1] 内存地址 41612616
b3 内存地址 41689864
b3[-1] 内存地址 41694472
写出斐波那契数列数列
def fibonacci(num):
fibs = [0,1]
for i in range(num-2):
fibs.append(fibs[-2]+fibs[-1]) #倒数第二个+倒数第一个数的结果,追加到列表
print(fibs)
fibonacci(10)
# 每一项都等于前两项之和
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
推导式有两种:列表推导式和字典推导式
进程 process 线程 threading
一个进程可以是多个线程
io密集型使用多线程, cpu密集型使用多进程
多线程 只能实现并发,不能实现并行
多进程 并行执行,真正意义上的并发
GIL锁(线程锁)任何进程中,一次只能有一个线程在执行(线程共享资源,加锁可以一次只有一个线程对资源进行操作),在遇到阻塞(不是耗时)的时候,会自动切换线程。
session与cookie的区别
session存储在服务器上的php指定目录中(session_dir)的位置
cookie存储在客户端,请求令牌
Redis命令的时间复杂度
mysql 语句 重点 唯一索引 和 连表查询
Python调用js的三方库 execjs js2py PyV8
js逆向
禁用右键和F12 可以新开一个页面提前打开F12,然后再访问网页
无限debugger 在debugger那一行右键 Add conditional breakpoint(添加条件断点),输入false然后回车,再点击断点继续运行按钮(角尖朝右的蓝三角)就可以跳过debugger
爬虫遇到js混淆怎么办?
- 使用在线反混淆网站
-
- 找正则方法(RegExp) 去掉检测代码是否被格式化的js 正则代码或者修改返回值
- (可有可没有)用浏览器的console执行代码里面看起来是变量的语句,获取到结果后,全局替换
- fiddler替换原js文件
- 打断点分析
scrapy 的创建命令
scrapy startproject 项目名 #创建新项目
scrapy genspider 文件名 爬取网站域名 # 创建爬取文件
scrapy crawl (爬虫文件中定义的name) #爬虫执行命令
scrapy 的优势 异步 在请求过程中可以使用中间件进行处理
scrapy 的[三种启动方式] (https://blog.csdn.net/qq_17449435/article/details/115207910)
frida hook绕过vpn的方法 调用的方法名有 NetworkInterface、NetworkCapabilities
frida hook java函数没有hook到,怎么解决?
1. app的操作没有触发调用该函数
2. 切换classloaders Java.enumerateClassLoaders()
Android的四大组件: 活动(Activity)、服务(Services)、广播接收器(Broadcast Receiver)、内容提供者(Content Provider)
Activity 可以理解为界面,一个Activity就是一个界面
Services 相当于Windows上的一个后台进程
Broadcast Receiver 用于响应来自其他应用程序或者系统的广播
Content Provider 用于进程间的交互,通常通过请求从一个应用程序向其他应用程序提供数据。
java 加载so文件的方法
System.loadLibrary("random") #完整so文件名为librandom.so
new JMEncryptBox(); # 完整文件名为 libJMEncryptBox.so
java so文件是如何生成的 NDK
java so文件是如何生成的
frida hook so文件中的方法,使用的函数名
1. 直接hook函数名(EXPORT 后面的名字)
Module.getExportByName('so文件名', '方法名')
2. 使用内存地址hook (函数的偏移地址 EXPORT所在行的 .text:000000000000dddd ----> 0xdddd)
Module.findBaseAddress("so文件名").add(函数的偏移地址)