Hướng dẫn python code review interview questions - câu hỏi phỏng vấn đánh giá mã python

Bài viết này ban đầu được xuất bản trên cổng khách hàng Red Hat. Thông tin có thể không còn là hiện tại.

Hầu hết các lập trình viên của chúng tôi đều trải qua các cuộc phỏng vấn kỹ thuật mỗi lần một lần. Vào những thời điểm khác, nhiều người trong chúng ta ngồi ở phía đối diện của bàn chạy những cuộc phỏng vấn này. Cổ phần cao, cảm xúc chạy mạnh mẽ, áp lực trí tuệ tích tụ. Tôi đã thấy rằng một đánh giá mã đáng tiếc có thể biến thành một cái gì đó tương tự như một cuộc phỏng vấn công việc khắc nghiệt.

Mặc dù về mặt lý thuyết, vì lợi ích tốt nhất của toàn đội là kết thúc với mã chất lượng cao, các biến thể trong nền tảng kỹ thuật của cá nhân, sự khác biệt về văn hóa, định kiến ​​được xây dựng dựa trên kinh nghiệm trước đây, sự kỳ quặc về tính cách và thậm chí cả tính khí có thể khiến mọi người chiến đấu với nhau vấn đề tương đối không quan trọng.

Xem xét một yêu cầu kéo tưởng tượng. Ở đó chúng tôi thường có hai diễn viên: tác giả và người đánh giá mã. Đôi khi các tác giả có xu hướng đánh giá quá cao chất lượng mã của họ, điều này gây ra cho họ là phòng thủ quá mức và thậm chí có thể thù địch với bất kỳ đối số nào. Mọi người xem xét mã có thể thấy mình đang ở trong một vị trí quyền lực để đánh giá tác phẩm của tác giả. Một khi các diễn viên va chạm với một vấn đề mà họ đứng trên mạng và đủ mạnh mẽ, tất cả đều công bằng trong tình yêu và chiến tranh.

Một hiện tượng thú vị khác mà tôi gặp phải trong khi xem xét mã Python có thể được quy cho hàng rào thấp của Python đối với người mới đến. Các lập trình viên chuyển đổi từ các ngôn ngữ khác mang theo phong tục và thành ngữ mà họ đã quen với "tiếng mẹ đẻ" của họ. Tôi thường có thể tìm ra từ mã Python của họ cho dù tác giả là cựu lập trình viên Java, Perl hay Bash. Nhiều như tôi ngưỡng mộ các công nghệ và chuyên môn khác, tôi tin rằng việc viết mã là hiệu quả và thú vị nhất với ngôn ngữ thay vì kéo dài nó ngoài thiết kế dự định của nó.

Trong bài viết này, tôi sẽ tập trung vào kinh nghiệm cá nhân của mình trong việc tác giả và xem xét mã Python từ cả hai quan điểm tâm lý và kỹ thuật. Và tôi sẽ làm như vậy, hãy ghi nhớ mục tiêu cuối cùng là đạt được sự cân bằng giữa các đánh giá mã là thú vị và có kết quả về mặt kỹ thuật.

Tại sao chúng tôi xem lại mã

Mục đích ngay lập tức nhất của đánh giá mã là làm cho mã tốt hơn bằng cách tập trung nhiều nhãn cầu vào nó. Nhưng đánh giá mã dường như còn nhiều hơn thế!

Đó cũng là một cách để các kỹ sư giao tiếp, học hỏi và thậm chí giao tiếp qua một chủ đề có ý nghĩa và thú vị lẫn nhau. Trong một nhóm nơi cả hai kỹ sư cấp cao và cơ sở làm việc cùng nhau, một đánh giá mã cung cấp cơ hội cho các kỹ sư cơ sở quan sát các bậc thầy trong công việc và học hỏi từ họ.

Đến lượt, người cao niên có cơ hội huấn luyện các kỹ sư đồng nghiệp, bị thách thức và do đó chứng minh thẩm quyền của họ (rất lành mạnh). Mọi người đều có thể thấy vấn đề từ các quan điểm khác nhau, cuối cùng đóng góp cho kết quả tốt hơn.

Đối với mã hóa Pythonistas trưởng thành với người mới, đánh giá mã là một cách để dạy họ cách chúng ta làm mọi thứ trong Python với mục tiêu tạo ra các lập trình viên Python thành ngữ từ chúng.

Vì lợi ích lớn hơn

Điều tốt nhất chúng ta có thể làm về khía cạnh tâm lý là, với tư cách là một tác giả, từ bỏ sự gắn bó cảm xúc của chúng ta với mã của chúng ta và, với tư cách là một người đánh giá, có ý thức kiềm chế bản thân tấn công các ý tưởng của các tác giả khác, thay vào đó tập trung vào việc tư vấn cho họ.

Để đánh giá là một trải nghiệm hiệu quả và tương đối thoải mái, một người đánh giá nên luôn tích cực, biết ơn, thực sự khen ngợi công việc và tài năng của tác giả trong một vấn đề chân thật. Những thay đổi được đề xuất nên được chứng minh bằng cơ sở kỹ thuật vững chắc và không bao giờ bởi sở thích cá nhân của người đánh giá.

Đối với các tác giả, nó có thể giúp tiếp tục nhắc nhở bản thân họ có bao nhiêu thời gian và công sức để các nhà phê bình làm việc với mã của tác giả - phản hồi của họ là quý giá!

Nghe có vẻ lý tưởng, cách tiếp cận của tôi nhằm mục đích hạ thấp cái tôi của tôi bằng cách tối ưu hóa cho một đội ngũ lành mạnh hơn và một công việc thú vị. Tôi nghi ngờ rằng nó có thể đến với chi phí của chất lượng bị xâm phạm của mã chúng tôi cùng nhau sản xuất, nhưng với tôi đó là giá trị nó. Hy vọng của tôi ở đây là ngay cả khi chúng ta hợp nhất mã tối ưu phụ, cuối cùng chúng ta sẽ học hỏi từ đó và nhân tố lại sau. Đó là một chi phí rẻ hơn nhiều so với việc kết thúc với một đồng nghiệp căng thẳng, tuyệt vọng và hủy hoại.

Khi tôi là một tác giả

Là một tác giả, tôi không đưa ra các yêu cầu kéo (PRS) một cách nhẹ nhàng. Mã giá trị trong ngày của tôi có khả năng khiến các nhà phê bình đồng nghiệp bận rộn trong vài giờ. Tôi biết rằng đó là một nỗ lực khó khăn và tốn kém. Đánh giá mã thích hợp có thể yêu cầu các đồng đội của tôi đảo ngược logic kinh doanh kỹ sư đằng sau sự thay đổi, thực hiện mã theo dõi, tiến hành các thí nghiệm suy nghĩ và tìm kiếm các trường hợp cạnh. Tôi luôn ghi nhớ điều đó và cảm thấy biết ơn về thời gian của họ.

Tôi cố gắng giữ cho những thay đổi của mình nhỏ. Thay đổi càng lớn, càng cần nhiều nỗ lực để các nhà đánh giá hoàn thành đánh giá. Điều đó mang lại cho những thay đổi nhỏ hơn, bị cô lập một cơ hội tốt hơn để điều trị chất lượng, trong khi những đốm màu rất lớn và lộn xộn của nguy cơ khác biệt nhắm mắt làm ngơ lên ​​PR của tôi.

Mã bị phá hủy tốt kèm theo các bài kiểm tra, các thay đổi được ghi lại đúng cách tuân thủ các chính sách của nhóm-những phẩm chất PR đó là dấu hiệu của sự tôn trọng và chăm sóc đối với người đánh giá. Tôi cảm thấy bản thân tự tin hơn khi tôi chạy đánh giá bản thân nhanh chóng chống lại PR tiềm năng của mình trước khi gửi nó cho các kỹ sư đồng nghiệp.

Khi tôi là người đánh giá

Đối với tôi, những phẩm chất quan trọng nhất của mã là sạch sẽ và pythonic như hoàn cảnh cho phép.

Mã sạch có xu hướng được cấu trúc tốt, trong đó các bộ phận khác biệt về mặt logic được phân lập với nhau thông qua các ranh giới rõ ràng. Lý tưởng nhất, mỗi phần là chuyên giải quyết một vấn đề duy nhất. Như Zen of Python đã nói: & nbsp; "Nếu việc thực hiện dễ giải thích, đó có thể là một ý tưởng tốt".

Dấu hiệu của mã rõ ràng bao gồm các chức năng tự ghi chép và các biến mô tả các thực thể có vấn đề, không phải chi tiết thực hiện.

Thực sự có khả năng đọc, mặc dù tôi sẽ không đổ mồ hôi đầy đủ về việc tuân thủ PEP8 khi nó trở nên nitpicking và bikeshing.

Tôi ca ngợi mã hóa của tác giả trên vai của những người khổng lồ - trừu tượng hóa các vấn đề vào các cấu trúc/thuật toán dữ liệu chính tắc và làm việc từ đó. Điều đó mang lại cho tôi cảm giác ấm áp của tác giả thuộc cùng một bang hội thương mại với bản thân tôi, và tự tin rằng cả hai chúng tôi đều biết những gì mong đợi từ mã.

Khi tôi là một con trăn

Định nghĩa của mã là Pythonic có xu hướng hơi mơ hồ và chủ quan. Nó dường như bị ảnh hưởng bởi thói quen, hương vị của một người, đã chọn thành ngữ và tiến hóa ngôn ngữ. Tôi giữ điều đó trong tâm trí và kiềm chế bản thân khỏi truyền giáo nhận thức cá nhân của tôi về những gì Pythonic đối với đồng bào Pythonistas.

Phát biểu từ kinh nghiệm của tôi trong lĩnh vực này, hãy để tôi cung cấp cho người đọc một số ít các quan sát mã mà tôi đã gặp, cùng với các đề xuất tận dụng các tính năng có nguồn gốc từ Python mà những người có nền tảng khác nhau có thể không biết.

Mô hình lập trình hợp lý

Mọi người đến từ Java có xu hướng biến mọi thứ thành một lớp học. Đó có lẽ là do Java thực thi rất nhiều mô hình OOP. Các lập trình viên Python được hưởng quyền tự do chọn một mô hình lập trình phù hợp nhất cho nhiệm vụ.

Việc lựa chọn triển khai dựa trên đối tượng trông hợp lý với tôi khi có sự trừu tượng rõ ràng cho nhiệm vụ được giải quyết. Sự trạng thái và các vật thể đánh gốm là một lý do mạnh mẽ khác để đi theo con đường OOP.

Nếu ưu tiên của tác giả là giữ các chức năng liên quan với nhau, việc đẩy chúng đến một lớp là một tùy chọn để xem xét. Các lớp như vậy có thể không bao giờ cần khởi tạo, mặc dù.

Các chức năng đứng tự do rất dễ nắm bắt, súc tích và ánh sáng. Khi một hàm không gây ra tác dụng phụ, nó cũng tốt cho & nbsp; chức năng & nbsp; lập trình.

Vòng lặp pythonic

Mọi người đến từ C có thể cảm thấy như ở nhà với chỉ số & NBSP; ________ 38 & nbsp; Loops:

    # Non-Pythonic
    choices = ['red', 'green', 'blue']
    i = 0
    while i < len(choices):
        print('{}) {}'.format(i, choices[i]))
        i += 1

hoặc với & nbsp; ________ 39 & nbsp; các vòng như thế này:

    # Non-Pythonic
    choices = ['red', 'green', 'blue']
    for i in range(len(choices)):
        print('{}) {}'.format(i, choices[i]))

Khi không cần chỉ mục, một cách pythonic hơn sẽ là chạy A & nbsp; ________ 39 & nbsp; vòng qua một bộ sưu tập:

    # Pythonic!
    choices = ['red', 'green', 'blue']
    for choice in choices:
        print(choice)

Nếu không, & nbsp; Enumerate & nbsp; Bộ sưu tập và chạy A & nbsp; ________ 39 & nbsp; vòng lặp qua bảng liệt kê:

    # Pythonic!
    choices = ['red', 'green', 'blue']
    for idx, choice in enumerate(choices):
        print('{}) {}'.format(idx, choice))

Như một lưu ý phụ, Python's & nbsp; ________ 39 & nbsp; vòng lặp hoàn toàn khác với những gì chúng ta có trong C, Java hoặc JavaScript. Về mặt kỹ thuật, đó là A & nbsp; foreach & nbsp; loop.

Điều gì sẽ xảy ra nếu chúng ta có nhiều bộ sưu tập để lặp lại? Ngây thơ như nó có thể nhận được:

    # Non-Pythonic
    preferences = ['first', 'second', 'third']
    choices = ['red', 'green', 'blue']
    for i in range(len(choices)):
        print('{}) {}'.format(preferences[i], choices[i]))

Nhưng có một cách tốt hơn - sử dụng & nbsp; zip:

    # Pythonic!
    preferences = ['first', 'second', 'third']
    choices = ['red', 'green', 'blue']
    for preference, choice in zip(preferences, choices):
        print('{}) {}'.format(preference, choice))

Sự hiểu biết, không có vòng lặp nhỏ

Ngay cả một vòng lặp pythonic hoàn hảo cũng có thể được cải thiện hơn nữa bằng cách biến nó thành một danh sách hoặc sự hiểu biết từ điển. Hãy xem xét khá là một vòng lặp để xây dựng một danh sách phụ trong một điều kiện:

    # Non-Pythonic
    oyster_months = []
    for month in months:
        if 'r' in month:
            oyster_months.append(month)

Liệt kê hiểu biết & nbsp; giảm toàn bộ vòng lặp thành một lớp lót!

    # Pythonic!
    oyster_months = [month for month in months if 'r' in month]

Từ điển Hiểu hoạt động tương tự, nhưng đối với các loại ánh xạ.

Chữ ký có thể đọc được

Khác với nhiều ngôn ngữ, trong Python, tên của các tham số chức năng luôn là một phần của chữ ký chức năng:

    >>> def count_fruits(apples, oranges):
    ...     return apples + oranges
    ... 
    >>> count_fruits(apples=12, oranges=21)
    >>> count_fruits(garlic=14, carrots=12)
    TypeError: count_fruits() got an unexpected keyword argument 'garlic'

Kết quả có hai mặt: người gọi có thể đề cập rõ ràng đến một tên tham số để cải thiện khả năng đọc mã. Tác giả của chức năng nên nhận thức được người gọi có thể ràng buộc với một tên được phát hành một lần và hạn chế thay đổi tên trong API công khai.

Ở bất kỳ giá nào, chuyển các tham số được đặt tên cho các chức năng mà chúng tôi gọi là thêm vào khả năng đọc mã.

Được đặt tên là bộ dữ liệu để đọc

Gói các công cụ có cấu trúc thành một tuple là một công thức để truyền đạt nhiều mục với một chức năng. Rắc rối là nó nhanh chóng trở nên lộn xộn:

    # Non-Pythonic
    >>> team = ('Jan', 'Viliam', 'Ilya')
    >>> team
    ('Jan', 'Viliam', 'Ilya')
    >>> lead = team[0]

Được đặt tên là Tuples & nbsp; chỉ cần thêm tên vào các phần tử Tuple để chúng ta có thể thưởng thức ký hiệu đối tượng để giữ chúng:

    # Non-Pythonic
    choices = ['red', 'green', 'blue']
    for i in range(len(choices)):
        print('{}) {}'.format(i, choices[i]))
0

Sử dụng các bộ dữ liệu được đặt tên cải thiện khả năng đọc với chi phí tạo thêm một lớp. Mặc dù vậy, hãy nhớ rằng & nbsp; ____ 43 & nbsp; các chức năng của nhà máy tạo ra một lớp mới bởi & nbsp; ________ 44'ing một mẫu - có thể làm chậm mọi thứ trong một vòng lặp chặt chẽ.

Ngoại lệ, không kiểm tra

Tăng một ngoại lệ là một phương tiện chính để truyền đạt các lỗi trong chương trình Python. Yêu cầu tha thứ hơn là sự cho phép, phải không?

    # Non-Pythonic
    choices = ['red', 'green', 'blue']
    for i in range(len(choices)):
        print('{}) {}'.format(i, choices[i]))
1

Mặc dù vậy, hãy cẩn thận với các ngoại lệ trong các vòng lặp chặt chẽ - chúng có thể làm chậm mã của bạn.

Nói chung, bạn nên làm các lớp ngoại lệ tích hợp. Điều đó giúp truyền đạt rõ ràng các lỗi cụ thể cho vấn đề của chúng tôi và phân biệt các lỗi bong bóng theo mã của chúng tôi với các lỗi khác, ít mong đợi hơn.

Không gian tên ad-hoc

Khi chúng ta gặp các biến va chạm, chúng ta có thể muốn cách ly chúng với nhau. Cách rõ ràng nhất là bọc ít nhất một trong số họ thành một lớp:

    # Non-Pythonic
    choices = ['red', 'green', 'blue']
    for i in range(len(choices)):
        print('{}) {}'.format(i, choices[i]))
2

Nhưng có một lối tắt pythonic tiện dụng:

    # Non-Pythonic
    choices = ['red', 'green', 'blue']
    for i in range(len(choices)):
        print('{}) {}'.format(i, choices[i]))
3

& Nbsp; Simplenamespace & nbsp; đối tượng hoạt động giống như bất kỳ trường hợp lớp nào - chúng ta có thể thêm, thay đổi hoặc xóa các thuộc tính bất cứ lúc nào.

Từ điển goodies

Python & nbsp; dict & nbsp; là một loại dữ liệu chính tắc được hiểu rõ giống như một perl & nbsp; ____ 45 & nbsp; hoặc java & nbsp; ________ 46. Tuy nhiên, trong Python, chúng tôi có thêm một vài tính năng tích hợp như trả lại giá trị cho một khóa bị thiếu:

    # Non-Pythonic
    choices = ['red', 'green', 'blue']
    for i in range(len(choices)):
        print('{}) {}'.format(i, choices[i]))
4

Cài đặt khóa có điều kiện nếu nó không có mặt:

    # Non-Pythonic
    choices = ['red', 'green', 'blue']
    for i in range(len(choices)):
        print('{}) {}'.format(i, choices[i]))
5

Hoặc tự động tạo giá trị ban đầu cho các khóa bị thiếu:

    # Non-Pythonic
    choices = ['red', 'green', 'blue']
    for i in range(len(choices)):
        print('{}) {}'.format(i, choices[i]))
6

Một từ điển duy trì thứ tự chèn chính:

    # Non-Pythonic
    choices = ['red', 'green', 'blue']
    for i in range(len(choices)):
        print('{}) {}'.format(i, choices[i]))
7

Những người mới đến có thể không biết về những công cụ nhỏ tiện lợi này - hãy nói với họ!

Đi cho lặp đi lặp lại

Khi nói đến các bộ sưu tập, đặc biệt là những cái lớn hoặc đắt tiền để tính toán, khái niệm & nbsp; khả năng lặp lại & nbsp; khởi động ngay. Để bắt đầu, a & nbsp;

    # Non-Pythonic
    choices = ['red', 'green', 'blue']
    for i in range(len(choices)):
        print('{}) {}'.format(i, choices[i]))
8

Nhiều loại tích hợp đã được lặp lại. Đối tượng người dùng có thể trở nên có thể lặp lại bằng cách hỗ trợ giao thức Iterator:

    # Non-Pythonic
    choices = ['red', 'green', 'blue']
    for i in range(len(choices)):
        print('{}) {}'.format(i, choices[i]))
9

Vì vậy, chúng có thể được lặp lại trên một vòng lặp:

    # Pythonic!
    choices = ['red', 'green', 'blue']
    for choice in choices:
        print(choice)
0

cũng như trong nhiều bối cảnh khác, nơi dự kiến ​​của một người khác:

    # Pythonic!
    choices = ['red', 'green', 'blue']
    for choice in choices:
        print(choice)
1

Các chức năng của người dùng được gọi là & NBSP; Trình tạo:

    # Pythonic!
    choices = ['red', 'green', 'blue']
    for choice in choices:
        print(choice)
2

Khái niệm về một loại khác được xây dựng chắc chắn vào cơ sở hạ tầng Python và nó được coi là Pythonic để tận dụng các tính năng có khả năng lặp đi lặp lại.

Bên cạnh việc được xử lý bởi các toán tử tích hợp, còn có một bộ sưu tập các chức năng trong & nbsp; itertools & nbsp; mô-đun được thiết kế để tiêu thụ và/hoặc sản xuất iterables.

Tính chất để đóng gói dần dần

Java và C ++ đặc biệt nổi tiếng trong việc thúc đẩy bảo vệ trạng thái đối tượng bằng cách vận hành thông qua các phương thức "người truy cập" (còn được gọi là getters/setters). Một giải pháp thay thế pythonic cho họ dựa trên tính năng & nbsp; ____ 49 & nbsp; Không giống như các lập trình viên Java, Pythonistas không bắt đầu với việc trồng getters và setters vào mã của họ. Họ bắt đầu với các thuộc tính đơn giản, không được bảo vệ:

    # Pythonic!
    choices = ['red', 'green', 'blue']
    for choice in choices:
        print(choice)
3

Khi cần bảo vệ phát sinh, chúng tôi biến một thuộc tính thành A & NBSP; Property & NBSP; bằng cách thêm các điều khiển truy cập vào setter:

    # Pythonic!
    choices = ['red', 'green', 'blue']
    for choice in choices:
        print(choice)
4

Các thuộc tính python được triển khai trên đầu & nbsp; mô tả & nbsp; đây là một cơ chế cấp thấp hơn nhưng phổ biến hơn để có được quyền truy cập thuộc tính.

Người quản lý bối cảnh bảo vệ tài nguyên

Thông thường các chương trình để có được tài nguyên, sử dụng chúng và dọn dẹp sau đó. Một triển khai đơn giản có thể trông như thế này:

    # Pythonic!
    choices = ['red', 'green', 'blue']
    for choice in choices:
        print(choice)
5

Trong Python, chúng ta có thể đặt lại điều này thành một thứ gì đó cô đọng hơn, tận dụng giao thức & nbsp; Trình quản lý bối cảnh:

    # Pythonic!
    choices = ['red', 'green', 'blue']
    for choice in choices:
        print(choice)
6

Biểu thức theo A & nbsp; ________ 50 & nbsp; phải hỗ trợ giao thức Trình quản lý ngữ cảnh. Của nó & nbsp; ________ 51 & nbsp; và & nbsp; ________ 52 & nbsp; các phương thức ma thuật sẽ được gọi tương ứng trước và sau các câu lệnh bên trong & nbsp; ____ ____ 50 & nbsp; block.

Các nhà quản lý bối cảnh là thành ngữ trong Python cho tất cả các loại tình huống kiểm soát tài nguyên: làm việc với các tệp, kết nối, khóa, quy trình. Để đưa ra một vài ví dụ, mã này sẽ đảm bảo rằng kết nối với máy chủ web được đóng sau khi thực thi hết & nbsp; ________ 50 & nbsp; block: block:

    # Pythonic!
    choices = ['red', 'green', 'blue']
    for choice in choices:
        print(choice)
7

& NBSP;

    # Pythonic!
    choices = ['red', 'green', 'blue']
    for choice in choices:
        print(choice)
8

Người trang trí để thêm chức năng

Python & nbsp; trang trí & nbsp; làm việc bằng cách gói một chức năng với một chức năng khác. Các trường hợp sử dụng bao gồm ghi nhớ, khóa, xử lý trước/sau, kiểm soát truy cập, thời gian, và nhiều hơn nữa.

Xem xét một triển khai ghi nhớ đơn giản:

    # Pythonic!
    choices = ['red', 'green', 'blue']
    for choice in choices:
        print(choice)
9

Đây là nơi các nhà trang trí Python có ích:

    # Pythonic!
    choices = ['red', 'green', 'blue']
    for idx, choice in enumerate(choices):
        print('{}) {}'.format(idx, choice))
0

Sức mạnh của các nhà trang trí xuất phát từ khả năng sửa đổi hành vi chức năng theo cách không xâm lấn và phổ quát. Điều đó mở ra & nbsp; khả năng & nbsp; để giảm tải logic kinh doanh vào một nhà trang trí chuyên dụng và sử dụng lại nó trên toàn bộ cơ sở mã.

Thư viện tiêu chuẩn Python cung cấp nhiều nhà trang trí làm sẵn. Ví dụ: công cụ ghi nhớ trên có sẵn trong thư viện tiêu chuẩn:

    # Pythonic!
    choices = ['red', 'green', 'blue']
    for idx, choice in enumerate(choices):
        print('{}) {}'.format(idx, choice))
1

Các nhà trang trí đã đi vào API công khai trong các dự án lớn như Django hoặc Pytest.

Gõ vịt

Gõ vịt & nbsp; được khuyến khích cao trong Python vì hiệu quả và linh hoạt hơn. Trường hợp sử dụng thường xuyên liên quan đến việc mô phỏng các loại python tích hợp như container:

    # Pythonic!
    choices = ['red', 'green', 'blue']
    for idx, choice in enumerate(choices):
        print('{}) {}'.format(idx, choice))
2

Mô phỏng giao thức container đầy đủ đòi hỏi nhiều phương pháp ma thuật phải có mặt và thực hiện đúng. Điều này có thể trở nên tốn nhiều công sức và dễ bị lỗi. Một cách tốt hơn là cơ sở các thùng chứa người dùng trên đầu A & nbsp; tương ứng & nbsp; lớp cơ sở trừu tượng:

    # Pythonic!
    choices = ['red', 'green', 'blue']
    for idx, choice in enumerate(choices):
        print('{}) {}'.format(idx, choice))
3

Chúng ta không chỉ phải thực hiện ít phương pháp ma thuật hơn, khai thác ABC đảm bảo rằng tất cả các phương thức giao thức bắt buộc đều được áp dụng. Điều này một phần giảm thiểu tính mong manh vốn có của gõ động.

Gõ ngỗng

Kiểm tra loại dựa trên phân cấp loại là một mô hình phổ biến trong các chương trình Python. Những người có nền tảng bằng các ngôn ngữ được đánh giá theo thống kê có xu hướng giới thiệu các loại kiểm tra loại đặc biệt như sau:

    # Pythonic!
    choices = ['red', 'green', 'blue']
    for idx, choice in enumerate(choices):
        print('{}) {}'.format(idx, choice))
4

Mặc dù không nản lòng trong Python, kiểm tra loại có thể được thực hiện tổng quát và đáng tin cậy hơn bằng cách kiểm tra chống lại các loại cơ sở trừu tượng:

    # Pythonic!
    choices = ['red', 'green', 'blue']
    for idx, choice in enumerate(choices):
        print('{}) {}'.format(idx, choice))
5

Điều này được gọi là "gõ ngỗng" theo cách nói của Python. Nó ngay lập tức làm cho kiểm tra loại tương thích với cả loại tích hợp và người dùng kế thừa từ các lớp cơ sở trừu tượng. Ngoài ra, kiểm tra chống lại ABC trao quyền cho giao diện dựa trên giao diện, trái ngược với so sánh các loại dựa trên phân cấp, so sánh:

    # Pythonic!
    choices = ['red', 'green', 'blue']
    for idx, choice in enumerate(choices):
        print('{}) {}'.format(idx, choice))
6

Thay thế cho kiểm tra loại ad-hoc được trồng vào mã là & nbsp; gõ dần dần & nbsp; kỹ thuật được hỗ trợ đầy đủ kể từ Python 3.6. Nó dựa trên ý tưởng chú thích các biến quan trọng với thông tin loại, sau đó chạy A & NBSP; Phân tích tĩnh & NBSP; qua mã được chú thích như thế này:

    # Pythonic!
    choices = ['red', 'green', 'blue']
    for idx, choice in enumerate(choices):
        print('{}) {}'.format(idx, choice))
7

Việc gõ tĩnh có xu hướng làm cho các chương trình đáng tin cậy hơn bằng cách tận dụng thông tin loại rõ ràng, tính tương thích của các loại tính toán và thất bại một cách duyên dáng khi phát hiện lỗi loại. Khi gõ gợi ý được thông qua bởi một dự án, các chú thích loại có thể thay thế hoàn toàn các kiểm tra loại ad-hoc trong suốt mã.

Công cụ quyền lực của Pythonista

Nó có thể xảy ra với một người đánh giá, rằng một giải pháp hiệu quả hơn có thể khả thi ở đây và đó. Để thiết lập các cơ sở kỹ thuật vững chắc bằng cách ủng hộ đề xuất tái cấu trúc của họ với các số cứng thay vì trực giác hoặc sở thích cá nhân, một phân tích nhanh có thể có ích.

Trong số các công cụ tôi sử dụng khi nghiên cứu cho một giải pháp tốt hơn là & nbsp; dis & nbsp; (để phân tích mã byte), & nbsp; timeit & nbsp; (để đo mã thời gian chạy mã) và & nbsp;

Hạnh phúc khi xem xét!

Làm cách nào để xem lại mã Python?

Danh sách kiểm tra đánh giá mã Python:..
Xác minh các yêu cầu của bạn. Đánh giá mã không tồn tại trong chân không. ....
Kiểm tra khả năng đọc của mã của bạn. ....
Kiểm tra xem yêu cầu kéo (PR) có tương ứng với giao thức cơ bản hay không. ....
Hãy chắc chắn rằng mã của bạn đáp ứng các yêu cầu của bạn. ....
Kiểm tra mã của bạn để bảo mật. ....
Documentation..

Làm thế nào để bạn sửa đổi cho một cuộc phỏng vấn ở Python?

Làm thế nào để nổi bật trong một cuộc phỏng vấn mã hóa Python..
Lặp lại với Enumerate () thay vì phạm vi ().
Sử dụng danh sách toàn diện thay vì bản đồ () và bộ lọc ().
Gỡ lỗi với điểm dừng () thay vì in ().
Chuỗi định dạng với dây F ..
Sắp xếp danh sách phức tạp với Sắp xếp ().

Tôi nên mong đợi điều gì trong một cuộc phỏng vấn đánh giá mã?

Trọng tâm của cuộc phỏng vấn nên là mã của họ, cách thức hoạt động, lý do tại sao họ đưa ra những lựa chọn mà họ đã làm, v.v.Trước khi phỏng vấn, bạn nên lên kế hoạch dành một hoặc hai giờ để đọc mã của ứng viên, điều hành nó và chuẩn bị các câu hỏi tiếp theo để hỏi khi bạn phỏng vấn họ.. Before the interview, you should plan to spend an hour or two reading the candidate's code, running it, and preparing follow-up questions to ask when you interview them.

Các câu hỏi mã hóa được hỏi trong cuộc phỏng vấn cho Python là gì?

Câu hỏi phỏng vấn mã hóa Python..
1) Cách tốt nhất để gỡ lỗi chương trình Python là gì?....
2) Từ khóa Python ngụ ý gì?....
3) Làm cách nào để tạo ra một danh sách?....
4) Chính xác thì một mảng numpy là gì?....
5) Trong Python, theo cách nào bạn có thể tạo ra một mảng numpy trống rỗng?....
6) Trong Python, chỉ số tiêu cực là gì ?.