Chris在开发API服务方面有多年的经验. 他最喜欢使用aiohttp包, SQLAlchemy(蒸馏器), 和PostgreSQL栈, 但他也熟悉弗拉斯克, MongoDB, Redis, and more. 他是Indico Data solutions后端团队的一员,Indico Data solutions是一家机器学习API和工具提供商,负责开发处理大数据处理和分析的后端服务. Chris在AWS、GCE和Azure云方面也有出色的技能.
Lambda表达式 是一种创建单行匿名函数的速记技术吗. Their simple, 内联特性通常(尽管并非总是)比正式函数声明的替代方案更易于阅读和简洁. 另一方面, 它们简洁的行内性质, by definition, 很大程度上限制了它们的能力和适用性. 匿名和内联, 在代码中的多个位置使用相同lambda函数的唯一方法是冗余地指定它.
列表理解 为创建列表提供简洁的语法. 列表推导式通常用于创建列表,其中每个元素都是对另一个序列或可迭代对象的每个成员应用某些操作的结果. 它们还可以用于创建成员满足特定条件的元素的子序列. 在Python中,列表推导式提供了使用内置函数的替代方法 map() and filter() functions.
由于lambda表达式和列表推导的应用用法可能重叠, 关于何时何地使用one vs . one,众说纷纭. the other. 有一点要记住, though, 列表推导式是否比使用的类似解决方案执行得更快 map and lambda (一些快速测试产生了大约10%的性能差异). 这是因为调用lambda函数会创建一个新的堆栈帧,而列表推导式中的表达式不会这样做.
生成器表达式 在语法和功能上是否与列表推导式相似,但两者的操作和方式存在一些相当显著的差异, accordingly, 什么时候应该使用它们. In a nutshell, 迭代生成器表达式或列表推导本质上也是一样的, 但是列表推导式将首先在内存中创建整个列表,而生成器表达式将根据需要动态创建项. 因此,生成器表达式可以用于非常大的(甚至无限的)序列及其惰性(i.e.(按需)生成值可以提高性能并降低内存使用. 值得注意的是, though, 标准的Python列表方法可以用于列表推导的结果, 但不是直接在生成器表达式上.
问:考虑下面两种初始化数组和生成数组的方法. 生成的数组有何不同,为什么要使用一种初始化方法. the other?
>>> # INITIALIZING AN ARRAY -- METHOD 1
...
>>> x = [[1,2,3,4]] * 3
>>> x
[[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]
>>>
>>>
>>> # INITIALIZING AN ARRAY -- METHOD 2
...
>>> y = [[1,2,3,4] for _ in range(3)]
>>> y
[[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]
>>>
>>> # WHICH METHOD SHOULD YOU USE AND WHY?
>>> # MODIFYING THE x ARRAY FROM THE PRIOR CODE SNIPPET:
>>> x[0][3] = 99
>>> x
[[1, 2, 3, 99], [1, 2, 3, 99], [1, 2, 3, 99]]
>>> # UH-OH, DON’T THINK YOU WANTED THAT TO HAPPEN!
...
>>>
>>> # MODIFYING THE y ARRAY FROM THE PRIOR CODE SNIPPET:
>>> y[0][3] = 99
>>> y
[[1, 2, 3, 99], [1, 2, 3, 4], [1, 2, 3, 4]]
>>> # THAT’S MORE LIKE WHAT YOU EXPECTED!
...
问:下面第二个append()语句会打印出什么?
>>> def append(list=[]):
... #追加列表的长度到列表
... list.追加(len(列表)
... return list
...
>>> append(['a','b'])
['a', 'b', 2]
>>>
>>> append() # calling with no arg uses default list value of []
[0]
>>>
>>> append() # but what happens when we AGAIN call append with no arg?
>>> append() # first call with no arg uses default list value of []
[0]
>>> append() # but then look what happens...
[0, 1]
>>> append() # successive calls keep extending the same default list!
[0, 1, 2]
>>> append() # and so on, and so on, and so on...
[0, 1, 2, 3]
As noted in 为什么有这么多蟒蛇?,坦率地说,这是一个有点棘手的问题,因为它是畸形的. Python本身只不过是一个接口定义(对于任何语言规范都是如此),它有多种实现. Accordingly, the question of whether “Python” is interpreted or compiled does not apply to the Python language itself; rather, 它适用于Python规范的每个特定实现.
假设候选人提到了unittest(如果没有的话), 你可能只想当场结束面试!), you should also ask them to describe the key elements of the unittest framework; namely, test fixtures, test cases, 测试套件和测试运行器.
关于什么时候使用Python是项目的“正确选择”的问题, 完整的答案还取决于与语言本身无关的一些问题, 比如优先技术投资, 团队的技能组合, and so on. 尽管如上所述的问题暗示了对严格技术答案的兴趣, 在面试中提出这些额外问题的开发者总是会得到我的“更多分数”,因为这表明他们意识到了, 以及对, “更大的图景”(i.e.,不仅仅是所采用的技术). Conversely, 回答说Python永远是正确的选择,这显然是一个不成熟的开发人员的标志.
问:Python语言有哪些缺点?
For starters, 如果你精通一门语言, 你知道它的缺点, 所以诸如“没有什么我不喜欢的”或“它没有缺点”之类的回答确实很能说明问题.
对于这个问题,最常见的两个有效答案是:
全局解释器锁(GIL). CPython(最常见的Python实现)不是完全线程安全的. 以支持多线程Python程序, CPython提供了一个全局锁,必须由当前线程持有,才能安全地访问Python对象. As a result, 无论存在多少线程或处理器, 在任何给定时间只有一个线程被执行. 相比之下,值得注意的是PyPy实现 本文前面讨论过 提供无堆栈模式,支持微线程实现大规模并发.
Execution speed. Python可能比编译语言慢,因为它是解释型的. (Well, sort of. See our 前面的讨论中 on this topic.)