Pull to refresh
83
0
Егор Суворов @yeputons

User

Send message

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

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

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

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

Куда нажать, чтобы выработать необходимый инструментарий?

Мне лично очень помогал регулярный вопрос: "а что вы чувствуете, а не думаете или считаете?". То есть в начале вообще не въезжал, как отвечать и куда смотреть. Пробовал перебирать названия и примерять на себя: "не, это вообще не грусть, стыд похож, бессилие есть, может, злоба? А как я ощущаю злость? В смысле никак не ощущаю?". Потом и какие-то ощущения начал замечать, и связь между наличием этих ощущений и, например, продуктивностью и возможностью вылезти из листания лент и пойти работать. Потом какие-то паттерны стали проявляться. Теперь можно их заранее предвидеть и понять, например, что на задачу X конкретно мне надо пять минут рабочего времени и шесть часов перед этим выть на стену, потому что у неё есть свойства Y и Z, которые мне почему-то на данный момент мешают. Да, чёткого рационального объяснения нет, всё должно получиться за пять минут, но закономерность хорошо прослеживается.

Расширенная версия: "что хочется сделать/сказать, кому?", "что хочется, чтобы ответили?". Именно с акцентом на вот эту часть, которой почему-то хочется чего-то нерационального.

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

А эмоциональные вещи даже проверить невозможно.

Свои можно, постфактум. Если научиться отличать состояния "что-то мне плохо" от "мне весьма хорошо", что может быть на удивление нетривиально. Мне кажется, если хотеть максимизировать именно вот это своё непонятное ощущение "мне хорошо", то придётся научиться его хотя бы измерять. А это точно к рациональности никакого отношения не имеет.

Дальше можно уже рациональность при желании примешивать, строить модели, пользоваться. Например, замечать, что "если я сделал X - дальше мне хорошо" или "если я делаю Y прямо сейчас, то наверняка мне плохо, просто я ещё не заметил". Но проверять модели наверняка в 99% случаев придётся всё ещё иррациональными методами вроде "посмотреть на себя и почувствовать, что происходит", а не расшифровкой ЭЭГ.

Не автор, но частично отвечу: списывания на онлайн-соревнованиях много. А это в том числе и обычные олимпиады из-за COVID-19, например, школьный этап всероссийской олимпиады. Там совершенно чудесные истории про списывание, когда копировали код с номерами строк и это работало: https://codeforces.com/blog/entry/96490

И эти тривиальные части одинаковы у разных людей.

Похожи - да. Но не одинаковы и почти всегда что-нибудь сделать либо "через одно место", либо у кого-то свой хитрый трюк. По моему опыту решения и просмотра глазами решений в задаче на >= 50 строк кода два участника просто не могут получить одинаковое решение (даже с точностью до небольших преобразований). Да даже в задаче на пять строк и две формулы это маловероятно (хоть и случается): кто-то напишет всё в одну строчку, кто-то вынесет все промежуточные вычисления в отдельные переменные, кто-то только часть, а ещё про оператор % вспомнит только половина, а вторая половина напишет `a - a / b * b`.

А тупого списывания на уровне "немного переименовали переменные, поменяли for на while" очень много: его просто сделать и ничего не сломать. Даже что-нибудь в функцию переносить - уже появляется риск сломать.

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

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

На победу или хотя бы top-100 99% участников (цифра с потолка) в онлайн-соревнованиях не рассчитывают. А заиметь какой-то определённый рейтинг может быть нужно по каким-то причинам. Поэтому читерство цветёт и процветает, вот чудесный пост на Codeforces про то как автор контеста пошёл ловить читеров в их чаты: https://codeforces.com/blog/entry/95415

А вот про списывание на школьном этапе всероссийской олимпиады: https://codeforces.com/blog/entry/96490 . Общего рейтинга нет, но плюшки за проход на региональный этап могут выдавать в зависимости от школы, начиная от "можно не делать домашку".

Любопытно, что даже на русском не очень много материалов с описанием произошедшего: пост на VC, статья на РБК, пост на Хабре, да и вроде всё.

А вот на английском вообще ни одного материала не вижу. У кого-нибудь получилось найти?

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

  • Считайте, что C++ - надмножество Си и писать надо почти так же.

  • Следуйте рекомендациям с https://twitter.com/affectivecpp , например:

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

Мне кажется, что проблема скорее в том, что метод createResource() по своей сигнатуре возвращает некоторый тип T, единственное ограничение на который со стороны самого метода createResource() — он должен реализовывать Resource. Не очень понятно, как такое вообще трактовать.

Например, если считать, что generic-методы — это методы, которые работают для какого-то выбранного T, то есть вопрос: а кто "выбирает" тип T?

Если тип T выбирает сам метод (как сейчас по факту и происходит: для набора параметров возвращается какой-то конкретный тип T), то вызывающий код не имеет права пользоваться никакими знаниями про тип T, кроме того, что он реализует Resource. Такая конструкция в языке Java уже есть: просто ставим возвращаемый тип Resource без всяких extends.

Если тип T выбирается вызывающим кодом, то получается, что метод должен уметь возвращать экземпляр произвольного типа T. Вызывающий код выбрал, какой T ему нужен (например, одновременно реализующий Resource и List<> — такие теоретически существуют), а метод должен этому удовлетворить. Что, разумеется, некоторый абсурд: метод даже не знает, что за T выбрал вызывающий код. Именно поэтому внутри тела метода приходится делать небезопасное преобразование к типу T — компилятор абсолютно правильно не может доказать, что FileResource является каким-то произвольным T.

> Если уж два указателя равны, так они таки равны. И либо оба можно использовать, либо оба нельзя использовать.

Так они же не "равны", они "compare equal", если я правильно понял. То есть верно `p == q`. А то, что их можно при этом одинаково использовать, вроде нигде не написано?

В чистом Haskell, мне кажется, нельзя, там типы нельзя передавать в качестве аргументов функций. Или получаем зависимые типы (dependent types) и какую-нибудь Agda.

Кажется, должны помочь type variables/generics? Например:

from typing import TypeVar

T = TypeVar('T')
def foo(a: T) -> T:
    return a

x: int = foo(20)   # ok
y: str = foo('x')  # ok
z: str = foo(20)   # incompatible types in assignment

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

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

  2. В частности, если мы пишем какое-нибудь владеющее дерево/список, то при наивной реализации (через unique_ptr и сгенерированные деструкторы) для его уничтожения требуется стек размера с глубину этого дерева. Можно случайно переполнить стек и даже не догадаться: рекурсии-то мы нигде явно не писали, она скрыта.

  3. Деструкторы провоцируют писать логику для закрытия/сброса буферов именно в деструкторах. Создаётся ложное ощущение, что это безопасно, хотя на самом деле ошибки при закрытии (диск отвалился => не удалось файл записать) тут либо полностью игнорируются, либо приводят к падению приложения. Если же, например, есть явный вызов close(), который надо делать абсолютно всегда (либо под угрозой назальных демонов, либо чего-нибудь попроще), то за его наличием следить проще и привычнее.

либо усложнять код чтобы все сводилось в одну точку.

А goto в нужную точку в хвосте функции для освобождения не помогает, как в ядре Linux часто делают? Или ресурсы часто не так линейно вкладываются?

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

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

#define MAXN (int)1e6 + 1
int data[2 * MAXN];  // int data[2 * (int)1e6 + 1];

Хотели объявить массив размера два миллиона и два элемента, а получили массив размера два миллиона и один элемент.

Чинится легко — добавляем вокруг каждой такой макроконстанты круглые скобки.

А дальше выбираем в своём проекте: ничего с этим не делать, забанить #define для констант, разрешить и форсить наличие круглых скобок (только где обязательны или вообще везде — отдельный вопрос) на code review/автоматически/не форсить вообще и разгребать редкие последствия.

Конечно, если много раз писал #define, то скобки наверняка на автомате ставишь. Вот и холивар: кому-то это вообще риском не кажется, просто "надо уметь писать", а кому-то риском кажется. Потом скатываемся в стандартный спор на тему "нужны ли code style", "какой code style использовать"...

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

Я вот во втором лагере. Данный пример вижу так:

Если вы не используете венгерскую нотацию в том или ином виде, то там будет не number, а какое-нибудь другое название.

Например, есть ли ошибка в следующем коде, если он компилируется и не падает?

long long timeout_min =
    ((long long)read_config("timeout_sec") + 59) / 60;

Ответ: а фиг его знает.

Если там возвращается double (потому что в JSON только вещественные числа) — то, наверное, тут хотели округлить секунды вверх до минут. А вот если там случайно возвращается сишная строка, то вы только что взяли в качестве количества секунд значение указателя. И никаких предупреждений компилятора не получили даже на самом высоком уровне предупреждений.

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

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

> И совсем уж нубовский вопрос: какое такое сакральное преимущество даёт C++ системном программировании что бы это нельзя было сделать на си?

Ни один язык не даёт сакральных преимуществ над другим. Даже если (что не так в случае Си и C++) является строгим надмножеством другого; не всегда больше возможностей — это хорошо.

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

Код соответствует стандарту С++, если он компилируется компилятором С++.

Каким из компиляторов? Они, бывает, отличаются и добавляют свои собственные расширения. А ещё поведение отличается между ОС, потому что помимо компилятора есть стандартная библиотека и протекающие абстракции.

Ill-Formed No Diagnostics Required куда делся?

Уточнение к любым моим советам из интервью: они, конечно же, в основном основаны на моём опыте. Мне много где сильно повезло с обстоятельствами. Если у вас другие обстоятельства, какие-то мои рекомендации могут оказаться лично вам даже вредны (sic!)

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

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

Приёмная комиссия ВУЗа (если речь про бакалавриат) никаких решений уже давно не принимает. За год (или чуть меньше) до поступления публикуется список льгот, которые дают различные олимпиады, список необходимых ЕГЭ — всё. Летом просто сортируются публичные списки подавших документы по определённым правилам и зачисляются верхние строчки, пока не закончатся места.

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

Если не ошибаюсь, только два вуза могут проводить собственные экзамены — МГУ и СПбГУ, причём делает это только МГУ. Плюс можно проводить отдельный конкурс на "творческие специальности", куда программирование не относится. Некоторые вузы (вроде МФТИ) устраивают "собеседование" с абитуриентами, но это юридически не влияет на то, будет ли студент зачислен на определённую программу обучения. Вот что там происходит с разделением на потоки/группы внутри программы или будут ли на собеседовании переубеждать поступить в другое место (это я уже фантазирую) — другое дело.

Information

Rating
Does not participate
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Date of birth
Registered
Activity