安全面试题整理

摘要

开始学安全了,安全面试题整理,涉及安全,python,数据库,网络,系统等等。。。

python

快速排序

1
2
3
4
5
6
7
8
9
10
11
12
arry=[1,10,7,8,9,77,1000,33,57,35,3,2,5]
def quick_sort(arr):
if len(arr) <= 1:
return arr
else:
base = arr[0]
less = [v for v in arr[1:] if v<=base]
more = [v for v in arr[1:] if v>base]
return quick_sort(less) + [base] + quick_sort(more)

a = quick_sort(arry)
print(a)

条件推导,列表推导

条件推导

1
2
3
4
value1:如果条件表达式condition成立,返回value1 ; 如果条件表达式不成立,返回value2 ;
condition:条件表达式
Value2:如果条件表达式condition成立,返回value1 ; 如果条件表达式不成立,返回value2 ;
value1 if condition else Value2
1
print("老司机说:x是偶数") if x%2 == 0 else print("老司机说:x是奇数")

列表推导

列表推导式是条件推导式和循环一起配合使用,并返回一个列表,并且整个表达式需要在[]内,因为返回值也是列表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
'''
语法一:
exp1:在for循环中,如果x的值满足条件表达式condition(即条件表达式成立),返回exp1;条件表达式不成立则不返回
x:for循环中变量
data:一个序列(比如:列表/元组/字符串等)
condition:条件表达式
'''

[exp1 for x in data if condition]

'''
语法二:
exp1:在for循环中,如果x的值满足条件表达式condition(即条件表达式成立),返回exp1;条件表达式不成立则返回exp2
condition:条件表达式
exp2:在for循环中,如果x的值满足条件表达式condition(即条件表达式成立),返回exp1;条件表达式不成立则返回exp2
x:for循环中变量
data:个序列(比如:列表/元组/字符串等)

'''

[exp1 if condition else exp2 for x in data]
1
2
a = [x*10 for x in range(0,10) if x <8]
b = [x*10 if x % 2 == 0 else x*100 for x in range(0,10)]

判断某个类是否有某种属性

用hasaddr 查看

1
2
hasattr(object, name)
hasattr(list, 'append')

用dir查看所有属性

1
dir()

直接测试是否具有,然后异常捕获

1
2
3
4
5
6
7
objlist = dir(k)
if 'att' in objlist:
#do some thing you need
print k.att
else:
#error: has not attribute
pass

__init____new__

__new__方法用于创建对象并返回对象
当返回对象时会自动调用__init__方法进行初始化。
__new__方法是静态方法,而__init__是实例方法

装饰器 应用场景

1
2
3
4
5
6
7
8
9
10
11
12
 def outer(n):       # 第一层:接收装饰器的参数
def decorator(func): # 第二层:接收被装饰函数
def wrapper(*args,**kwargs): # 接收被装饰函数的参数
print(f'等待{n}s登陆')
print('登陆成功.....')
func(*args,**kwargs)
return wrapper # 返回第三层函数名
return decorator # 返回第二层函数名

@outer(2)
def f():
print('我要买东西')

python的方法

Python的方法主要有3个,即静态方法(staticmethod),类方法(classmethod)和实例方法
静态方法 staticmethod
无需实例化,可直接调用 调用静态方法格式:类名.静态方法名(参数列表)

设计的概念,设计模式

链表排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# -*- coding: utf-8 -*-'

class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None

class Solution(object):
def sortList(self, head):
if not head or not head.next:
return head

prev, slow, fast = None, head, head

while fast and fast.next:
prev, slow, fast = slow, slow.next, fast.next

prev.next = None # 将链表切断,分为head和slow两条子链

"""
等价以下代码
l1 = self.sortList(head)
l2 = self.sortList(slow)
return self.merge(l1, l2)
"""
return self.merge(*map(self.sortList, (head, slow)))

def merge(self, l1, l2):
dummy = l = ListNode(None)

while l1 and l2:
if l1.val < l2.val:
l.next, l, l1 = l1, l1, l1.next
else:
l.next, l, l2 = l2, l2, l2.next

l.next = l1 or l2
"""
l1,l2长度不一样时,l.next为l1,l2中比另一个长度长的子链
如 l1: 1->2 l2: 3->4->5, l.next为5
等价于以下代码
if l1:
l.next = l1
else:
l.next = l2
"""

return dummy.next


if __name__ == "__main__":
s = Solution()
l = head = ListNode(None)
for val in [0, 4, 1, 6, 7]:
l.next = ListNode(val)
l = l.next

li = s.sortList(head.next)
while li:
print li.val
li = li.next

数据库

MySQL 引擎

InnoDB

  • InnoDB引擎提供了对数据库ACID事务的支持,并且实现了SQL的四种隔离级别。
  • 该引擎还提供了行级锁定和外键约束,它的设计目标是处理大容量数据库系统,它本身其实就是基于MySQL后台的完整数据库系统,MySQL运行时InnoDB会在内存中建立缓冲池,用于缓冲数据和索引。
  • 但是该引擎不支持FULLTEXT类型的索引
  • 而且它没有保存表的行数,当SELECT COUNT(*) FROM TABLE需要扫描全表
  • 当需要使用数据库事务时,该引擎是首选。
  • 由于锁的粒度更小,写操作不会锁定全表,所以在高并发时,使用InnoDB会提升效率。但是使用行级锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB同样会锁定全表

适用场景:
经常更新的表,适合多并发的更新请求
支持事务
可以从灾难中恢复(通过bin-log日志等)
外键越苏。只有它支持外键
支持自动增加列属性auto_increment

InnoDB和MyISAM 区别

  • 事务:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持,提供事务支持已经外部键等高级数据库功能。

  • 性能:MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快。

  • 行数保存:InnoDB 中不保存表的具体行数,也就是说,执行select count() fromtable时,InnoDB要扫描一遍整个表来计算有多少行,但是MyISAM只要简单的读出保存好的行数即可。注意的是,当count()语句包含where条件时,两种表的操作是一样的。

  • 索引存储:对于AUTO_INCREMENT类型的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中,可以和其他字段一起建立联合索引。MyISAM支持全文索引(FULLTEXT)、压缩索引,InnoDB不支持。

    MyISAM的索引和数据是分开的,并且索引是有压缩的,内存使用率就对应提高了不少。能加载更多索引,而Innodb是索引和数据是紧密捆绑的,没有使用压缩从而会造成Innodb比MyISAM体积庞大不小。

    InnoDB存储引擎被完全与MySQL服务器整合,InnoDB存储引擎为在主内存中缓存数据和索引而维持它自己的缓冲池。InnoDB存储它的表&索引在一个表空间中,表空间可以包含数个文件(或原始磁盘分区)。这与MyISAM表不同,比如在MyISAM表中每个表被存在分离的文件中。InnoDB 表可以是任何尺寸,即使在文件尺寸被限制为2GB的操作系统上。

  • 服务器数据备份:InnoDB必须导出SQL来备份,LOAD TABLE FROM MASTER操作对InnoDB是不起作用的,解决方法是首先把InnoDB表改成MyISAM表,导入数据后再改成InnoDB表,但是对于使用的额外的InnoDB特性(例如外键)的表不适用。

MyISAM应对错误编码导致的数据恢复速度快。MyISAM的数据是以文件的形式存储,所以在跨平台的数据转移中会很方便。在备份和恢复时可单独针对某个表进行操作。

6)锁的支持:MyISAM只支持表锁。InnoDB支持表锁、行锁 行锁大幅度提高了多用户并发操作的性能。但是InnoDB的行锁,只是在WHERE的主键是有效的,非主键的WHERE都会锁全表的。

索引

BTree和B+Tree详解

参考:https://blog.csdn.net/hao65103940/article/details/89032538
B+树索引是B+树在数据库中的一种实现,是最常见也是数据库中使用最为频繁的一种索引。B+树中的B代表平衡(balance),而不是二叉(binary),因为B+树是从最早的平衡二叉树演化而来的。在讲B+树之前必须先了解二叉查找树、平衡二叉树(AVLTree)和平衡多路查找树(B-Tree),B+树即由这些树逐步优化而来。

二叉查找树

二叉树具有以下性质:左子树的键值小于根的键值,右子树的键值大于根的键值。

平衡二叉树(AVL Tree)

平衡二叉树(AVL树)在符合二叉查找树的条件下,还满足任何节点的两个子树的高度最大差为1。

平衡多路查找树(B-Tree)

B-Tree是为磁盘等外存储设备设计的一种平衡查找树。因此在讲B-Tree之前先了解下磁盘的相关知识。

系统从磁盘读取数据到内存时是以磁盘块(block)为基本单位的,位于同一个磁盘块中的数据会被一次性读取出来,而不是需要什么取什么。

InnoDB存储引擎中有页(Page)的概念,页是其磁盘管理的最小单位。InnoDB存储引擎中默认每个页的大小为16KB,可通过参数innodb_page_size将页的大小设置为4K、8K、16K,在MySQL中可通过如下命令查看页的大小:

1
mysql> show variables like 'innodb_page_size';

而系统一个磁盘块的存储空间往往没有这么大,因此InnoDB每次申请磁盘空间时都会是若干地址连续磁盘块来达到页的大小16KB。InnoDB在把磁盘数据读入到磁盘时会以页为基本单位,在查询数据时如果一个页中的每条数据都能有助于定位数据记录的位置,这将会减少磁盘I/O次数,提高查询效率。

B-Tree结构的数据可以让系统高效的找到数据所在的磁盘块。为了描述B-Tree,首先定义一条记录为一个二元组[key, data] ,key为记录的键值,对应表中的主键值,data为一行记录中除主键外的数据。对于不同的记录,key值互不相同。

一棵m阶的B-Tree有如下特性:

  • 每个节点最多有m个孩子。
  • 除了根节点和叶子节点外,其它每个节点至少有Ceil(m/2)个孩子。
  • 若根节点不是叶子节点,则至少有2个孩子
  • 所有叶子节点都在同一层,且不包含其它关键字信息
  • 每个非终端节点包含n个关键字信息(P0,P1,…Pn, k1,…kn)
  • 关键字的个数n满足:ceil(m/2)-1 <= n <= m-1
  • ki(i=1,…n)为关键字,且关键字升序排序。
  • Pi(i=1,…n)为指向子树根节点的指针。P(i-1)指向的子树的所有节点关键字均小于ki,但都大于k(i-1)
    B树和B+树的区别
    1)B-树的关键字和记录是放在一起的,叶子节点可以看作外部节点,不包含任何信息;B+树的非叶子节点中只有关键字和指向下一个节点的索引,记录只放在叶子节点中。
      2)在B-树中,越靠近根节点的记录查找时间越快,只要找到关键字即可确定记录的存在;而B+树中每个记录的查找时间基本是一样的,都需要从根节点走到叶子节点,而且在叶子节点中还要再比较关键字。从这个角度看B-树的性能好像要比B+树好,而在实际应用中却是B+树的性能要好些。因为B+树的非叶子节点不存放实际的数据,这样每个节点可容纳的元素个数比B-树多,树高比B-树小,这样带来的好处是减少磁盘访问次数。尽管B+树找到一个记录所需的比较次数要比B-树多,但是一次磁盘访问的时间相当于成百上千次内存比较的时间,因此实际中B+树的性能可能还会好些,而且B+树的叶子节点使用指针连接在一起,方便顺序遍历(例如查看一个目录下的所有文件,一个表中的所有记录等),这也是很多数据库和文件系统使用B+树的缘故。

那么为什么说B+树比B-树更适合实际应用中操作系统的文件索引和数据库索引?

1) B+树的磁盘读写代价更低
  B+树的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对B 树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就降低了。
2) B+树的查询效率更加稳定
  由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

聚簇索引与非聚簇索引

聚簇索引并不是一种单独的索引类型,而是一种数据存储方式。
术语‘聚簇’表示数据行和相邻的键值聚簇的存储在一起。
如下图,左侧的索引就是聚簇索引,因为数据行在磁盘的排列和索引排序保持一致

聚簇索引的好处:

按照聚簇索引排列顺序,查询显示一定范围数据的时候,由于数据都是紧密相连,数据库不不用从多个数据块中提取数据,所以节省了大量的io操作。

聚簇索引的限制:

  • 对于mysql数据库目前只有innodb数据引擎支持聚簇索引,而Myisam并不支持聚簇索引。

  • 由于数据物理存储排序方式只能有一种,所以每个Mysql的表只能有一个聚簇索引。一般情况下就是该表的主键。

  • 为了充分利用聚簇索引的聚簇的特性,所以innodb表的主键列尽量选用有序的顺序id,而不建议用无序的id,比如uuid这种。

网络

http状态码

  • 301 Moved Permanently 永久移动。
  • 302 Found 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI
  • 304 Not Modified 未修改。
  • 307 Temporary Redirect 临时重定向
  • 400 Bad Request 客户端请求的语法错误,服务器无法理解
  • 401 Unauthorized 请求要求用户的身份认证
  • 403 Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求
  • 404 Not Found 服务器无法根据客户端的请求找到资源(网页)。
  • 405 Method Not Allowed 客户端请求中的方法被禁止
  • 500 Internal Server Error 服务器内部错误,无法完成请求
  • 502 Bad Gateway 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
  • 503 Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
  • 504 Gateway Time-out 充当网关或代理的服务器,未及时从远端服务器获取请求
  • 505 HTTP Version not supported

tcp三次握手四次挥手

数据结构与算法

数组

排序后切片

1
2
3
4
def second_smallest(arr):
#升序排列1位置对应数组第二小元素
arr=sorted(arr)
return arr[1]