1、数据表student有id,name,score,city字段,其中name中的名字可有重复,需要消除重复行,请写sql语句
select distinct name from student
2、10个Linux常用命令
ls pwd cd touch rm mkdir tree cp mv cat more grep echo
3、简述mysql和redis区别
redis: 内存型非关系数据库,数据保存在内存中,速度快
mysql:关系型数据库,数据保存在磁盘中,检索的话,会有一定的Io操作,访问速度相对慢
4、简述同源策略
同源策略需要同时满足以下三点要求:
1)协议相同
2)域名相同
3)端口相同
http:www.test.com与https:www.test.com 不同源——协议不同
http:www.test.com与http:www.admin.com 不同源——域名不同
http:www.test.com与http:www.test.com:8081 不同源——端口不同
只要不满足其中任意一个要求,就不符合同源策略,就会出现“跨域”
5、简述Django的orm:
ORM,全拼Object-Relation Mapping,意为对象-关系映射
实现了数据模型与数据库的解耦,通过简单的配置就可以轻松更换数据库,
而不需要修改代码只需要面向对象编程,orm操作本质上会根据对接的数据库引擎,
翻译成对应的sql语句,所有使用Django开发的项目无需关心程序底层使用的是MySQL、Oracle、sqlite....,
如果数据库迁移,只需要更换Django的数据库引擎即可
6、zip函数用法:
zip()函数在运算时,会以一个或多个序列(可迭代对象)做为参数,
返回一个元组的列表。同时将这些序列中并排的元素配对。
zip()参数可以接受任何类型的序列,同时也可以有两个以上的参数;当传入参数的长度不同时,
zip能自动以最短序列长度为准进行截取,获得元组。
实例:取一个字符串数据的公公前缀
7、常用sql语句:
show databases;
show tables;
desc 表名;
select * from 表名;
delete from 表名 where id=5;
update students set gender=0,hometown="北京" where id=5
8、MyISAM 与 InnoDB 区别:
a、InnoDB 支持事务,MyISAM 不支持,这一点是非常之重要。
事务是一种高级的处理方式,如在一些列增删改中只要哪个出错还可以回滚还原,
而 MyISAM就不可以了;
b、MyISAM 适合查询以及插入为主的应用,
InnoDB 适合频繁修改以及涉及到安全性较高的应用;
c、InnoDB 支持外键,MyISAM 不支持;
d、对于自增长的字段,InnoDB 中必须包含只有该字段的索引,
但是在 MyISAM表中可以和其他字段一起建立联合索引;
e、清空整个表时,InnoDB 是一行一行的删除,效率非常慢。
MyISAM 则会重建表;
9、简述python垃圾回收机制:
python垃圾回收主要以引用计数为主,标记-清除和分代清除为辅的机制,
其中标记-清除和分代回收主要是为了处理循环引用的难题。
引用计数算法:当有1个变量保存了对象的引用时,此对象的引用计数就会加1
当使用del删除变量指向的对象时,如果对象的引用计数不为1,比如3,
那么此时只会让这个引用计数减1,即变为2,当再次调用del时,变为1,
如果再调用1次del,此时会真的把对象进行删除
10、描述数组、链表、队列、堆栈的区别
数组与链表是数据存储方式的概念,数组在连续的空间中存储数据,
而链表可以在非连续的空间中存储数据;
队列和堆栈是描述数据存取方式的概念,队列是先进先出,而堆栈是后进先出;
队列和堆栈可以用数组来实现,也可以用链表实现
11、请解释或描述一下Django的架构
对于Django框架遵循MVC设计,并且有一个专有名词:MVT
M全拼为Model,与MVC中的M功能相同,负责数据处理,内嵌了ORM框架
V全拼为View,与MVC中的C功能相同,接收HttpRequest,业务处理,返回HttpResponse
T全拼为Template,与MVC中的V功能相同,负责封装构造要返回的html,内嵌了模板引擎
12、Post请求和get请求区别?
相同:两者都是基于TCP协议工作的。
区别:
1.GET请求一般会被浏览器主动cache,POST不会
(这点很重要,cache刷新页面浏览器不会再请求服务器,
如果设置了max-age的话,减轻服务器负载,提升用户体验)
2.GET请求中传送的参数是有长度限制的(协议规范没有,各个浏览器有,IE最短是2083bytes),
POST没有(但受服务器处理能力影响)。程序内部调用则URL长度不受限制。
3.GET参数是明文保存在URL中,POST参数保存在body中。
13、Session和Cookie的区别?
相同:两者都是用来跟踪浏览器用户身份的会话方式
区别:
1.cookie保存在客户端,session在服务器端
2.保存在客户端就意味着cookie可能被分析并用来实施cookie欺骗,而session不会(也只是相对安全)
3.session存在服务器端就意味着需要消耗服务器性能。
4.cookie的大小会被浏览器限制,一般是4KB(包括key-value),session没有理论限制。
小结:cookie和session两者各有优缺点,实际使用中可将两者结合。
14、创建一个简单tcp服务器需要的流程
1.socket创建一个套接字
2.bind绑定ip和port
3.listen使套接字变为可以被动链接
4.accept等待客户端的链接
5.recv/send接收发送数据
15、scrapy和scrapy-redis有什么区别?为什么选择redis数据库?
1.scrapy是一个Python爬虫框架,爬取效率极高,具有高度定制性,但是不支持分布式。
而scrapy-redis是一套基于redis数据库、运行在scrapy框架之上的组件,
可以让scrapy支持分布式策略,Slaver端共享Master端redis数据库里的item队列、请求队列和请求指纹集合。
2.为什么选择redis数据库,因为redis支持主从同步,而且数据都是缓存在内存中的,
所以基于redis的分布式爬虫,对请求和数据的高频读取效率非常高。
16、可变与不可变类型
1.解释两种类型:
不可变对象 -- 该对象所指向的内存中的值不能被改变。当改变某个变量时候,由于其所指的值不能被改变,
相当于把原来的值复制一份后再改变,这会开辟一个新的地址,变量再指向这个新的地址。
可变对象 -- 该对象所指向的内存中的值可以被改变。变量(准确的说是引用)改变后,实际上是其所指的值
直接发生改变,并没有发生复制行为,也没有开辟新的出地址,通俗点说就是原地改变。
2.两种类型分别有哪些:
不可变:int,float,str,tuple
可变: list,dict,set
17、谈谈浅拷贝与深拷贝
1.python中有值类型与引用类型之分(对应不可变与可变对象)
2.由于值类型的对象在内存中占固定内存空间,所以他们的值保存在栈,按值访问数据
而引用类型的对象大小不固定,所以只将它们的内存地址(它是固定的)存放在栈,由于内存地址指向
实际对象,所有引用类型是按引用访问
3.浅拷贝实现:只复制某个对象的内存地址,新旧变量共享同一内存同一对象。
深拷贝实现:直接复制对象本身,新的对象是独立的,拥有不一样的内存地址,对原对象的修改不影响新对象。
18、__new__和__init__的区别
1. new在init之前执行,前者可决定是否调用后者
2. 在OOP中,实例化遵循 创建x,初始化x,返回x (x=实例对象)这么个顺序,new是创建,init是初始化
19、*args and **kwargs如何使用?
*args代表位置参数,它会接收任意多个参数并把这些参数作为元组传递给函数。
**kwargs代表的关键字参数,允许你使用没有事先定义的参数名,kwagrs是一个dict;
另外,位置参数一定要放在关键字参数的前面。
20、线程与进程的区别
从四个方面来分析:
1.调度方不同:进程是操作系统调度的基本单位,而线程是cpu调度的基本单位。
2.开销不同:创建一个进程需要系统单独分配新的地址空间,代价昂贵;而创建新的线程可以直接
使用进程的内存空间,所以进程开销大于线程。
3.通信方式不同:进程间通信一般通过HTTP或RPC方式;而同一进程下的不同线程间是共享全局变量的,通信更简便。
4.健壮性不同:单个进程死掉不会影响其他进程,而单个线程死掉会导致整个进程死掉。
21、谈谈设计模式
1. 解释一下什么是设计模式
简述:是经过总结、优化后的可重用解决方案。它是一种代码设计思想,不同的模式解决不同的问题,
跟编程语言不相关。
2. 你知道哪些设计模式,代码如何实现
a. 工厂模式: 是一个在软件开发中用来创建对象的设计模式。(详解工厂模式:https://www.cnblogs.com/lizhitai/p/4471952.html)
意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。
适用性:
当一个类不知道它所必须创建的对象的类的时候。
当一个类希望由它的子类来指定它所创建的对象的时候。
当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
b. 单例模式:
意图: 保证程序运行时全局环境中只有一个该类的实例
适用性:无论何时何处调用该类,都能使用同一个该类的实例对象的时候。
代码实现:
class Singleton: #一个通用的单例超类,其他类继承即可(也可通过装饰器实现)
def __new__(cls, *args, **kw):
if not hasattr(cls, '_instance'):
cls._instance = object.__new__(cls)
return cls._instance
class SingleSpam(Singleton):
def __init__(self, s):
self.s = s
def __str__(self):
return self.s
c. 装饰模式:
意图:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。
适用性:
1. 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
2. 处理那些可以撤销的功能
d. 迭代器模式:
意图:提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。
适用性:
1. 访问一个聚合对象的内容而无需暴露它的内部表示。
2. 支持对聚合对象的多种遍历。
3. 为遍历不同的聚合结构提供一个统一的接口(即, 支持多态迭代)。
代码实现:
# 使用magic方法构建迭代器
class iterable2:
def __init__(self,container):
self._a = container
self._index= -1
def __iter__(self):
return self
def __next__(self):
try:
ret = self._a[self._index+1]
self._index += 1
return ret
except:
raise StopIteration
22、with语句应用场景是?有什么好处?能否简述实现原理
场景:with语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,
释放资源,比如文件使用后自动关闭、线程中锁的自动获取和释放等。
好处:不需要人为释放资源。
原理:with 主要用到一个概念:上下文管理器。
1. 程序运行时,将with后紧跟的对象(一般是个class示例)称作上下文管理器。这个class必须
定义两个方法,__enter__()方法和__exit__(),前者的返回对象赋值给as后面变量。
2. 运行中如果发生了异常,那么将会把异常的类型,值和追踪传递给__exit__()方法。如果__exit__()
方法返回值为true,那么这个异常将会被抑制,否则这个异常将会被重新抛出。
3. 如果没有发生异常,也会调用__exit__()方法,但是传入的参数为None, None, None。
通常也是在这里放入代码进行如文件流/会话的关闭等操作。
23、TCP与UDP区别;简述三次握手和四次挥手过程
相同:传输层协议,用于报文传输
不同:TCP比UDP可靠,是面向连接的,拥有三次握手和四次挥手、以及超时重传、拥塞控制等机制来保证传输过程可靠,安全。
而UDP传输过程简单,快速高效,且开销小,因为没有建立连接的过程,报文头部仅8字节,TCP头部20字节以及40字节可选项。
但是它没有ACK和序列号机制,无法解决报文丢失和顺序错乱问题。
TCP只能点对点,UDP可以一对一,一对多,多对多。
三次握手:
1. client发送SYN(seq=x)报文 => server(client状态变为SYN_SENT)
2. server发送ACK(seq=x+1)以及SYN(seq=y)报文 =>client (server状态变为SYN_RECV)
3. client发送ACK(seq=y+1) => server (client变为ESTABLISHED,服务器收到后也变为ESTABLISHED)
四次挥手:
1. client发送FIN(seq=x) =>server (client变为FIN_WAIT_1)
2. server先回复ACK(seq=x+1) => client (server只要收到FIN报文就会变为CLOSE_WAIT, client变为FIN_WAIT_2)
3. server发送完剩余的数据报文后,再发送FIN(seq=y) =>client (server变为LAST_CHECK)
4. client发送ACK(seq=y+1) => server (client变为TIME_WAIT)
server收到ACK后直接就关闭closed状态,但client要等2MSL(最大报文生存时间)才会变为closed。
client的状态转变顺序:established-->fin_wait_1->fin_wait_2->time_wait->closed
server的状态转变顺序: established-->close_wait->last_ack->closed
24、说说悲观锁和乐观锁
悲观锁与乐观锁是在资源并发中常见的两种锁设计方式。
1.悲观锁
它的特点是,先获取锁,再做业务操作。即认为在它去操作数据库数据的同时,老是有人来抢,索性直接先获取锁,
谁都抢不了,我先来。在mysql中的实现是“select … for update”语句或者直接“update... where...”,
两者都能获得排它锁,防止别人操作。
悲观锁因为要使用事务,降低了DB并发性能,适合强一致性的场景。
2.乐观锁
它的特点是,先做业务操作,失败后就等着别人释放锁。即认为在它去操作数据库的同时,没有人跟他抢,那就不加锁了。
直接修改业务数据。如果执行修改语句的时候发现资源被别人上了锁,就进入锁等待。等别人释放锁后它再执行。
mysql中如何实现:
给表增加一个字段叫版本号:version,int类型,修改一次加个1。然后通过几行SQL语句实现:
SELECT DATA,version as old_v FROM xxx
rows = UPDATE SET data=data-1,version=version+1 WHERE version=old_v
if rows > 0:
//修改成功
else:
//修改失败,然后重新再走一次此流程,直到成功(但是retry会造成较大的开销)。
乐观锁适用于读多写少,并发冲突较少的场景。
25、链表和顺序表储存时各自有什么优点?
1.顺序表存储
原理:顺序表存储是将数据元素放到一块连续的内存存储空间,
存取效率高,速度快。但是不可以动态增加长度
优点:存取速度高效,通过下标来直接存储
缺点:插入和删除比较慢,不可以增长长度
比如:插入或者删除一个元素时,整个表需要遍历移动元素来重新排一次顺序
2.链表存储
原理:链表存储是在程序运行过程中动态的分配空间,只要存储器还有空间,就不会发生存储溢出问题
优点:插入和删除速度快,保留原有的物理顺序,比如:插入或者删除一个元素时,需要改变指针指向即可
缺点:查找速度慢,因为查找时,需要循环链表访问
26、数据仓库是什么?
概念:
数据仓库是一个面向主题的、集成的、稳定的、反映历史变化的、
随着时间的流逝发生变化的数据集合。它主要支持管理人员的决策分析。
数据仓库收集了企业相关内部和外部各个业务系统数据源、归档文件等一系列历史数据,
最后转化成企业需要的战略决策信息。
特点:
1. 面向主题:根据业务的不同而进行的内容划分;
2. 集成特性:因为不同的业务源数据具有不同的数据特点,当业务源数据进入到数据仓库时,
需要采用统一的编码格式进行数据加载,从而保证数据仓库中数据的唯一性;
3. 非易失性:数据仓库通过保存数据不同历史的各种状态,并不对数据进行任何更新操作。
4. 历史特性:数据保留时间戳字段,记录每个数据在不同时间内的各种状态。
27、使用redis搭建分布式系统时如何处理网络延迟和网络异常?
由于网络异常的存在,分布式系统中请求结果存在“三态”的概念,
即三种状态:“成功”、“失败”、“超时(未知)”
当出现“超时”时可以通过发起读取数据的操作以验证 RPC 是否成功(例如银行系统的做法)
另一种简单的做法是,设计分布式协议时将执行步骤设计为可重试的,即具有所谓的“幂等性”