Comments 71
Спецы формируются через страдания. И это, кстати, не только про программирование ;)
Мыши страдали, но продолжали жрать питона!
С пет проектами похожая ситуация.
Вроде бы раньше хотел сделать все и сразу… И выгарал, пока доводил страницу/код до идеального состояния.
А теперь просто думаю, зачем что-то делать самому/своё, если можно взять готовое и накидать контента и получится то, что хотел.
"Мне 33 годика"
А мне через пару месяцев 60. Но в целом все так.
По частностям - я последние 10 лет фрилансер, лет 25 назад перешел из программистов в юникс сисадмина, а потом, ес-но, в девопс.
спасибо за статью, очень интересная и без видимых огрехов. я не нашла к чему придраться (а я это обожаю, ведь это словно хакерство в социуме), со всеми пунктами, ну, согласна.
и да, у программиста может быть девушка. даже у программиста-девушки может быть девушка:) ладно, если серьезно, то я вообще не понимаю, откуда этот миф, что админ или прогер совершенно не следят за собой. я поменяла много фирм, и везде программисты (увы, мужчины, но) ухожены, имеют жен и детей. а встретишь вне работы - и не угадаешь, что он программист. тут даже я покаюсь, что своей девушке уделяю меньше времени, чем компьютеру.
Ну.... вот лично у меня это работает так... если начинаются понты со сном, то скатываюсь в субдепрессию, что приводит к:
- снижению продуктивности в целом
- энергия в основном тратится на какие-то несложные вещи вроде поигрулек, и то не факт, порой даже поиграть оказывается сложно (попробуйте не спав неделю-две нормально зарубить какого-нибудь Сёки-но-Ками в Геншине, у меня было так, что вообще прям не могу сообразить куда бежать и шо делать)
- если на работу энергии хватает, то на все остальное - типа приборки и проч - уже нет
Я думаю, что вот все эти стереотипы про программист_ов они либо про очень сильно запаренных работой и выгоревших, либо еще что.
P.S. Если взять просто человека с диагностированной депрессией, то он, внезапно, хорошо подойдет почти под все стереотипы, если подумать
А процент каких-либо психических особенностей/расстройств у программист_ов выше, чем в среднем по популяции
А шо ж тогда к девушкам от мужчин столько претензий по поводу этого самого "бессмысленного" слежения за собой? Или это другое?
а работаю я в среднем 4 часа в день (но это прям чистое время, без перерывов и приёма пищи)
И это правильно.
Во-первых, при офисной работе из 8 часов на собственно работу хорошо, если уходит половина.
А во-вторых, каждый последующий час приводит к накоплению усталости и снижению КПД. Не получится зарабатывать в 2 раза больше, тратя на работу в 2 раза больше времени.
Хорошая летняя статья. Спасибо!
Это особенно зашло: "Если непонятно, что делает код, то разбейте его на небольшие функции и дайте функциям и переменным нормальные названия."
Многое в статье вижу про "эмоциональный капитал", который не получить никак кроме через пережить самому. Потому для офисных джунов это ересь - мир совсем другой. Отлучался из программирования на 10+ лет в недвижимость - сделки между людьми на критичные суммы очень нехило прокачивают этот скилл.
В целом согласен, хотя клиенты с их фантазиями есть, скорее, у меньшей части программистов, так что программист, если в общем, это не про клиентов.
А чел, который берет интервью у себя самого, называется "не интересный никому, кроме себя". К сожалению, такой вариант отсутствует в списке ответов. ?
а где-то в полночь я, как Золушка, превращаюсь в тыкву и начинаю программировать, как я это называю, "спинным мозгом" - я пишу какой-то код, он даже работает, но вот голова не понимает, что вообще я написал и зачем
Сам периодически с таким сталкиваюсь, независимо от времени суток - причем, страшно, когда на следующий день смотришь на код и думаешь "как я мог такое написать". Это, скорее, возникает на долгих, монотонных задачах. И несмотря на довольно большой опыт, не всегда удаётся ловить и прерывать себя на таких состояниях, для себя пока использую работу по таймеру, но и это не панацея
зачем работать на тут, когда можно работать на там
В 33 года я тоже так думал. Десяток лет спустя у меня той работы не стало. За последние два года такой работы я больше найти не смог. И хотя я не в России, думаю, в этом вопросе это ничего особо не меняет. Американские компании не хотят нанимать людей, не находящихся легально в США. Все remote вакансии неявно предполагают, что кандидат должен легально находится в США. За два года я пожалуй встретил только два исключения, когда целенаправленно искали за пределами США. И вторая проблема. Они теперь стали хитромордыми и либо ищут людей, что бы платить им по локальному рынку, либо открывают филиалы, что бы нанимать локально, т.е., опять же, что бы платить по локальному рынку.
А пока та работа у меня была, я тоже думал, и зачем люди за "копейки" работают локально, если можно удалённо работать за гораздо большие деньги.
Они всегда так делали, не могу сказать как было до 2007, но когда начал работать с американцами сразу стало понятно что они платят по местному рынку, но может немного больше. Просто платят в баксах, а после резкого скачка курса вдруг оказывается что и зп подросла. Но это все потом нивелируется разными оговорками, снижением часов и сроков. И гдето через годик все опять приходит к местному уровню. Попытки получить ставки побольше натыкались на требования жить поближе к сюзерену ;)
Полагаю, что мне сильно повезло, но мне 15 лет платили по американскому рынку. Собственно, по прошествии двух лет, уже не полагаю, а я просто уверен, что мне крупно повезло тогда.
Но это все потом нивелируется разными оговорками, снижением часов и сроков. И гдето через годик все опять приходит к местному уровню. Попытки получить ставки побольше натыкались на требования жить поближе к сюзерену ;)
Думаю сильно от работодателя зависит. Работал с 2007 по 2013 год на одну американскую компанию удаленно из российской глубинки, ЗП в долларах за этот период все время росла, с 1500 доросла до 3500.
Удивлён, что вы вообще нашли американскую контору, которая платила по ставкам США человеку, который в США не находится. Я с американцами работаю с 2013 года, и ни разу с таким не сталкивался?. Они всегда искали людей в Европе, Индии или Китае целенаправленно, чтобы меньше платить.
Они теперь стали хитромордыми и либо ищут людей, что бы платить им по локальному рынку, либо открывают филиалы, что бы нанимать локально, т.е., опять же, что бы платить по локальному рынку.
Стандартный вопрос: а зачем им тогда нанимать "чужих" людей, если за те же деньги можно нанять "своих" людей?
Всегда интересно почитать статью от интересного человека.
Спасибо!)
Большинство прогеров думают что пробились к вершинам, но на самом деле они просто туда всплыли (с)
Отругайте человека — и он забудет это через неделю. Похвалите человека — и он будет помнить об этом всю жизнь.
К сожалению, наоборот: человеку свойственно лучше запоминать плохое.
Именно поэтому не существует антонима к слову "злопамятный".
у нас не существует антонима к слову "ущербный", значит нормальных людей не существует, все мудаки. (такого же уровня логика). Человеку свойственно помогать и быть добрым, противоположное - это патология.
У Вас очепятка во фразе "Прокрастинация, выгорание и тлен"
Зачем постить мусорные бессмысленные опросы в конце? Тут вроде не Youtube, нагревать "алгоритм" опросами не нужно.
"на днях мне написал клиент, что приложение не работает. Пробую открыть сайт - виснет намертво, но и ошибки не выдаёт."
Вот это везуха! Обычно после такого письма пробуешь, а всё открывается. Потом приходится неделю выяснять, что конкретно у клиента не работает.
Тоесть получается ChatGPT может заменить программиста, сам придумает и напишет необходимый код и решение
Мне 33 годика, из них лет 13 у меня жёсткое программирование, и я помидор на питоне.
Фух, наконец
![после попыток так тридцати что-то таки получилось. после попыток так тридцати что-то таки получилось.](https://habrastorage.org/getpro/habr/upload_files/862/dc0/dcc/862dc0dcc6a5a6594b6353957f0ac1f9.png)
Все логично, и помидорство и философский пофигизм, но как-то скучно так работать.
Если меня проект не торкает, лучше сразу слиться.
В django все запросы к базе — ленивые, и строчка _ = Subscription.objects.filter(...) только создавала запрос, но не выполняла его, поэтому запись не блокировалась!
Я не силён в этом, но со стороны БД, запроса нет = ничего не изменяется, а то что запрос начинает выполняться сейчас или на 20-50 секунд позже ничего не меняется (за исключением того, что списание пойдёт через 20-50 секунд). Или тут какая-то фича джанга, что он выполняет его дважды если ленивый, или где-то в коде дублирование, что списывает и в начале (секретное место) и лениво "через 20-50 секунд", но при этом не списывает в начале, так как идёт блок неленивый, который блокирует и списывает разово /fantasy. Можете, пожалуйста, пояснить этот момент?
Код ожидает что после SELECT FOR UPDATE никто другой эту строчку в БД модифицировать не сможет. Но т.к. запрос по факту в БД не ушёл - параллельно второй процесс может создать race condition и обработать строку более 1 раза
Да, может обработать, но суть как раз в том, что эта строка до старта обработки пусть меняется как может, но после селекта уже не меняется. У нас нет селекта, потому апдейтить может кто угодно и как угодно, что для нашей операции (списать деньги и продлить подписку с техническим селектом) неважно. Что и возвращает к вопросу тому, что это не объясняет двойного списания.
Допустим возвращаемся к моменту примера с двумя участками 0сек и 20-50сек и пусть 200$ на счету, подписка 100$.
- Ситуация race condition. w1 (lazy) создаёт (но не исполняет) селект фор апдейт. На 0 секунд у нас нет кода нет блока, ничего нет. Есть w2 (неизвестный) который берёт и исполняет чего-то списывая 100$ на что-то, потом приходит w1 (через 20-50 секунд) и списывает ещё 100 добавляя месяц (тут опять же уровень изолированности транзакций описанный ниже).
- Ситуация race condition. w1 (не lazy) создаёт (и исполняет делая блок) селект фор апдейт. На 0 секунд есть блок есть селект есть списывания и добавления. Есть w2 (неизвестный) который уже не может взять и исполнить чего-то списывая 100$ (и по идее должен ожидать выполнения w1, после чего возможны различные ситуации в зависимости от уровня изолированности транзакций БД если брать ПГ в частности).
В любом из двух случаях проблема в w2 что это такое, что оно делает и почему оно списывает. То есть для того чтоб не получить отрицательный баланс при одновременном обращении и недостатке средств вопросов нет. Вопрос как раз в том, из-за чего происходит второе списание.
По куску кода автора сложно понять что там происходит и что он вообще лочит.
Может это не таблица с фактическими суммами, а список JOBов для какого-то обработчика который по крону стартует раз в минуту. Если так, то при запуске нового старый инстанс ещё может не завершиться и он этот же джоб два раза обработает. Или ещё что, гадать не охота.
Именно поэтому я и попросил пояснить немного, почему получалось двойное обновление, т.к. всё что описано автором совсем не объясняет двойное списание. Или для кого-то из гуру данной вещи очевидно и он может описать то, что "очевидно" из приведённого кода. На мой дилетантский jango взгляд и объяснениям рядом я понял, что списание происходит не сразу а "чуть позже" и это ну никак с т.з. логики не влияет на то что "если позже, то надо делать 2 раза".
Есть вероятность, что автор даже не стал искать этот самый w2, так как предложенного решения достаточно, что бы устранить проблему клиента.
У меня тоже сложилось впечатление (по другим местам), что автор предпочитает подорожником и изолентой лечить всё, но думал что я тут что-то недопредставляю.
У нас есть подписки (Subscription) и платежи (SubscriptionPayment) с ForeignKey к подписке.
Есть функция для продления подписки. Пусть она вызывается параллельно из 2 потоков.
Первый поток:
Находит Subscription, которую пора продлевать
Ищет, был ли SubscriptionPayment, скажем, за последние 3 дня - не находит - значит, пора списывать
Триггерит внешний API для списания денег клиента
Параллельно второй поток:
Находит Subscription, которую пора продлевать
Ищет, был ли SubscriptionPayment, скажем, за последние 3 дня - не находит - значит, пора списывать
Триггерит внешний API для списания денег клиента
Первый поток:
4. Если внешний API отработал без ошибок, то создаёт SubscriptionPayment
Второй поток:
4. Если внешний API отработал без ошибок, то создаёт SubscriptionPayment
SELECT_FOR_UPDATE
делает так, что на первом шаге один из потоков получает блокировку на Subscription, и второй поток ждёт, пока первый поток не разлочит Subscription в конце транзакции (т.е. уже после создания SubscriptionPayment). Когда второй поток переходит к шагу 2, он уже находит существующий платёж.
Если я где-то туплю - дайте знать. Я могу.
Возможно у меня профессиональная деформация, так как я постоянно имею дело с фин. транзакциями, и имею большой опыт с ленивыми транзакциями и Django-ой, но проблема здесь для меня была очевидна сразу...
Так как база — это собственно источник информации о состоянии — и он должен быть единственным, то идея правильная, но есть нюанс... В вашем способе факт блокировки записи и является промежуточным "состоянием" процесса платежа.
Это нехорошо: блокировка у вас долгая, и все это время держит базу данных "привязанной" к конкретному процессу — в результате все равно ненадежно. Поэтому в платежах обычно делают два шага: создают (быстро-быстро) намерение, а потом либо его завершают платежом либо фейлят (т. е. неудачный платеж). Так база оказывается более эффективной.
Ну а искать тогда можно не платеж, а намерение (его конечно тоже через select for update надо делать, но это микросекунды).
Да, задержка между 1 шагом и завершение триггера списания, громадная. Если система высоконагружена боюсь всё колом в очередях встанет.
А можно к Вам вопрос как к человеку с постоянными фин. транзакциями — насколько часто режим транзакций баз отличен от "по умолчанию" хотя бы до repeatable read (и аналогов) и serialazable (и аналогов)?
Я обращаю внимание на различия в типах самих транзакций — либо это рандомные транзакции или идет event stream. Плюс насколько часто меняются значения.
В моей ЛИЧНОЙ практике необходимость читать много раз запись неизменной не попадалась. Изменения баланса я делаю обычно атомарной транзакцией: считал значение, записал изменение — за один вызов. Чтобы использовать более высокие уровни изоляции... даже не знаю — это скорее для подведения балансов может быть нужно, когда важно чтобы разные концы базы данных не менялись в течение процесса. Но я бы делал это просто на реплике, либо на снапшоте базы данных. Это надежнее и базу не грузит.
Пишут, что полезно, когда нужно выбирать на какой счет из списка счетов блокировку средств ставить, для меня — теория. Лично не сталкивался.
Интересно. Спасибо. По вовлеченных людей - в точку. Я вообще понял, что для каждого дела есть коридор мотивации. Выше, ниже - плохо и неэффективно.
Иногда я нахожу баги в коде, даже когда я уже не работаю. Как-то я отдыхал и вдруг вспомнил, что инициализировал список как [set()] * 10
вместо [set() for _ in range(10)]
. Проверил - так оно и есть! Красивый баг, пойманный в уме. (с)
Объясните в чем баг?
Результат ведь один и тот же.
items = [set()]*10
items
# [set(), set(), set(), set(), set(), set(), set(), set(), set(), set()]
items[1].add(12345)
items
# [{12345},{12345},{12345},{12345},{12345},{12345},{12345},{12345},{12345},{12345}]
items2 = [set() for _ in range(10)]
items2
# [set(), set(), set(), set(), set(), set(), set(), set(), set(), set()]
items2[1].add(12345)
items2
# [set(), {12345}, set(), set(), set(), set(), set(), set(), set(), set()]
Я точно Джун - мне потребовалось 10 минут экспериментировать с add() и даже append(), чтобы понять, какой код вы хотели, и почему первый вариант не подходит)))
Указатели наносят ответный удар!
(Для читателей: в первом случае создался один объект, а в массив загнали всего лишь 10 указателей на него; во втором случае каждый раз создавался новый объект, как, собственно, аффтар и планировал с самого начала).
Детская ошибка всех тех, кто не заморачивается пониманием того, что есть объект и что есть указатель на объект. В наше время это было то, с чего обучение, собственно, начиналось.
Мать моя!!!!!
Спасибо, наглядно.
Очень интересно читать, пишите ещё))
Вот за что люблю Хабр, читаю очень давно, но эта статься заставила таки завести аккаунт, потому что это самое лучшее, что я видел здесь. Подача просто классная, эта ирония и все все, подпишусь под каждым словом. Я и сам тот еще погромист(за этот каламбур отдельное спасибо) и многое до боли знакомо и по неволе читаешь и улыбаешься. И вот за эту улыбку автору огромное человеческое спасибо!
Я вот раньше тоже как-то переживал за проекты, (а потом мне прострелили колено), а потом пришло осознание, что никакой код не вечен.
Все мы знаем про жизненные циклы ПО, и самое важное в них — это то, что рано или поздно любой код будет удален.
Хотелось бы дополнить автора, что конечно стоит писать как можно лучший код, оптимальный, элегантный...но когда уже написано 100 костылей, то написать 101 костыль действительно мудрое решение. (◕ᴗ◕)
Я примерно одного возраста и опыта с автором, закончил тот же факультет. Но видимо совсем другого поля ягода. Я системный программист, пишу на C/C++ (а на горизонте маячит великолепный Rust) всякие драйвера, ОС и прошивки. Я всегда работал в компаниях и предпочитаю офис. У меня никогда не возникало желание все бросить и пойти торговать помидорами, а из отпуска я возвращаюсь с восторженным чувством "ура! Кодить!". Отдыхаю я путешествиями или дачами, но и пет-проекты конечно тоже есть, но они материальны и приносят вполне ощутимую пользу мне самому. В общем программисты бывают разные)
>ВМК МГУ
У Столярова?)
Зарегистрировался на Хабре только для того, чтобы сказать спасибо автору за статью. Для меня, начинающего человека в этом деле этот пост оказался максимально полезным. Не могу сказать, чем именно, но это то самое чувство, когда польза есть, хоть и не в состоянии её чётко сформулировать. Очень мотивирует и объясняет суть программиста. Спасибо вам большое.
Быстрая упаковка знаний в голову - это, несомненно, здорово, но я боюсь, что курсы не упакуют главное: любовь к программированию.
В этом вы, безусловно, правы, но судя по вашему предыдущему безобразному поведению, у меня складывается ощущение, что вас в детстве ментор онлайн-курсов покусал.
Спасибо автору за статью! Прям смакуешь от текстов вместе с ним ??
Что для меня значит быть программистом