Python2018秋招(笔者亲身经历)

HalifaxMartina 发布于1年前

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

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

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

算法编程题

1 冒泡排序

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

代码:

# 交换排序 . 冒泡排序
L = [1, 3, 2, 32, 5, 4]

defBubble_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]

defInsert_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)

# 空间复杂度为 O 1 ),时间复杂度为 O n*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]

defSelect_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. 斐波那契数列

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

代码:

# 最简单的方法为数组,其次为循环,最垃圾的为递归,到了 40 就算好久。。日后再琢磨数组
a=[1,1]

deffn(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 丰¥ 270997 梁 hfjak

代码:

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)

fori 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 = []

forid 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 存储引擎,最大表尺寸为 65536TB 。 MySQL 数据库的最大有效表尺寸通常是由操作系统对文件大小的限制决定的,而不是由 MySQL 内部限制决定。

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

Oracle 支持大多数平台;而 MySQL 支持各种平台,适合 Linux 。至于速度, Oracle 在 Linux 下的性能,在少量数据时速度低于 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

deff1(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 服务器, 客户端使用的操作系统和浏览器的名称和版本 .

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

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

4 HTTP 中常见的状态码

1 开头(信息)

2 开头(成功)

200 ( OK ):请求成功

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

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

3 开头(重定向)

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

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

4 开头(客户端错误)

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

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

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

5 开头(服务器错误)

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

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

503 ( Service Unavailable ):服务器宕机

5 Scrapy 如何处理反爬虫

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

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

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

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

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

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

7 Flask 框架的优势

一、整体设计方面

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

二、路由设计

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

三、应用模块化设计

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

四、配置

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

8 待续 ...

其他杂项

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

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

2 知道 cpy 和 pypy 么

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 待续 ...

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

查看原文: Python2018秋招(笔者亲身经历)

  • redswan
  • goldenleopard
  • orangeswan
  • blackswan
  • ticklishcat
  • whitesnake