发布于 2026-01-06 9 阅读
0

Python/Django 开发人员面试问答(#1)

Python/Django 开发人员面试问答(#1)

大多数软件工程师都会对技术面试感到畏惧,而我最近也开始面试别人。所以,这次我打算把我技术面试中遇到的所有问题都整理出来。希望这能帮助你们了解面试中会问到哪些类型的问题。可以把这个系列作为准备指南,帮助你们在面试中脱颖而出。

有些问题可能与 Python 和 Django 有关,但大多数问题都适用于任何软件工程岗位和 Web 应用程序开发人员。

这次面试是针对 Python 开发人员的职位,他们也希望候选人精通 Django,因此你会看到很多与 Django 架构和设计相关的问题。

1. 让我们来研究斐波那契数列的递归实现。

传递“n”,返回斐波那契数列第 n 个位置的值。

解答:斐波那契数列的计算方法有两种:迭代法和递归法。面试官只想要递归法的解法。

def fibonacci(n):
    if n == 0 or n == 1:
      return n
    return fibonacci(n-1) + fibonacci(n-2) 
Enter fullscreen mode Exit fullscreen mode

这个方案对于较小的数字(n=10)运行良好
,耗时0:00:00.001004秒;
但对于n=35,耗时0:00:05.157989秒,这太长了。
因此,接下来我被要求优化这个方案。

理想解决方案:使用动态规划,我将找到的每个值存储在一个字典中,这样下次查找该数字的斐波那契数列时,就可以直接从“value_dict”中查找。

def fibonacci(n, value_dict):
    # the first two values of fibonacci is always 0,1
    if n == 0 or n == 1:
        return n
    # if fibonacci(n) is already calculated then return it from dict 
    if value_dict.get(n):
        return value_dict[n]
    #else store it in dict and return next time it is called for.
    else:
        value_dict[n] = fibonacci(n-2,value_dict) + fibonacci(n- 
        1,value_dict)
        return value_dict[n]

print(fibonacci(100, {}))
Enter fullscreen mode Exit fullscreen mode

2. 什么是装饰器?编写一个装饰器来记录函数的参数。

解决方案
装饰器是一种接收另一个函数并为其添加功能而不直接修改函数本身的函数。它通过使用包装函数来实现这一点。

def decorator(func):
    def wrapper(*args):
        print("Logging the parameter of ", func, " is ", args)
        return func
    return wrapper

@decorator
def operation(x, y):
    return x+y

operation(5,20)
Enter fullscreen mode Exit fullscreen mode

@decorator 只是语法糖,它等价于
res = decorator(operation(5,20))

3. 什么是 GIL(全局解释器锁)?它如何实现 Python 中的多线程?

解决方案:GIL(全局解释器锁)是一种确保 Python 解释器在同一时间只能被一个线程持有的锁。这意味着在任何时刻,只能有一个线程处于执行状态。这就是 Python 成为单线程编程语言的原因。引入 GIL 是为了解决 Python 用于垃圾回收的引用计数问题。

你可能会问,Python 中的多线程模块是如何工作的呢?
其实,全局解释器锁只对 CPU 密集型操作生效。因此,如果存在任何影响或使用 CPU 的代码,它会自动切换到单线程模式。但所有常规程序仍然可以以多线程方式运行。

4. 什么是 WSGI 和 UWSGI?

解决方案
Web 服务器网关接口(WSGI),顾名思义,是应用程序与 Web 服务器之间的接口。Django
提供 runserver 用于开发和调试,但生产环境通常使用 WSGI,并可结合 nginx、apache 甚至 uwsgi 服务器等 Web 服务器。WSGI
和 uwsgi 都是协议,它们与 Web 服务器协同工作,为生产环境中的应用程序提供高性能支持。

因此,当客户端向 Django 应用程序发出请求时,该请求会由 Nginx 或其他 Web 服务器读取。然后,Nginx 将此请求传递给 uWSGI 服务,uWSGI 服务再将其传递给相应的 Django 应用程序。

5. 我们可以在 Dango 中编写自定义查询集吗?如何编写?

解决方案
是的,我们可以通过自定义 Manager 来创建自定义查询集。Manager 是 Django 模型获取数据库查询操作的接口。每个模型至少包含一个 Manager。
我们可以通过重写 Manager.get_queryset() 方法来覆盖 Manager 的基本查询集。

class Employees(models.Model):
      name = models.CharField(max_length=50)
      location = models.CharField(max_length=100)
Enter fullscreen mode Exit fullscreen mode

运行后,Employees.objects.all()它将返回数据库中的所有员工。
现在,如果我们想自定义此结果,使其仅返回多伦多地区的员工,则可以使用 Manager 进行如下设置。

class TorontoEmployeesManager(models.Manager):
      def get_queryset(self):
          return super().get_queryset().filter(location="Toronto")

class Employees(models.Model):
      name = models.CharField(max_length=50)
      location = models.CharField(max_length=100)

      objects = models.Manager()
      toronto_objects = TorontoEmployeesManager()
Enter fullscreen mode Exit fullscreen mode

现在,Employees.toronto_objects.all()只会安排多伦多办事处的员工返回工作岗位。

6. arr1 = list(range(10)); arr2 = arr1; arr3 = arr1[:]

arr2 是否等于 arr3?

解决方案
否,arr2 = arr1它会创建一个对 arr1 的新引用并将其赋值给 arr2。而,arr3 = arr1[:]它会复制 arr1 的内容并将其赋值给一个名为 arr3 的新变量。

arr1 = [1,2,3,4]
arr2 = arr1
arr3 = arr1[:]
arr1.append(5)
print(arr2) # [1,2,3,4,5]
print(arr3) # [1,2,3,4]
Enter fullscreen mode Exit fullscreen mode

7. 如何隐藏类变量,使其无法在类外部访问?

class Sample:
  def __init__(self, a, b):
    self.a = a
    self.b = b
Enter fullscreen mode Exit fullscreen mode

a 和 b 应该对课堂外部隐藏。

解决方案:

class Sample:
  def __init__(self, a, b):
    self.__a = a # using double underscore hides class variable
    self.__b = b
Enter fullscreen mode Exit fullscreen mode

8. Django 中的中间件是什么?如何创建自定义中间件?

答:
中间件是一种底层插件,可以用来接入 Django 的请求/响应流程。Django 项目创建时默认已经有一些中间件可用,可以在 settings.py 文件中找到。
我们也可以创建自定义中间件,并将其添加到现有中间件的列表中。

要创建自定义中间件,需要遵循以下结构:

# Middleware class should always consist __init__() and __call__()
class MyCustomMiddleware():
      def __init__(self, get_response):
          self.get_response = get_response #get_response is the view which will be called after this middleware/ or its the next middleware in the list.

      def __call__(self, request):
          # write the code to be executed before calling view here

          response = self.get_response(request) #pass the request to view and get the response back, which will be returned.

          # write the code to be executed after calling view here.
          return response
Enter fullscreen mode Exit fullscreen mode

将此中间件添加到 settings.py 文件中的“Middleware”部分。同时,请确保中间件的调用顺序正确。因为在处理请求时,它是从上到下调用​​的;而在返回响应时,它是从下到上调用的。

希望这对您有所帮助!

如果您想支持我的工作,请访问 https://www.buymeacoffee.com/manishanaidu

文章来源:https://dev.to/manishanaidu/python-django-developer-interview-questions-and-answer-1-3l82