• Ответ на викторину

    Что выведет код?

    javascript
    function sum(a, b) {
    return a + b;
    }
    console.log(sum(1, "2"));

    Правельный ответ: 12

    В JavaScript оператор + работает хитро: если хотя бы один из операндов является строкой, движок выполняет конкатенацию (склеивание) строк, а не математическое сложение. Число 1 неявно приводится к строке «1», и в результате «1» + «2» дает строку «12».

  • Ответ на викторину

    Дан следующий код. Что произойдёт при выполнении этого кода?
    rust
    fn main() {
    let mut s = String::from("hello");
    let r = &mut s;
    r.push_str(" world");
    let r2 = &s;
    println!("{}", r2);
    }

    Правильный ответ: Код не скомпилируется из-за нарушения правил заимствования (cannot borrow s as immutable because it is also borrowed as mutable)

    В Rust нельзя одновременно иметь активную изменяемую ссылку (&mut s) и неизменяемую ссылку (&s). Здесь r (изменяемая) ещё в области видимости, когда создаётся r2 (неизменяемая), что приводит к ошибке компиляции.

  • Ответ на викторину

    Нужно рассчитать комиссию 0.1% от суммы 123.45 ₽ и вычесть её.

    Правильный ответ: BigDecimal amountBD = BigDecimal.valueOf(amount); BigDecimal commission = amountBD.multiply(BigDecimal.valueOf(0.001)).setScale(2, RoundingMode.HALF_EVEN);

    Почему это так и в чем заключаются ловушки остальных вариантов:
    Почему A — плохо (Ошибка точности)
    Использование double для денег — это грех в финтехе.
    double использует двоичную арифметику с плавающей точкой (IEEE 754). Число 0.1 или 123.45 не могут быть представлены в двоичной системе абсолютно точно.
    При умножении 123.45 * 0.001 вы можете получить что-то вроде 0.12345000000000001. При конвертации обратно в копейки (целые числа) это приведет к ошибке на 1 копейку. В масштабах банка это миллионные убытки.
    Почему B — самая опасная ловушка (Конструктор BigDecimal)
    Многие джуны знают, что для денег нужен BigDecimal, и выбирают этот вариант. Но это ошибка.
    Конструктор new BigDecimal(double) берет точное двоичное представление числа.
    Если вы напишете new BigDecimal(123.45), вы получите не 123.45, а:
    123.4500000000000028421709430404007434844970703125
    Вы просто переносите ошибку double внутрь BigDecimal.
    Почему C — неполноценно (Отсутствие округления)
    BigDecimal.valueOf(double) — это правильно, так как этот метод сначала конвертирует число в строку (Double.toString()), а потом создает BigDecimal. Вы получите чистые 123.45.
    Но: В варианте C нет округления.
    Результат умножения 123.45 * 0.001 будет 0.12345.
    В банковской системе нельзя хранить 0.12345 рубля. Нужно округлить до 2 знаков (копеек). Без setScale вы получите ошибку при попытке сохранить это в БД или при дальнейших расчетах.
    Почему D — идеально
    BigDecimal.valueOf(amount): Безопасная конвертация из double (через строку).
    multiply: Точное вычисление.
    setScale(2, RoundingMode.HALF_EVEN): Самый важный пункт.
    Мы явно указываем, что нам нужно 2 знака после запятой (валюта).
    RoundingMode.HALF_EVEN (Банковское округление) — это стандарт в финтехе. Оно минимизирует статистическую ошибку при массовых вычислениях (округляет к ближайшему четному числу, если цифра ровно посередине, например, 0.5).

  • Ответ на викторину

    В игре на Unity машинка едет с постоянной скоростью и перепрыгивает через трамплин. Движение реализовано в Update(), а физический прыжок через AddForce() — в FixedUpdate(). Игрок жалуется: на мощном ПК машинка прыгает выше и дальше, чем на слабом ноутбуке. В чем причина?

    Правильный ответ: Физический движок пересчитывает скорость только в FixedUpdate(), но если машину двигать в Update() — это накладывается поверх физики, создавая разный суммарный импульс в зависимости от FPS.

    Update() вызывается каждый кадр (разное количество раз в секунду). FixedUpdate() вызывается с фиксированным интервалом (обычно 50 раз/сек).
    Если менять положение или скорость машины в Update(), то между вызовами FixedUpdate() накопится разное количество микро-перемещений. При прыжке AddForce() добавляет импульс в момент вызова, но текущая скорость перед прыжком уже искажена ручным движением в Update().Результат: на высоком FPS — машина влетает в трамплин с большей ручной скоростью (из Update()), прыжок получается выше и дальше.Правильно: либо всё движение через FixedUpdate() и Velocity, либо умножать на Time.deltaTime и не трогать физику напрямую в Update().

  • Ответ на викторину

    В игровом движке метод Update() вызывается каждый кадр. В какой ситуации следующий код приведет к катастрофическому падению FPS (фризу) или зависанию игры на несколько секунд?

    // Псевдокод на C# (Unity-style)
    void Update() {
    if (Input.GetKeyDown(KeyCode.Space)) {
    List allEnemies = FindAllObjectsOfType();
    foreach (Enemy e in allEnemies) {
    while (Vector3.Distance(Player.Position, e.Position) < 100f) {
    e.MoveTowardsPlayer(1f);
    }
    }
    }
    }

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

    Условие while (Distance < 100f) не гарантирует, что MoveTowardsPlayer сократит дистанцию до значения ниже 100 (например, если моб застрял в стене или движется слишком медленно). Если дистанция никогда не станет меньше 100, цикл станет бесконечным. Игровой поток (Main Thread) зависнет намертво, так как Update() не завершится. Это Hard Lock, а не просто просадка FPS.

  • Ответ на викторину

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

    console.log(‘1’);
    setTimeout(() => console.log(‘2’), 0);
    Promise.resolve().then(() => console.log(‘3’));
    console.log(‘4’);

    Правильный ответ: 1 4 3 2

    почему именно этот ответ:
    1 и 4 выведутся сразу, так как это обычный синхронный код.
    3 выведется следующим, потому что коллбэк промиса попадает в очередь микротасок (Microtasks). Движок выполняет их сразу же, как только завершился синхронный код.
    2 выведется последним. Несмотря на задержку в 0 миллисекунд, setTimeout помещает коллбэк в очередь макротасок (Macrotasks), которые выполняются строго после полной очистки очереди микротасок.

  • Ответ на викторину

    Что такое социальная инженерия?

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

  • Ответ на викторину

    Дан Java-код с классом Test, который демонстрирует порядок выполнения:

    public class Test {
      static {
        System.out.print("1 ");
      }
      { 
        System.out.print("2 ");
      }
      public Test() {
        System.out.print("3 ");
      }
    }
    
    public static void main(String[] args) {
      new Test();
    }
    

    Что выведет этот код при запуске?

    Правильный ответ: 1 2 3

    Объяснение:
    Статический блок (static {}) выполняется первым при загрузке класса в JVM
    Блок инициализации экземпляра ({}) выполняется перед конструктором при создании объекта
    Конструктор выполняется последним

  • Ответ на викторину

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

    Ответ: На деле средняя удельная мощность Солнца всего ~0,2 мВт/кг (энергия рождается только в ядре, а масса огромна), тогда как активный компост/преющие листья выделяют 10–50 Вт/кг за счёт метаболизма микроорганизмов. Разница в ~50 000–250 000 раз в пользу листьев.

    Вот цифры (удельная мощность, Вт/кг):
    Куча преющих листьев: ≈ 1–2 Вт/кг
    Спящий человек: ≈ 1 Вт/кг
    Солнце (в среднем): ≈ 0,2 Вт/кг
    Солнце (в ядре, где идёт термояд): ≈ 0,001–0,01 Вт/кг
    То есть килограмм листьев может быть в сотни раз «горячее» килограмма солнечного термоядерного реактора, если измерять мощность на весы.
    Алексей Семихатов был бы доволен таким ответом.

  • Ответ на викторину

    У вас есть HTTP-хэндлер, который читает тело запроса (io.ReadCloser) и передаёт его в функцию process(data []byte). Как правильно спроектировать обработку большого входящего потока, чтобы не положить сервер из-за памяти?

    Правильный ответ Чанки с sync.Pool и воркеры

    Пояснение:

    ReadAll положит сервер при большом теле.
    Чанки с sync.Pool и воркеры — стандарт.
    io.TeeReader — оверхед с диском,
    process(), который внутри вызовет ioutil.ReadAll — блокировка хэндлера.