汇集天下武学——Python笔试题

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 是否成功(例如银行系统的做法)

        另一种简单的做法是,设计分布式协议时将执行步骤设计为可重试的,即具有所谓的“幂等性”

你可能感兴趣的:(汇集天下武学——Python笔试题)