面试题

本文涵盖Python进阶技巧,包括字典操作、格式化字符串、装饰器、RESTful API设计、Django与Flask框架对比及应用,深入探讨数据库优化、并发编程、HTTP协议、上下文管理等核心概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、在python中遍历字典的时候不能对字典本身做涉及键的操作
2、%和format的区别
    c = (220,220)
    s1 = "坐标为%s"%(c,)
    s2 = "坐标为{}".format(c)
    print(s1,s2)
    输出结果:
    坐标为(220, 220) 坐标为(220, 220)

    python3.6版本format多了个f-strings
    name = "李优秀"
    age  = "20"
    s1 = "{}is{}".format(name,age)
    s2 = f"{name}is{age}"
    print(s1,s2)

    # format通过对象属性
    class Person():
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def __str__(self):
            return "{self.name}is{self.age}".format(self = self)

    p = Person("李优秀",18)
    print(p)
    输出结果:
    李优秀is18
3、可变对象不能做函数参数
    def foo(arg,li = []):
        li.append(arg)
        return li
    list1 = foo(21)
    list2 = foo(21,[1,])
    list3 = foo(28)
    print(list1,list2,list3)

    输出结果:
    [21, 28] [1, 21] [21, 28]

4、打乱列表内容
    import random
    list1 = [1,2,3,4,5]
    random.shuffle(list1)
    print(list1)

5、装饰器

        1、装饰函数带参数和返回值
        def outer(f):
            def inner(*arg,**karg):
                print("xxxx")
                ret = f(*arg,**karg)
                print("xxxxx")
                return ret
            return inner


        @outer
        def foo(name):
            print(name+":你好")
            return 5
        a = foo("long")
        print(a)


        2、带参数的装饰器
        3、多个装饰器装饰同一个函数的时候执行顺序
        4、带返回值的装饰器
        5、装饰类的装饰器
        https://q1mi.github.io/PythonBlog/post/advanced_decorator/


6、不成功剥皮函数
    list1 = [11,[22,3],[4,],[55,66],8,[9,[7,[12,[34,[26]]]]]]
    def f(x):
        ret = []
        for b in x:
            if isinstance(b,list):
                for a in f(b):
                    ret.append(a)
            else:
                ret.append(b)
        return ret
    ret1 = f(list1)
    print(ret1)

7、时间间隔

    import datetime

    now_time = datetime.datetime.now()
    day_7_later = datetime.timedelta(days=7)
    ret = now_time+day_7_later
    print(now_time,ret)

    输出结果:
    2019-03-01 20:33:35.350343 2019-03-08 20:33:35.350343


8、Django请求生命周期
   1.浏览器发送请求
   2.执行遵循wsgi协议的模块(本质是socket服务端)进行初次封装
   3.然后将初次封装的数据交给Django进行再次封装(封装request),例如session,和csrf_token
   4.经过中间件process_request
   5.进行路由匹配
   6.经过process_view中间件
   7.到视图函数,可能会涉及到ORM访问数据库,与模板渲染
   8.经过process_response中间件
   9.到wsgi进行数据封装返回到浏览器

9、什么是WSGI(web服务网关接口)
		web服务网关接口
		实现该协议的模块:
			- wsgiref
			- werkzurg
			- uwsgi
10、什么是接口:
    一种就是:URL
    一种就是做约束用(一般在c#和java中存在)
11、restful api规范:
    1.根据method不同,进行不同操作(GET,POST,PUT,DELETE,PATCH)
    2.面向资源编程:http://xxxxxxxx/api/v1/名词
    3.体现是API:http://xxxxxxxx/api/.....
    4.体现版本:http://xxxxxxxx/api/v1/.....
    5.https:
    6.在响应时添加状态码(200,300,400,500)
    7.条件:https://xxxxxxxxxxxxxxxxxxxx?page = 1&size = 10
    8.返回值
        https://www.luffycity.com/api/v2/salary
			GET: 所有列表
			{
				code: 10000,
				data: [
					{'id':1,'title':'高亮'},
					{'id':1,'title':'龙泰'},
					{'id':1,'title':'小东北'},
				]
			}

			POST: 返回新增的数据
				{'id':1,'title':'高亮'}

			https://www.luffycity.com/api/v2/salary/1/
			GET: 获取单条数据
					{'id':1,'title':'高亮'}
			PUT:更新
					{'id':1,'title':'高亮'}
			PATCH: 局部更新
					{'id':1,'title':'高亮'}
			DELETE:删除
    9.返回错误信息{
        code:1001,
        erro:'xxxx错误'
    }
    10.Hyermedia API
    ret = {
        code:1000,
        data:{
            id:'',
            name:'',
            depart_id:'http://xxxxxxxx/api/v1/depart/8/'   //返回路由查询路径
        }
    }
12、django rest framework
    django rest framework的作用?
		快速搭建基于restful规范的接口。
    框架组件有哪些?(10)
        - 版本
        - 权限
            -  写一个类并注册到权限类,在类的的has_permission方法中编写认证逻辑。
			    - True
				- False
            当用户登录时候获取当前用户所有权限并放入session,(获取带参数URL:request.get_full_path()  获取不带参数URL:request.path)
            然后再次访问其他页面,获取当前url并在session中进行匹配。
            如果没有匹配成功,则在中间件返回“无权访问”
		- 认证
		    登录认证
		    -  写一个类并注册到认证类,在类的的authticate方法中编写认证逻辑。
			- 认证成功(user,auth)
			- raise AuthticateFaild(....)
			- None
		- 访问频率限制(列表insert方法)
		    -  写一个类并注册到频率类,在类的的 allow_request/wait 方法中编写认证逻辑。
				allow_request
					- True
					- False  如果返回False,那么就要执行wait

		    匿名用户:以IP地址为键,以时间戳为值(无法控制,因为用户可以换代理IP)
		    登录用户:以用户名为键,以时间戳为值(登录用户:如果有很多账号,也无法限制)
		    默认将访问记录放在缓存中:redis/memcached

        - 路由
		        - 可以通过as_view传参数,根据请求方式不同执行相应的方法
			    - 可以在url中设置一个结尾,类似于: .json

        - 视图
		    - 帮助开发者提供了一些类,并在类中提供了多个方法以供我们使用。
			面试题:你的写的类都继承过哪些类?
			class View(object):

			class APIView(View):

			class GenericAPIView(views.APIView):

			class GenericViewSet(ViewSetMixin, generics.GenericAPIView)

			class ModelViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet):
		- 序列化:(用到了类中__new__方法,单个对象和多个对象)
		        - 对queryset序列化以及对请求数据格式校验
		        ser =XX(queryset,many=True) # ListSerializer对象
			    ser =XX(obj, many=False)    # XX对象

                from rest_framework.serializers import Serializer

                class XX(Serializer):
                    pass
                ser =XX(queryset,many=True) # ListSerializer对象
                ser =XX(obj, many=False)    # XX对象

                - 列表生成式

                - 根据字符串的形式,自动导入模块并使用反射找到模块中的类【参考:s9day108】。

		- 解析器
			    - 根据ContentType请求头,选择不同解析器对 请求体中的数据进行解析。
				POST /index/ http1.1.\r\nhost:11.11.11.11\r\nContent-Type:url-formendo.... \r\n\r\nuser=alex&age=123
				POST /index/ http1.1.\r\nhost:11.11.11.11\r\nContent-Type:application/json\r\n\r\n{....}
		- 分页
		    	- 对从数据库中获取到的数据进行分页处理: SQL -> limit offset
				- 根据页码:http://www.luffycity.com/api/v1/student/?page=1&size=10
				- 根据索引:http://www.luffycity.com/api/v1/student/?offset=60&limit=10
				- 根据加密:http://www.luffycity.com/api/v1/student/?page=erd8
				页码越大速度越慢,为什么以及如何解决?
				  原因:页码越大向后需要扫描的行数越多,因为每次都是从0开始扫描。
				  解决:
						- 限制显示的页数
						- 记录当前页数据ID最大值和最小值,再次分页时,根据ID现行筛选,然后再分页。

		- 渲染器
		    - 根据URL中传入的后缀,决定在数据如何渲染到到页面上。




13、vue 发ajax请求时的this作用域



14、视图FBV和CBV
     FBV和CBV本质是一样的
     基于函数的视图叫做FBV,基于类的视图叫做CBV
     在python中使用CBV的优点:
         1.提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
         2.可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性

15、跨域
    - 为什么会有跨域?
        因为浏览器的同源策略导致,只有相同IP之间才能进行数据交互(开放:src 禁止:ajax)
    - 如何跨域?
        - 绕过浏览器同源策略就可以跨域。
            1. jsonp(只能发get请求,并且要求双方得规定好)
                动态创建script标签
                同源策略会阻止ajax请求;不阻止具有src属性的标签
                <script src='xxxx'></script>
            2. cors
                设置响应头,
                      简单请求
                      和复杂请求
                        1.请求以 GET, HEAD 或者 POST 以外的方法发起请求。
                        或者,使用 POST,但请求数据为 application/x-www-form-urlencoded,
                         multipart/form-data 或者 text/plain 以外的数据类型。
                         比如说,用 POST 发送数据类型为 application/xml 或者 text/xml 的 XML 数据的请求。
                        2.使用自定义请求头(比如添加诸如 X-PINGOTHER)
                        options请求做预检,加content_type,
                class CORSMiddleware(MiddlewareMixin):
                    def process_response(self,request,response):

                        # 允许所有域名来获取我的数据
                        response['Access-Control-Allow-Origin'] = "*"
                        if request.method == "OPTIONS":
                            # 允许你携带
                            response['Access-Control-Allow-Headers'] = "Content-Type"
                            # 允许你发送DELETE,PUT
                            response['Access-Control-Allow-Methods'] = "DELETE,PUT,POST"
                        return response


16、 你理解的Http协议?
    1.
        - 建立在tcp之上
        - 一次请求一次响应然后断开连接(无状态、短连接)
        - 请求和响应
            发送:请求头\r\n\r\n请求体
                  host:www.luffy.com\r\ncontent-type:application/json\r\n\r\n请求体
            响应:响应头\r\n\r\n响应体
    2.
    	Http协议就是一个传输数据格式。

		我原来学习django框架,从socket服务端开始学起。
		自己创造了一个socket服务器来充当:网站。
		浏览器当socket客户端。
		更清楚的明白到底http协议是什么?
			- 请求头 请求头
			- 响应头 响应头
		一次请求响应后,断开连接。
	3.常见请求头:Accept-Encoding,User-Agent(浏览器的身份标识字符串),Referer(表示浏览器所访问的前一个页面),Content-Type(	请求体的MIME类型 (用于POST和PUT请求中)),Accept,Cookie,Host
    4. 常见的请求体?
            Form表单提交:
                POST /index http1.1\r\nhost:www.luffycity.com...\r\n\r\nusername=alex&password=123&...
            Ajax请求:
                POST /index http1.1\r\nhost:www.luffycity.com...\r\n\r\nusername=alex&password=123&...
                POST /index http1.1\r\nhost:www.luffycity.com...\r\n\r\n{“username”:"alex","password":123}
            补充:django中获取请求体
                - request.POST
                - request.body
18、ORM方法
    class Depart(models.Model): 5个部门
        title = models.CharField(...)

    class User(models.Model):   10个用户
        name = models.CharField(...)
        email = models.CharField(...)
        dp = models.FK(Depart)
    result = models.User.objects.all().only('id','name','email')
    models.User.objects.all().values( 'id','name')
    models.User.objects.all().values_list( 'id','name')
    seleted_related,主动做连表查询(1次链表)result = User.objects.all().seleted_related('dp')
    prefetch_related:
         select * from user ;
         通过python代码获取:dp_id = [1,2]
         select * from depart where id in dp_id
        2次单表查询result = User.objects.all().prefetch_related('dp')
    数据量比较大,不会使用FK,允许出现数据冗余。
19、setting中根据字符串的形式,自动导入模块并使用
    利用a,b = xxx.split('.',maxlenth = 1)或a,b = xxx.split('.',1)
    import importlib
    m = importlib.import_module(a)
    cls = getattr(m,b)
    obj = cls()

20、 django中间件是什么?
    django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。
    在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件
    中间件中一共有四个方法:
        process_request
        process_view
        process_exception
        process_response

21、 使用中间件做过什么?
		- 内置
			- csrf
			- session
		- 自定义
			- 登录认证
			- 权限
			- cors
        - 登录认证,不再需要在每个函数中添加装饰器
        - 权限,当用户登录时候获取当前用户所有权限并放入session,然后再次访问其他页面,获取当前url并在session中进行匹配。如果没有匹配成功,则在中间件返回“无权访问”
        - 跨域,
                - jsonp,动态创建一个script标签。
                - cors,设置响应头
                应用:本地开始前后端分离的时使用。


22、 原生Ajax:XMLHttpRequest对象:

		原生Ajax:XMLHttpRequest对象:
				var xhr = new XMLHttpRequest()

				xhr.onreadystatechange = function(){
					if(xhr.readyState == 4){
						// 已经接收到全部响应数据,执行以下操作
						var data = xhr.responseText;
						console.log(data);
					}
				};

				xhr.open('POST', "/test/", true);

				// 设置请求头
				xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');

				// 发送请求
				xhr.send('n1=1;n2=2;');

23、 如果代码出现bug,你们是如何解决?
        创建一个bug分支,然后进行bug处理,处理完毕后,合并到master分支。
        删除bug分支
        回到dev分支继续开发。

24、 git rebase的作用?
    保持提交记录的整洁。

25、 redis和mysql
		mysql是一个软件,帮助开发者对一台机器的硬盘进行操作。
		redis是一个软件,帮助开发者对一台机器的内存进行操作。
		缓存,优先去redis中获取,如果没有就是数据库。

26 redis是什么?
		用于操作内存的软件。
		- 可以做持久化:
			- AOF:
			- RDB:
		- 相当于是大字典

		- 单进程单线程


27、 F和Q
        F,更新数据库字段
	    Q, 构造复杂条件

28、 git协同开发
	    a. 怎么通过git做得协同开发?

		b. 是否做代码review?

		c. 开发过程中出现bug如何做?

		d. git rebase作用?

		e. 给别人开源代码贡献力量。

		f. 使用的github、gitlab ?

		PS:隐藏明感信息


29、Django和flask的区别

30、 Flask提供的功能
    配置文件
        app.config.from_object("类的路径")
        app.config["xx"] = xxx
        应用:
            Django中间件
            rest framework全局配置

31、 session的原理
    1、当请求到来时从用户的cookie中把值取出(浏览器)
    2、在视图中解密,反序列化,以字典的方式放到内存中,
    3、请求结束把session序列化加密

32、 Flask中g的生命周期?
33、 g和session一样吗?
34、 g和全局变量一样吗?
35、 谈谈你对django和flask的认识?
36、 上下文管理
37、 什么是响应式布局?

38、给出m长的0或1,然后最多补n个0,求最长连续1后或前补完0。连续最长1
        n = int(input(">>"))
        m = int(input(">>"))
        lis = [int(input(">>")) for i in range(n)]
        
        lis.append(0)
        cnt_list = []
        flag = 0
        start = 0
        for i in range(len(lis)):
            if lis[i] == 1:
                if flag == 0:
                    flag = 1
                    start = i
            else:
                end = i
                if flag == 1:
                    flag = 0
                    cnt_list.append([start, end])
                    start = end = 0
        
        ever_max_len = []
        for k in range(len(cnt_list)-1):
            if k < len(cnt_list) - 1:
                num = cnt_list[k+1][0]-cnt_list[k][1]
                print(num)
                if num <= m:
                    ever_max_len.append(cnt_list[k][1]-cnt_list[k][0]+cnt_list[k+1][1]-cnt_list[k+1][0]+num)
                else:
                    ever_max_len.append(max(cnt_list[k][1]-cnt_list[k][0]+m, cnt_list[k+1][1]-cnt_list[k+1][0]+m))
        print(max(ever_max_len))
39、threading.local
			应用:
				- Flask上下文管理中的Local类更高级
				- DBUtils线程池的模式一:为每个线程创建一个连接。
				- SQLAlchemy
					from sqlalchemy.orm import sessionmaker
					from sqlalchemy import create_engine
					from sqlalchemy.orm import scoped_session
					from models import Student,Course,Student2Course

					engine = create_engine(
							"mysql+pymysql://root:123456@127.0.0.1:3306/s9day120?charset=utf8",
							max_overflow=0,  # 超过连接池大小外最多创建的连接
							pool_size=5,  # 连接池大小
							pool_timeout=30,  # 池中没有线程最多等待的时间,否则报错
							pool_recycle=-1  # 多久之后对线程池中的线程进行一次连接的回收(重置)
						)
					SessionFactory = sessionmaker(bind=engine)

					# 为每个线程创建一个连接
					session = scoped_session(SessionFactory)


					def task():
						ret = session.query(Student).all()
						# 将连接交还给连接池
						session.remove()


					from threading import Thread

					for i in range(20):
						t = Thread(target=task)
						t.start()
40、上下文管理
41、 为什么要创建两个Local?或两个LocalStack?
			- 编写离线脚本时,需要配置文件,而配置文件存放在app中。
			- 编写离线脚本时,不需要请求相关的数据。

			所以,将app和请求相关的数据分开:
				- 应用上下文(app,g)
				- 请求上下文(request,session)

42、 Flask程序有几个Local和LocalStack?


			请求LocalStack,帮助开发对stack对应列表操作
				请求Local = {
					1212:{
						stack:[ctx,]
					}
				}


			应用LocalStack,帮助开发对stack对应列表操作
				应用Local = {
					1212:{
						stack:[app_ctx,]
					}
				}


43、web运行时多个app离线脚本(web runtime):
				请求Local = {
					1111:{
						stack:[ctx1,]
					},
					1112:{
						stack:[ctx2,]
					},
					1113:{
						stack:[ctx3,]
					}
				}

				应用Local = {
					1111:{
						stack:[app_ctx1,]
					}
					1112:{
						stack:[app_ctx2,]
					},
					1113:{
						stack:[app_ctx3,]
					}
				}
			多app离线脚本:
				from flask import current_app
				app1 = create_app()
				app_ctx1 = app1.app_context() # app_ctx = app/g

				app2 = create_app()
				app_ctx2 = app2.app_context() # app_ctx = app/g

				with app_ctx1: # __enter__,通过LocalStack放入Local中
					print(current_app) # app1
					with app_ctx2:
						print(current_app) # app2

					print(current_app) # app1
44、如何对对象做约束
			Java:
				- 接口,约子类中必须包含某个方法(约束)。
					Interface IMessage:
						def func1(self):
							pass
						def func2(self):
							pass

					class Msg(IMessage):
						def func1(self):
							print('func1')
						def func2(self):
							print('func1')

				- 抽象方法/抽象类,约子类中必须包含某个方法。(约束+继承)
					class abstract IMessage:
						def abstract func1(self):
							pass
						def abstract func2(self):
							pass

						def func3(self):
							print('asdfasdf')

					class Msg(IMessage):
						def func1(self):
							print('func1')
						def func2(self):
							print('func1')

			Python:
				- 接口(无)
				- 抽象方法/抽象类(有,ABC)

				- 类继承+异常

					class IMessage(object):

						def func1(self):
							raise NotImplementedError('子类没有实现func1方法')


					class Msg(IMessage):
						def func1(self):
							print('123')


					obj = Msg()
					obj.func1()

			有什么用?用于告知其他人以后继承时,需要实现那个方法,如:

				class BaseAuthentication(object):
					"""
					All authentication classes should extend BaseAuthentication.
					"""

					def authenticate(self, request):
						"""
						Authenticate the request and return a two-tuple of (user, token).
						"""
						raise NotImplementedError(".authenticate() must be overridden.")

					def authenticate_header(self, request):
						"""
						Return a string to be used as the value of the `WWW-Authenticate`
						header in a `401 Unauthenticated` response, or `None` if the
						authentication scheme should return `403 Permission Denied` responses.
						"""
						pass


			以后自己开发时,如何使用?
				需求:
					class BaseMessage(object):

						def send(self):
							raise NotImplementedError('必须实现send方法')


					class Msg(BaseMessage):
						def send(self):
							print('发送短信')


					class Wechat(BaseMessage):
						def send(self):
							print('发送微信')


					class Email(BaseMessage):
						def send(self):
							print('发送邮件')



					class DingDing(BaseMessage):
						def send(self):
							print('发送钉钉提醒')
45、 metaclass作用:指定类由那个type创建?(type泛指继承type的所有类)

46、 数据库如何加锁?
			终端1:
				begin;
				select * from tb for update;
				commit;

			终端2:
				begin;
				select * from tb for update;
				commit;

47、什么时候需要加锁?
			- 计数
			- 应用场景:
				- 商品数量

48、视图、触发器、函数、存储过程是什么?

49、 执行计划
			explain select * from tb;
			 id
				查询顺序标识
					如:mysql> explain select * from (select nid,name from tb1 where nid < 10) as B;
					+----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
					| id | select_type | table      | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
					+----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
					|  1 | PRIMARY     | <derived2> | ALL   | NULL          | NULL    | NULL    | NULL |    9 | NULL        |
					|  2 | DERIVED     | tb1        | range | PRIMARY       | PRIMARY | 8       | NULL |    9 | Using where |
					+----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
				特别的:如果使用union连接气值可能为null


			select_type
				查询类型
					SIMPLE          简单查询
					PRIMARY         最外层查询
					SUBQUERY        映射为子查询
					DERIVED         子查询
					UNION           联合
					UNION RESULT    使用联合的结果
					...
			table
				正在访问的表名


			type
				查询时的访问方式,性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const
					ALL             全表扫描,对于数据表从头到尾找一遍
									select * from tb1;
									特别的:如果有limit限制,则找到之后就不在继续向下扫描
										   select * from tb1 where email = 'seven@live.com'
										   select * from tb1 where email = 'seven@live.com' limit 1;
										   虽然上述两个语句都会进行全表扫描,第二句使用了limit,则找到一个后就不再继续扫描。

					INDEX           全索引扫描,对索引从头到尾找一遍
									select nid from tb1;

					RANGE          对索引列进行范围查找
									select *  from tb1 where name < 'alex';
									PS:
										between and
										in
										>   >=  <   <=  操作
										注意:!= 和 > 符号


					INDEX_MERGE     合并索引,使用多个单列索引搜索
									select *  from tb1 where name = 'alex' or nid in (11,22,33);

					REF             根据索引查找一个或多个值
									select *  from tb1 where name = 'seven';

					EQ_REF          连接时使用primary key 或 unique类型
									select tb2.nid,tb1.name from tb2 left join tb1 on tb2.nid = tb1.nid;



					CONST           常量
									表最多有一个匹配行,因为仅有一行,在这行的列值可被优化器剩余部分认为是常数,const表很快,因为它们只读取一次。
									select nid from tb1 where nid = 2 ;

					SYSTEM          系统
									表仅有一行(=系统表)。这是const联接类型的一个特例。
									select * from (select nid from tb1 where nid = 1) as A;
			possible_keys
				可能使用的索引

			key
				真实使用的

			key_len
				MySQL中使用索引字节长度

			rows
				mysql估计为了找到所需的行而要读取的行数 ------ 只是预估值

			extra
				该列包含MySQL解决查询的详细信息
				“Using index”
					此值表示mysql将使用覆盖索引,以避免访问表。不要把覆盖索引和index访问类型弄混了。
				“Using where”
					这意味着mysql服务器将在存储引擎检索行后再进行过滤,许多where条件里涉及索引中的列,当(并且如果)它读取索引时,就能被存储引擎检验,因此不是所有带where子句的查询都会显示“Using where”。有时“Using where”的出现就是一个暗示:查询可受益于不同的索引。
				“Using temporary”
					这意味着mysql在对查询结果排序时会使用一个临时表。
				“Using filesort”
					这意味着mysql会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。mysql有两种文件排序算法,这两种排序方式都可以在内存或者磁盘上完成,explain不会告诉你mysql将使用哪一种文件排序,也不会告诉你排序会在内存里还是磁盘上完成。
				“Range checked for each record(index map: N)”
					这个意味着没有好用的索引,新的索引将在联接的每一行上重新估算,N是显示在possible_keys列中索引的位图,并且是冗余的。
50、慢日志?
			- 查询时间久
			- 未命中索引

			修改配置:
				slow_query_log = ON                            是否开启慢日志记录
				long_query_time = 2                              时间限制,超过此时间,则记录
				slow_query_log_file = /usr/slow.log        日志文件
				log_queries_not_using_indexes = ON     为使用索引的搜索是否记录
51、无法命中的情况?
52、数据库优化方案:
			- 不使用select *
			- 短索引
			- 使用链表代替子查询
			- 固定长度在前面
			- 分库分表
			- 组合索引 > 索引合并
			- 内存代替链表
				- choices
			- limit
			- 读写分离(主从)
			- 分页
			- 缓存
53、谈谈你对面向对象的认识。

54、Local的作用?
    类似于threading.local的作用,但是是他的升级版(greentlet.get_current())
    __storage__ = {
        1231: {},
        1231: {}
    }
55、LocalStack作用?
    将Local中__storage__的值维护成一下结构:
    __storage__ = {
        1231: {stack:[],},
        1231: {stack:[],}
    }
56、web知识
    - 请求和响应:
        - 请求:
            "GET /index http1.1\r\nhost:c1.com\r\nContent-type:asdf\r\nUser-Agent:aa\r\nreferer:www.xx.com;cookie:k1=v1;k2=v2;\r\n\r\n"
        - 响应:
            "HTTP/1.1 200 \r\nSet-Cookies:k1=v1;k2=v2,Connection:Keep-Alive\r\nContent-Encoding:gzip\r\n\r\n<html>asdfasdfasdfasdfdf</html>"
    - 携带常见请求头
        - user-agent
        - referer
        - host
        - content-type
        - cookie
    - csrf
        - 原因1:
            - 需要浏览器+爬虫先访问登录页面,获取token,然后再携带token去访问。
        - 原因2:
            - 两个tab打开的同事,其中一个tab诱导你对另外一个tab提交非法数据。
57、 OSI 7层模型

58、 三次握手、四次挥手?

59、 TCP和UDP区别?

60、 路由器和交换机的区别?

61、 ARP协议?

62、 DNS解析?

63、 Http和Https?

64、 进程、线程、协程区别?

65、 GIL锁

66、 进程如何进程共享?

67、twisted是什么以及和requests的区别?
    requests是一个Python实现的可以伪造浏览器发送Http请求的模块。
        - 封装socket发送请求

    twisted是基于事件循环的异步非阻塞网络框架。
        - 封装socket发送请求
        - 单线程完成并发请求
        PS: 三个相关词
            - 非阻塞:不等待
            - 异步:回调
            - 事件循环:一直循环去检查状态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值