您的位置:首页 > 脚本大全 > > 正文

python爬虫面试经历(搞定这套Python爬虫面试题面试会so easy)

更多 时间:2021-10-23 10:13:04 类别:脚本大全 浏览量:1840

python爬虫面试经历

搞定这套Python爬虫面试题面试会so easy

先来一份完整的爬虫工程师面试考点:

python爬虫面试经历(搞定这套Python爬虫面试题面试会so easy)

一、 python 基本功

1、简述python 的特点和优点

python 是一门开源的解释性语言,相比 java c++ 等语言,python 具有动态特性,非常灵活。

2、python 有哪些数据类型?

python 有 6 种内置的数据类型,其中不可变数据类型是number(数字), string(字符串), tuple(元组),可变数据类型是 list(列表),dict(字典),set(集合)。

3、列表和元组的区别

列表和元组都是可迭代对象,能够对其进行循环、切片等,但元组 tuple 是不可变的。元组不可变的特性,使得它可以成为字典 dict 中的键。

4、python 是如何运行的

cpython:

python 程序运行时,会先进行编译,将 .py 文件中的代码编译成字节码(byte code),编译结果储存在内存的 pycodeobject 中,然后由 python 虚拟机解释运行。当程序运行结束后,python 解释器会将 pycodeobject 保存到 pyc 文件中。每一次运行时 python 都会先寻找与文件同名的 pyc 文件,如果 pyc 存在则比对修改记录,根据修改记录决定直接运行或再次编译后运行,最后生成 pyc 文件 。

5、python 运行速度慢的原因

a). python 不是强类型的语言,所以解释器运行时遇到变量以及数据类型转换、比较操作、引用变量时都需要检查其数据类型。

b). python 的编译器启动速度比 java 快,但几乎每次都要启动编译。

c). python 的对象模型会导致访问内存效率变低。numpy 的指针指向缓存区数据的值,而 python 的指针指向缓存对象,再通过缓存对象指向数据:

python爬虫面试经历(搞定这套Python爬虫面试题面试会so easy)

6、面对 python 慢的问题,有什么解决办法

a). 可以使用其他的解释器,比如 pypy 和 jython 等。

b). 如果对性能要求较高且静态类型变量较多的应用程序,可以使用 cpython。

c). 对于 io 操作多的应用程序,python 提供 asyncio 模块提高异步能力。

7、描述一下全局解释器锁 gil

每个线程在执行时候都需要先获取 gil,保证同一时刻只有一个线程可以执行代码,即同一时刻只有一个线程使用 cpu,也就是说多线程并不是真正意义上的同时执行。但是在 io 操作时,是可以释放锁的(这也是 python 能够异步的原因)。而且如果想要利用多核 cpu,那么可以使用多进程。

8、深拷贝 浅拷贝

深拷贝是将对象本身复制给另一个对象,浅拷贝则是将对象的引用复制给另一个对象。所以当复制后的对象改变时,深拷贝的原对象值不会改变,而浅拷贝原对象的值会被改变。

9、is 和 == 的区别

is 表示的是对象标示符(object identity),而 == 表示的是相等(equality)。

is 的作用是用来检查对象的标示符是否一致,也就是比较两个对象在内存中的地址是否一样,而 == 是用来检查两个对象是否相等。但是为了提高系统性能,对于较小的字符串 python 会保留其值的一个副本,当创建新的字符串的时候直接指向该副本即可。如:

a = 8
b = 8
a is b

10、文件读写

简述文件读取时 read 、readline、readlines 的区别和作用

他们的区别除了读取内容范围不同外,返回的内容类型也不同。

read()会读取整个文件,将读取到底的文件内容放到一个字符串变量,返回 str 类型。

readline()读取一行内容,放到一个字符串变量,返回 str 类型。

readlines() 读取文件所有内容,按行为单位放到一个列表中,返回 list 类型。

11、请用一行代码实现

请分别使用匿名函数和推导式这两种方式将 [0, 1, 2, 3, 4, 5] 中的元素求乘积,并打印输出元组。

  • ?
  • 1
  • 2
  • print(tuple(map(lambda x: x * x, [0, 1, 2, 3, 4, 5])))
  • print(tuple(i*i for i in [0, 1, 2, 3, 4, 5]))
  • 12、请用一行代码实现

    用 reduce 计算 n 的阶乘(n!=1×2×3×...×n)

  • ?
  • 1
  • print(reduce(lambda x, y: x*y, range(1, n)))
  • 13、请用一行代码实现

    筛选并打印输出 100 以内能被 3 整除的数的集合

  • ?
  • 1
  • print(set(filter(lambda n: n % 3 == 0, range(1, 100))))
  • 14、请用一行代码实现

  • ?
  • 1
  • text = 'obj{"name": "pic", "data": [{"name": "async", "number": 9, "price": "$3500"}, {"name": "wade", "number": 3, "price": "$5500"}], "team": "hot"'
  • 打印文本中的球员身价元组,如 (  5500)

  • ?
  • 1
  • print(tuple(i.get("price") for i in json.loads(re.search(r'[(.*)]', text).group(0))))
  • 15、请写出递归的基本骨架

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • def recursions(n):
  •  if n == 1:
  •  # 退出条件
  •  return 1
  •  # 继续递归
  •  return n * recursions(n - 1)
  • 16、切片

    请写出下方输出结果

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • tpl = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
  • print(tpl[3:])
  • print(tpl[:3])
  • print(tpl[::5])
  • print(tpl[-3])
  • print(tpl[3])
  • print(tpl[::-5])
  • print(tpl[:])
  • del tpl[3:]
  • print(tpl)
  • print(tpl.pop())
  • tpl.insert(3, 3)
  • print(tpl)
  • [15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
  • [0, 5, 10]
  • [0, 25, 50, 75]
  • 85
  • 15
  • [95, 70, 45, 20]
  • [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
  • [0, 5, 10]
  • 10
  • [0, 5, 3]
  • 17、文件路径

    打印输出当前文件所在目录路径

  • ?
  • 1
  • 2
  • import os
  • print(os.path.dirname(os.path.abspath(__file__)))
  • 打印输出当前文件路径

  • ?
  • 1
  • 2
  • import os
  • print(os.path.abspath(__file__))
  • 打印输出当前文件上两层文件目录路径

  • ?
  • 1
  • 2
  • import os
  • print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
  • 18、请写出运行结果,并回答问题

  • ?
  • 1
  • 2
  • 3
  • tpl = (1, 2, 3, 4, 5)
  • apl = (6, 7, 8, 9)
  • print(tpl.__add__(apl))
  • 问题:tpl 的值发生变化了吗?

    运行结果如下:

    (1, 2, 3, 4, 5, 6, 7, 8, 9)

    答:元组是不可变的,它是生成新的对象

    19、请写出运行结果,并回答问题

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • name = ('james', 'wade', 'kobe')
  • team = ['a', 'b', 'c']
  • tpl = {name: team}
  • print(tpl)
  • apl = {team: name}
  • print(apl)
  • 问题:这段代码能运行完毕吗?为什么?它的运行结果是?

    答:这段代码不能完整运行,它会在 apl 处抛出异常,因为字典的键只能是不可变对象,而 list 是可变的,所以不能作为字典的键。运行结果是:

  • ?
  • 1
  • 2
  • {('james', 'wade', 'kobe'): ['a', 'b', 'c']}
  • typeerror
  • 20、装饰器

    请写出装饰器代码骨架

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • def log(func):
  •  def wrapper(*args, **kw):
  •  print('call %s():' % func.__name__)
  •  return func(*args, **kw)
  •  return wrapper
  • 简述装饰器在 python 中的作用:

    在不改动原函数代码的情况下,为其增加新的功能。

    21、多进程 多线程

    多进程更稳定还是多线程更稳定?为什么?

    多进程更稳定,它们是独立运行的,不会因为一个崩溃而影响其他进程。

    多线程的致命缺点是什么?

    因为所有线程共享进程的内存,所以任何一个线程挂掉都可能直接造成整个进程崩溃。

    进程间通信有哪些方式?

    共享变量、队列、管道。

    好了,本文就给大家介绍到这里,祝大家面试so easy!

    原文链接:https://www.jianshu.com/p/4e92215b587d

    您可能感兴趣