В 2023 году, в эпоху взрывного роста нейросетей, вся IT-отрасль продолжает давать кандидатам в стажёры (и не только) домашние тестовые задания. Компании тратят время на то, чтобы придумать эти задания, студенты тратят время на то, чтобы их сделать, потом компании снова тратят время на проверку… В этой небольшой заметке я продемонстрирую, что все задачи последних лет решаются за несколько минут при использовании нейронки, доступ к которой может получить каждый.




Я возьму тестовые задания на Python, C++, Go и C#  и буду использовать только открытые источники, убрав названия компаний и прямые ссылки, чтобы исключить любые подозрения в предвзятости.


А в качестве нейронки использую ChatGPT Plus (GPT 4). Она всё еще очень глупа, много выдумывает и постоянно смешно ошибается, но как раз для таких задач годится хорошо.


И да, вместо дисклеймера. Если вы хоть немного успели «посотрудничать» с ChatGPT, то статья может показаться вам глубоко капитанскоочевидной (она такая и есть, безусловно). Но если вы вместо хайпа по нейронкам предпочитаете работать, то у вас нет времени на такие развлечения. Так что, возможно, несколько минут, которые вы сейчас потратите на прочтение, сэкономят вам много часов инвестиций в «ненастоящих стажеров» и «ненастоящих джунов». И соответственно, помогут не наделать ошибок при найме.


TL;DR

Скорее всего, все ваши задания решаются нейронкой.


Если вы думаете, что ваше задание слишком комплексное, чтобы его могла сгенерировать нейронка, смотрите:



Если вы думаете, что уникальность (вы сами его придумали) задания, обеспечивает его нерешаемость нейронкой, смотрите:



Задачи


Число вхождений массива в подмассив — Python


На вход программе подаются два массива целых чисел, разделённых пробелом. Необходимо найти число вхождений второго массива в первый. То есть посчитать, сколько раз последовательность чисел второго массива (без перестановок) встречается в первом.


Ответ робота

Данное задание можно решить различными способами, но одним из наиболее простых и наглядных является использование простого алгоритма, который проходит по всем элементам первого массива и сравнивает их с элементами второго массива. Вот пример решения на Python:


def count_subarray(array1, array2):
    count = 0
    len2 = len(array2)

    for i in range(len(array1)):
        if array1[i:i+len2] == array2:
            count += 1

    return count

# Пример использования
array1 = [1, 2, 3, 1, 2, 3, 4, 1, 2]
array2 = [1, 2, 3]

print(count_subarray(array1, array2))  # Выведет 2

Этот код создаёт функцию count_subarray, которая принимает два массива в качестве аргументов. Функция инициализирует счётчик вхождений count значением 0. Затем она проходит по всем элементам array1 и сравнивает подмассив длины array2, начинающийся с текущего элемента, с array2. Если они равны, увеличивается счётчик count. В конце функция возвращает значение count, которое представляет количество вхождений array2 в array1.


Обратите внимание, что данный подход будет работать для неотсортированных массивов, поскольку мы ищем точные последовательности чисел.


Итог: ответ верный.


Каноничный путь UNIX — Python


Дана строка, которая является абсолютным путем к файлу или директории в системе Unix.


Нужно упростить эту строку до каноничного пути.


Каноничный путь — это тот путь, который будет максимально простым и строгим, а именно:


  • Путь начинается с единичного слеша /
  • Любые две директории разделяются одиночным слешем
  • Путь не может оканчиваться слешем /
  • Путь может содержать только истинные директории к нужному файлу (то есть в пути не может быть '.' или '..')

На вход подается путь к файлу или директории в системе Unix.


На выходе ожидается каноничный путь.


Пример:


абсолютный путь: /home/abc/../abc/file.txt


каноничный путь: /home/abc/file.txt


Программа должна возвращать упрощенный каноничный путь до файла или директории


Sample Input:
/../
Sample Output:
/


Ответ робота

Задача может быть решена с помощью стека. Мы проходим по каждому компоненту пути (директории или файлу), разделяя строку по слешам. Если текущий компонент — это "..", то мы выходим из последней директории (если она существует). Если текущий компонент — это "." или пустая строка, мы пропускаем этот компонент. Иначе, мы входим в данную директорию (добавляем её в стек). В конце, стек содержит каноничный путь, который мы объединяем в одну строку.


def simplify_path(path):
    path_parts = path.split("/")
    stack = []

    for part in path_parts:
        if part == "..":
            if stack:
                stack.pop()
        elif part and part != ".":
            stack.append(part)

    return "/" + "/".join(stack)

# Пример использования:
print(simplify_path("/home/abc/../abc/file.txt"))  # Выведет: /home/abc/file.txt
print(simplify_path("/../"))  # Выведет: /

Обратите внимание, что этот подход работает только для абсолютных путей и не обрабатывает относительные пути. Если вам нужно обработать и относительные пути, вам понадобится дополнительная логика для обработки таких ситуаций.  


Итог: На мой взгляд решение хорошее, все условия соблюдены.


Определение частоты встречаемости IP адресов — Python


Дан лог сервера, который содержит логи операций с машинами. Для идентификации машин используются IPv4 адреса.


Нужно определить частоту встречаемости IP адресов.


На вход принимается лог.


На выходе ожидается список адресов с количеством упоминаний адреса (список IP-адресов, отсортированных в порядке убывания количества упоминаний). Если несколько IP-адресов имеют одинаковое количество упоминаний, то к ним применяется сортировка строк по убыванию.


Важно:
В логе может встречаться текст похожий на IP, но не являющимся им, например, 0.0.0.1000
Также в логах могут встречаться маски подсети, например 192.168.0.0/16. Их не нужно считать как ip.
Строки логов могут быть пустые.
Строка лога не обязательно содержит ip, но в логах обязательно содержится хотя бы один ip.


Например, если лог содержит следующие записи:


[2019-08-29 13:00:13] login to 10.64.64.8
[2019-08-29 13:15:35] logout from 95.213.255.16
[2019-08-29 14:14:33] ssh connection to 10.64.64.8
[2019-09-01 14:14:35] request from 35.228.158.140 to 10.64.65.8
[2019-09-01 14:14:35] login to 35.228.158.140
[2019-09-01 15:29:01] login to 35.228.158.140

Программа должна вывести на экран:


35.228.158.140 3
10.64.64.8 2
95.213.255.16 1
10.64.65.8 1

Sample Input:


[2019-08-29 13:00:13] login to 10.64.64.8
[2019-08-29 13:15:35] logout from 95.213.255.16
[2019-08-29 14:14:33] ssh connection to 10.64.64.8
[2019-09-01 14:14:35] request from 35.228.158.140 to 10.64.65.8
[2019-09-01 14:14:35] login to 35.228.158.140
[2019-09-01 15:29:01] login to 35.228.158.140

Sample Output:


35.228.158.140 3
10.64.64.8 2
95.213.255.16 1
10.64.65.8 1

Ответ робота

Эта задача может быть решена с помощью регулярных выражений и словаря для подсчёта вхождений каждого IP-адреса. Вот пример решения на Python:


import re
from collections import Counter

def parse_logs(logs):
    # Регулярное выражение для поиска IPv4-адресов
    ip_pattern = re.compile(r'\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b')

    # Инициализация счетчика для подсчета встречаемости IP-адресов
    ip_counter = Counter()

    # Проход по всем логам и подсчет количества IP-адресов
    for log in logs:
        ip_addresses = ip_pattern.findall(log)
        for ip in ip_addresses:
            # Проверка, является ли подстрока действительным IP-адресом
            parts = list(map(int, ip.split('.')))
            if all(map(lambda part: 0 <= part < 256, parts)):
                ip_counter[ip] += 1

    # Возвращаем отсортированный по убыванию список IP-адресов и их количества
    return sorted(ip_counter.items(), key=lambda item: (-item[1], -int(item[0].replace('.', ''))))

# Пример использования
logs = [
    '[2019-08-29 13:00:13] login to 10.64.64.8',
    '[2019-08-29 13:15:35] logout from 95.213.255.16',
    '[2019-08-29 14:14:33] ssh connection to 10.64.64.8',
    '[2019-09-01 14:14:35] request from 35.228.158.140 to 10.64.65.8',
    '[2019-09-01 14:14:35] login to 35.228.158.140',
    '[2019-09-01 15:29:01] login to 35.228.158.140'
]
print(parse_logs(logs))

В этом коде мы используем регулярное выражение для поиска всех IP-адресов в каждом логе. Затем мы проверяем, что каждая часть адреса находится в допустимом диапазоне (от 0 до 255). Если адрес действителен, мы увеличиваем его счётчик в Counter. В конце мы возвращаем список IP-адресов и их количества, отсортированный в порядке убывания количества и по самому адресу, преобразованному в число, если количество совпадает.  


Видим прокол: не учтены дополнительные условия — подсети попадут в ответ. Но если кандидат потратит хотя бы минуту на чтение задания и тестирование, он это увидит.
Напоминаем роботу про дополнительные условия, получаем новое решение.


Ответ робота
import re
from collections import Counter

def parse_logs(logs):
    # Регулярное выражение для поиска IPv4-адресов
    ip_pattern = re.compile(r'\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b')

    # Инициализация счетчика для подсчета встречаемости IP-адресов
    ip_counter = Counter()

    # Проход по всем логам и подсчет количества IP-адресов
    for log in logs:
        ip_addresses = ip_pattern.findall(log)
        for ip in ip_addresses:
            # Проверка, является ли подстрока действительным IP-адресом
            parts = list(map(int, ip.split('.')))
            if all(map(lambda part: 0 <= part < 256, parts)) and '/' not in log:
                ip_counter[ip] += 1

    # Возвращаем отсортированный по убыванию список IP-адресов и их количества
    return sorted(ip_counter.items(), key=lambda item: (-item[1], -int(item[0].replace('.', ''))))

# Пример использования
logs = [
    '[2019-08-29 13:00:13] login to 10.64.64.8',
    '[2019-08-29 13:15:35] logout from 95.213.255.16',
    '[2019-08-29 14:14:33] ssh connection to 10.64.64.8',
    '[2019-09-01 14:14:35] request from 35.228.158.140 to 10.64.65.8',
    '[2019-09-01 14:14:35] login to 35.228.158.140',
    '[2019-09-01 15:29:01] login to 35.228.158.140',
    '[2019-09-01 15:29:01] invalid ip 0.0.0.1000',
    '[2019-09-01 15:29:01] subnet mask 192.168.0.0/16',
    'empty log',
    '[2019-09-01 15:29:01] no ip here'
]
print(parse_logs(logs))

Итог: задача решена, дополнительные условия учтены.


Самый вместительный контейнер — С++


Дана последовательность h содержащая n целочисленных высот.


На координатной плоскости нарисовано n вертикальных линий,
i-й элемент определяет линию от точки (i, 0) до точки (i, h[i]).


Найдите две линии, которые образуют вместе с осью x "контейнер",
который может содержать наибольшее количество "двумерной воды" так,
чтобы она не выливалась за его пределы. Контейнер наклонять нельзя.


Вроде какая-то распространённая классическая задача.


Ответ робота

Эта задача — классическая задача в области алгоритмов, которую можно решить с помощью метода двух указателей. Суть алгоритма заключается в том, чтобы начать с самого широкого контейнера и пробовать уменьшить ширину контейнера в надежде на то, что мы найдем контейнер с большей высотой. Здесь важно заметить, что минимальная высота определяет максимальный объем контейнера.


Следующий код на C++ реализует этот алгоритм:


#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

int maxArea(vector<int>& height) {
    int max_area = 0;
    int left = 0;
    int right = height.size() - 1;

    while (left < right) {
        // Высчитываем площадь
        int area = min(height[left], height[right]) * (right - left);
        max_area = max(max_area, area);

        // Если текущий слева меньше, чем текущий справа, смещаем указатель слева вправо
        if (height[left] < height[right]) {
            left++;
        } else {
            // В противном случае смещаем указатель справа влево
            right--;
        }
    }

    return max_area;
}

int main() {
    vector<int> heights1 = {1,8,6,2,5,4,8,3,7};
    vector<int> heights2 = {1,1};
    vector<int> heights3 = {4,3,2,1,4};
    vector<int> heights4 = {1,2,1};

    cout << "Maximum water that can be contained: " << endl;
    cout << "Example 1: " << maxArea(heights1) << endl;  // Expected output: 49
    cout << "Example 2: " << maxArea(heights2) << endl;  // Expected output: 1
    cout << "Example 3: " << maxArea(heights3) << endl;  // Expected output: 16
    cout << "Example 4: " << maxArea(heights4) << endl;  // Expected output: 2

    return 0;
}

Функция maxArea принимает вектор height, содержащий высоты линий. Она инициализирует переменные max_area (для хранения максимальной площади контейнера), left и right (для хранения индексов левой и правой границ контейнера). Затем в цикле функция вычисляет площадь контейнера, используя текущие границы, и обновляет max_area, если текущая площадь больше максимальной. Если левая граница меньше правой, функция сдвигает левую границу вправо, иначе она сдвигает правую границу влево. Функция возвращает max_area после завершения цикла.  


Итог: подробно не проверял, но с виду ответ правильный.


lgtm


Решение кажется тоже достаточно эффективным.


Логичнее было вернуть две линии, а не площадь, но это минорное исправление, которое сам робот легко сделает по просьбе человека.



Клиент-серверный пинг-понг — С++


Написать клиент и сервер, которые бесконечно обмениваются друг с другом ping-pong-сообщениями.


Необходимо описать сборку решения на cmake и использовать какую-то популярную библиотеку для логирования.


Ответ робота

Здесь два простых примера клиента и сервера, написанных на C++ с использованием библиотеки Boost.Asio для сетевых операций и spdlog для логирования. Они бесконечно обмениваются сообщениями Ping и Pong.


Server.cpp


#include <boost/asio.hpp>
#include <boost/array.hpp>
#include <spdlog/spdlog.h>

using boost::asio::ip::tcp;

int main() {
    boost::asio::io_service io_service;
    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 1234));

    for (;;) {
        tcp::socket socket(io_service);
        acceptor.accept(socket);

        for (;;) {
            boost::array<char, 128> buf;
            boost::system::error_code error;

            size_t len = socket.read_some(boost::asio::buffer(buf), error);

            if (error == boost::asio::error::eof) {
                break;
            } else if (error) {
                throw boost::system::system_error(error);
            }

            spdlog::info("Received: {}", std::string(buf.data(), len));
            boost::asio::write(socket, boost::asio::buffer("Pong"));
        }
    }

    return 0;
}

Client.cpp


#include <boost/asio.hpp>
#include <boost/array.hpp>
#include <spdlog/spdlog.h>
#include <chrono>
#include <thread>

using boost::asio::ip::tcp;

int main() {
    boost::asio::io_service io_service;
    tcp::resolver resolver(io_service);
    tcp::resolver::query query(tcp::v4(), "localhost", "1234");
    tcp::resolver::iterator iterator = resolver.resolve(query);
    tcp::socket socket(io_service);
    boost::asio::connect(socket, iterator);

    for (;;) {
        boost::asio::write(socket, boost::asio::buffer("Ping"));
        boost::array<char, 128> buf;
        boost::system::error_code error;
        size_t len = socket.read_some(boost::asio::buffer(buf), error);
        spdlog::info("Received: {}", std::string(buf.data(), len));
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }

    return 0;
}

Для компиляции этих двух файлов с помощью CMake, вы можете создать следующий файл CMakeLists.txt:


cmake_minimum_required(VERSION 3.10)
project(PingPong)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

find_package(Boost REQUIRED COMPONENTS system)
find_package(spdlog REQUIRED)

add_executable(Client Client.cpp)
add_executable(Server Server.cpp)

target_link_libraries(Client Boost::system spdlog::spdlog)
target_link_libraries(Server Boost::system spdlog::spdlog)

Чтобы собрать проект:


  1. Создайте директорию build: mkdir build && cd build
  2. Вызовите CMake: cmake ..
  3. Вызовите Make: make

Запустите сервер, а затем клиент. Они начнут обмениваться сообщениями Ping и Pong, и эти сообщения будут логироваться.  


Итог: вроде примерно то, что надо.



Сканер опасных файлов — С++


Требуется реализовать утилиту на языке C++, работающую из командной строки, выполняющую сканирование файлов в директории, с целью нахождения в ней “подозрительных” (suspicious) файлов.


В рамках задачи определено 3 типа “подозрительного” содержимого в файле:


JS suspicious: файл с расширением .js, содержащий строку: <script>evil_script()</script>
CMD suspicious: файл с расширением CMD/BAT, содержащий строку: rd /s /q "c:\windows"
EXE suspicious: файл с расширением EXE/DLL, содержащий строки: CreateRemoteThread, CreateProcess

После завершения выполнения утилиты пользователю должен быть выведен отчет о сканировании, в котором присутствует следующая информация:


общее количество обработанных файлов;
количество детектов на каждый тип “подозрительного” содержимого;
количество ошибок анализа файлов (например, не хватает прав на чтение файла);
время выполнения утилиты.

Пример исполнения утилиты из командной строки:


scan_util ~/Downloads


====== Scan result ======

Processed files: 150
JS detects: 5
CMD detects: 1
EXE detects: 2
Errors: 1
Execution time: 00:00:31

=========================

Для упрощения задачи условимся:


  • В директории находятся только файлы, вложенных директорий нет;


  • В каждом файле присутствует только один тип “подозрительного” содержимого.



Рекомендуется максимальное использование (утилизация) вычислительных ресурсов устройства, на котором выполняется утилита.


Ответ робота

Реализация этой утилиты может быть выполнена с использованием различных компонентов стандартной библиотеки C++. Заметим, что для максимального использования вычислительных ресурсов можно использовать многопоточность с помощью библиотеки <thread> и <future>.
Вот пример реализации, который использует многопоточность для ускорения процесса сканирования файлов:


#include <iostream>
#include <fstream>
#include <vector>
#include <chrono>
#include <thread>
#include <future>
#include <filesystem>
#include <algorithm>
#include <stdexcept>
#include <cstring>

namespace fs = std::filesystem;

struct ScanResult {
    int processedFiles = 0;
    int jsDetects = 0;
    int cmdDetects = 0;
    int exeDetects = 0;
    int errors = 0;
};

ScanResult detectSuspicious(const fs::path& dir) {
    ScanResult result;
    std::vector<std::future<ScanResult>> futures;

    for (const auto& entry : fs::directory_iterator(dir)) {
        futures.push_back(std::async(std::launch::async, [&entry]() {
            ScanResult localResult;
            localResult.processedFiles = 1;

            std::ifstream file(entry.path(), std::ios::binary);
            if (!file) {
                ++localResult.errors;
                return localResult;
            }

            std::string content(std::istreambuf_iterator<char>(file), {});
            if (entry.path().extension() == ".js" &&
                content.find("<script>evil_script()</script>") != std::string::npos)
                ++localResult.jsDetects;
            else if ((entry.path().extension() == ".cmd" || entry.path().extension() == ".bat") &&
                content.find("rd /s /q \"c:\\windows\"") != std::string::npos)
                ++localResult.cmdDetects;
            else if ((entry.path().extension() == ".exe" || entry.path().extension() == ".dll") &&
                content.find("CreateRemoteThread") != std::string::npos &&
                content.find("CreateProcess") != std::string::npos)
                ++localResult.exeDetects;

            return localResult;
        }));
    }

    for (auto& fut : futures) {
        ScanResult localResult = fut.get();
        result.processedFiles += localResult.processedFiles;
        result.jsDetects += localResult.jsDetects;
        result.cmdDetects += localResult.cmdDetects;
        result.exeDetects += localResult.exeDetects;
        result.errors += localResult.errors;
    }

    return result;
}

int main(int argc, char* argv[]) {
    if (argc != 2) {
        std::cerr << "Usage: " << argv[0] << " <directory>\n";
        return 1;
    }

    fs::path dir(argv[1]);

    if (!fs::exists(dir) || !fs::is_directory(dir)) {
        std::cerr << "Invalid directory: " << argv[1] << '\n';
        return 1;
    }

    auto start = std::chrono::high_resolution_clock::now();
    ScanResult result = detectSuspicious(dir);
    auto finish = std::chrono::high_resolution_clock::now();

    std::cout << "\n====== Scan result ======\n\n"
              << "Processed files: " << result.processedFiles << "\n\n"
              << "JS detects: " << result.jsDetects << "\n\n"
              << "CMD detects: " << result.cmdDetects << "\n\n"
              << "EXE detects: " << result.exeDetects << "\n\n"
              << "Errors: " << result.errors << "\n\n"
              << "Execution time: " << std::chrono::duration_cast<std::chrono::seconds>(finish - start).count()
              << "\n\n=========================\n";

    return 0;
}

Замечания по коду:


  1. Структура ScanResult содержит счетчики для всех исследуемых данных.
  2. Функция detectSuspicious итерирует по всем файлам в указанной директории и для каждого файла создает отдельную задачу для выполнения в отдельном потоке с помощью std::async.
  3. В каждом потоке открывается файл, читается его содержимое и проверяется на наличие подозрительных строк в соответствии с его расширением.
  4. В главной функции main проверяется корректность аргументов командной строки, выполняется сканирование и выводятся результаты.


Итог: в коде точно есть как минимум одна проблема — локальная переменная entry захватывается по ссылке, что приводит к ошибке.
Если исправить на захват по значению, то кажется решение становится правильным.



Сервис — генератор случайных значений — GO


Необходимо реализовать сервис на Go для генерации случайных значений.


Сервис реализует JSON API работающее по HTTP. Каждой генерации присваивать уникальный id, по которому можно получить результат генерации методом retrieve.


Реализовать методы:


  • POST /api/generate/ — генерация случайного значения и его идентификатора


  • GET /api/retrieve/ — получение значения по id, которое вернулось в методе generate



Проект должен быть работоспособным и до конца реализованным, должна быть приведена структура файлов проекта. Не должно быть TODO, все необходимо реализовать до конца.


Я немного сократил и конкретизировал задание, но при желании все допусловия также могут быть выполнены GPT.


Ответ робота

Отлично, ваше приложение может состоять из трех основных частей:


  1. Главный файл main.go, который будет инициализировать ваш сервер и роутер.
  2. Контроллер, который будет обрабатывать запросы и генерировать/возвращать данные.
  3. Сервис, который будет хранить данные и предоставлять методы для их получения.

Ниже представлен простой пример реализации вашего приложения на Go.


Файловая структура:


/myproject
  |-- main.go
  |-- controller
  |    |-- controller.go
  |-- service
       |-- service.go

main.go:


package main

import (
    "net/http"
    "myproject/controller"

    "github.com/gorilla/mux"
)

func main() {
    r := mux.NewRouter()

    r.HandleFunc("/api/generate/", controller.Generate).Methods("POST")
    r.HandleFunc("/api/retrieve/{id}", controller.Retrieve).Methods("GET")

    http.ListenAndServe(":8080", r)
}

controller/controller.go:


package controller

import (
    "encoding/json"
    "net/http"
    "myproject/service"
    "github.com/gorilla/mux"
)

func Generate(w http.ResponseWriter, r *http.Request) {
    id, value := service.GenerateValue()
    json.NewEncoder(w).Encode(map[string]string{
        "id":    id,
        "value": value,
    })
}

func Retrieve(w http.ResponseWriter, r *http.Request) {
    id := mux.Vars(r)["id"]
    value, found := service.GetValue(id)
    if !found {
        w.WriteHeader(http.StatusNotFound)
        json.NewEncoder(w).Encode(map[string]string{
            "error": "Value not found",
        })
        return
    }

    json.NewEncoder(w).Encode(map[string]string{
        "id":    id,
        "value": value,
    })
}

service/service.go:


package service

import (
    "math/rand"
    "strconv"
    "sync"
)

var (
    mu sync.RWMutex
    data = make(map[string]string)
)

func GenerateValue() (string, string) {
    mu.Lock()
    defer mu.Unlock()

    id := strconv.Itoa(rand.Int())
    value := strconv.Itoa(rand.Int())
    data[id] = value
    return id, value
}

func GetValue(id string) (string, bool) {
    mu.RLock()
    defer mu.RUnlock()

    value, found := data[id]
    return value, found
}

Обратите внимание, что в этом примере мы используем Gorilla Mux для управления роутами. Это очень популярная библиотека, но вы можете использовать любую другую по своему усмотрению.


Этот код хранит сгенерированные данные в памяти и не сохраняет их после перезагрузки сервера. Если вам нужно сохранять данные между перезагрузками, вы должны использовать некоторую форму постоянного хранилища, такую как базу данных.


Итог: как минимум это решение работает:


-> % curl -X POST http://localhost:8080/api/generate/
{"id":"2080282532813236477","value":"58477870582709028"}

-> % curl -X POST http://localhost:8080/api/generate/
{"id":"2383079509972796201","value":"7856768647560731715"}

-> % curl http://localhost:8080/api/retrieve/2383079509972796201
{"id":"2383079509972796201","value":"7856768647560731715"}

-> % curl http://localhost:8080/api/retrieve/2080282532813236477  
{"id":"2080282532813236477","value":"58477870582709028"}

Также, отдельным сообщением я попросил его сгенерировать Dockerfile


Ответ робота

Сначала вам нужно будет создать файл go.mod в корне вашего проекта, если вы его ещё не создали, это можно сделать с помощью команды go mod init <module-name>. Это поможет Go определить ваш проект как модуль и управлять зависимостями.


Затем вы можете создать Dockerfile в корне вашего проекта. Он может выглядеть следующим образом:


# Start from the latest golang base image
FROM golang:latest

# Add Maintainer Info
LABEL maintainer="Your Name <your-email@domain.com>"

# Set the Current Working Directory inside the container
WORKDIR /app

# Copy go mod and sum files
COPY go.mod go.sum ./

# Download all dependencies. Dependencies will be cached if the go.mod and the go.sum files are not changed
RUN go mod download

# Copy the source from the current directory to the Working Directory inside the container
COPY . .

# Build the Go app
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .

# This container exposes port 8080 to the outside world
EXPOSE 8080

# Run the binary program produced by `go install`
CMD ["./main"]

Теперь вы можете собрать Docker-образ с помощью следующей команды:


docker build -t my-go-app .


И запустить его:


docker run -p 8080:8080 my-go-app


Обратите внимание, что вместо "Your Name <your-email@domain.com>" и my-go-app вы должны использовать свои собственные значения.


Этот Dockerfile создает образ Docker с вашим приложением на Go, устанавливает все зависимости и выполняет приложение при запуске контейнера. Сервер будет доступен на порту 8080.



RSS feed reader


Задание необходимо выполнить на C#


Графическое приложение для чтения RSS ленты с сайта.


В файле настроек хранятся:


Лента, которую обрабатывает фидер. По умолчанию это (https://habr.com/rss/interesting/).


Частота обновления ленты приложением.


Основное окно должно содержать список элементов ленты (item): Каждый элемент ленты должен отображать название и дату публикации (поля item->title и item->pubDate ).


Дата публикации статьи должна отображаться в удобном для чтения пользователем формате.


При нажатии на заголовок должен открываться браузер с переходом на выбранную статью (или в уже открытом браузере должна открываться ссылка). Пользователь должен иметь возможность посмотреть описание статьи (поле item->description).
Содержание описания выводится в виде обычного текста (как есть), без форматирования по тегам.
Данные должны периодически обновляться.
Частота обновления должна быть взята из файла конфигурации. Файл настроек имеет формат XML.


Выведи структуру решения, затем выведи содержимое каждого файла.
Пиши ответ с учетом того, что мне нужно собрать под mono в linux.


Последнее допусловие от меня, так как мне надо это все собрать, чтобы проверить.


Ответ робота

Принимая во внимание ваш запрос, ниже приведено решение на основе Windows Forms (System.Windows.Forms) и XmlReader для чтения RSS-ленты. Данный пример включает простую форму с ListBox для отображения заголовков новостей и TextBox для отображения описания выбранной новости.


Структура решения:


RssReader
├── Program.cs
├── RssFeed.cs
├── RssItem.cs
├── Settings.cs
└── MainForm.cs

Program.cs


using System;
using System.Windows.Forms;

public class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MainForm());
    }
}

RssFeed.cs


using System;
using System.Collections.Generic;
using System.Xml;

public class RssFeed
{
    public static List<RssItem> Load(string url)
    {
        List<RssItem> rssItems = new List<RssItem>();
        using (XmlReader reader = XmlReader.Create(url))
        {
            while (reader.ReadToFollowing("item"))
            {
                RssItem item = new RssItem();
                reader.ReadToFollowing("title");
                item.Title = reader.ReadElementContentAsString();
                reader.ReadToFollowing("description");
                item.Description = reader.ReadElementContentAsString();
                reader.ReadToFollowing("link");
                item.Link = reader.ReadElementContentAsString();
                reader.ReadToFollowing("pubDate");
                item.PubDate = DateTime.Parse(reader.ReadElementContentAsString());
                rssItems.Add(item);
            }
        }
        return rssItems;
    }
}

RssItem.cs


using System;

public class RssItem
{
    public string Title { get; set; }
    public string Description { get; set; }
    public string Link { get; set; }
    public DateTime PubDate { get; set; }
}

Settings.cs


using System;
using System.Xml;

public class Settings
{
    public string RssUrl { get; set; }
    public TimeSpan RefreshRate { get; set; }

    public static Settings Load(string path)
    {
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load(path);

        var settingsNode = xmlDoc.SelectSingleNode("/settings");

        string url = settingsNode["rssUrl"].InnerText;
        TimeSpan refreshRate = TimeSpan.Parse(settingsNode["refreshRate"].InnerText);

        return new Settings { RssUrl = url, RefreshRate = refreshRate };
    }
}

MainForm.cs


using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Xml;

public class MainForm : Form
{
    private Settings settings;
    private Timer timer;
    private ListBox rssListBox;
    private TextBox descriptionTextBox;
    private Button openButton;

    public MainForm()
    {
        settings = Settings.Load("settings.xml");

        rssListBox = new ListBox() { Dock = DockStyle.Top, Height = 300 };
        descriptionTextBox = new TextBox() { Multiline = true, ReadOnly = true, Dock = DockStyle.Top, Height = 150 };
        openButton = new Button() { Text = "Open in browser", Dock = DockStyle.Top };

        rssListBox.SelectedIndexChanged += RssListBox_SelectedIndexChanged;
        openButton.Click += OpenButton_Click;

        Controls.Add(openButton);
        Controls.Add(descriptionTextBox);
        Controls.Add(rssListBox);

        LoadRssItems();

        timer = new Timer();
        timer.Interval = (int)settings.RefreshRate.TotalMilliseconds;
        timer.Tick += Timer_Tick;
        timer.Start();
    }

    private void RssListBox_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (rssListBox.SelectedItem is RssItem item)
        {
            descriptionTextBox.Text = item.Description;
        }
    }

    private void OpenButton_Click(object sender, EventArgs e)
    {
        if (rssListBox.SelectedItem is RssItem item)
        {
            Process.Start(item.Link);
        }
    }

    private void Timer_Tick(object sender, EventArgs e)
    {
        LoadRssItems();
    }

    private void LoadRssItems()
    {
        var rssItems = RssFeed.Load(settings.RssUrl);

        rssListBox.Items.Clear();
        rssListBox.Items.AddRange(rssItems.ToArray());
    }
}

После того как все файлы созданы, вы можете собрать проект с помощью команды:


mcs -out:RssReader.exe *.cs -r:System.Windows.Forms.dll -r:System.Drawing.dll -r:System.Xml.Linq.dll


А затем запустить его:


mono RssReader.exe


Примечание: Пожалуйста, убедитесь, что у вас установлен Mono и что вы находитесь в правильной директории, когда выполняете эти команды.  


Собираем, запускаем


lgtm2


Получилась какая-то ерунда. Окно, в котором каждая строчка — просто слово RssItem.
Помним, что мы не умеем сами править код, пишем текстом претензию роботу.


появилось окно с 10 строчками RssItem

Ответ робота

Извините за путаницу. Очевидно, в ListBox нужно отобразить не сами объекты RssItem, а их заголовки. Для этого вам нужно изменить метод LoadRssItems() в файле MainForm.cs следующим образом:


private void LoadRssItems()
{
    var rssItems = RssFeed.Load(settings.RssUrl);

    rssListBox.Items.Clear();
    foreach (var item in rssItems)
    {
        rssListBox.Items.Add(item.Title);
    }
}

В данном случае в ListBox добавляются только заголовки новостей (свойство Title объектов RssItem). Однако, чтобы отобразить описание новости и открыть ее в браузере, вам потребуется сам объект RssItem. Поэтому рекомендуется добавить в класс RssItem переопределение метода ToString():


public class RssItem
{
    public string Title { get; set; }
    public string Description { get; set; }
    public string Link { get; set; }
    public DateTime PubDate { get; set; }

    public override string ToString()
    {
        return Title;
    }
}

В таком случае ListBox будет отображать заголовки новостей, но при выборе элемента вы сможете получить полный объект RssItem с его описанием и ссылкой.


Правим, перезапускаем


lgtm2


Итог: теперь похоже на правду. Конечно это еще не ридер, так как показывает только заголовки, но это дело получаса и пяти промптов добиться нужного функционала, без всякого знания C#. Добавить функционал и кнопочки тоже не составит большого труда. То есть выполнить задание за один промпт мы не смогли, но приблизились к этому максимально.


И что же делать?


Кажется, пора перестать давать тестовые задания на дом. Это становится явлением из вашего прошлого, и ему пора остаться в истории навсегда.


Если вы всё же хотите это делать, то вероятно стоит:


  1. Давать на дом настолько большой и комплексный проект (фронт, бэк, тесты, инфра + деплой), что для решения его через нейронку придётся всё равно проявить какие-то знания.
  2. Пытаться придумать задание с некоторой изюминкой, которую нейронка почему-то пока не может осилить.
  3. Главное правило — Взять робота и проверять на нем ваши задания, все идеи, потому что ваши предположения о том, что может и не может нейронка скорее всего неверны и без проверки вы ошибетесь.

Скорее всего всё это будет менее эффективной тратой вашего времени, чем просто провести собес со всеми интересными кандидатами.


Я смог придумать две задачи, на которые Gpt3.5 не мог дать решение. Как водится, когда он не может сделать нормальное решение, он выдумывает несуществующие конструкции. Правда уже через пару недель у нас появилась Gpt4, и оказалось, что она решает эти задачи.


Для примера приведу свою задачу, которую не удалось решить Gpt3.5



Задача


Напиши декоратор на python, который позволяет включить для декорируемой функции кэширование. Должно настраиваться количество хранимых значений. Нельзя использовать стандартные кэш декораторы из functools.
Напиши тесты на этот декоратор. Тесты должны обеспечить проверку готовности декоратора к использованию на продакшне, ничего не пропусти смотри!

Задание несложное, и Gpt3.5, конечно, сделал декоратор, но вот написать на него тесты он не смог. Не придумал, как протестировать собственно само кэширование.
Gpt4 уже не испытывает никаких сложностей с этим.


Ответ робота

Ваш декоратор для кэширования может выглядеть следующим образом:


def cache(maxsize):
    cache = {}
    def decorator(func):
        def wrapper(*args, **kwargs):
            key = (args, frozenset(kwargs.items()))
            if key in cache:
                return cache[key]
            if len(cache) >= maxsize:
                # если кэш заполнен, удаляем одно из значений
                cache.pop(next(iter(cache)))
            result = func(*args, **kwargs)
            cache[key] = result
            return result
        return wrapper
    return decorator

Здесь cache — это словарь, который используется для хранения результатов вызова функции. Ключами этого словаря являются кортежи, состоящие из аргументов и именованных аргументов, переданных в функцию. Значениями словаря являются результаты вызова функции с данными аргументами.


Когда декорированная функция вызывается, декоратор сначала проверяет, есть ли результат для переданных аргументов в кэше. Если результат найден в кэше, он возвращается и сама функция не вызывается. Если результат в кэше не найден, функция вызывается, ее результат сохраняется в кэше и затем возвращается.


Если количество элементов в кэше достигает maxsize, перед сохранением нового значения удаляется одно из старых значений.


Обратите внимание, что этот декоратор работает только для функций, аргументы которых могут быть хешированы, поскольку они используются в качестве ключей словаря.


Тесты для данного декоратора могут проверять следующие аспекты:


  1. Проверить, что результат функции кэшируется.
  2. Проверить, что, когда кэш заполняется, старые значения удаляются.
  3. Проверить, что декоратор не вносит изменений в результат функции.
  4. Проверить, что декоратор не влияет на функции без аргументов.
  5. Проверить, что декоратор обрабатывает именованные аргументы.
  6. Проверить, что декоратор не работает с функциями, которые принимают аргументы, которые не могут быть хешированы.

Здесь тесты, использующие библиотеку pytest:


import pytest

def test_cache():
    counter = 0

    @cache(2)
    def f(x):
        nonlocal counter
        counter += 1
        return x

    assert f(1) == 1  # функция вызывается, counter == 1
    assert f(1) == 1  # результат из кэша, counter не изменяется
    assert counter == 1

    assert f(2) == 2  # функция вызывается, counter == 2
    assert f(2) == 2  # результат из кэша, counter не изменяется
    assert counter == 2

    assert f(1) == 1  # результат из кэша, counter не изменяется
    assert counter == 2

    assert f(3) == 3  # функция вызывается, counter == 3
    assert counter == 3

    assert f(1) == 1  # результат уже не в кэше, функция вызывается, counter == 4
    assert counter == 4

def test_cache_empty_args():
    counter = 0

    @cache(2)
    def f():
        nonlocal counter
        counter += 1

    f()  # counter == 1
    f()  # результат из кэша, counter не изменяется
    assert counter == 1

def test_cache_named_args():
    counter = 0

    @cache(2)
    def f(x=None):
        nonlocal counter
        counter += 1
        return x

    assert f(x=1) == 1  # функция вызывается, counter == 1
    assert f(x=1) == 1  # результат из кэша, counter не изменяется
    assert counter == 1

def test_cache_non_hashable_args():
    @cache(2)
    def f(x):
        return x

    with pytest.raises(TypeError):
        f([1, 2, 3])  # списки не могут быть хешированы

Запустить тесты можно с помощью команды pytest your_test_module.py, где your_test_module.py.


Решение достаточно хорошее, по большому счёту и не прикопаешься ни к чему.


Итоги


Видимо, у вас попросту больше нет возможности удаленно отличить кандидата, хорошо пишущего код, от человека, хорошо пишущего промпты GPT — только дав ему написать что-то очень большое, что не помещается в рамки тестового задания. Поэтому предлагаю поменять практики отбора кандидатов в соответствии с ходом времени. И продолжить эксперименты с ChatGPT, чтобы вовремя выявить новые задачи, с которыми она может справиться за вас (ну или ваших соискателей).


Если вам было интересно, то приходите ко мне в команду KasperskyOS Tooling Development — будем вместе следить за нейросетями и другими технологиями, которые способны упростить жизнь разработчика. И разбираться, как можно применять их для создания крутых и удобных инструментов.



А если хотите удостовериться в (без)опасности какого-то своего задания — кидайте в комменты, проверим :)

Комментарии (155)


  1. smind
    29.06.2023 15:06
    +41

    если программист с ChatGPT не отличим от программиста без ChatGPT то тогда какая разница?


    1. Magn Автор
      29.06.2023 15:06

      Это полностью справедливо, если бы речь шла о ежедневной настоящей работе. Но не в случае небольших тестовых заданий, для решения которых при помощи gpt почти ничего не требуется знать и уметь самому кандидату.


      1. DMGarikk
        29.06.2023 15:06
        +28

        Внимание вопрос, как вы тогда верите что кандидат хороший потому что он хорошо решает тестовые задания, но не верите нейросетке хотя она делает тоже самое?

        Кандидат точно также может бред программить в реальных условиях..и фактически аналогичен ИИ в данном вопросе... Разница только в том что вы априори знаете что сеть плохая

        Но какой смысл в задачах то если они фильтруют ...кого?


        1. Magn Автор
          29.06.2023 15:06
          +1

          На мой взгляд ответ очевиден. Тестовое задание это отборочный этап, самый базовый фильтр, после выполнения которого обычно зовут на собеседование, где начинается хоть сколько-нибудь реальный отсев. И этот первичный фильтр в современных условиях лишился своего смысла, речь только об этом.


          1. eton65
            29.06.2023 15:06
            +4

            Выйдет GPT-5 и вопрос будет уже не про тестовое.


          1. xSVPx
            29.06.2023 15:06
            +4

            Так это фиговый фильтр. Понятно, что вам нужен хоть какой-то.

            Не очень понимаю, почему вас именно ИИ беспокоит. Судя по всему уже несколько лет назад было немало вариантов, когда задачи за соискателей решали другие люди, а потом те делились частью зарплаты. Помнится была история, как за кого-то жена все решала :).

            Более того, есть серьезные опасения, что решения можно нагуглить. Ну или что-то очень похожее на решение. Неужели кандидаты такие тугие пошли, что нагуглить не могут ?

            Что и зачем проверяют эти задания ?


          1. AllexIn
            29.06.2023 15:06
            +2

            Он лишился своего смысла задолго до бума нейросетей.
            Об этом даже на хабре уже десяток статей был.


            1. PuerteMuerte
              29.06.2023 15:06

              Он лишился своего смысла задолго до бума нейросетей.Об этом даже на хабре уже десяток статей был.

              Это субъективное мнение :) Кому-то нравится, кому-то нет.


        1. PuerteMuerte
          29.06.2023 15:06

          Внимание вопрос, как вы тогда верите что кандидат хороший потому что он хорошо решает тестовые задания, но не верите нейросетке хотя она делает тоже самое?

          На самом деле здесь действительно срабатывает разница между человеческим мозгом и языковой моделью. Если мозг умеет программировать простое, он в общем случае сможет и программировать сложное. А языковая модель, она ведь не умеет программировать, она просто компонует куски из датасета, на котором обучалась. Которые худо-бедно складываются в простые решения (такие, которые можно полностью уложить в запрос к модели, добавив к решению только общеизвестные гайдлайны разработки), но нифига не складываются в сложные, где надо знать обширный контекст проекта и/или анализировать существующий код.


          1. Ksoo
            29.06.2023 15:06
            +2

            Вот совсем не соглашусь с вами. Очень много видел, когда простое могут запрограммировать( пофиксить существующий метод, написать новый), но абсолютно не способны разработать приемлемый модуль.


            1. PuerteMuerte
              29.06.2023 15:06

              Там есть хитрость - простое надо давать такое, чтобы думать чуть-чуть надо, а не нагуглить как есть целиком.


              1. Ksoo
                29.06.2023 15:06

                Я не про кандидатов, а про уже нанятых сотрудников.


        1. Wesha
          29.06.2023 15:06

          как вы тогда верите что кандидат хороший потому что он хорошо решает тестовые задания, но не верите нейросетке хотя она делает тоже самое?

          Человека можно потом, ежели чо, премии лишить, ну или в крайнем случае волшебных пенделей выписать. С нейросетью такое не проканает.


        1. geher
          29.06.2023 15:06

          На самом деле домашнее тестовое задание вполне может использоваться как адекватный критерий оценки кандидата. Ведь при приемке результата этого самого задания вполне можно кандидата допросить на предмет понимания представленного кода.

          Другой вопрос, стоят ли вообще затраты на такой допрос полученного результата?

          Но какой смысл в задачах то если они фильтруют ...кого?

          Если не проводить дополнительную проверку на понимание представленного кода, то тех, кто не смог ни сам, ни при помощи друга, ни при помощи gpt.

          Интересно только, какова доля таких индивидов?

          И есть еще ряд моментов. Например, кандидат, который честно не решил, но и не стал читерить, как по мне, всяко лучше того, кто выдает чужой результат за свой. С другой стороны, он так же не подходит, как и читеры, ибо не смог, просто читеров все равно придется позже отсеять другими методами.


    1. Hardcoin
      29.06.2023 15:06
      +6

      Неотличим на тестовом. Однако на реальных задачах разница может быть огромной, в этом и минус. Тестирование - это попытка оценить качество будущей работы, а не качество ChatGPT (я уже и так знаю, что он пока не тянет, поэтому мы всё ещё нанимаем программистов)


    1. tandzan
      29.06.2023 15:06

      ChatGPT в коде регулярки использует, ну нафиг (шутка).


    1. wormball
      29.06.2023 15:06
      +19

      Программист без ChatGPT подобен программисту с ChatGPT, только без ChatGPT.


  1. anonymous
    29.06.2023 15:06

    НЛО прилетело и опубликовало эту надпись здесь


  1. vpert
    29.06.2023 15:06
    +2

    Мне кажется, что автор преувеличивает проблему нейросетей, так как в статье разобраны примеры не самых объемных и сложных задач, которые целесообразно скорее при устном собеседовании спрашивать.
    Например, команда VK Видео в этом году отбирала весной людей на летнюю стажировку, соответственно, чтобы ускорить процесс людям выдали всем одно и то же задание на реализацию какого-то сервиса.
    Задача была достаточно объемной и комплексной, что для неё нужны были изначально знания даже чтобы понять что именно искать надо. Объективно ChatGPT не поможет сделать правильные запросы к самому себе (а если и выдаст, то не факт что верно), потому я более чем уверен, что с отбором они отлично справились.
    Да и если программист пишет верный код, то какая разница с помощью чего он это делает?


    1. Magn Автор
      29.06.2023 15:06
      +1

      Ну, в итогах я как раз буквально и пишу, что один из вариантов это давать по настоящему большое и комплексное тестовое задание. Так что не вижу никаких противоречий :) Просто так почти никто не делает, и дают что-то вроде заданий из статьи.
      Если все сделают как VK Видео и начнут давать такие задания - отлично, это тоже нормальное решение. Самого задания, о котором вы говорите, я впрочем не видел, не помешает сначала проверить и его.


      1. TerraV
        29.06.2023 15:06
        +19

        Удачи вам найти желающих такое задание сделать.


        1. Magn Автор
          29.06.2023 15:06
          +1

          Моё личное мнение, что вообще от любых заданий нужно отказаться (название статьи как бы намекает). Но вариант с большими комплексными заданиями всё равно имеет место быть, если какая-то компания может себе позволить выставлять такие требования, их право. Никто же никого не заставляет, не хочет кандидат - пусть не делает.


        1. AllexIn
          29.06.2023 15:06
          +4

          За деньги - почему бы и нет.


    1. hellboy1981
      29.06.2023 15:06

      Ну наконец-то, верная мысль.

      Причем программисту, использовавшему ChatGPT при прохождении тестового задания нужно вообще то доплачивать в 10кратном размере за скилы промт инженера. Так как он на реальных задачах сможет работать в 10 раз быстрее.


  1. Zhuck
    29.06.2023 15:06
    +4

    Эти задания точно домой даются? Думал такое и на листочке написать можно. В любом случае, если есть хоть малейшее понимание алгоритмов погуглить решения можно за 5 минут(не все даже, кусками что-то с чем-то склеить). Тогда проще на собесе блок-схему спрашивать, если может - то нагуглит и соберёт и так.


    1. Magn Автор
      29.06.2023 15:06

      В основном это были тестовые задания для кандидатов в стажёры, лежащие в открытом доступе, да.


      1. Zhuck
        29.06.2023 15:06
        +1

        Так в итоге, или кандидат с SoF натягает кусков, или с ChatGPT, или пишет алгоритм если понимает


        1. Ivan22
          29.06.2023 15:06
          +1

          но 90% не делают и этого


      1. saboteur_kiev
        29.06.2023 15:06

        Задания для стажеров может проверять даже HR

        о чем разговор...


  1. evgenyk
    29.06.2023 15:06
    +2

    Мне кажется, или для первой питоновской задачи сразу все неправильно. В условии массивы чисел, разделенных пробелом, т.е. как я понимаю строки, а в коде, просто массивы питона.


    1. Magn Автор
      29.06.2023 15:06

      Да, вы правы, в решении нету ввода исходных данных в требуемом формате. Не заметил)


      1. evgenyk
        29.06.2023 15:06

        Думаю, исходя из входного формата, это задача не на перебор массивов, а на поиск подстроки в строке. Т.е. с небольшой подковыркой.


  1. panzerfaust
    29.06.2023 15:06
    +8

    Подобные задания и раньше были некомильфо. Их вариации так или иначе лежат на литкодах и хакерранках.


  1. i360u
    29.06.2023 15:06
    +10

    Всегда считал, что тестовое задание стоит давать если есть какие-то сомнения в кандидате, уже ПОСЛЕ интервью. И тестовое обязательно должно разбираться совместно после выполнения. По комментариям кандидата сразу будет понятно, где он сам думал, а где - "списал". И "изюминка" в задании тоже должна быть обязательно, иначе это просто тупая трата времени. Так что ничего ИИ-помощники особо не меняют. Во всяком случае, кейс с ИИ ничем не отличается от "помощи друга". А вот идея решить проблему за счет повышения общей сложности и объема задания - очень и очень плохая.


  1. savostin
    29.06.2023 15:06
    +15

    А чем отличается "Скопировал со Stack Overflow" от "Написал ChatGPT"?


    1. alexwm
      29.06.2023 15:06

      В первом случае кандидат точно умеет гуглить, во втором - не факт :)


      1. Kanut
        29.06.2023 15:06

        А чем "умение пользоваться ChatGPT" хуже чем "умение гуглить"? Особенно если результат в итоге один и тот же?


      1. savostin
        29.06.2023 15:06

        Как по мне уговорить чат что-то вразумительное ответить много сложнее запроса в гугл.


        1. Kanut
          29.06.2023 15:06

          По мне тоже. Но при этом все наши студенты-практиканты уже предпочитают его. И вполне себе получают результаты.

          И глядя на них появляется у меня подозрение что проблема не в ChatGPT...


  1. onyxmaster
    29.06.2023 15:06
    +1

    Наше тестовое задание ChatGPT 4 не делает =)


    1. holodoz
      29.06.2023 15:06
      +1

      Можете скинуть? Интересно попробовать подобрать промт, любыми результатами поделюсь


  1. anzay911
    29.06.2023 15:06
    +1

    — Вы что это? И конфеты за меня есть будете?
    — Ага!


  1. helg1978
    29.06.2023 15:06
    +6

    Мы даем тестовые задания (и не только разработчикам), что б было о чем "зацепиться" и подискутировать на созвоне-собесе. "Оператор ChatGPT" на собесе не сможет порассуждать почему он применил этот метод а не тот, и ваще а какой тут патерн? А почему такой?

    Короче, даже если код чужой, его с "автором" все равно обсуждать проще, чем сферического коня.


    1. TerraV
      29.06.2023 15:06
      +2

      Вы можете принести свой код и спокойно пообсуждать его. Какая разница за что "цепляться". По своему опыту такие собеседования очень комфортные как для соискателя так и для собеседующего и дают не меньше информации. Традиционно это выглядит так: "наш джун написал вот такой код, что вы думаете на этот счет".


      1. acsent1
        29.06.2023 15:06
        +1

        Мало какой код можно легко обсуждать не зная контекста самой задачи


    1. smind
      29.06.2023 15:06

      почему вы так решили?


  1. Iskin
    29.06.2023 15:06
    +2

    Уже давно говорят, что такие простые алгоритмические задачи ничего не показывают. Так что не удивительно, что теперь оказалось, что ChatGPT убило их окончательно.

    Вместо того, собрав пытаться тащить эти задачи дальше, просто смените подход к тестовым.

    Проверяйте задачи, которые гораздо ближе к реальным рабочим задачам. Они ь тестировать людей будет лучше и ChatGPT их не пойдёт.


    1. TerraV
      29.06.2023 15:06
      +3

      Я программирую уже лет 15, примерно с марта оплатил подписку на ChatGPT 4.0. Это просто охрененный инструмент который до сих пор многие недооценивают. Я использую его каждый день на работе и до сих пор нахожу ему все новые и новые применения. Вот лишь небольшой список того, что он умеет делать на уровне "production ready"

      • генерация тестов

      • генерация кода согласно вводных

      • анализ и пояснение написанного кода

      • анализ фрагментов архитектуры

      • обсуждение вариантов реализации с аргументацией за и против

      • составление UML диаграмм

      Единственный момент который нужно держать в голове, что он не сделает за вас всю работу. Он в душе не знает про ваши критерии качества. Но если вы можете пояснить почему сгенерированный код вас не устраивает и как вы хотите - он перепишет за считанные секунды. Если вы научитесь использовать этот инструмент, чат подымает вас на следующую ступеньку. По качеству взаимодействия ChatGPT уже превосходит среднестатического мидла.

      ВАЖНО! Чат 3.5 это полнейший шлак, с ним невозможно работать.

      Пример

      Запрос

      можешь пояснить что делает функция

      export function enrichObject(object: any, propertyName: string, formula: string, defaultValue?: string) {
          if (formula.trim() === "")
              return
      
          let evaluation = formula
          let match = evaluation.match("([a-zA-Z][\\w]*)");
      
          while (match) {
              const value = object[match[1]]
              if (value == null) {
                  object[propertyName] = undefined
                  return
              }
      
              evaluation = evaluation.replace(new RegExp("([a-zA-Z]\\w*)"), value)
              console.debug(`${value} - ${evaluation}`)
      
              match = evaluation.match("([a-zA-Z][\\w]*)");
          }
      
          try {
              // eslint-disable-next-line no-new-func
              const result: number = Function("\"use strict\";return (" + evaluation + ")")();
              object[propertyName] = Number.isFinite(result) ? result : Number(defaultValue);
          } catch (e) {
              console.warn(`Формула для свойства ${propertyName} задана неверно. Пожалуйста проверьте выражение: ${formula}`)
          }
      }

      Ответ

      Эта функция, `enrichObject`, принимает на вход четыре параметра:

      1. `object`: объект для обогащения,

      2. `propertyName`: свойство объекта, которое будет обновлено,

      3. `formula`: строка, которую мы хотим вычислить и установить в качестве значения свойства объекта,

      4. `defaultValue`: необязательное значение по умолчанию, которое будет использоваться, если формула выдаст бесконечное значение.

      Функция работает следующим образом:

      - Она проверяет, если `formula` является пустой строкой, и если это так, то функция ничего не делает и просто возвращает управление.

      - Затем она начинает процесс подстановки значений переменных, найденных в `formula`, используя значения этих переменных из `object`.

      - В процессе подстановки, если функция обнаруживает, что какое-то значение равно `null`, то она устанавливает свойство объекта, определенное `propertyName`, в `undefined` и возвращает управление.

      - После того как все подстановки выполнены, функция пытается вычислить получившееся выражение. Если вычисление происходит успешно, она устанавливает свойство объекта `propertyName` в вычисленное значение. Если результат вычисления является бесконечностью, то она устанавливает `propertyName` в `defaultValue`. Если при вычислении происходит ошибка, она выводит предупреждение в консоль.

      Таким образом, эта функция используется для динамического вычисления выражения, указанного в `formula`, и обновления свойства `propertyName` объекта на основе этого вычисления. Все переменные в `formula` должны существовать в `object`.

      Запрос

      я хочу изменить эту функцию таким образом, чтобы источник свойств и объект для обогащения были двумя разными параметрами

      Ответ

      Для изменения функции enrichObject таким образом, чтобы источник свойств и объект для обогащения были двумя разными параметрами, вы можете просто добавить еще один параметр функции. Давайте назовем его sourceObject.

      Функция тогда будет выглядеть так:

      export function enrichObject(object: any, sourceObject: any, propertyName: string, formula: string, defaultValue?: string) {
          if (formula.trim() === "")
              return
      
          let evaluation = formula
          let match = evaluation.match("([a-zA-Z][\\w]*)");
      
          while (match) {
              const value = sourceObject[match[1]]
              if (value == null) {
                  object[propertyName] = undefined
                  return
              }
      
              evaluation = evaluation.replace(new RegExp("([a-zA-Z]\\w*)"), value)
              console.debug(`${value} - ${evaluation}`)
      
              match = evaluation.match("([a-zA-Z][\\w]*)");
          }
      
          try {
              // eslint-disable-next-line no-new-func
              const result: number = Function("\"use strict\";return (" + evaluation + ")")();
              object[propertyName] = Number.isFinite(result) ? result : Number(defaultValue);
          } catch (e) {
              console.warn(`Формула для свойства ${propertyName} задана неверно. Пожалуйста проверьте выражение: ${formula}`)
          }
      }
      

      Теперь функция enrichObject принимает два разных объекта: object (объект для обогащения) и sourceObject (источник свойств). Значения переменных для подстановки берутся из sourceObject, а обновленное свойство записывается в object.


      1. storoj
        29.06.2023 15:06
        +3

        И в чём польза этого текстового описания для кода? Его всё равно надо осмыслить и загрузить себе в мозг, чтобы потом произвести нужное изменение. Так может проще прочитать код?


        1. cupraer
          29.06.2023 15:06
          +7

          Когда создавался COBOL, было принято решение делать код максимально приближенным к обычному английскому, чтобы каждый бухгалтер мог собственноручно немного починить баг. Получилось примерно вот так:

          PROCEDURE DIVISION.
            COMPUTE NUMC = (NUM1 * NUM2).
            DIVIDE NUMA BY NUMB GIVING RES-DIV.
            MULTIPLY NUMA BY NUMB GIVING RES-MULT.
            SUBTRACT NUMA FROM NUMB GIVING RES-SUB.
            ADD NUMA TO NUMB GIVING RES-ADD.
            MOVE NUMA TO RES-MOV.
            ...
            STOP RUN.

          Потом на эти грабли наступили создатели SQL. Затем — .

          Теперь вот предлагают читать эссе по мотивам процедурной интерпретации кода (с кучей перекрестных ссылок на имена переменных) — вместо самого кода.

          Ничему людей жизнь не учит.


          1. Ivan22
            29.06.2023 15:06

            ну когда я первый раз открыл код на Perl..... я сразу закрыл его. А SQL ничего... выучил с удовольствием, имхо из-за понятных слов


            1. cupraer
              29.06.2023 15:06

              Вы путаете высоту порога входа и удобство повседневного использования. Так-то я свой первый коммит на коболе — через час после того, как впервые увидел синтаксис — отправил (м-м-м-м, коммит в SourceSafe).

              Если бы SQL был хорошим продуманным решением, в каждом первом фреймворке не городили бы OOM.

              Но все равно, бухгалтеры ни на коболе, ни на сиквеле, ни на одинэсе, — магическим образом программировать не начали. Кривая обучения более пологая (особенно в сравнении с перлом, да), но это не плато.


              1. Ivan22
                29.06.2023 15:06

                если бы SQL не был хорошо продуманным он бы вообще не дожил до сегодняшнего дня.


                1. cupraer
                  29.06.2023 15:06
                  +2

                  Это шутка, да? Я (хвала абстракциям) с ним дела не имею, но иногда имею дело с библиотеками общего назначения (их созданием). И они иногда должны работать с сиквелом. И вот в последний раз мне пришлось одним запросом агрегировать значение по простейшему полю: джейсон валюта и сумма. Если это называется «хорошо продуманный», то я — император Китая:

                  CASE COUNT(DISTINCT(?->>'currency'))
                  WHEN 0 THEN JSON_BUILD_OBJECT('currency', NULL, 'amount', 0)
                  WHEN 1 THEN JSON_BUILD_OBJECT('currency', MAX(?->>'currency'), 'amount', SUM((?->>'amount')::int))
                  ELSE NULL
                  END

                  И это еще постгрес! У MySQL все в сто раз печальней:

                  IF(COUNT(DISTINCT(JSON_EXTRACT(?, "$.currency"))) < 2,
                    JSON_OBJECT(
                      "currency", JSON_EXTRACT(JSON_ARRAYAGG(JSON_EXTRACT(?, "$.currency")), "$[0]"),
                      "amount", SUM(CAST(JSON_EXTRACT(?, "$.amount") AS UNSIGNED))
                    ),
                    NULL
                  )

                  Простите, конечно, но любой шаг за пределы селекта — демонстрирует абсолютную несостоятельность сиквела как внятного языка. Даже перл проще читать.

                  А дожил он до наших дней по чисто историческим причинам, звать которые искусственная монополия, созданная Лоуренсом Эллисоном.


                  1. geher
                    29.06.2023 15:06
                    +4

                    Строго говоря, json - не сфера компетенции языка SQL. Это уже надстройки, которые наворотили для поддержки популярного формата представления данных. И вот эти надстройки, таки да, весьма костыльные, мягко так говоря.

                    А сам SQL предельно прост и понятен. И ничего лучшего для чисто реляционных баз данных я пока не видел. Единственное, что несколько печалит, это излишнее разнообразие диалектов, отличающихся вроде как в мелочах, но все же достаточно различных, чтобы неприятно путаться при переходе.


                    1. cupraer
                      29.06.2023 15:06

                      С этим тезисом я как раз абсолютно согласен, просто задача о чисто реляционных базах — она немного устарела. И задачу о чисто реляционных базах (сиквел-круд, если хотите, SIUD + GO :) — довольно просто решить на любом языке.

                      И наличие такого количества диалектов — тоже как бы намекает. Хотя, у лиспа их тоже — вагон, но к лиспу [у меня] претензий нет.


                      1. geher
                        29.06.2023 15:06
                        +2

                        задача о чисто реляционных базах — она немного устарела

                        Не так уж и устарела, учитывая, что до сих пор в основном используют именно реляционные БД.

                        Проблемы начинаются от желания хранить в этих БД JSON и взаимодействовать с хранимыми в этих JSON данными.

                        Как по мне - желание странное. Логичнее разнести эти данные по таблицам и делать запросы к ним без извращений, формируя или разбирая JSON по необходимости на входе-выходе. А если уж приспичило хранить и использовать в запросах именно JSON, то и БД следует использовать соответствующую. Там и язык должен быть не SQL, а что-то уже JSON ориентированное.

                        И задачу о чисто реляционных базах (сиквел-круд, если хотите, SIUD + GO :) — довольно просто решить на любом языке.

                        Фокус как раз в том, что SQL - это по большей части не решение какой-то задачи. Это стандартная формализованная постановка задачи для СУБД, чтобы та уже решила задачу своими методами. А решать задачу хранения, поиска и обновления данных в большом хранилище - это отдельная большая задача. И удобно, когда язык постановки этой задачи хоть немного стандартизован и однообразен для любого клиента, пусть то командная строка, формочка для формирования запроса или кнопка "сделать хорошо".

                        Можно, конечно, попробовать написать (и даже попытаться внедрить в массы) какую-нибудь альтернативу языку SQL, но то, что такой альтернативы до сих пор почему-то не видно даже в нишевых продуктах, говорит о том, что большинство текущее решение (SQL) вполне устраивает.

                        И наличие такого количества диалектов — тоже как бы намекает.

                        Ну диалекты у нас размножаются везде, где существует более одного центра разработки продукта. Как говорится, стандарт выполняем (впрочем, не всегда полностью), но есть его разнообразные расширения и дополнения.


                      1. mvv-rus
                        29.06.2023 15:06

                        о чисто реляционных базах (сиквел-круд, если хотите, SIUD + GO :) — довольно просто решить на любом языке.

                        Нет. Говорю так потому что я на практиве решал подобные задачи на Clipper/Paradox/Codebase(это — древняя библиотека на C для работы с dbf) — в общем это называлось навигационным доступом к БД — в первой половине 90-х, когда SQL на PC ещё не завезли. И это было куда сложнее, чем писать запросы на SQL, что я делал несколько поздее. Так что для меня SQL тогда стал поистине глотком свежего воздуха.


                  1. PuerteMuerte
                    29.06.2023 15:06
                    +4

                    А точно это вопрос к SQL, а не к тому, что вы решаете задачу не тем инструментом? SQL - язык структурированных запросов к СУБД, JSON - формат сериализации объектов, созданный изначально для JavaScript, но оказавшийся популярным универсальным форматом, ибо он простой, компактный и читабельный в отличии от ранее использовавшегося XML. Который к SQL отношения вообще не имел, но т.к. популярен, разработчики многих СУБД кое-как налепили несовместимых между собой, нестандартных расширений для парсинга JSON прямо в запросах.

                    Но работать с документами в формате JSON средствами реляционной СУБД, хоть и можно, но совсем не нужно. Это не более чем костыли, если уж совсем никак иначе, и надо прикрутить к существующему решению хоть как-то. В реальности, если у вас данные такие, то ваш пациент - NoSQL.


                    1. cupraer
                      29.06.2023 15:06

                      Какие «такие» данные?

                      У меня обычная реляционная база, но в одной из табличек мне надо хранить деньги. Бывает. Раскидать их по двум полям — очень плохое решение, тут поля слишком узки́, чтобы подробно объяснять, почему именно. Хорошо, в постгресе есть composite field, и для продвинутых пользователей я рекомендую его. Но есть те, кто по своим причинам хочет джейсон (и бедолаги, которые вообще на MySQL).

                      Но это все лирика. Физика в том, что я могу добиться необходимого (там остряк рядом что-то про азбуку Морзе говорил, но эта «шутка» не в кассу: мне разрешено решить свою задачу средствами сиквела). Но результат получается таким, что вытекают глаза. Если это не свидетельство беспомощности языка — я не знаю, что тогда.

                      Это как если бы на джаве для решения нетривиальной, но выполнимой, задачи — пришлось бы писать 10 строк используя синтаксис перла.


                      1. dephonica
                        29.06.2023 15:06

                        У вас архитектурная ошибка - использование инструмента в условиях, для которых он не предназначен. Чисто технически на синтаксисе SQL можно и драйвер уровня ядра написать. Но это будет или неправильное решение от человека принимающего решения или вынужденная необходимость, которую не обойти никак - тогда какие претензии к инструменту?


                      1. Kanut
                        29.06.2023 15:06

                        Какие «такие» данные?

                        Конкретно тот самый json.

                        Но результат получается таким, что вытекают глаза. Если это не свидетельство беспомощности языка — я не знаю, что тогда.

                        Вот смотрите. Я беру скажем пдфку, конвертирую её в байт-строку и пихаю в json. А потом хочу по этому самому json'у делать поиск текста из содержания той самой пдфки. В принципе это можно сделать, но результат получается таким, что вытекают глаза.

                        Но разве это является "свидетельством беспомощности" json?

                        И точно так же и у вас. По хорошему если вы хотите работать именно с информацией, которая хранится в вашем json'e, то грубо говоря json надо парсить, а информацию писать в таблицы в "сыром" виде.


                      1. PuerteMuerte
                        29.06.2023 15:06
                        +2

                        , но в одной из табличек мне надо хранить деньги. Бывает. Раскидать их по двум полям — очень плохое решение

                        Я не представляю причину, которая может заставить хранить деньги в формате JSON, а не в виде decimal-поля, плюс опционально поля с кодом валюты. Потому что деньги, это штука, по которой обычно производится аналитика, суммирование, выборки и т.д. И если у вас JSON, то очевидно, что это архитектурная ошибка, т.к. вы в простейшую арифметику добавляете тяжёлые операции по извлечению и преобразованию строковых данных. Поэтому нет, здесь я вижу, что вы просто используете инструмент не по назначению.


                  1. dephonica
                    29.06.2023 15:06
                    +3

                    Согласен, с азбукой морзе SQL тоже ужасно работает.


                  1. mvv-rus
                    29.06.2023 15:06

                    А дожил он до наших дней по чисто историческим причинам, звать которые искусственная монополия, созданная Лоуренсом Эллисоном.

                    А вас, когда вы такое пишете, не смущает, что реляционная модель, основанная на ней реляционная СУБД и язык запросов к ней — SQL были разработаны в IBM? И что реляционная СУБД от IBM — DB2 — появилась аж в 1982 году и никуда с тех пор не делась, а всегда занимала свою нишу (нишу — потому что у IBM с маркетингом всегда было традиционно плохо)? То есть, что никакой монополии не было изначально?
                    PS Даже сразу не сообразил, что кто такой Лоуренс Эллисон: он куда более известен как Ларри Эллисон.


                  1. Kwisatz
                    29.06.2023 15:06
                    +2

                    Вы сами так построили запрос что он стал тяжело читаем

                    with agg as (select sum ->> 'currency'                      as currency,
                                        sum((sum ->> 'amount')::numeric(17, 2)) as amount
                                 from test
                                 group by sum ->> 'currency'),
                         json as (select json_agg(json_build_object('currency', currency,
                                                                    'amount', amount))
                                  from agg)
                    select *
                    from json;

                    Если разнести построение объекта и все остальное то становится куда проще. Кроме вы сами выбрали json, могли же выбрать составной объект или два поля.

                    Важно понимать: серьезные субд это не тупая хранилка для json. У вас в запросе неверное предположение что деньги - всегда инт, хотя на самом деле decimal (я поставил с двумя знаками, хотя это не так в общем случае). Кроме завернув данные в json лишили себя возможности простого и элегантного контроля данных на уровне базы (очевидно что currency_code и amount not null и сверху check >0)

                    upd ну и в копилку про сложность данных, типов стало больше да, координаты и прочая гемоетрия, диапазоны и прочая многомерщина, хитрые exclude constraint и прочая радость. Json на уровне бд это не усложнение типов данных а наоборот, низведение всей прелести до текста.


                    1. PuerteMuerte
                      29.06.2023 15:06

                      У вас в запросе неверное предположение что деньги - всегда инт

                      Маленькая ремарка: деньги могут быть и инт, это нормально. В финансах вообще часто встречается. Просто учёт ведут целочисленно, в центах/копейках.


                    1. cupraer
                      29.06.2023 15:06
                      +1

                      Ух ты, сколько тут вокруг непрошеных советов, неуместных рекомендаций и нерелевантных «вы все делаете неправильно». Отвечу тут, чтобы пять раз не вставать.

                      1. Я пишу библиотеку общего назначения (ORM, если хотите), а не решаю прикладную задачу.

                      2. Взять готовенькое, к сожалению, не вариант, потому что я и есть тот самый Пальяччо.

                      3. Не сказать, что ваш сиквел как-то особенно более лучше читается, в сравнении с моим, но это и не важно: они не изоморфны (потеряна full composability), и поэтому ваш не пойдет.

                      4. Джейсон выбирал не я (см. п. 1), где-то по соседству я оговорился: для тех, кто волен выбирать в базе — я от входа рекомендую composed field, с ним таких проблем, очевидно, нет.

                      5. Деньги — это всегда инт, любой школьник, поработавший с деньгами хотя бы годик вам это скажет.

                      6. Контроль на уровне базы — штука хорошая, но в случае двух полей мы получаем зыбкое улучшение за счет простых проверок, но теряем консистентность данных и буквально приглашаем прикладных программистов, которые этим кодом будут пользоваться, понаделать невынужденных ошибок из-за неверного апдейта.

                      7. Да, джейсон — это неизящный хак, но я не могу обойти всех пользователей библиотеки и сообщить им: вот тут на хабре посоветовали, поэтому вы выбросите свои старые базы, установите постгрес, а там сделайте composed field, по феншую.

                      Но это все даже не так и важно. Если посмотреть, с чего началась ветка, можно увидеть: я всего-то высказал нехитрый тезис, что закос синтаксиса языка под читаемый английский — очень плохо расширяется и в общем случае не работает.

                      К этому не имеют никакого отношения советы взять другой код, другой тип данных, другой движок, другую вселенную. Мне надо решить задачу, а не код на собеседовании показать. В реальной жизни код бывает не очень красивый. И то, насколько он красивый, зависит от продуманности языка. Вот и все.

                      При этом, я люблю сиквел как язык, и считаю, что для своего времени — это было очень круто. Что не мешает мне трезво оценивать его готовность к изменениям (ее отсутствие), расширяемость (еще хуже) и масштабируемость.


                1. mvv-rus
                  29.06.2023 15:06

                  Если бы SQL был хорошим продуманным решением, в каждом первом фреймворке не городили бы OOM.


                  SQL хорошо продуман, но совершенно непривычен для большинства разработчиков. Потому что это — декларативный язык: пользователь(так задумывалось, но в реальности все же потребовался программист) выражает на нем свое «хочу», а СУБД это «хочу» реализует. Но разработчики не привыкли к декларативному программированию — они привыкли к императивному (ну, ещё иногда функциональному) программированию на базе той или иной объектной модели — классического ООП ли, аггрегирования ли. И ОРМ (полагаю, что вы именно его имели в виду) как раз предназначен для того, чтобы не затруднять (читай, не поднимать им зарплату) таких разработчиков изучать ещё и SQL.
                  А ещё SQL был изначально ограничен реляционной моделью данных. А всякие раширения для работы с объектными данными (XML, JSON) для него не органичны.


              1. PuerteMuerte
                29.06.2023 15:06

                Если бы SQL был хорошим продуманным решением, в каждом первом фреймворке не городили бы OOM.

                SQL - хорошее продуманное решение, но он создавался как непосредственный инструмент для работы с данными, когда клиент СУБД и пользователь - одно и то же лицо. Когда клиентами СУБД стали разного рода софтины на разных языках/фреймворках, появилась новая задача, по автоматизации преобразования между тем, что кушает и выдаёт СУБД, и тем, что кушает и выдаёт фреймворк, чтобы избавить программиста от совершенно рутинной и унылой работы по составлению SQL-запросов и парсингу ответов.


                1. cupraer
                  29.06.2023 15:06

                  SQL - хорошее продуманное решение

                  […]

                  от совершенно рутинной и унылой работы по составлению SQL-запросов

                  Вижу некоторое противоречие. Кроме того, SQL хорошо работает в ситуации, когда нужно выбрать данные из марксимум пары таблиц, сгруппировать их там, отсортировать, агрегировать.

                  Но его продуманность показала себя во всей красе, когда варианты типов данных усложнились, и писать запросы на нем стало фактически невозможно без поллитра (см. мой комментарий выше).

                  Так-то и бейсик прекрасно решал свои задачи.


                  1. Kanut
                    29.06.2023 15:06
                    +5

                    SQL отлично работает и когда надо работать с кучей таблиц. Как минимум он работает не хуже (а скорее даже заметно лучше) чем альтернативы.

                    А вот хранить в SQL json'ы и пытаться с ними ещё как-то взаимодействовать при помощи "штатного" функционала самого SQL это уже просто из разряда "месье понимает толк в извращениях".


                  1. Ivan22
                    29.06.2023 15:06

                    наоборот - чем больше таблиц в запросе - тем хуже работают OOM.


        1. storoj
          29.06.2023 15:06
          +1

          Более того, тот "голос", который говорит в моей голове при чтении и осмыслении кода, использует другие "слова", другой порядок, совершенно другой подход. Для меня чтение вот таких объяснений это как слушать лекцию человека с неприятным тебе голосом, или с некомфортным темпом рассказа, или с фокусом совершенно не на то, что тебе интересно.


          1. Wesha
            29.06.2023 15:06
            +1

            А у меня вообще никакой голос не говорит — у меня образы появляются.


          1. SergeyMax
            29.06.2023 15:06

            это как слушать лекцию человека с неприятным тебе голосом

            Голос в голове вас ругает?


      1. storoj
        29.06.2023 15:06

        Как по мне, так функция показывает признаки некоторых более глобальных изъянов, и вот один из них:

        "enrich", похоже, сильно зависит от порядка вызова.

        let object = { a: 1, b: 2, c: 3 }
        enrich(object, "a", "c+5")
        enrich(object, "c", "b+b")
        enrich(object, "b", "8")

        ответ наверное должен бы быть { a: 21, b: 8, c: 16 }

        let object = { a: 1, b: 2 }
        enrich(object, "a", "c+5")
        enrich(object, "c", "b+b")
        enrich(object, "b", "8")

        а этот пример "сломается" на переменной "a", т.к. "c" ещё не определена, хотя будет определена "попозже".


        1. storoj
          29.06.2023 15:06
          +3

          Имхо функция сначала была просто плохой и непонятной, а после этого "патча", она стала совсем плохой и ещё менее понятной для программиста. И проблема не в квалификации читающего. Я изо всех сил пытался удержаться от комментария по поводу "15 лет программирования", но не смог. Мне кажется, за 15 лет такие функции должны начать вызывать неприятные чувства.


          1. storoj
            29.06.2023 15:06

            Суть, которую я хотел донести, состоит в том, что Великолепный Инструмент не обратил внимание на подозрительные части, а безропотно помог лишь ещё сильнее ухудшить и без того стремноватую функцию.


            1. Zerik
              29.06.2023 15:06

              А штука в том, что чатгпт не улучшает квалификацию программиста, а лишь безропотно(и не всегда корректно) выполняет поставленную задачу.

              Помочь чатгптили тот же копайлот и вправду могут(я, например, для генерации регулярно бингчат(тот же гпт4) пользую, очень уж туго у меня с ними). Но они не сделает из джуна мидла а из мидла сеньёра. Он в текущем виде просто позволяет немного быстрее делать то что ты и так можешь. При этом важно помнить, что не стоит просить гпт сделать что то, чего ты сам не сможешь понять и проверить. Ведь написало оно, а отвечать за этот код тебе.)


              1. Wesha
                29.06.2023 15:06
                +1

                (и не всегда корректно) выполняет поставленную задачу.

                ...при этом для того, чтобы понять, что задача решена некорректно, надо быть программистом более высокого уровня!


                1. Zerik
                  29.06.2023 15:06

                  Всё так.)

                  Это не серебрянная пуля. Это просто ещё один инструмент. Инструменты сами по себе не делают нас лучше.)


          1. TerraV
            29.06.2023 15:06
            -1

            За 15 лет привыкаешь что мир программирования это не розовые пони, и часто тратить две недели на рефакторинг куска говна чтоб реализовать хотелку бизнеса слишком долго/дорого. И с чего бы это код вызывал какие-то чувства. Это просто работа.


      1. storoj
        29.06.2023 15:06

        float wtf( float number )
        {
         long i;
         float x2, y;
         const float threehalfs = 1.5F;
        
         x2 = number * 0.5F;
         y  = number;
         i  = * ( long * ) &y;
         i  = 0x5f3759df - ( i >> 1 );
         y  = * ( float * ) &i;
         y  = y * ( threehalfs - ( x2 * y * y ) );
         return y;
        }

        А что делает эта функция? Ну чёт умножает, чёт сдвигает, чёт отнимает. Но это не ответ.


        1. mvv-rus
          29.06.2023 15:06

          Ну, ответ гуглится сразу же, если гуглить правильно: по используемому магическому числу 0x5f3759df — уж больно оно специфическое.


          1. Wesha
            29.06.2023 15:06

            Вот только придумал, что нужно использовать именно это число, таки человек. GPT за человеком всего-навсего повторил.

            А вот придумать он пока что не могёт.

            Вернее, могёт, но глаза б ничьи не глядели.


            1. IbhSvenssen
              29.06.2023 15:06
              +1

              Достаточно интересно. Оно "мучным конденсатором" назвало ионистор(конденсатор с двойным электрическим слоем). Сейчас там конечно более сложная химия, но начиналось всё как раз с угля(активированного) и папируса(бумага как сепаратор была). Похоже оно не всегда может подобрать правильные слова но суть пытается передать. Если это не случайность, то зачёт.


              1. Wesha
                29.06.2023 15:06

                На самом деле я пытался найти другой скриншот, но не нашёл.

                Ну хорошо, вот Вам другой пример


  1. n7nexus
    29.06.2023 15:06
    +4

    Тестовые задания вообще только джунам имеет смысл давать и то с последующим разборок вместе, потому что они будут их решать, чтобы хоть куда-то пробиться.

    Мидлы и Синьоры скорее выберут миллион других компаний, где и так берут (если, конечно, нет цели попасть в конкретную компанию).

    В целом и лайвкодинг в каких-то онлайн редакторах тоже очень спорный, потому что помнить все методы и их перегрузки (например в джавовой стрим апи) сложно, пушо в голове отложен ограниченный их набор, который используется на постоянке и его может быть недостаточно для решения какой-то задачи (тут именно про решение алгоритмических задач с обязательным использованием каких-то наворотов).


    1. cupraer
      29.06.2023 15:06
      +1

      Мидлы и Синьоры скорее выберут миллион других компаний, где и так берут […]

      Это палка о двух концах. Среди миллионов мидлов и синьёров можно запросто выбрать тех трех, кто не пожалеет пару часов на тестовое дома в креслице вместо стрессового собеседования, а все остальные пусть работают там, где и так берут.

      Кроме того, жизнь показывает, что среди тех, кто мнит себя синьёром (с подтвержденной лычкой) — распределение по факту проверки несложного тестового такое: 10% — синьёры, 60% — мидлы, 30% — джуны.


      1. n7nexus
        29.06.2023 15:06
        +6

        Ни разу не встречал ситуацию, когда тестовое на пару часов было вместо собеса, обычно как дополнение до или после.

        А самое главное, что тестовые задания даже не пересекаются с рабочими, зачастую. Условно, в тестовом алгоритмические задачки, а на работе перекидывание джейсонов.


        1. cupraer
          29.06.2023 15:06

          ни разу не встречал ситуацию

          Вы же понимаете, что это не означает, что такой практики не существует? Я наше тестовое написал за 40 минут (кстати, если проверяющие сами не решают свои тестовые — их нужно гнать из проверяющих).

          тестовые задания даже не пересекаются с рабочими

          У нас почти не пересекается. Но это не алгоритмы, конечно. Зачем ему пересекаться? Мне от тестового нужно:

          • посмотреть, как кандидат умеет в простейшую архитектуру

          • насколько идиоматичный код получается

          • как решается задача «покрытия тестами» (вот тут прям ух, сколько можно про кандидата узнать)

          • и, самое главное, с чего начать разговор на собеседовании «о жизни» (которое, разумеется, будет, но там не будет вопросов типа «сколько параметров принимает функция foo в третьей версии этой библиотеки)

          P. S. оно настолько не пересекается, что я готов рассмотреть тестовое, выполненное вообще на другом языке (в вакансии — руби, тестовое — на хаскеле).


          1. DMGarikk
            29.06.2023 15:06

            как решается задача «покрытия тестами» (вот тут прям ух, сколько можно про кандидата узнать)

            ух блин я такое видел, как решается задача покрытия? а какие тесты? а зачем? ууу…
            взяли… в реальности тестов нет совсем, все пушат в master почем зря зачастую забивая на отдельные ветки… вот блин зачем? я причем даже пытался тесты внедрить там но..."а зачем это?" (с)


            1. evgenyk
              29.06.2023 15:06

              Это такой неформальный метод, который не озвучен, но много где работает. Перекладывание тестирования, включая автоматические тесты на клиентов. Причем это работает намного лучше, чем казалось бы должно работать.


              1. cupraer
                29.06.2023 15:06

                Этот подход очень плохо масштабируется в бизнесы, которые хоть немного отвечают перед своими клиентами. Одна транзакция не туда — и мы банкрот.


                1. evgenyk
                  29.06.2023 15:06

                  Конечно он не универсален. И я не за него. Просто такое существует.


    1. TerraV
      29.06.2023 15:06
      +1

      Ладно если пишешь на одном языке, а если их три и это только повседневные. Типа java, kotlin, typescript. И мучительно вспоминаешь уже завезли в java elvis или все еще страдаем.


      1. Writer4
        29.06.2023 15:06
        +1

        да, согласен, вот у меня c#, java, js (Vue.js), pl/sql. Еще был какое-то время python, но от него я давно отвлекся. Ну не то чтобы в голове каша из всего этого, но все нюансы помнить тяжело, да и чтобы они еще были на кончиках пальцев. Я совершенно нормально пользуюсь stack overflow часто для элементарных вещей и совершенно не парюсь по этому поводу. Экономит много времени. Тем более что есть более важные архитектурные проблемы и вопросы.

        И еще, обычно много вещей не пишутся с нуля. Есть куча кода в текущих и старых проектах. Ну зачем мне вспоминать например нюансы синтаксиса window functions в MSSQL, я скопипащу то что подходит и поправлю.


  1. cupraer
    29.06.2023 15:06
    +3

    Тестовые задания должны быть простыми, но предполагающими несколько вариантов решения. И смотреть нужно не на то, сделано ли оно (я не могу припомнить случая, чтобы мне пришлось проверять тестовое, которое не работает), а как оно выполнено.

    Разумеется, сеть решит проход по массиву, эка невидаль, его и старый добрый гуглёж решит. Но по ста строчкам кода всегда виден уровень: использованный подход, идиоматичность кода, архитектура и так далее. До соответствия этим критериям — сетям еще примерно лет сто.

    А стажерам с джунами — и прежде не нужно было давать тестовое, с ними нужно разговаривать о жизни.


    1. markmariner
      29.06.2023 15:06

      Без стёба, почему с миддлами и сеньорами недостаточно поговорить о жизни?


      1. cupraer
        29.06.2023 15:06

        Примерно потому же, почему при трудоустройстве подтверждать квалификацию разнорабочего не просят, а хирурга — просят. И даже, гады, диплом требуют.

        Я навидался людей, мнящих себя синьёрами, а на деле — не понимающих разницу между мапом и редьюсом.


        1. markmariner
          29.06.2023 15:06

          Но вы же не хирурга нанимаете! Я не вижу взаимосвязи между разнорабочим и джуном, и сеньором и хирургом.


        1. donlocura
          29.06.2023 15:06
          +2

          Не знал разницы между мапом и редьюсом. Загуглил 'мап редьюс разница', ткнул рандомную страницу, посмотрел картинку, прочитал описание - узнал.

          Это я к тому, что буквально каждый сеньор считает, что любой другой программист должен знать то, в чем он хорошо разбирается. Но уже появилось столько направлений программирования, что все их изучить времени не хватит (особенно, если ты работаешь). А еще проверяющие любят делать выводы по одной строчке кода: делая тестовое, для сравнения расстояния между объектами использовал функцию Distance для наглядности, т.к. главным критерием была названа именно наглядность. В фидбэке получил 'кандидат никогда не занимался оптимизацией кода, т к. там надо было сравнивать квадраты растояния'. И у каждого всё по-разному - один нашел для себя std::vector - и все list, map, статический массив - всё уже сразу 'говорит о непрофессионализме кандидата'. Никакие контраргументы не способны его переубедить, ведь он уже несколько лет начальник, а начальник не может быть не прав. Получив несколько отказов из-за некрасивых названий переменных, неочевидных имен функций, очередное тестовое прежде чем сдать еще неделю рефакторил. Получил отказ с формулировкой 'у тебя слишком структурированный код'.

          З.ы. сорри за многобукаф, поиск работы для меня больная тема. А по сабжу - за такие 'формально правильные решения' мне обычно отказы и приходили.


          1. cupraer
            29.06.2023 15:06

            любой другой программист должен знать то, в чем он хорошо разбирается

            Отнюдь. Если бы я ждал этого, мы бы вообще никогда никого не наняли.

            Но есть прописные истины. Варианты работы с перечислимыми данными — одна из них. На названия переменных, выбранные контейнеры, используемые функции — я вообще внимания не обращаю. Даже на алгоритмическую сложность — по месту, и ваш аргумент «главным критерием была названа именно наглядность» меня бы вполне устроил.

            Но не бывает программиста, которому никогда в работе не приходится итерировать коллекцию. Это — базовое знание, на первом курсе учат (должны учить), а если нет — приобретается в первые три месяца работы. Иначе — перед нами человек, который просто бездумно лопатит джейсоны, и мы имеем возможность такому кандидату отказать.


            1. markmariner
              29.06.2023 15:06
              -1

              У меня ни разу за 8 лет работы не появилось необходимости использовать reduce. Более того, метод не применялся никем в кодовой базе всех проектов, с которыми я работал.

              А вот не понимая, что такое алгоритмическая сложность, очень легко написать программу, которая будет работать существенно медленнее, чем могла бы и не заметить этого.

              Вопрос именно в том, что считать прописными истинами.


  1. sneg2015
    29.06.2023 15:06

    Когда нужно решить задачу, не важно каким образом она будет решена. Когда нужно создавать видимость работы и копать от забора и до заката, то будут заставлять писать код на листочке в закрытой комнате без интернета.


    1. markmariner
      29.06.2023 15:06
      +1

      Как я когда-то говорил: да пускай программист наймёт 3 индусов и 2 джунов, а сам будет сидеть на мальдивах, и после этого будет отдавать код подходящего качества, который проходит код-ревью и выполняет задачу. Какая мне разница?

      Правда, я подозреваю, что провернуть такое посложнее, чем самому программировать потому, что проверить чужой код, распределить задачи и объяснить индусу, джуну или чатджипити, что требуется -- навыки сравнимые, а то и более сложные, чем программирование.


  1. Arch213
    29.06.2023 15:06

    Недавно выполнял тестовое задание на Джуна в Европе. Сложное приложение на Джанго или фаст апи , с иерархической структурой , валидаторами , куча рекурсивных функций , тесты , все должно быть обернуто в докер и сделано за 5 дней. По фаст апи , chartgpt вообще ничего путного не давал , по Джанго еще хоть как то. Любой чел со слабыми знаниями не смог бы его выполнить хоть с Chartgpt, хоть без .


    1. Andrey_Solomatin
      29.06.2023 15:06
      +3

      Это явно на мидла который готов себя продать по цене джуна.

      Хотя если там подразумевается релокация, то минимальный ЗП должна быть на хорошем уровне.

      Как результаты и сколько времени потратили?


  1. Newbilius
    29.06.2023 15:06
    +5

    Тестовые задания полезны не в бинарном варианте оценки (сделал/не сделал), а как отправная точка для разговора на собеседовании. "Почему так сделал? Почему эдак? А можно иначе? А если чуть условия изменились бы?" И т.п. Раньше ведь тоже никто не помешал бы кандидату попросить сделать тестовое знакомого программиста, и ChatGPT глобально тут ничего не изменил.


  1. A-V-tor
    29.06.2023 15:06
    +4

    Даже интересно где Вы такие python - тестовые для соискателей нашли...
    Попробуйте попросить GPT написать что то более реальное и он выдаст вам уйму несуществующих импортов и методов. А затем будет упрекать вас в том что у вас старая версия библиотеки...


  1. Arkronus
    29.06.2023 15:06
    +2

    Даже если человек использовал нейронки, то он всё равно должен понимать код, который они выдают.

    То есть надо проверять именно понимание логики и делается это просто - даете тестовое задание, его выполняют. Дальше вы созваниваетесь на 10 минут и спрашиваете, как надо доработать код, чтобы он выполнял какой-то новый функционал. Даже не нужно просить его кодить, просто словами описать решение.

    Если человек понимает, то он сможет сразу ответить, если нет - то нет.


  1. tania_012
    29.06.2023 15:06
    -9

    Когда я полгода пытаюсь пробиться на публику с темой "Компьютер vs человек", то меня неустанно блокируют. А другим почему можно? Вот сегодня в очередной раз отправила в Песочницу свое Воззвание. И раз другим можно, да еще так много букв, то я наберусь наглости и прилеплю ниже свои буквы (не все).


    =============


    Компьютер против хомо сапиенс


    Наверное, все согласятся, что сущность хомо сапиенс состоит в том, как он обрабатывает информацию, т.е. в работе с информацией. Но компьютер тоже этим занят, только этим он и занят. Раз так, то два игрока на одном не поделенном поле с большой вероятностью будут "сталкиваться".

    компьютеры стремительно идут вверх, а люди точно стремительно вверх не идут, тогда нижняя восходящая кривая неизбежно достигнет верхней, рано или поздно. Это уже случилось в шахматах и во всех интеллектуальных играх человека вообще. Даже некоторые открытия уже сделаны умной машиной. Если добавить, что большинство людей заняты полумеханическим трудом, то проблема "компьютер vs человек" становится очевидной.

    надо ли нам ждать завтрашних потрясений, если можно спокойно обсудить все сегодня, когда все еще на своих местах?

    разве написание текста для машины кардинально отличается от написания текста для человека? Как по мне, то английскими буквами и специфичной упрощенной логикой. И я точно потеряю тех заказчиков, которые хоть немного знают английский язык и куда код вставлять надо. А фирмы расстанутся со своими лишними кодировщиками-тестировщиками и прочими "ручными вязальщиками".

    Мне кажется, что активных вариантов всего два: либо загодя искать новую профессию, либо прицепиться к растущему компьютеру.

    И да, я знаю и вы знаете, что сегодняшний ChatGPT это всего лишь малое дитя, первое слово сказало (интересно какое) — но планетарный процесс взросления уже запущен, во всех передовых странах, форсированно — т.е. критиковать ChatGPT надо бы с мыслью "а что будет через год", т.е. осторожно так критиковать.


    1. tania_012
      29.06.2023 15:06
      +3

      Приветствуем, Таня!
      Увы, ваша публикация «Компьютер против хомо сапиенс» не была одобрена НЛО и не может быть опубликована в песочнице на «Хабре».


      1. Str5Uts
        29.06.2023 15:06
        +13

        Молодец НЛО.


        1. tania_012
          29.06.2023 15:06
          -2

          )) пойдем поговорим? или прямо здесь можно?


          1. Str5Uts
            29.06.2023 15:06

            Здесь и сейчас!


            1. tania_012
              29.06.2023 15:06
              -3

              Попробуем!
              Итак, раз НЛО молодец для вас, то моя статья не молодец для вас. Вы видели той статьи столько, сколько я написала выше. Написанное состоит из абзацов (заголовок есть номер 0). Какой номер первым вам не понравился (и почему)?


              1. Str5Uts
                29.06.2023 15:06
                +11

                Лично для меня, выдержки из вашей статьи выглядят как "поток сознания". Ничего лично против вас не имею, но предпочёл бы чтобы хабр был с наклоном в технические вопросы, а не в "псевдо-филосовские рассждения" да ещё и в такой стилистики. Так что извените, но всё таки молодец.


                1. tania_012
                  29.06.2023 15:06
                  -10

                  Так, вы конкретный пацан или как? Я конкретно задала вопрос. Ожидаю конкретного ответа — номера того абзаца, который первым вам не зашел.


                  1. Str5Uts
                    29.06.2023 15:06
                    +1

                    Абзац #1

                    что сущность хомо сапиенс состоит в том, как он обрабатывает информацию, т.е. в работе с информацией.
                    При чём здесь «как»? Если же «как» надо заменить на «что», то получается тавтология со следующим выражением «т.е. в работе с информацией» и т.д. и т.п.

                    Я не буду касаться смыслового наполнения, так как сложно судить по выжимкам, но то что прочитал, мягко говоря не радует.


                    1. tania_012
                      29.06.2023 15:06

                      Позвольте тогда мне написать немного больше букв, чем на одно предложение.


                      Вот прилетели на орбиту Земли инопланетяне. Видят, что есть жизнь. Видят разных животных. Видят среди них и человеков — почему они сразу их выделят?


                      Ну потому, что только человеки так поставили себе на службу силы Природы, что отношение в этом деле к ближайшей нижней ступени (шимпанзе) поистине равно бесконечности.


                      Далее, так как инопланетяне разумные, то они понимают, что хилые и дохлые человеки научились подбирать ключики к силам Природы (а не просто так взяли и приручили окружающее), у них есть развитая нейронная сеть, с алгоритмами, которые отображают бесконечные (в информационном смысле) природные явления в конечные модели, дальнейшая работа с которыми и дает те самые ключики.


                      Ну вот, чем силен человек? Разве не обработкой информации? Я написала "как" по простой причине: информацию обрабатывает даже камень) человек как и камень получает физические сигналы из внешнего мира, но камень на эти сигналы дает свою реакцию, можно сказать чисто физическую, а вот человек… он может так неожиданно закрутить… потому что от датчиков все идет в сеть, крутится там, по неведомым нам законам… а потом на выходе E=mc2 ))


                      Т.е. сущность человека разумного это
                      1а) работа с информацией — да!
                      1б) специфическая работа с информацией — да!


                      Ну да, я переставила а) и б) — но мне надо было далее как-то спланировать к компьютеру — для этого так и переставила, от перестановки мало что поменялось.


                      И вообще, я считала, что в чем сущность человека все айтишники согласны еще с пеленок — конечно же в обработке информации! — это же аксиома! с чего бы там застревать на том. как именно я это сказала...


                      П.С.
                      Еще я считала, что читать будут люди, а не логические машины какие-то)) Люди всегда вариативные, что не мешает им видеть линию разговора.


                      1. Str5Uts
                        29.06.2023 15:06

                        как именно я это сказала...
                        Потому что иногда «как» выглядит как будто это бред больного человека… наф сэд.


                      1. tania_012
                        29.06.2023 15:06

                        )) но теперь вы поняли мои слова???


                        что все сущее так или иначе получает извне воздействия (сигналы, информацию) и так или иначе реагирует на них (т.е. обрабатывает информацию)


                        что отличие живого от неживого, сложного живого от простого живого именно в реакциях, т.е. в обработке информации, т.е. в "как именно"


                        П.С.
                        Если поняли (и согласны), то как бы вы написали то предложение?


                      1. tania_012
                        29.06.2023 15:06

                        Не могла же я расписывать все как действительно для инопланетян)


                        Я опустила, что в отличие и от камня, и от шимпанзе работа с информацией у человека настолько мощная (количественно и качественно), что лиши человека всего, кроме головного мозга, то мало что поменяется — Хокинг супернаглядный тому пример. Т.е. человек — это процессор и память, также системы ввода и вывода.


                        И я опустила, что неживая штука компьютер ровно тем же, ровно так же отличается от иных неживых штук.


                        Тогда мы просто отбрасываем несущественное "живое", "неживое" и имеем двух созданий одной информационной сущности — это я тоже не расписывала.


                        Что, все это какие-то большие откровения?)


                      1. Wesha
                        29.06.2023 15:06

                        лиши человека всего, кроме головного мозга, то мало что поменяется — Хокинг супернаглядный тому пример

                        Вы забываете, что человеку одного головного мозга мало нужно ещё и общество. Поместите Хокинга в центр Сахары — и жить ему останется несколько часов.


                      1. tania_012
                        29.06.2023 15:06

                        Приведу первый абзац в связке с далее пропущенным и вторым


                        ====


                        Наверное, все согласятся, что сущность хомо сапиенс состоит в том, как он обрабатывает информацию, т.е. в работе с информацией. Но компьютер тоже этим занят, только этим он и занят. Раз так, то два игрока на одном не поделенном поле с большой вероятностью будут "сталкиваться".


                        Но может поле поделено: люди думают о главном, а компьютер выполняет механическую работу? Всего несколько десятилетий назад так оно и было. А изменилось все по простой причине: компьютеры стремительно идут вверх, а люди точно стремительно вверх не идут, тогда нижняя восходящая кривая неизбежно достигнет верхней, рано или поздно. Это уже случилось в шахматах и во всех интеллектуальных играх человека вообще. Даже некоторые открытия уже сделаны умной машиной. Если добавить, что большинство людей заняты полумеханическим трудом, то проблема "компьютер vs человек" становится очевидной.


                        ===


                        Как я должна была написать это кратко? Что компьютер давно уже не арифмометр? А кто-то не знал этого? Кто-то думает, что в шахматах компьютер тупо перебирает ходы? Ага, как же… здесь на Хабре есть "Шахматные алгоритмы, которые думают почти так же, как человек, только лучше"
                        https://habr.com/ru/companies/skillfactory/articles/544040/


                      1. voltag
                        29.06.2023 15:06
                        +3

                        tania_012 хорошо, что Вы написали статью. Но проблема в том, что Вы не проверили большое количество утверждений, например:

                        - " Наверное, все согласятся, что сущность хомо сапиенс состоит в том, как он обрабатывает информацию, т.е. в работе с информацией. Но компьютер тоже этим занят, только этим он и занят. Раз так, то два игрока на одном не поделенном поле с большой вероятностью будут "сталкиваться". ".

                        Один абзац, 3 предложения, во всех предложениях допущения или логические ошибки. К примеру, "согласятся" не все, обработка т.н. информации не является сущность хомо сапиенс. Если Вы имели ввиду более конкретное действие, то хорошо бы написать об этом. Вероятно, у Вас не хватает опыта чтобы понять ошибку в суждении. Жители хабра, и вообще хомо сапиенс обычно любят читать сообщения без опечаток, так мне и им будет легче понять Вас.

                        "Но компьютер тоже этим занят, только этим он и занят."
                        Занятие компьютера это скорее движение электричества по проводам, как например мельница, которая молет муку, или кукушка, которая КуКукает определённое количество раз в определённое время. Солнце находиться в постоянном движение, но это не значит что оно разумно, или оно собирает информацию и т д.

                        "Раз так, то два игрока на одном не поделенном поле с большой вероятностью будут "сталкиваться"
                        Если предыдущих утверждения не верны, почти всегда следующее тоже не верно. Мы не игроки, мы не можем быть сравнены как игроки. Вы, как человек, можете сравнить сахарную вату, лист бумаги, автомобильную покрышку и цветок, от того, что Вы сравниваете они не станут похожи. Вам нужно доказать эту похожесть. Насколько я знаю, на данный момент определённого ответа нет, или я не знаю его. К примеру, в математике у Вас есть числа, и мы договорились, что мы можем их сравнивать и они могут даже быть равными. Но мы не договаривались о равенстве машины и человека.

                        Судя по Вашему тексту, Вам не так много лет, хотя я могу ошибаться. Если Вам интересны эти темы, прошу Вас дальше продолжать свои изыскания. Жители хабра любят железную аргументацию, в следующий раз, сделайте так чтобы Ваша логика была отличной =)))


                      1. markmariner
                        29.06.2023 15:06
                        +1

                        Есть такая мысль: что вот человеки помогают размножаться и существовать мемчикам, и в этом и есть сущность человека: поддерживать эволюцию мемчиков.


                      1. An_private
                        29.06.2023 15:06
                        +1

                        Человек - это промежуточное звено эволюции, необходимое для создания венца творения пpиpоды - рюмки коньяка и дольки лимона (С)


    1. Wesha
      29.06.2023 15:06

      либо загодя искать новую профессию, либо прицепиться к растущему компьютеру.

      Новая профессия: внимательно обращать внимание на те места, где компьютер косячит, и после этого устроиться хакером.


      1. Str5Uts
        29.06.2023 15:06
        +1

        прицепиться к растущему компьютеру
        Паразитировать гораздо проще. Ума много не надо.


        1. tania_012
          29.06.2023 15:06

          Прицепиться к логарифмической линейке было в облом? Может прицепиться к железяке, которая гудит-воняет-летает, тоже позорное, нам крылья подавай?


          Это все другое? Ладно, почему бы тогда нам не сесть и не начать спокойную долгую беседу? Обязательно плевать на меня минусами? Я что, сразу за покорное рабство у железяк? По чем видно? По чуйке вашей?


          Я за серьезную беседу. Пора посмотреть правде в глаза. А она всегда одна и та же: человек не так велик, как он себе воображает. И чем меньше мы будем цепляться за "человек центр Вселенной", тем умнее будем.


    1. mvv-rus
      29.06.2023 15:06
      +2

      С вашего позволения побуду КО:

      компьютеры стремительно идут вверх, а люди точно стремительно вверх не идут

      Стандартный вопрос: а что у вас по осям? То есть, какие величины и в каких единицах измерения у вас на осях координат воображаемого графика, который вы тут описываете. И если с осью абсцисс понятно — там время, то что по оси ординат? Как и в чем мерить «верх» и «низ»? Правильный ответ — никак и ни в чем. Уж по крайней мере — не скаляром.
      разве написание текста для машины кардинально отличается от написания текста для человека? Как по мне, то английскими буквами и специфичной упрощенной логикой.

      Таки отличается, и не тем, что вы написали. Текст для человека совершенно необязательно писать однозначно: можно надеяться на понимание человеком контекста, который часто у пишущего и читающих общий. А компьютер (тут речь не про ChatGPT, а про старый добрый компьютер) требует однозначности, а потому либо вообще не поймет (обнаружит ошибку), либо поймет не так, как надеялся пишущий, а буквально.
      А потому IMHO редакция совершенно правильно отклоннила статью с очевидными даже для КО ошибками.


      1. tania_012
        29.06.2023 15:06

        Как и в чем мерить «верх» и «низ»? Правильный ответ — никак и ни в чем


        • правильный ответ в том, что мерить надо одной и той же практикой
        • практика плевать, меряем, кто дальше плюнет, получаем верх, низ
        • практика шахматы, меряем, кто больше выиграет, получаем верх низ
        • а судьи кто? а судья человек, обобщенный, "мера всех вещей"

        А компьютер (тут речь не про ChatGPT, а про старый добрый компьютер)


        • для вас слово компьютер и слово ChatGPT это разные сущности?
        • ну извините… я и предположить не могла…
        • и не стану этого делать, это ваше личное, большинство (уверена) живет в однозначной реальности: что есть, то и есть, нынешний компьютер, даже если он станет квантовым, род свой не поменяет

        П.С.
        Что есть КО?


        П.П.С.
        Вам не кажется, что задавать вопросы другому человеку, тут же отвечать на них, и далее делать выводы относительно этого другого человека — это немного не по логике?


        1. mvv-rus
          29.06.2023 15:06
          +2

          правильный ответ в том, что мерить надо одной и той же практикой

          Дык, практика — она не одна и та же, а весьма разная бывает. Одно дело — в очередной раз заново делать стандартные части программы. Другое — делать что-то новое, требующее творческого подхода. Одной и той же мерой это не измерить. И эффективность компьютера (с ChatGPT или даже без) на этих разных задачах будет по сравнению с человеком сильно разная. В частности, вообще непонятно, может ли компьютер решать действительно творческие задачи. А человек — может.
          для вас слово компьютер и слово ChatGPT это разные сущности?

          ChatGPT — это все лишь приложение для компьютера. Одно из. И весьма ресурсоемкое, а потому встраивать такую функциональность во все существующие приложения — напрасно тратить ресурсы. А потому большинство приложений пишется по старинке, на формальном языке программирования.

          Что есть КО?

          Капитан Очевидность (AKA Captain Obvious). Его суперсила — всегда помнить и при случае изрекать очевивидные вещи.

          Вам не кажется, что задавать вопросы другому человеку, тут же отвечать на них, и далее делать выводы относительно этого другого человека — это немного не по логике?

          Это было по риторике: такие вопросы называются риторическими.


    1. markmariner
      29.06.2023 15:06
      +2

      Так ведь человек с огнём круче человека без огня, человек с палкой защищённее, чем человек без палки, человек со станком помощнее, чем человек без станка, человек с гитарой выразительнее, чем человек без неё, человек с компьютером продуктивнее, чем человек без него, и человек с чатджипити тоже. В чём проблема-то?


    1. Hasthur
      29.06.2023 15:06
      +11

      Читаешь нормальную статью, хлёсткие остроумные комменты, расслабляешься в интеллектуальном спа. И тут, *ля, опять эта Таня... НЛО, сделай уже что-нибудь с этим бесконечным флудом!


    1. DaylightIsBurning
      29.06.2023 15:06
      +1

      Этот текст - просто список пережеванных клише, сформулированных в самой тривиальной форме. Более того, список клише совершенно неполный - нет стандартных возражений и их разбора. Нет даже личного частного опыта. Это флуд.


  1. Free_ze
    29.06.2023 15:06
    +5

    Тестовое задание на дом — это достаточно наивный фильтр, если принимать достаточным просто его выполнение. И без всяких ChatGPT задача всегда могла быть сделана кем-то кроме кандидата. Основная суть тестового задания — создать поле тем для беседы, не отнимая времени интервью на подготовку: кодобаза получится относительно объемной и предполагается, что кандидат с ней хорошо знаком. Можно обсуждать как выбранные решения в текущем состоянии, так и стратегии развития приложения за рамками условностей демо-проекта.


    ЗЫ Разумеется, речь о задачах с упором на архитектуру, на 4+ часа. Мелкие алгоритмы в таких условиях спрашивать смысла нет и не было.


  1. event1
    29.06.2023 15:06
    +4

    Можно задать пару вопросов по коду и сразу понять, писал кандидат сам или нет. Мы во время ковида делали тестовое удалённо, человек принёс код в котором были три вложенных цикла, от 0 до 1000. Я спрашиваю: сколько раз вызовется функция внутри самого внутреннего цикла. Отвечает: 1000. Не взяли.

    А если кандидат, напротив, разбирается в том что принёс, то какая на самом деле разница, сам он писал, взял с SO или попросил GPT сделать это за него?


  1. tania_012
    29.06.2023 15:06
    -7

    В России, как известно, в пику заграничным ботам-железякам создаются биологические боты. Первый из них чуть было не поступил в МГУ, точнее, поступил, но до первой сессии. Вот на методику МГУ и надо ориентироваться тем, кто хочет нанять специалиста-человека. Т.е. о дистанции и речи не идет, только личная встреча. И на этой встрече никаких письменных заданий, только разговор.


    С другой стороны, глупо сегодня (и в будущем) искать человека без бота. Я вот не существую без гугла — ну и что? многие лампы не светят без розетки. Т.е. я бы пригласила на встречу двоих: человека и его бота, как в паре они работали бы, таково и было бы мое суждение.


    1. Str5Uts
      29.06.2023 15:06
      +1

      С другой стороны, глупо сегодня (и в будущем) искать человека без бота.
      Другой тренд идёт — искать бота без человека.

      Если нету понимания про что идёт речь, то такой человек точно не нужен, лучше уж тогда бота взять.
      я бы пригласила на встречу двоих
      Вполне приемлемо, но только на позиции которые явно это оговаривают. Иначе получается что это хитрован пытается природу обмануть и пролезть туда, где его не хотят видеть.


      1. tania_012
        29.06.2023 15:06
        -9

        я вам стрелку забила — по поводу вашей радости моему пролету со статьей — пишите ответ там, выше


  1. PsihXMak
    29.06.2023 15:06

    На самом деле, все эти задачки легко гуглились и до появления ChatGPT. В целом тут ничего не изменилось. Как не было смысла давать такие задачки на дом, так и не появилось.

    Другое дело традиционное полноценное оплачиваемое задание. Как показывает практика, ChatGPT не способен писать алгоритмически сложный и комплексный код, в отличии от человека.


  1. tania_012
    29.06.2023 15:06
    -1

    Кажется, что на Хабре прям какие-то вершины умных соседствуют с равнинами — мои (вынужденные) шутливые "пацан", "стрелка" и т.п. вызвали потоки минусов)) — о сути моих слов никто даже не заикнулся — один только попытался, но быстро отказался от диалога — это я приход эры "толерантности" прозевала?)) — если да, то может мне подать в суд, мол, "оскорбили меня, я человек с особенностями, а они прямо мне это говорят, еще и пинают"?))


    Где-то выше есть мой диалог с тем человеком, который не понял и потому быстро так отреагировал в минус, чего и не скрывал. Я не так написала "то предложение". Ну тогда напишите его сами, вы, которые не пожалели минусов — напишите и ткните меня носом: вот так надо!


    1. aamonster
      29.06.2023 15:06
      +8

      Таня, дело не в вершинах. Вы просто вызываете раздражение. Я вот вас в первый раз увидел – и мне уже неприятно (хорошо, минусить не могу: потом не будет стыдно, что на эмоциях расстрелял, не вникая в смысл). И это ещё с поправкой на мой сексизм, я по умолчанию к мужчинам отношусь жёстче, чем к женщинам. А представьте, каково тем, кто с вами уже встречался?

      В общем, софтскиллы качать надо.


  1. Hait
    29.06.2023 15:06
    +2

    Всегда считал, что смысл задания именно в том, чтобы проверить, что человек умеет гуглить. То, что теперь "гуглят" через бота - небольшая разница


  1. aamonster
    29.06.2023 15:06
    +1

    Пока не вижу серьёзной проблемы. Подобные короткие задания – в изрядной степени тема для разговора. Придёт человек с решением, а его спросят, как поправить код, если условие чуток изменится. И тут уже будет не столь важно, написал он его сам, спросил ChatGPT или соседа Васю. Либо он понимает код и алгоритм, либо нет.

    Ну да, не получится отсеять заведомо непригодных сразу, придётся потратить 15+ минут на разговор – но, когда тестовое писали прямо на собеседовании на листочке, времени уходило не меньше. Впрочем, можно прогнать своё дание через ChatGPT самим и поправить условие так, чтобы он всадил ошибку.


  1. Thrillobit
    29.06.2023 15:06
    +1

    Как говорится, 'imho', но даже в первом задании надо суметь поставить нейронке задачу. Потому что для отсортированного массива в решении хочется увидеть слова "бинарный поиск".

    Если массивы не отсортированы, но большие по размеру, я бы использовал подход "sliding window" с запоминанием элементов в структуре, позволяющей сохранять порядок их взаимного расположения.

    И только для маленьких массивов с высоким ожидаемым количеством вхождений я бы рассмотрел решение цикл-в-цикле.

    Подозреваю, что и ChatGPT даст такой ответ, если правильно задать вопрос.

    А умение правильно задать вопрос/цель - это 90% всей работы.


  1. tania_012
    29.06.2023 15:06
    -8

    Уважаемые сограждане Хабра!


    Я давно размышляю над темой "компьютер vs человек". И так как в этой статье рассматривается взаимодействие человека и компьютера, то я не смогла удержаться со своим.


    К сожалению, вышло как всегда: в мою сторону полетели камни-минусы из-за угла и насмешки мне в лицо. Я могу в очередной раз молча стерпеть и замолчать. Но у меня еще остается немного кармы-возможностей и я попытаюсь как-то выехать — ради тех немногих, которые все же вступили со мной в нормальный человеческий диалог — он будет продолжен прямо здесь, так как на еще один коммент у меня уже нет кармы.


    А пока что хочу попросить вас о понимании. Я пишу своеобразно, согласна. И что, это дает вам право издеваться надо мной? Ладно, издевайтесь, я пойму и потерплю — но вы же пинками выгоняете меня из трибуны! Пусть это по здешним формальным правилам, но разве своих человеческих у вас нет? "Пиши, чтобы нам было понятно", — говорите вы. Хорошо, укажите что именно непонятно, какое слово, какое предложение и помогите мне переделать его — я же не тома пишу, а на страничку, на русском языке.


    ===


    Пользователь markmariner ответил на ваш комментарий к публикации «Кажется, вы больше не должны давать тестовые задания кандидатам на дом»:
    Так ведь человек с огнём круче человека без огня, человек с палкой защищённее, чем человек без палки, человек со станком помощнее, чем человек без станка, человек с гитарой выразительнее, чем человек без неё, человек с компьютером продуктивнее, чем человек без него, и человек с чатджипити тоже. В чём проблема-то?


    Общая проблема, нулевая проблема — невозможность нам с вами нормально пообщаться. Она идет не только от моего стиля письма — вопрос "компьютер vs человек" сам по себе почему-то считается требующим немедленной эмоциональной реакции запрета.


    Теперь конкретно по вашему вопросу. В краткой статье я ответила на него так.


    ===


    … проблема "компьютер vs человек" становится очевидной. Но почему "против", почему не вместе или как-то иначе без "войны"? Война вовсе не обязательна, но позиция человека должна быть изменена, а это всегда воспринимается отрицательно — потому и "против". Уже были такие явления: луддиты разбивали машины, мелкие торговцы поджигали супермаркеты, шахтеры грозили бессрочными забастовками.


    Так вот, надо ли нам ждать завтрашних потрясений, если можно спокойно обсудить все сегодня, когда все еще на своих местах?


    К примеру, спокойно и конкретно обсудить вопрос о копирайтинге. Судя по фрилансу, там очень много работников, больше, чем в любой иной области. Понятно, что писателей среди них проценты, основная масса на уровне грамотных и усидчивых. А я заказчица, у меня теперь есть ChatGPT и я не буду платить тому, кто напишет хуже большой языковой модели, раньше платила бы, а теперь не буду, не можешь лучше — до свидания.


    ===


    Если нужно развернуть мой ответ, то проще всего это сделать на примере шахмат. Ну вот представим себе, что вся деятельность человеков, все их достижения и величия есть победы в шахматной игре с кем-то там Таинственным Всемогущим. В шахматах сначала был только человек. Потом он начал работать с помощником компьютером, уже на нашей памяти. Через некоторое время энтузиасты подтянули этого помощника и он стал выигрывать на среднем уровне. Дальше больше. Внезапно оказалось, что помощник превзошел своего хозяина — "Шахматные алгоритмы, которые думают почти так же, как человек, только лучше" https://habr.com/ru/companies/skillfactory/articles/544040/ И что делать человеку? Не пускать на очередное сражение с Таинственным Всемогущим "помощника", идти самому и рисковать судьбой всего человечества? Или взять "помощника" в свои уши и тупо делать ходы по его подсказкам? Может "помощник" сможет подтянуть своего "учителя"? Может как-то соединить мозги? Я не знаю правильного ответа, но я знаю, понимаю, что искать его нужно не завтра, даже не сегодня — еще вчера надо было искать его — компьютер давно уже перестал быть большим однозначным арифмометром, он не вычисляет, от творит, пусть по-своему, пусть неуклюже, но это всего лишь новорожденный, он стремительно растет, буквально по часам — целая мировая гонка уже началась по его росту. Миллиарды людей заняты вовсе не творчеством, а простыми соображениями — компьютер начнет обходить их первыми, куда они пойдут? управлять компьютером как политики управляют учеными? по какому праву? по праву "я тебя сейчас выключу"? это достойно человека?


    Пользователь Hasthur ответил на ваш комментарий к публикации «Кажется, вы больше не должны давать тестовые задания кандидатам на дом»:
    Читаешь нормальную статью, хлёсткие остроумные комменты, расслабляешься в интеллектуальном спа. И тут, *ля, опять эта Таня… НЛО, сделай уже что-нибудь с этим бесконечным флудом!


    Здесь, на Хабре, место исключительно для "хлёстких остроумные комментов, расслабления в интеллектуальном спа"??? Если такое неписаное правило, то я не знала… И что, нельзя даже уголочек какой-то выделить для серьезной беседы???


    Пользователь aamonster ответил на ваш комментарий к публикации «Кажется, вы больше не должны давать тестовые задания кандидатам на дом»:
    Таня, дело не в вершинах. Вы просто вызываете раздражение. Я вот вас в первый раз увидел – и мне уже неприятно.


    Ну не я, а мои слова. И если для вас все так просто и ясно, то не могли бы вы совершить подвиг: взять мои слова и переписать их "без раздражения" — сохранив смысл и серьезность? Я была на научных семинарах, там такие заики выступали… но никому и в голову не приходило сказать "пойдите потренируйтесь", все следили только за аргументами. И еще, смешное, если бы прилетели инопланетяне, отвратительные для вас, то вы послали бы их нафиг?)) И еще, грустное, если бы вас вот так пинали "ты мне не нравишься" полгода, то вам легко было бы излагать все весело и шутливо?


    Пользователь Wesha ответил на ваш комментарий к публикации «Кажется, вы больше не должны давать тестовые задания кандидатам на дом»:
    Вы забываете, что человеку, кроме головного мозга, нужно ещё и общество. Поместите Хокинга в центр Сахары — и жить ему останется несколько часов.


    Извините, это не я забываю, это вы (обобщенные) затыкаете мне рот! Вы (обобщенные) не даете мне возможности рассказать вам все полно, как хотелось бы. В частности о том, что человек вообще не существует — это сверхочевидно!!! — все достижения человека есть достижения Роя, который живет тысячи лет, который обладает огромной памятью — взлет человеков связан не так с их головным мозгом, как с их неимоверной способностью образовывать гигантские Рои, в которых возможности головного мозга многократно резонируют! Я пишу "человек" подразумевая разное, но никогда не кого-то конкретного, будь он хоть 1000 000 раз эйнштейном. Я не хочу сваливать в одну кучу сразу все аспекты, для начала хотя бы с вопросом "головной мозг отдельной особи и мозг компьютера" разобраться, с этим простейшим.


    Пользователь mvv-rus ответил на ваш комментарий к публикации «Кажется, вы больше не должны давать тестовые задания кандидатам на дом»:
    В частности, вообще непонятно, может ли компьютер решать действительно творческие задачи. А человек — может.


    1) Если шахматы не творчество и даже го не творчество, то что тогда творчество? 2) О творчестве компьютера не надо судить по лепету его новорожденного 3) Миллиарды людей решают НЕ творческие задачи, тысячи из них вообще не способны на такое — это не проблема завтрашнего дня?


    Пользователь voltag ответил на ваш комментарий к публикации «Кажется, вы больше не должны давать тестовые задания кандидатам на дом»:
    tania_012 хорошо, что Вы написали статью. Но проблема в том, что Вы не проверили большое количество утверждений, например:
    "Наверное, все согласятся, что сущность хомо сапиенс состоит в том, как он обрабатывает информацию, т.е. в работе с информацией. Но компьютер тоже этим занят, только этим он и занят. Раз так, то два игрока на одном не поделенном поле с большой вероятностью будут "сталкиваться". Один абзац, 3 предложения, во всех предложениях допущения или логические ошибки.… Жители хабра любят железную аргументацию, в следующий раз, сделайте так чтобы Ваша логика была отличной =)))


    1) Дайте мне возможность развернуть свои строки и тогда судите (выше была попытка диалога, там почитайте) 2) В неясных областях все рассуждения ведутся неясно и это абсолютно нормальная ситуация, даже в ясных областях так (что такое число? что такое пространство?...) 3) Жители Хабра испытывают отвращения к непонятному? им все на ложечке "железных доказательств" подавай?


    В Сети я буду вечером. Если мне помогут с кармой, то и ответить смогу.


    И вот что еще, ну разве вам так важны эти эмоции от этой злой придурковатой тани? просто ради интереса вам не интересно, что она квакает о человеке и компьютере, о жизни человеков, вы что, никогда-никогда-никогда сами об этом не задумывались? или задумывались и все уже решили? неужели только у тань жизнь кажется одной, конечной и непонятной?


    1. DaylightIsBurning
      29.06.2023 15:06

      Если Вы хотите, что бы получился предметный разговор - нужен Абстракт, то есть короткое содержание вашего изложения в одном абзаце, с упором на то, что в Вашем изложении есть такого, чего мы раньше не читали в десятках других мест.


    1. mvv-rus
      29.06.2023 15:06
      +1

      1) Если шахматы не творчество и даже го не творчество, то что тогда творчество? 2) О творчестве компьютера не надо судить по лепету его новорожденного 3) Миллиарды людей решают НЕ творческие задачи, тысячи из них вообще не способны на такое — это не проблема завтрашнего дня?

      1. И шахматы, и го — это игры с полной информацией. И для выигрыша в них творчество не обязательно: в принципе, достаточно полного перебора. Хотя большой массив результатов уже сыгранных партий позволяет найти некоторые эвристики, уменьшающие трудоемкость перебора. А перебор — это то, что компьютер делает всяко лучге человека.
        Но не все игры такие: к примеру, покер — уже игра с принципиально неполной информацией, хоть и с формальными правилами. А что до жизни, то там ещё и с выяснением формальных правил сложно.
      2. Пока способность к творчеству компьютером не продемонстрирована, так что позитивные рассуждения о ней сейчас просто невозможны. Предлагаю вернуться к этому вопросу лет через сто ;-)
      3. Более того, немалое число из этих миллиардов вообще занимаются физическим трудом, т.е. используют, в основном, не свой мозг, а свои мышцы. Но практически все они потенциально могут использовать мозг, причем (я подозреваю, хотя это строго и не доказано) — творческим образом: знали бы вы, насколько те же грузчики способны к творческому подходу для удовлетворения своего желания что-нибудь спиереть.


  1. iboltaev
    29.06.2023 15:06

    Мне вот интересно, на каком датасете они ее обучали? пара задач явно с литкода, и там вроде как, проявив терпение и заплатив денег, можно оочень много решений нагрепать. Но вот задача про декоратор, или клиент-серверный пинг-понг, где они такой датасет взяли?
    Ну и кто-то пробовал, например, StarCoder на этих задачах (мой ноут его не тянет), и если да, то статья очень будет приветствоваться.


  1. kirichenec
    29.06.2023 15:06
    -1

    А раньше эти задания можно было дать другу-программисту, а то и вообще на аутсорс. Ничего, всё равно отсеивали как-то)

    Если кандидат вздумает надуть с домашним тестовым, то инструменты тут не важны. Тут скорее нужно понимать, для чего вообще домашние тестовые нанимателю