Python2018秋招(笔者亲身经历)

毕业即失业,苦逼的大四狗伤不起哟。

又到了一年一度的秋招了,笔者也在拉勾,智联,boss直聘注册了,投了50份简历,3个面试,然而全挂了。

笔者痛定思痛决定将自己的经历贴出,希望可以帮到要面试的同学。

雨轩恋原创 转载请注明来源 雨轩恋i - 博客园  http://www.cnblogs.com/yuxuanlian/

算法编程题

1 冒泡排序

思想:冒泡排序从小到大排序:一开始交换的区间为0~N-1,将第1个数和第2个数进行比较,前面大于后面,交换两个数,否则不交换。再比较第2个数和第三个数,前面大于后面,交换两个数否则不交换。依次进行,最大的数会放在数组最后的位置。然后将范围变为0~N-2,数组第二大的数会放在数组倒数第二的位置。依次进行整个交换过程,最后范围只剩一个数时数组即为有序。

代码:

#交换排序.冒泡排序
L = [1, 3, 2, 32, 5, 4]
def Bubble_sort(L):
    for i in range(len(L)):
        for j in range(i+1,len(L)):
            if L[i]>L[j]:
                # temp = L[j]
                # L[j] = L[i]
                # L[i] = temp
                L[i], L[j] = L[j], L[i]#交换顺序

    print (L)
Bubble_sort(L)

2 插入排序

思想:插入排序从小到大排序:首先位置1上的数和位置0上的数进行比较,如果位置1上的数大于位置0上的数,将位置0上的数向后移一位,将1插入到0位置,否则不处理。位置k上的数和之前的数依次进行比较,如果位置K上的数更大,将之前的数向后移位,最后将位置k上的数插入不满足条件点,反之不处理。

代码:

#1.直接插入排序
L = [1, 3, 2, 32, 15, 5, 4]
def Insert_sort(L):
    for i in range(1,len(L)):
        for j in range(0,i):#这里面其实也是从前向后比较
            if L[i]<L[j]:
                L.insert(j,L[i])#在不大于的位置插入L[i],这个时候,列表加长了1,L[i]插入到指定位置了,但它的值也向后移动了一位
                L.pop(i+1)#把原来L[i]的值删除。
    print(L)
    #空间复杂度为O1),时间复杂度为On*n
Insert_sort(L)
# print sorted(L)#自带的两种排序
# L.sort()
# print L

3 选择排序

思想:选择排序从小到大排序:一开始从0~n-1区间上选择一个最小值,将其放在位置0上,然后在1~n-1范围上选取最小值放在位置1上。重复过程直到剩下最后一个元素,数组即为有序。

代码:

L = [6, 3, 2, 32, 5, 4]
def Select_sort(L):
    for i in range(0,len(L)):
        for j in range(i,len(L)):
            if L[i] > L[j]:         #打擂台的形式
                # temp = L[i]
                # L[i] = L[j]
                # L[j] = temp
                L[i],L[j] = L[j],L[i]
    return  L
print (Select_sort(L))

4 快速排序

思想:快速排序从小到大排序:在数组中随机选一个数(默认数组首个元素),数组中小于等于此数的放在左边,大于此数的放在右边,再对数组两边递归调用快速排序,重复这个过程。

代码:

#1.高质量代码
def quick_sort(lists, left, right):
    # 快速排序
    if left >= right:
        return lists
    key = lists[left]
    low = left
    high = right
    while left < right:
        while left < right and lists[right] >= key:
            right -= 1
        lists[left] = lists[right]
        while left < right and lists[left] <= key:
            left += 1
        lists[right] = lists[left]
    lists[left] = key
    quick_sort(lists, low, left - 1)
    quick_sort(lists, left + 1, high)
    return lists
print (quick_sort(L,0,5))

  1. 斐波那契数列

斐波那契数列,又称黄金分割数列,指的是这样一个数列:0112358132134、……在数学上,斐波纳契数列以如下被以递归的方法定义:F0=0F1=1Fn=F(n-1)+F(n-2)

代码:

#最简单的方法为数组,其次为循环,最垃圾的为递归,到了40就算好久。。日后再琢磨数组
a=[1,1]
def fn(n):
    count=0
    f0=1
    f1=1
    f2=0
    while count<n:
        count+=1
        f2=f1+f0
        f0=f1
        f1=f2
        a.append(f2)
    print('%s项的项数为:%s'%(b,f2))
    print('斐波那契数列为:')
    print(a)
b=int(input('请输入项数:'))
fn(b-2)

6 二分法查找

思想:二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。 此方法适用于不经常变动而查找频繁的有序列表。

代码:

l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
find_num = int(input('请输入一个数字:'))
start = 0
end = len(l) - 1

while True:
    middle = (start + end) // 2
    if find_num == l[middle]:
        print('找到了!索引是:', middle)
        break
    elif find_num > l[middle]:
        start = middle + 1
    elif find_num < l[middle]:
        end = middle - 1
    if start > end:
        print('没找到!', find_num)
        break

7 一个不知道长度的字符串,即很长很长的字符串,求字符串每个词的数量

类似a=dkjhagklfh丰¥270997hfjak

代码:

str='mynameisbobiamfromchina嘿嘿嘿嘿'
str=','.join(str) #以逗号分隔字符串
print(str)
li=str.split(',')
print(li) #变成列表了
#统计每一个字符出现的次数:
for i in set(li):
    if li.count(i) >= 1:
        print('%s 出现了%d !'%(i, li.count(i)))

8 多重嵌套列表,输出成一个列表,类似[1,[2[3,4],5],6,7],输出[1,2,3,4,5,6]

代码:

l=[1,2,[3,4,[5,6],[7,8],9],10]
l1=[]
#递归函数实现:
def getitem(l):
    for item in l:
        if isinstance(item,list):
            getitem(item)
        else:
            print(item)
            l1.append(item)

getitem(l)
print(l1)

9 手写列表逆输出,[1,2,4,5,3,6]输出[6,3,5,4,2,1]

代码:

a=[0,1,2,3,4,5,6,7,8,9,10]
b=[]
print(a[::-1]) #逆输出

#手写代码
count=len(a)
for i in range(len(a),0,-1):
    count-=1
    b.append(a[count])
print(b)

10 列表去重,也是不知道长度,[1,2,3,2,3,1,2,3,1,1,1]输出[1,2,3]

代码:

ids = [1,2,3,3,4,2,3,4,5,6,1,6,4,3,2,3,]
news_ids = []
for id in ids:
    if id not in news_ids:
        news_ids.append(id)
print (news_ids)

 

11 待续...

数据库相关知识

 

1 MySQL数据库与Oracle数据库的区别。

1、体积不同。

Oracle它体积比较庞大,一般是用来开发大型应用(例如分布式)的。而MySQL的体积相对来说比较小,较之Oracle更容易安装、维护以及管理,操作也简单,最重要的是它是三个中唯一一个开源数据库,但目前也属于Oracle公司的产品了。

2、容量不同。

Oracle容量无限,根据配置决定;而MySQL使用MyISAM存储引擎,最大表尺寸为65536TBMySQL数据库的最大有效表尺寸通常是由操作系统对文件大小的限制决定的,而不是由MySQL内部限制决定。

3、平台支持及速度的区别。

Oracle支持大多数平台;而MySQL支持各种平台,适合Linux。至于速度,OracleLinux下的性能,在少量数据时速度低于MySQL,在千万级时速度快于MySQL

4、数据库崩溃造成的影响不同。

Oracle数据库崩溃后恢复很麻烦,因为他把很多东西放在内存里;数据库连接要慢些,最好用连接池;而MySQL使用缺省的IP端口,但是有时候这些IP也会被一些黑客闯入,使用MyISAM配置,不慎损坏数据库,结果可能会导致所有的数据丢失。

2 MySQL数据库中查100w条数据和Oracle中查100w条数据的区别。

MySQL数据库实现分页比较简单,提供了 LIMIT函数。一般只需要直接写到sql语句后面就行了。

LIMIT子 句可以用来限制由SELECT语句返回过来的数据数量,它有一个或两个参数,如果给出两个参数, 第一个参数指定返回的第一行在所有数据中的位置,从0开始(注意不是1),第二个参数指定最多返回行数。例如:

select * from table WHERE LIMIT 10; #返回前10

select * from table WHERE LIMIT 0,10; #返回前10

select * from table WHERE LIMIT 10,20; #返回第10-20行数据

ORCALE数据库实现分页查询可以使用 row_number()函数或者使用rownum 虚列两种方法。

第二种方法:直接使用rownum 虚列

select * from

(select t.*,rownum as rowno from TABLE1 )

where rowno between 10 and 20

这两种方法比较,显然第二种方法比较好。因为不用order by语句,会提高检索数据的速度的,尤其数据量越大时,第二种方法快速检索数据越明显。

 

3 SQL注入是什么。

SQL注入:利用现有应用程序,将(恶意)SQL命令注入到后台数据库引擎执行的能力,这是SQL注入的标准释义。

随着B/S模式被广泛的应用,用这种模式编写应用程序的程序员也越来越多,但由于开发人员的水平和经验参差不齐,相当一部分的开发人员在编写代码的时候,没有对用户的输入数据或者是页面中所携带的信息(如Cookie)进行必要的合法性判断,导致了攻击者可以提交一段数据库查询代码,根据程序返回的结果,获得一些他想得到的数据。

4 数据库的三范式。

第一范式:确保每列的原子性.

第二范式:在第一范式的基础上更进一层,目标是确保表中的每列都和主键相关.

第三范式:在第二范式的基础上更进一层,目标是确保每列都和主键列直接相关,而不是间接相关.

 

5 什么是事务,MySQL如何支持事务。

MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!

MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。

事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。

事务用来管理 insert,update,delete 语句

一般来说,事务是必须满足4个条件(ACID)::原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。

6 MySQL主键和外键的区别。

主键是能确定一条记录的唯一标识,比如,一条记录包括身份正号,姓名,年龄。身份证号是唯一能确定你这个人的,其他都可能有重复,所以,身份证号是主键

外键用于与另一张表的关联。是能确定另一张表记录的字段,用于保持数据的一致性。一个表可以有多个外键。

 

 

 

7 使用ORM和原生SQL的优缺点。

ORM框架:

    对象关系映射,通过创建一个类,这个类与数据库的表相对应!类的对象代指数据库中的一行数据。

简述ORM原理:

    让用户不再写SQL语句,而是通过类以及对象的方式,和其内部提供的方法,进行数据库操作!把用户输入的类或对象转换成SQL语句,转换之后通过pymysql执行完成数据库的操作。

ORM的优缺点:

  优点:

    提高开发效率,降低开发成本

    使开发更加对象化

    可移植

    可以很方便地引入数据缓存之类的附加功能

  缺点:

    在处理多表联查、where条件复杂之类的查询时,ORM的语法会变得复杂。就需要写入原生SQL

8.待续...

技能和项目

1 装饰器的写法以及应用

#装饰器的应用场景:比如插入日志,性能测试,事务处理,缓存等等场景。
def outer(func):
    def inner(*args,**kwargs):
        print("认证成功!")
        result = func(*args,**kwargs)
        print("日志添加成功")
        return result
    return inner

@outer
def f1(name,age):
    print("%s 正在连接业务部门1数据接口......"%name)

# 调用方法
f1("jack",18)
#装饰器调用方法,其实是把函数 f1 当成 outer的参数

 

2 生成器的写法以及应用

#如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?
# 这样就不必创建完整的list,从而节省大量的空间。
# Python中,这种一边循环一边计算的机制,称为生成器(Generator

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
fib(8)
#生成器调用方法,其实是

3 HTTP中常见的请求头

Accept:浏览器端可以接受的媒体类型,通配符 * 代表任意类型

Accept-Encoding:浏览器申明自己接收的编码方法,例如: Accept-Encoding: zh-CN,zh;q=0.8

Accept-Language: 浏览器申明自己接收的语言,

Connection: Connection: keep-alive 当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。

Referer:当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器籍此可以获得一些信息用于处理。

User-Agent:告诉HTTP服务器, 客户端使用的操作系统和浏览器的名称和版本.

CookieCookie是用来存储一些用户信息以便让服务器辨别用户身份的(大多数需要登录的网站上面会比较常见),比如cookie会存储一些用户的用户名和密码,当用户登录后就会在客户端产生一个cookie来存储相关信息,这样浏览器通过读取cookie的信息去服务器上验证并通过后会判定你是合法用户,从而允许查看相应网页。

一般爬虫的代理设置就在User-Agent里面

4 HTTP中常见的状态码

1开头(信息)

       2开头(成功)

           200OK):请求成功

           202Accepted):已接受请求,尚未处理

           204No Content):请求成功,且不需返回内容

       3开头(重定向)

           301Moved Permanently):被请求的资源已永久移动到新位置

           301Moved Temporarily):被请求的资源已临时移动到新位置

       4开头(客户端错误)

           400Bad Request):请求的语义或是参数有错

           403Forbidden):服务器拒绝了请求

           404Not Found):未找到请求的资源

       5开头(服务器错误)

          500Internal Server Error):服务器遇到错误,无法完成请求

          502Bad Getway):网关错误,一般是服务器压力过大导致连接超时       

          503Service Unavailable):服务器宕机

5 Scrapy如何处理反爬虫

  1. 随机user-agent
  2. 添加Referer
  3. 延时处理
  4. 随机代理ip

6 Scrapy爬虫程序中断如何继续

总之我们要想保证爬取数据的完整就要牺牲程序的效率。

1.把所有爬取过的url列表保存到一个文件当中,然后再次启动的时候每次爬取要和文件当中的url列表对比,如果相同则不再爬取。

2.scrapy再次启动爬取的时候和数据库里面的数据做对比,如果相同则不存取。

3.就是利用Request中的优先级(priority

7 Flask框架的优势

一、整体设计方面

首先,两者都是非常优秀的框架。整体来讲,两者设计的哲学是区别最大的地方。Django提供一站式的解决方案,从模板、ORMSessionAuthentication等等都分配好了,连app划分都做好了,总之,为你做尽量多的事情,而且还有一个killer级的特性,就是它的admin,配合django-suit,后台就出来了,其实最初Django就是由在新闻发布公司工作的人设计的。Flask只提供了一些核心功能,非常简洁优雅。它是一个微框架,其他的由扩展提供,但它的blueprint使它也能够很方便的进行水平扩展。

二、路由设计

Django的路由设计是采用集中处理的方法,利用正则匹配。Flask也能这么做,但更多的是使用装饰器的形式,这个有优点也有缺点,优点是读源码时看到函数就知道怎么用的,缺点是一旦源码比较长,你要查路由就不太方便了,但这也促使你去思考如何更合理的安排代码。

三、应用模块化设计

Django的模块化是集成在命令里的,也就是说一开始Django的目标就是为以后玩大了做准备的。每个都是一个独立的模块,为以后的复用提供了便利。Flask通过Blueprint来提供模块化,自己对项目结构划分成不同的模块进行组织。

四、配置

Django的配置主要还是靠settings.py来做,当然为了DevelopmentProduction环境分离,还有一些方法来处理配置。Flask的配置很灵活,有多种方法配置,不同环境的配置也非常方便。

8 待续...

 

 

 

其他杂项

1 你在学校都学过什么课程

...数据结构,软件工程,软件测试,计算机网络以及各种语言。。。

2 知道cpypypy

CPython

   Python官方网站下载并安装好Python2.7后,就直接获得了一个官方版本的解释器:Cpython,这个解释器是用C语言开发的,所以叫 CPython,在命名行下运行python,就是启动CPython解释器,CPython是使用最广的Python解释器。

IPython

  IPython是基于CPython之上的一个交互式解释器,也就是说,IPython只是在交互方式上有所增强,但是执行Python代码的功能和CPython是完全一样的,好比很多国产浏览器虽然外观不同,但内核其实是调用了IE

PyPy

  PyPy是另一个Python解释器,它的目标是执行速度,PyPy采用JIT技术,对Python代码进行动态编译,所以可以显著提高Python代码的执行速度。

3 周末有什么打算

...作为一名肥宅,我只想在宿舍腐烂

4 平时熬夜么

...不熬夜啊,只是修仙而已

5 为什么学习Python

...人生苦短,我用Python

6 你老家是山西的,你想在北京发展吗

...不打算在北京发展,为什么我要投北京公司的简历

7 你还有什么问题要问我的吗

...为什么HR问的问题都这么千奇百怪

8 在学校的英语和数学怎么样

...只听过雅蠛蝶和为什么1+1=2

9 除了语言课,你在学校在哪一方面的专业课比较好

...LOL吗,我亚索贼6

10 能说说瀑布模型开发吗

...制定计划、需求分析、软件设计、程序编写、软件测试和运行维护等六个基本活动

11 什么是OOP,即面向对象编程思想

...OOP,不就是OPPO Find X 你值得拥有

12 如果你学的Python,突然有个小项目需要用到java,你会怎么做

...我选择删除数据库,然后跑路

13 待续...

 

以上的题就随缘发挥吧。。。

 

猜你喜欢

转载自www.cnblogs.com/yuxuanlian/p/9973492.html