Câu hỏi phỏng vấn Python Developer

76 Các câu hỏi phỏng vấn Python Developer được chia sẻ bởi các ứng viên

Chuẩn bị cho một cuộc phỏng vấn chủ yếu là dành thời gian để xem xét kỹ lưỡng các mục tiêu và trình độ của bạn so với vị trí và nhà tuyển dụng. Để thực hiện được điều này, bạn nên thực hiện tìm hiểu về công ty và xem xét cẩn thận mô tả công việc và bản thân để có cuộc phỏng vấn tốt nhất. Dưới đây là những câu hỏi phỏng vấn vị trí Python Developer thường gặp.

Bộ câu hỏi phỏng vấn về thông tin cá nhân

Bạn hãy giới thiệu sơ lược về bản thân?

Giới thiệu thông tin cơ bản của bản thân là một trong những câu hỏi mở đầu của buổi phỏng vấn. Có thể người phỏng vấn của bạn biết vị trí bạn đang ứng tuyển và đã xem sơ yếu lý lịch của bạn. Tuy nhiên, bạn nên chuẩn bị một bài giới thiệu  ngắn gọn để đảm bảo họ biết bạn là ai và vai trò mà bạn đang phỏng vấn. Qua đây, nhà tuyển dụng cũng dễ trò chuyện trong những câu hỏi tiếp theo. Bạn hãy trả lời với sự tự tin, lời nói rõ ràng để lấy được thiện cảm từ cái nhìn đầu tiên.

Bạn hãy nói sơ lược về thông tin cá nhân như tên, tuổi để xưng hô cho thuận tiện. Tiếp theo bạn nên giới thiệu thông tin về bằng cấp, trường học hay các khóa đào tạo mình đã học. Bạn hãy chú trọng nói những kinh nghiệm liên quan đến công việc mà bạn có đối với một Python Developer .

Ngoài ra bạn cần lưu ý khi giới thiệu bản thân trong một cuộc phỏng vấn, về những việc cần làm, bạn cũng sẽ muốn lưu ý đến những việc không nên làm. Trong phần giới thiệu của bạn, hãy tránh:

  • Lan man trong phần giới thiệu của bạn
  • Cần nhắc lại phần giới thiệu của bạn
  • Vội vàng thông qua phần giới thiệu của bạn

Mục tiêu nghề nghiệp của bạn là gì?

Nhà tuyển dụng thường hỏi về mục tiêu tương lai của bạn để xác định xem bạn có khả năng gắn bó lâu dài với công ty hay không. Ngoài ra, câu hỏi này còn được dùng để đánh giá tham vọng, kỳ vọng của bạn đối với sự nghiệp và khả năng lập kế hoạch cho tương lai. Cách trả lời câu hỏi phỏng vấn này là bạn cần xác định rõ định hướng nghề nghiệp của mình là gì, đồng thời nói ra mục đích cuối cùng của bản thân muốn hướng tới ra sao.

Định hướng nghề nghiệp đưa ra cần thực tế, liên quan trực tiếp tới doanh nghiệp và công việc đang ứng tuyển kèm lý do: "Tôi muốn phát triển hơn nữa các kỹ năng chuyên môn cho công việc này. Tôi xác định đây là công việc yêu thích và muốn gắn bó lâu dài".

Vì sao bạn nghỉ việc ở công ty cũ?

Đây là một trong các câu hỏi thường gặp khi phỏng vấn và có thể gây khó khăn cho bạn. Chuẩn bị một câu trả lời chu đáo để người phỏng vấn tin tưởng rằng bạn đang cân nhắc về việc thay đổi công việc này. Thay vì tập trung vào những khía cạnh tiêu cực của vai trò hiện tại hoặc trước đây của bạn, hãy tập trung vào tương lai và những gì bạn hy vọng đạt được ở vị trí tiếp theo. Vì vậy, hãy đưa ra câu trả lời mà không ảnh hưởng gì đến kết quả phỏng vấn:

  • Trường hợp bị sa thải: Hãy nói rõ nguyên nhân phạm lỗi và bài học của bản thân rút ra để tránh lặp lại sai lầm.
  • Nếu tự nguyện nghỉ việc: Giải thích theo cách tích cực nhất. Ví dụ: Định hướng phát triển của công ty cũ không còn phù hợp; cơ hội để phát triển bản thân không cao, muốn tìm môi trường mới năng động hơn...

Điểm mạnh của bạn là gì? Lý do doanh nghiệp nên chọn bạn?

Nhà tuyển dụng muốn chắc chắn rằng bạn thật sự tự tin về những ưu điểm của mình hiện có. Vì vậy bạn hãy trả lời rõ ràng, dõng dạc nhưng cũng đừng nhắc lại tất cả những điều đã ghi trong CV. Bạn có thể kể thêm các điểm mạnh của mình hay đặt chúng vào tình huống cụ thể nhằm minh họa rõ ràng ưu điểm đó. Nhà tuyển dụng sẽ có cái nhìn sâu hơn về những lợi thế của bạn đấy.

Mức lương ở công ty cũ của bạn là bao nhiêu?

Kinh nghiệm phỏng vấn khi trả lời mức lương ở công ty cũ là:

  • Sử dụng con số chung chung: Thay vì nói con số chính xác, bạn có thể cung cấp  con số chung chung. 
  • Sử dụng một phạm vi: Bạn có thể cung cấp mức lương khởi điểm và mức lương hiện tại ở công ty cũ. 
  • Cung cấp con số chính xác: Bạn hoàn toàn có thể chia sẻ thẳng thắn nhưng nên cung cấp tổng mức lương hàng năm trước thuế TNCN để tránh tạo cảm giác lương của bạn đang ở mức thấp hơn.

Bạn mong muốn mức lương bao nhiêu?

Nhà phỏng vấn hỏi câu hỏi này để đảm bảo rằng kỳ vọng của bạn phù hợp với số tiền họ đã dự trù cho vai trò này. Nếu bạn đưa ra mức lương quá thấp hoặc cao hơn giá trị thị trường của vị trí đó, điều đó sẽ tạo ấn tượng rằng bạn không biết giá trị của mình.

Để trả lời các câu hỏi thường gặp khi phỏng vấn này, bạn nên tìm hiểu trước về mức lương chung cho vị trí cũng như mức độ kinh nghiệm của mình. Từ đó, bạn sẽ dung hòa để đưa ra mức lương không quá cao nhưng không phải thấp, đủ để thấy được giá trị bản thân.

Ngoài mức lương, bạn nên trao đổi thẳng thắn về các quyền lợi bảo hiểm xã hội, phụ cấp xăng, ăn uống; chế độ nghỉ thai sản... rõ ràng và cụ thể.

Bạn cũng nên hiểu rõ về lương gross net, cách tính lương gross sang net và ngược lại để deal được mức lương đúng với mong muốn của bản thân nhất.

Bạn có câu hỏi nào không?

Đây có thể là một trong những câu hỏi quan trọng nhất được hỏi trong quá trình phỏng vấn vì nó cho phép bạn tìm hiểu bất kỳ thông tin nào chưa được giải quyết và cho người phỏng vấn thấy bạn nghiêm túc với vai trò này. Hãy nhớ rằng bạn cũng đang phỏng vấn công ty. Hãy dành thời gian để hỏi người phỏng vấn về trải nghiệm của họ với công ty và giải quyết bất kỳ câu hỏi nào mà bạn có thể có. 

Bạn có thể tham khảo một số câu hỏi như sau:

  • Anh/ chị có thể  mô tả về văn hóa làm việc của công ty này không?
  • Có cơ hội thăng tiến và phát triển nghề nghiệp trong công ty không?
  • Có thông tin gì về quyền lợi và gói phúc lợi mà công ty cung cấp?
  • Làm thế nào để công ty đo lường và đánh giá hiệu suất làm việc của nhân viên?
  • Có những kế hoạch mở rộng hay phát triển mới trong tương lai không?
  • Có các cơ hội đào tạo hoặc học hỏi mới để cập nhật kiến thức không?
  • Có cơ hội tham gia vào các dự án đa dạng không?

Câu hỏi phỏng vấn Python Developer về chuyên môn

Tại sao bạn quyết định làm việc với Python?

Tôi quyết định làm việc với Python vì đây là một ngôn ngữ lập trình rất mạnh mẽ và đa dụng. Python cho phép tôi phát triển ứng dụng web, xử lý dữ liệu, thậm chí là triển khai trí tuệ nhân tạo. Cú pháp dễ đọc, cộng đồng lớn và các thư viện sẵn có làm cho việc phát triển nhanh chóng và hiệu quả hơn.

Bạn đã từng sử dụng công cụ kiểm soát phiên bản nào?

Tôi đã sử dụng Git là công cụ kiểm soát phiên bản chính của mình. Tôi thường sử dụng Git để theo dõi sự thay đổi trong mã nguồn, tạo các nhánh (branches) để làm việc song song và sau đó merge lại các thay đổi vào nhánh chính khi đã hoàn thành.

Bạn đã từng phải tối ưu hóa mã nguồn Python của mình chưa?

Có, tôi đã từng phải tối ưu hóa mã nguồn Python của mình để đảm bảo hiệu suất tốt nhất. Một ví dụ là khi tôi làm việc với xử lý dữ liệu lớn, tôi đã sử dụng generator để tránh tải toàn bộ dữ liệu vào bộ nhớ cùng lúc. Tối ưu hóa cũng bao gồm việc sử dụng các thư viện thích hợp và cải thiện thời gian chạy của các phần mã nguồn chậm

Cách sử dụng hàm any và all trong Python

any() và all() là 2 function sử dụng để check điều kiện trong 1 mảng kết quả, any sẽ trả về true khi tồn tại 1 giá trị true trong mảng truyền vào; ngược lại thì all chỉ trả về true khi tất cả các giá trị trong mảng truyền vào trả về true.

any() và all() được ứng dụng nhiều trong việc xử lý check điều kiện của các dữ liệu dạng List, Tuple hay Array nhằm kiểm tra điều kiện thỏa mãn của 1 thuộc tính trong tập dữ liệu; any tương đương với điều kiện OR và all tương đương với điều kiện AND

Làm thế nào để xử lý đa luồng trong Python

Python cung cấp thread module và threading module để bạn tạo và thực thi một thread, handle xử lý các tác vụ đa luồng. Mỗi thread trong Python đều có vòng đời gồm 3 giai đoạn: bắt đầu, chạy và kết thúc. Thread có thể bị ngắt (interupt) trong quá trình chạy, hoặc có thể tạm thời bị dừng (sleeping) trong khi các thread khác đang chạy (trạng thái yielding).

Để start một thread chúng ta dùng phương thức thread.start_new_thread bằng việc import module thread. Chúng ta cũng có thể sử dụng module threading với nhiều hỗ trợ mạnh mẽ và cao cấp hơn được Python thêm vào từ version 2.4. Ngoài các phương thức có trong module thread, threading còn cung cấp một số method khác như activeCount, currentThread, hay các phương thức triển khai đa luồng như run, start, join, …

Bạn có kinh nghiệm làm việc với các thư viện Python như NumPy và Pandas không? Hãy nêu một ví dụ về cách bạn đã sử dụng chúng trong dự án trước đây."

Bạn có thể tham khảo cách trả lời như sau:

Có, tôi đã có kinh nghiệm làm việc với NumPy và Pandas trong các dự án trước đây. Ví dụ, trong một dự án phân tích dữ liệu, tôi đã sử dụng NumPy để thực hiện các phép tính toán trên mảng số học và Pandas để xử lý dữ liệu tabular. Điều này giúp tôi nhanh chóng thực hiện các phân tích thống kê và trực quan hóa dữ liệu

Việc sử dụng NumPy và Pandas đã giúp tôi tối ưu hóa thời gian xử lý dữ liệu và cung cấp những thông tin cần thiết cho quá trình ra quyết định. Tôi đã học cách áp dụng những thư viện này một cách hiệu quả và biết cách tận dụng sức mạnh của chúng trong việc xử lý dữ liệu lớn và phân tích.

Kinh nghiệm “đậu” phỏng vấn vị trí Python Developer

Để buổi phỏng vấn diễn ra suôn sẻ và nắm chắc phần thành công, bạn cần chú trọng thêm các yếu tố:

Về trang phục

Khi đi phỏng vấn, bạn nên lựa chọn những loại trang phục lịch sự, nhã nhặn phù hợp với môi trường công sở. Tránh các trang phục sặc sỡ quá, khác biệt quá, trang điểm lòe loẹt quá đều không phù hợp với một buổi phỏng vấn

Kinh nghiệm về tác phong

Nên đến sớm 10 - 15 phút, để tránh trường hợp xảy ra các sự cố trên đường hay sự cố về trang phục. Những nhà tuyển dụng cũng thích những người đến sớm và có chuẩn bị tốt.

Tác phong chuyên nghiệp, giữ bản thân ở trạng thái bình tĩnh, lắng nghe câu hỏi phỏng vấn và lời lưu loát, rõ ràng. Hạn chế nói lắp, trả lời không rõ ràng, thiếu logic, mạch lạc

Chuẩn bị kỹ càng

Chuẩn bị kỹ thông tin về vị trí mình đang ứng tuyển. Bạn bước vào buổi phỏng vấn hiểu công việc này sẽ làm gì, cần kỹ năng gì. Việc này bắt nguồn từ việc bạn đã nghiên cứu kỹ JD, nghiên cứu công việc. Như vậy, bạn sẽ thể hiện tốt những thế mạnh của mình, điều này khiến nhà tuyển dụng ấn tượng về bạn.

Chia sẻ về các dự án mà bạn đã làm và cách bạn đã giải quyết các vấn đề trong quá trình phát triển. Điều này cho thấy khả năng ứng dụng kiến thức vào thực tế.

Định hình rõ câu hỏi và vấn đề

Trong buổi phỏng vấn giao dịch viên ngân hàng sẽ có rất nhiều câu hỏi được đưa ra. Do vậy để tránh tình trạng trả lời sai/nhầm nội dung câu hỏi, trả lời ấp úng, ngắt quãng,... bạn nên chuẩn bị trước những câu hỏi có thể gặp phải và đưa ra câu trả lời cho chúng.

Để tự tin hơn trong buổi phỏng vấn, bạn có thể liệt kê các câu hỏi và câu trả lời, sau đó học thuộc. Đồng thời, luôn giữ tâm thế bình tĩnh, phong thái tự tin, sẵn sàng đón nhận bất cứ câu hỏi phỏng vấn “khó nhằn” nào.

Câu hỏi phỏng vấn Python Developer & Cách trả lời

Dưới đây là 3 câu hỏi phỏng vấn Python Developer hàng đầu và cách trả lời chúng:

Câu hỏi #1: List và Array khác nhau thế nào?

List

Array

Python list linh hoạt và có thể lưu nhiều kiểu dữ liệu khác nhau. Python array là một bọc mỏng quanh C array.
List là một phần trong cú pháp của Python, nên không cần khai báo trước. Array cần được import, hoặc khai báo từ các thư viện khác (như numpy)
List có thể thay đổi kích thước một cách nhanh chóng vì Python khởi tạo thêm một số thành phần khác trong list ngay khi khởi tạo. Array không thay đổi kích thước được. Thay vào đó, các giá trị của một array sẽ được sao chép qua một array khác có kích thước lớn hơn.
List có thể chứa các dữ liệu không đồng nhất về kiểu. Array chỉ có thể chứa các dữ liệu đồng nhất về kiểu.
Không thể áp dụng các hàm toán học trực tiếp lên list. Thay vào đó, chúng phải được áp dụng lần lượt trên từng thành phần của list. Array được tối ưu hoá cho các phép tính số học.
List tiêu thụ nhiều bộ nhớ hơn vì chúng phân bổ thêm bộ nhớ cho một số thành phần bổ sung để dễ dàng đưa thêm thành phần vào list. Vì array không thay đổi kích thước sau khi khởi tạo, chúng tiêu thụ ít bộ nhớ hơn.

Câu hỏi #2: Làm cách nào để in hoa chữ cái đầu của một kí tự của chuỗi trong Python?

Trong Python, chuyện này trở nên đơn giản nhờ phương thức capitalize() có thể in hoa chữ cái đầu tiên của một chuỗi. Và nếu chuỗi đó đã được viết hoa sẵn chữ cái đầu thì qua phương thức trên, thì phương thức này sẽ return về chuỗi gốc ban đầu.

Ví dụ minh họa: 

Tài liệu VietJack

Câu hỏi #3: [::-1} có thể làm được gì?

[::-1} trong Python được dùng để đảo thứ tự của một mảng hay một trình tự nào đó. Cụ thể như sau:

Tài liệu VietJack

Output:

Tài liệu VietJack

Như vậy có thể thấy [::-1} sẽ in lại bản copy bị đảo ngược của cấu trúc dữ liệu có thứ tự như một mảng hay một danh sách, và tất nhiên là mảng hay danh sách cũ vẫn được giữ nguyên, nó sẽ return cho bạn một mảng/danh sách mới.

Câu hỏi phỏng vấn

Python Developer được hỏi... 02/06/2023

Hãy giải thích sự khác nhau giữa Bộ tạo (generator) và Bộ lặp (iterator) trong Python.

1 câu trả lời

Bộ lặp (iterator) trong Python đóng vai trò như một kẻ giữ chỗ cho các đối tượng để nó có thể duyệt qua. Bộ tạo (generator) tạo điều kiện dễ dàng cho việc tạo một bộ lặp tuỳ biến. Như vậy, một bộ tạo luôn luôn là một bộ lặp, nhưng không phải lúc nào một bộ lặp cũng là một bộ tạo.

Ngoài những khác biệt về cú pháp, còn có các khác biệt đáng kể sau:

Bộ tạo - Generator Bộ lặp - Iterator
Được thực thi thông qua 1 hàm. Được thực thi thông qua 1 lớp (class.)
Sử dụng từ khoá yield. Không dùng từ khoá yield.
Việc sử dụng tạo ra mã cô đọng. Việc sử dụng tạo ra mã nguồn kém cô đọng hơn (so với hàm tạo.)
Tất cả các biến địa phương trước câu lệnh yield đều được lưu trữ. Không có biến địa phương nào được sử dụng.
Ví dụ về một Bộ lặp:

# Hàm tạo tất cả các số không âm

# nhỏ hơn hoặc bằng một số không âm cho trước.

class UpTo:

# gán cho tham số giá trị mặc định 0

def __init__(self, max = 0):

self.max = max

def __iter__(self):

self.n = 0

return self

def __next__(self):

# Hàm next sẽ tạo một ngoại lệ

# khi gặp phải điều kiện kết thúc.

if self.n > self.max:

raise StopIteration

else:

result = self.n

self.n += 1

return result

for number in UpTo(5):

print(number)

Output:
0
1
2
3
4
5
Ví dụ về Bộ tạo:

# Hàm tạo tất cả các số nguyên không âm

# nhỏ hơn hoặc bằng một số nguyên không âm cho trước

def upto(n):

for i in range(n+1):

# Câu lệnh yield là điều làm cho đoạn mã này trở thành 1 hàm

# một bộ tạo  yield i for number in upto(5):

print(number)

 
 
Output:
0
1
2
3
4
5
Python Developer được hỏi... 06/06/2023

Defaultdict trong Python là gì?

1 câu trả lời

Từ điển Python, dict, chứa các từ và nghĩa như các cặp từ khoá - giá trị của bất kỳ kiểu dữ liệu gì. Defaultdict là một loại dữ liệu con của lớp dict dựng sẵn trong Python.

Defaultdict khác chỗ nào?

Defaultdict là kiểu dữ liệu con của lớp dict. Sự quan trọng của nó nằm ở chỗ nó cho phép mỗi từ khoá mới có một giá trị mặc định dựa vào kiểu từ điển được tạo.

Một defaultdict có thể được tạo bằng cách khai báo, một tham số có có thể có 3 giá trị; list, set, hoặc int. Tuỳ theo loại dữ liệu khai báo, từ điển sẽ được tạo và khi bất kỳ từ khoá nào chưa có trong default dict sẽ được thêm vào hoặc truy xuất. Nó sẽ được gán một giá trị mặc định thay vì báo lỗi KeyError.

Ví dụ:

Đoạn mã nhỏ dưới đây minh hoạ cách khởi tạo một từ điển đơn giản và khi truy xuất từ điển với một từ khoá không tồn tại, nó báo lỗi thế nào.

dict_demo = dict()

print(dict_demo[3])

Đoạn mã nhỏ dưới đây minh hoạ một biến defaultdict và hãy xem chuyện gì xảy ra.

from collections import defaultdict

defaultdict_demo = defaultdict(int)

print(defaultdict_demo[3])

Output: 0

Trong trường hợp này, chúng ta đã truyền int làm tham số quy định kiểu dữ liệu cho defaultdict. Do đó, khi truy xuất một từ khoá chưa tồn tại, từ khoá đó sẽ được thêm vào và được gán giá trị 0.

Ghi chú: Bạn cũng có thể truyền set hoặc list làm tham số cho defaultdict.

Python Developer được hỏi... 02/06/2023

Đơn nguyên (modules) Python là gì?

1 câu trả lời

Một đơn nguyên Python là tập tin Python bao gồm một bộ các hàm và biến để sử dụng trong một ứng dụng. Các biến có thể thuộc bất kỳ kiểu dữ liệu nào. Đơn nguyên có thể thuộc 1 trong 2 dạng:

  • Dựng sẵn (Built in)
  • Do người dùng định nghĩa (User-defined)

Lợi ích của đơn nguyên trong Python

Có một số lợi ích chủ chốt trong việc tạo và sử dụng đơn nguyên trong Python:

  • Mã nguồn có cấu trúc

Mã nguồn được tổ chức mạch lạc bằng cách nhóm chúng vào một tập tin Python. Việc này giúp cho quá trình phát triển trở nên dễ hơn, và ít bị lỗi hơn. Dễ hiểu và sử dụng mã nguồn hơn.

  • Tái sử dụng

Các tính năng định nghĩa trong một đơn nguyên có thể dễ dàng được sử dụng lại ở những phần khác của ứng dụng. Qua đó, chúng ta không phải viết lại các đoạn mã nguồn đã viết ở chỗ khác.

Python Developer được hỏi... 02/06/2023

Hãy đảo ngược chuỗi "Python" dùng phương pháp cắt lát (slicing.)

1 câu trả lời

Để đảo ngược một chuỗi bằng phương pháp cắt lát, chúng ta có thể dùng một trong các cách sau:

stringname[stringlength::-1] # method 1

Hoặc viết mà bỏ trống tham số độ dài chuỗi như sau:

stringname[::-1] # method2

Câu lệnh cắt lát có nghĩa bắt đầu tại vị trí độ dài chuỗi, và kết thúc tại vị trí index 0, mỗi bước dịch chuyển một bước có giá trị -1 (một bước lùi về phía sau.)

str="Python" # initial string

stringlength=len(str) # calculate length of the list

slicedString=str[stringlength::-1] # slicing

print (slicedString) # print the reversed string

Output: nohtyP

Đây là một cách để đảo ngược chuỗi. Các cách khác bao gồm phương pháp lặp và dùng lệnh join để nối chuỗi.

Python Developer được hỏi... 06/06/2023

Kiểm tra xem một chuỗi có chứa một chuỗi con khác hay không

1 câu trả lời

Có vài cách để thực hiện việc này. Trong phần này, chúng ta dùng hàm find

Hàm find kiểm tra xem chuỗi có chứa một chuỗi con hay không. Nếu có, nó trả về vị trí index đầu tiên của chuỗi con trong chuỗi cha. Nếu không, nó trả về -1.

Cú pháp chung là:

string.find(substring)

Ví dụ: 

a_string="Python Programming"

substring1="Programming"

substring2="Language"

print("Check if "+a_string+" contains "+substring1+":")

print(a_string.find(substring1))

print("Check if "+a_string+" contains "+substring2+":")

print(a_string.find(substring2))

 
Output:
Check if Python Programming contains Programming: 7
Check if Python Programming contains Language: -1

Các phương pháp khác là dùng toán tử in hoặc hàm count.

Python Developer được hỏi... 02/06/2023

Hãy thực hiện thuật toán Tìm kiếm Độ Rộng Trước Hết (Breadth First Search - BFS) bằng Python

1 câu trả lời

Hãy xem xét sơ đồ dưới đây qua đoạn mã bên dưới:

Tài liệu VietJack

graph =

{ 'A' : ['B','C'],

'B' : ['D', 'E'],

'C' : ['F'],

'D' : [],

'E' : ['F'],

'F' : []

 

} visited = [] # List to keep track of visited nodes.

queue = [] #Initialize a queue

def bfs(visited, graph, node):

visited.append(node)

queue.append(node)

 

while queue:

s = queue.pop(0)

print (s, end = " ")

 

for neighbour in graph[s]:

if neighbour not in visited:

visited.append(neighbour)

queue.append(neighbour)

 

# Driver Code

bfs(visited, graph, 'A')

Output: A B C D E F

Giải thích

Dòng 3-10: Sơ đồ trên được đại diện bằng một danh sách các điểm liền kề. Một cách dễ dàng để thực hiện việc này là dùng cấu trúc dữ liệu kiểu từ điển, trong đó mỗi đỉnh chứa một danh sách các điểm liền kề.

Dòng 12: visited là một danh sách để lưu trữ các nốt đã đi qua.

Dòng 13: queue là một danh sách để lưu trữ các nốt hiện đang trong hàng đợi.

Dòng 15-26: bfs theo thuật toán mô tả ở trên:

  • Nó kiểm tra và thêm nốt xuất phát vào danh sách visited và danh sách queue.
  • Kế đến, trong khi biến queue còn chứa các phần tử, nó tiếp tục lấy các phần tử đó ra khỏi hàng đợi, thêm nốt lân cận của nốt đó vào hàng đợi nếu nó chưa được đi qua, trong danh sách unvisited, và đánh dấu chúng là đã đi qua.
  • Việc này tiếp diễn cho đến khi hàng đợi trống rỗng.

Dòng 29: Tham số của hàm bfs là danh sách visited, sơ đồ dưới dạng 1 từ điển, và nốt xuất phát A.

Độ phức tạp về thời gian (Time Complexity)

Vì tất cả các nốt và đỉnh đều được đi qua, độ phức tạp về thời gian cho thuật toán BFS trên 1 sơ đồ là O(V + E) trong đó V là số đỉnh, và E là số cạnh.

Python Developer được hỏi... 06/06/2023

Hãy thực thi ký tự đại diện (wildcards) bằng Python

1 câu trả lời

Trong Python, bạn có thể thực thi ký tự đại diện bằng thư viện regex (regular expressions - biểu thức thông thường.)

Ký tự chấm "." được dùng thay cho dấu chấm hỏi "?" . Do đó, để tìm tất cả các từ phù hợp với mẫu màu, mã có thể trông như sau:

# Regular expression library
import re

# Add or remove the words in this list to vary the results
wordlist = ["color", "colour", "work", "working",
"fox", "worker", "working"]

for word in wordlist:
# The . symbol is used in place of ? symbol
if re.search('col.r', word) :
print (word)

 

Output: Color

Python Developer được hỏi... 06/06/2023

Hãy thực thi thuật toán sắp xếp sáp nhập (merge sort) bằng Python

1 câu trả lời

Đây là mã chương trình cho thuật toán sắp xếp sáp nhập:

def mergeSort(myList):
if len(myList) > 1:
mid = len(myList) // 2
left = myList[:mid]
right = myList[mid:]

# Recursive call on each half
mergeSort(left)
mergeSort(right)

# Two iterators for traversing the two halves
i = 0
j = 0

# Iterator for the main list
k = 0

while i < len(left) and j < len(right):
if left[i] < right[j]:
# The value from the left half has been used
myList[k] = left[i]
# Move the iterator forward
i += 1
else:
myList[k] = right[j]
j += 1
# Move to the next slot
k += 1

# For all the remaining values
while i < len(left):
myList[k] = left[i]
i += 1
k += 1

while j < len(right):
myList[k]=right[j]
j += 1
k += 1

myList = [54,26,93,17,77,31,44,55,20]
mergeSort(myList)
print(myList)

Output: [17, 20, 26, 31, 44, 54, 55, 77, 93]
Giải thích

Đây là cách tiếp cận đệ quy trong việc thực hiện thuật toán sắp xếp qua sáp nhập. Các bước cần để có được một mảng đã sắp xếp bằng phương pháp này có thể được mô tả dưới đây:

  • Danh sách được chia thành 2 nửa left (trái) và right (phải) trong mỗi bước lặp đệ quy, cho đến khi chỉ còn 2 thành phần kế cận nhau.
  • Bây giờ bắt đầu quá trình xếp thứ tự. Biến lặp i j lần lượt duyệt qua 2 nửa trong mỗi lần gọi. Biến lặp k duyệt qua toàn bộ danh sách và thực hiện các thay đổi dọc theo quá trình lặp.
  • Nếu giá trị ở vị trí i nhỏ hơn giá trị ở vị trí j, left[i] được gán cho myList[k] và tăng i lên một bước. Nếu không, then right[j] sẽ được chọn.
  • Cứ thế, các giá trị được gán qua k đều theo thứ tự.
  • Vào cuối vòng lặp, một trong hai nửa có thể chưa được lặp qua tất cả các nốt. Các giá trị của nó chỉ đơn giản được gán vào chỗ trống còn lại của danh sách.

Độ phức tạp về thời gian

Thuật toán thực thi trong O(n.logn). Đó là vì danh sách được chia thành log(n) lần gọi và quá trình sáp nhập mất một khoảng thời gian tuyến tính trong mỗi lần gọi hàm.

Python Developer được hỏi... 06/06/2023

Hãy thực thi thuật toán Dijkstra bằng Python

1 câu trả lời

Thuật toán cơ bản

  • Từ mỗi đỉnh chưa đi qua, hãy chọn đỉnh với khoảng cách nhỏ nhất và đi tới điểm đó.
  • Cập nhật khoảng cách cho mỗi đỉnh lân cận, của các đỉnh đã đi qua mà khoảng cách hiện hành lớn hơn tổng của nó, và trọng số của cạnh giữa 2 đỉnh.
  • Lập lại bước 1 và 2 cho đến khi tất cả các đỉnh được đi qua.

Dưới đây là đoạn mã thực hiện thuật toán trên

import sys

# Function to find out which of the unvisited node
# needs to be visited next
def to_be_visited():
global visited_and_distance
v = -10
# Choosing the vertex with the minimum distance
for index in range(number_of_vertices):
if visited_and_distance[index][0] == 0 \
and (v < 0 or visited_and_distance[index][1] <= \
visited_and_distance[v][1]):
v = index
return v

# Creating the graph as an adjacency matrix
vertices = [[0, 1, 1, 0],
[0, 0, 1, 0],
[0, 0, 0, 1],
[0, 0, 0, 0]]
edges = [[0, 3, 4, 0],
[0, 0, 0.5, 0],
[0, 0, 0, 1],
[0, 0, 0, 0]]

number_of_vertices = len(vertices[0])

# The first element of the lists inside visited_and_distance
# denotes if the vertex has been visited.
# The second element of the lists inside the visited_and_distance
# denotes the distance from the source.
visited_and_distance = [[0, 0]]
for i in range(number_of_vertices-1):
visited_and_distance.append([0, sys.maxsize])

for vertex in range(number_of_vertices):
# Finding the next vertex to be visited.
to_visit = to_be_visited()
for neighbor_index in range(number_of_vertices):
# Calculating the new distance for all unvisited neighbours
# of the chosen vertex.
if vertices[to_visit][neighbor_index] == 1 and \
visited_and_distance[neighbor_index][0] == 0:
new_distance = visited_and_distance[to_visit][1] \
+ edges[to_visit][neighbor_index]
# Updating the distance of the neighbor if its current distance
# is greater than the distance that has just been calculated
if visited_and_distance[neighbor_index][1] > new_distance:
visited_and_distance[neighbor_index][1] = new_distance
# Visiting the vertex found earlier
visited_and_distance[to_visit][0] = 1

i = 0

# Printing out the shortest distance from the source to each vertex
for distance in visited_and_distance:
print("The shortest distance of ",chr(ord('a') + i),\
" from the source vertex a is:",distance[1])
i = i + 1


Output:
The shortest distance of a from the source vertex a is: 0
The shortest distance of b from the source vertex a is: 3
The shortest distance of c from the source vertex a is: 3.5
The shortest distance of d from the source vertex a is: 4.5

Python Developer được hỏi... 02/06/2023

Hãy sáp nhập 2 danh sách đã xếp thứ tự

1 câu trả lời

# Merge list1 and list2 and return resulted list
def merge_lists(lst1, lst2):
index_arr1 = 0
index_arr2 = 0
index_result = 0
result = []

for i in range(len(lst1)+len(lst2)):
result.append(i)
# Traverse Both lists and insert smaller value from arr1 or arr2
# into result list and then increment that lists index.
# If a list is completely traversed, while other one is left then just
# copy all the remaining elements into result list
while (index_arr1 < len(lst1)) and (index_arr2 < len(lst2)):
if (lst1[index_arr1] < lst2[index_arr2]):
result[index_result] = lst1[index_arr1]
index_result += 1
index_arr1 += 1
else:
result[index_result] = lst2[index_arr2]
index_result += 1
index_arr2 += 1
while (index_arr1 < len(lst1)):
result[index_result] = lst1[index_arr1]
index_result += 1
index_arr1 += 1
while (index_arr2 < len(lst2)):
result[index_result] = lst2[index_arr2]
index_result += 1
index_arr2 += 1
return result


print(merge_lists([4, 5, 6], [-2, -1, 0, 7]))

Output: [-2, -1, 0, 4, 5, 6, 7]

Giải thuật trên là một cách trực quan hơn để giải quyết vấn đề.

  • Bắt đầu bằng danh sách rỗng. Danh sách sẽ được lấp đầy bằng tất cả các phần tử trong cả 2 danh sách theo thứ tự đã sắp xếp và trả về.
  • Kế đến khởi tạo 3 biến có giá trị 0 để lưu số chỉ mục (index) của mỗi danh sách.
  • Sau đó, so sánh các phần tử của 2 danh sách tại vị trí chỉ mục hiện hành, thêm số nhỏ hơn vào danh sách mới và tăng số chỉ mục lên 1 bước.
  • Lặp lại quá trình trên cho đến cuối các danh sách và thêm danh sách còn lại vào cuối danh sách đã sáp nhập.

Độ phức tạp về thời gian
Độ phức tạp về thời gian của thuật toán này là O(n+m)O(n+m) trong đó nn and mm là độ dài của các danh sách. Đó là vì cả 2 danh sách được duyệt qua ít nhất 1 lần.

Lưu ý: vấn đề này cũng có thể được giải quyết bằng cách sáp nhập tại chỗ.

Python Developer được hỏi... 06/06/2023

Tìm 2 số trong danh sách có tổng là 'k'

1 câu trả lời

def binarySearch(a, item, curr):
first = 0
last = len(a) - 1
found = False
index = -1
while first <= last and not found:
mid = (first + last) // 2
if a[mid] == item:
index = mid
found = True
else:
if item < a[mid]:
last = mid - 1
else:
first = mid + 1
if found:
return index
else:
return -1


def findSum(lst, k):
lst.sort()
for j in range(len(lst)):
# find the difference in list through binary search
# return the only if we find an index
index = binarySearch(lst, k -lst[j], j)
if index is not -1 and index is not j:
return [lst[j], k -lst[j]]

 

print(findSum([1, 5, 3], 2))
print(findSum([1, 2, 3, 4], 5))

Output:
None
[1,4]
Bạn có thể giải quyết vấn đề này bằng cách trước hết xếp thứ tự danh sách. Sau đó, với mỗi phần tử trong danh sách, dùng thuật toán tìm nhị phân để tìm số chênh lệch giữa tổng và phần tử đó. Nói cách khác, nếu tổng cho trước là k và phần tử đầu tiên của danh sách đã xếp thứ tự trong danh sách là

a0a_{0}a0​
chúng ta sẽ tìm phần tử bằng phương pháp nhị phân sao cho

a0a_{0}a0​
Việc tìm kiếm được lặp lại cho đến khi một phần tử được tìm thấy. Bạn có thể thực thi hàm binarySearch() theo bất kỳ cách nào bạn muốn, đệ quy hay lặp lại.

Độ phức tạp về thời gian

Vì hầu hết các hàm xếp thứ tự dựa trên so sách tối ưu nhất mất O(nlogn), hãy giả định rằng hàm .sort() của Python mất khoản thời gian tương tự. Hơn nữa, vì tìm nhị phân mất O(logn) thời lượng cho việc tìm ra một phần tử duy nhất, do đó, việc tìm tất cả n phần tử sẽ mất O(nlogn) thời lượng.

Python Developer được hỏi... 06/06/2023

Tìm số nguyên không lặp lại trong một danh sách

1 câu trả lời

Ở đây bạn có thể dùng từ điển Python để lưu số lần lặp lại của các phần tử.

Sample input:

[9,2,3,2,6,6]

def findFirstUnique(lst):
counts = {} # Creating a dictionary
# Initializing dictionary with pairs like (lst[i],(count,order))
counts = counts.fromkeys(lst, (0,len(lst)))
order = 0
for ele in lst:
# counts[ele][0] += 1 # Incrementing for every repitition
# counts[ele][1] = order
counts[ele] = (counts[ele][0]+1 , order)
order += 1 # increment order
answer = None
answer_key = None
# filter non-repeating with least order
for ele in lst:
if (counts[ele][0] is 1) and (answer is None):
answer = counts[ele]
answer_key = ele
elif answer is None:
continue
elif (counts[ele][0] is 1) and (counts[ele][1] < answer[1]):
answer = counts[ele]
answer_key = ele
return answer_key


print(findFirstUnique([1, 1, 1, 2]))

Output: 2
Các từ khoá trong từ điển counts là các phần tử của danh sách được cho và các giá trị là số lần phần tử đó xuất hiện trong danh sách. Chúng ta trả về phần tử xuất hiện nhiều nhất 1 lần ở dòng 23. Chúng ta cần duy trì thứ tự của các giá trị cập nhật cho mỗi từ khoá trong 1 giá trị danh sách cố định (tuple.)

Độ phức tạp về thời gian

Vì danh sách chỉ được duyệt qua 2 lần, và từ điển counts được khởi tạo với độ phức tạp thời gian biến đổi tuyến tính, độ phức tạp về thời gian của giải thuật này là tuyến tính, nghĩa là O(n).

Python Developer được hỏi... 02/06/2023

Tìm giá trị ở giữa của một danh sách liên kết (linked list)

1 câu trả lời

Ở đây bạn có thể dùng 2 con trỏ làm việc đồng thời. Hãy nghĩ về chúng theo cách này:

  • Con trỏ nhanh di chuyển 2 bước 1 lần cho đến cuối danh sách.
  • Con trỏ chậm di chuyển 1 bước 1 lần.
  • Khi con trỏ nhanh đến cuối danh sách, con trỏ chậm sẽ ở ngay giữa danh sách.

Dùng thuật toán này, bạn có thể làm cho quá trình nhanh hơn vì việc tính toán độ dài và việc duyệt đến điểm giữa cùng diễn ra đồng thời.

Độ phức tạp về thời gian

Bạn duyệt qua danh sách liên kết gấp đôi tốc độ, vì thế chắc chắn là nó nhanh hơn. Tuy nhiên, độ phức tạp của chỗ nghẽn cổ chai vẫn là O(n).

 

Python Developer được hỏi... 06/06/2023

Hãy đảo ngược k phần tử đầu tiên trong một hàng đợi.

1 câu trả lời

Kiểm tra để phát hiện dữ liệu đầu vào không hợp lệ, chẳng hạn như hàng đợi rỗng, và nếu k âm trên Dòng 2. Nếu dữ liệu đầu vào hợp lệ, bắt đầu bằng việc tạo ra một Stack. Các hàm stack là:

  • Hàm dựng (Constructor):myStack()
  • Thêm phần tử (Push Elements):push(int) để thêm phần tử vào stack.
  • Lấy phần tử ra (Pop elements):pop() xoá phần tử khỏi stack.
  • Kiểm tra rỗng (Check if empty):isEmpty() trả về True nếu stack rỗng, và False trong trường hợp ngược lại.
  • Trả về sau (Return back):back() trả về phần tử được thêm vào cuối stack mà không loại bỏ nó ra khỏi stack.
  • Trả về trước (Return front): front() trả về phần tử ở đầu stack mà không loại bỏ nó ra khỏi stack.

Hàm reverseK(queue, k) của chúng ta nhận một hàng đợi làm tham số đầu vào. k đại diện cho số phần tử muốn đảo ngược. Các hàm hàng đợi sẵn có là:

  • Hàm dựng (Constructor): myQueue(size) size should be an integer specifying the size of the queue.
  • Hàm xếp hàng (Enqueue): enqueue(int)
  • Hàm loại bỏ ra khỏi hàng (Dequeue): dequeue()
  • Kiểm tra rỗng isEmpty()
  • Kiểm kích thước: size()

Bây giờ, hay chuyển qua logic thực sự, lấy ra khỏi hàng k phần tử đầu tiên từ phía trước hàng đợi và đẩy chúng vào stack chúng ta đã tạo trước đó dùng hàm stack.push(queue.dequeue()) ở dòng 8.

Khi tất cả k phần tử đã được đẩy vào stack, bắt đầu lấy chúng ra và xếp hàng chúng vào cuối hàng đợi một cách tuần tự. Chúng ta sẽ làm việc này bằng hàm queue.enqueue(stack.pop()) ở dòng 12. Ở cuối bước này, chúng ta chỉ còn một stack rỗng và k phần tử đảo ngược sẽ được thêm vào phía sau của hàng đợi.

Bây giờ chúng ta phải dịch chuyển những phần tử đảo ngược này lên phía đầu của hàng đợi. Để làm việc này, chúng ta dùng hàm queue.enqueue(queue.dequeue()) ở đòng 16. Mỗi phần tử trước hết được lấy ra khỏi hàng đợi ở phía sau.

Python Developer được hỏi... 02/06/2023

Hãy tìm chiều cao của một Cây tìm nhị phân (Binary Search Tree - BST)

1 câu trả lời

Ở đây bạn có thể dùng đệ quy để tìm chiều cao của cây con bên phải và bên trái.

Giải thích

Ở đây, chúng ta trả về -1 nếu nốt là None. Kế đến, chúng ta gọi hàm findHeight() trên cây con bên trái và bên phải, và sau đó trả về giá trị lớn hơn + 1. Chúng ta sẽ không trả về 0 nếu nốt là None vì nốt lá sẽ có độ cao là 0.

Độ phức tạp về thời gian

Độ phức tạp về thời gian của đoạn mã trên là O(n)O(n) vì tất cả các nốt của toàn bộ cây phải được duyệt qua.

Python Developer được hỏi... 06/06/2023

Hãy chuyển đổi chồng lớn nhất (max heap) thành chồng nhỏ nhất (min heap)

1 câu trả lời

Ở đây chúng ta sẽ tối thiểu hoá chồng (Min Heapify) tất cả các nốt cha.

def minHeapify(heap, index):
left = index * 2 + 1
right = (index * 2) + 2
smallest = index
# check if left child exists and is less than smallest
if len(heap) > left and heap[smallest] > heap[left]:
smallest = left
# check if right child exists and is less than smallest
if len(heap) > right and heap[smallest] > heap[right]:
smallest = right
# check if current index is not the smallest
if smallest != index:
# swap current index value with smallest
tmp = heap[smallest]
heap[smallest] = heap[index]
heap[index] = tmp
# minHeapify the new node
minHeapify(heap, smallest)
return heap


def convertMax(maxHeap):
# iterate from middle to first element
# middle to first indices contain all parent nodes
for i in range((len(maxHeap))//2, -1, -1):
# call minHeapify on all parent nodes
maxHeap = minHeapify(maxHeap, i)
return maxHeap


maxHeap = [9, 4, 7, 1, -2, 6, 5]
print(convertMax(maxHeap))

Output: [-2, 1, 5, 9, 4, 6, 7]

Giải thích

Hãy nhớ rằng chúng ta có thể xem xét tham số được truyền maxHeap là một danh sách các số phần tử và xếp thứ tự chúng lại sao cho chúng đại diện một chồng nhỏ nhất một cách chính xác. Chúng ta là chính xác việc đó trong giải thuật này. Hàm convertMax() phục hồi các thuộc tính chồng trên tất cả các nốt từ nốt cha thấp nhất bằng cách gọi hàm minHeapify() trên mỗi phần tử.

Độ phức tạp về thời gian

Hàm minHeapify() được gọi cho nửa số nốt trong chồng. Hàm này mất O(log(n)) thời gian, và nó được gọi trên n2\frac{n}{2}2n​ nốt, nên giải thuật này mất O(nlog(n)) thời gian.

Python Developer được hỏi... 06/06/2023

Hãy phát hiện vòng lặp trong một danh sách liên kết

1 câu trả lời

Giải thích

Duyệt qua toàn bộ danh sách liên kết, và thêm mỗi nốt đã đi qua vào bộ visited_nodes. Ở mỗi nốt, chúng ta kiểm tra xem nốt đã được đi qua chưa. Theo nguyên tắc, nếu nốt đã được đi qua, một chu kỳ tồn tại.

Độ phức tạp về thời gian

Chúng ta duyệt qua danh sách 1 lần. Trung bình, truy tìm trong một bộ mất O(1) thời gian. Do đó, trung bình thời gian thực thi của thuật toán này là O(n). Tuy nhiên, trong trường hợp xấu nhất, việc tìm kiếm có thể tăng lên tới O(n), làm cho thuật toán mất O(n2)O(n^{2})

Python Developer được hỏi... 02/06/2023

Dữ liệu chuẩn mà Python cung cấp là gì? Phân biệt dữ liệu có thể thay đổi được (mutable) và dữ liệu không thay đổi được (immutable)?

1 câu trả lời

  • Kiểu dữ liệu mutable chuẩn là những giá trị có dữ liệu có thể thay đổi được gồm có: List, Set, Dictionary
  • Kiểu dữ liệu immutable chuẩn những giá trị có dữ liệu không thể thay đổi được  gồm có: Chuỗi, Tuple, Số
Python Developer được hỏi... 24/08/2023

Introduce yourself What is crud api Framework

Python Developer được hỏi... 30/08/2023

Giới thiệu bản thân Crud api Framework là gì?

Đang xem 41 - 60 trong 76 câu hỏi phỏng vấn

Xem câu hỏi phỏng vấn cho các công việc tương tự