1:Python列表、元组、字典的区别?
这个问题应该经常被问到,大家在这里详细做个解释。
列表(List),Python的列表实际上是一个动态数组,存储在一个连续的内存区块中,随机存取的复杂度是O(1),插入和删除元素时会造成内存块的移动,时间复杂度是O(n)。同时它是一个可变对象,当大家对列表进行赋值时获取到的只是它的内存地址,如果需要将列表里的内容全部复制给另一个变量,需要用到copy(浅拷贝)和deepcopy(深度拷贝)。
元组(Tuple),Python的元组是一个不可变的数据结构,它本质上也是一个数组。因为是不可变对象,所以Tuple的长度在创建时就是恒定的,所以大家也无法对它进行添加和删除元素的操作。不过在Tuple内所包含的对象是可变的。当大家把包含元组的变量赋值给另一个变量时,实际上是在内存中重新申请了一块内存空间用于新建了一个元组。
字典(Dict),Python的字典是一个哈希表,根据键值对(Key,Value)直接访问的数据结构。关于哈希函数在这里不多做解析,大家可以自行了解。如果字典在产生哈希冲突时,也就是Key遇到重复的时候。Python会通过开放定址法来计算下一个候选位置,反复测试最终保证生成的哈希值不会产生冲突。字典跟列表一样,也是可变对象,复制内容同样需要用到copy(浅拷贝)和deepcopy(深度拷贝)。
2:如何将一个字符串或者数字倒序输出?
字符串倒序,大家可以利用Python的切片对字符串进行倒序,参考如下代码:
str1="长风几万里,吹度玉门关"print(str1[::-1])
切片的参数格式:[start_index:stop_index:step]
如果大家不填写切片起止位置参数,那么默认是取字符串全部内容,当step参数(步长)为负数时,字符串会自动从右往左取值,-1就是依次取值,那么就自然是倒序了。
大家同样可以通过切片的原理对数字进行倒序输出。
#正整数的情况number=10002new_number=int(str(number)[::-1])#负整数的情况number=-10002new_number=int('-{0}'.format(str(abs(number))[::-1]))
3:谈一下Python的内存管理机制
Python内建了垃圾回收处理机制,引用计数是这个机制的一部分。
在Pyhton源码中,实际上是用Py_INCREF(op)和Py_DECREF(op)这两个宏来增加和减少引用计数。
当一个对象被创建、被赋值、被参数传递,函数返回之前的时候,它的引用计数值(ob_refcnt)都可能会被加1(INC),一直进行累加。
当对象变量失去作用域的时候,引用计数的值会减1(DEC)。
当一个对象的引用计数减少到0之后(ob_refcnt为0),Py_DECREF(op)会调用该对象"析构函数"(__del__)将其从内存中释放。
4:什么是Session、Cookie、Token?
Session是一个概念,信息存储在服务端。
Cookie是对Session的一种实现,并信息存储在客户端(浏览器)。
因为HTTP协议无状态的特性,以至于大家需要在浏览器和服务端之间建立一个用于识别用户身份和详细信息的凭证,这个凭证可以是Cookie、Token任意一种。
当用户登陆成功时,大家可以将其的身份凭证在服务端生成一个Session信息,保存在文件,数据库或者内存里,通常Session会有一个Sessionid。
因为访问服务端Session信息需要用到Sessionid,所以通常情况下,大家将Sessionid存在Cookie里。
Cookie其实信息在用户登陆产生Session信息之后再将Sessionid或者别的附加信息返回给客户端,由客户端存储在本地文件里。
当浏览器向服务端发起请求时会带着Cookie里的Sessionid访问服务端,服务端根据Sessionid找到存储好的Session信息,如果信息能找到并且内容无误,即视为访问有效。
Cookie除了存储Sessionid外也可以存储其他非敏感的信息(例如用户昵称,头像等),提供给浏览器直接使用,而不用每次都从服务端去拿。
关于Token,实际上用在基于RESTAPI相关的服务里比较多。
它的认证机制是当用户登陆后服务端算出一个Token信息存储在服务端并返回给客户端,内容通常包含用户id,当前时间戳,签名和其他信息。
Token在客户端一般存放于localStorage、cookie、或sessionStorage中。在服务器一般存于数据库中。
当客户端再次请求服务端时,会从本地拿到Token信息,并放在headers中,服务端收到请求,会自动去headers里拿到Token进行解析以用于识别用户身份。
5:GET和POST的区别和作用?
GET和POST在本质上没有区别,HTTP协议并没有规定GET和POST传输数据长度的限制。
唯一的限制可能存在于服务端的服务程序和浏览器。
通常在Nginx或者各种WebServer服务程序里会有定义GET和POST传输最大长度的限制。
而GET提交的数据长度限制通常取决于浏览器,每种浏览器的限制不一样。
在HTTP协议中,使用什么样的Method和数据如何传输其实没有相互的关系,在绝大多数的WebServer里。GET和POST提交的数据其实都在BODY区域内,大家既可以通过GET来传输文件,也可以通过POST来传输文件。
之所以通常定义GET用来获取数据,POST用来提交数据是因为GET请求是幂等的,POST请求不是。
幂等性是指一次和多次请求某一个资源应该具有同样的副作用。简单来说意味着对同一URL的多个请求应该返回同样的结果。
基于幂等的原则,大家用GET进行数据的添加修改删除时会有副作用,因为在网络情况不好的时候GET会自动尝试重试,增加了重复操作数据的风险。而用它获取数据就不会存在这样的风险,因为大家哪怕对一个资源请求100万次,它还是不会改变。
这个问题看面试官的技术水准,如果面试官愿意跟你聊得比较深入,那你可以这么回答。如果面试官自己心里也是一些标准答案的话,那建议只回答GET用于获取数据,POST用于提交数据。
另外DELETE方法其实也是幂等的,哪怕你删除100万次,数据其实也只会被删除一次。