Pull to refresh

Comments 63

UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
да ладно, полно статических языков где gc прекрасно работает

Статья применима не только к JS программистам, все поднятые проблемы актуальны и в других отраслях программирования:


  • знание языка против знания библиотек
  • алгоритмы
  • здоровый образ жизни

9-я ошибка — это писать на чистом JS в 2019-м году, когда можно потратить час на настройку и начать писать на TypeScript. (Несогласным — попробуйте, и, клянусь, через неделю вы будете поражаться, почему не сделали это раньше.)

Начинал, но преимуществ не почувствовал.
А вы от джейквери откажитесь.
Давно уже на jQuery ничего не делал, только тестовые странички.
Хотя хорошая библиотека была, одни массовые операции над элементами чего стоят.
Преимущество TypeScript начинает ощущаться пропорционально росту сложности проекта
Это просто пустые слова, по факту разницы не вижу, сложный проект или нет, кроме дополнительный autosuggest в IDE реальной пользы(с учетом оверхеда по времени и гемороя) Typescript не дает.
а статический анализ? он ещё на этапе написания кода позволяет выявить и избежать кучи ошибок. ну, и видимо вы никогда не пробовали рефакторить большие проекты, без TS даже переименование одного свойства это боль
Кучи ошибок? я с 2015 года вообще ни разу не работал с теми кто может в момент написания кода нагенерировать кучи ошибок, даже если ошибки появляются, их тут же видит разработчик, а если этого сразу не заметил, то непременно это заметят остальные разработчики или тестировщики и это за 2 секунды пофиксится. Как ни крути выйгрыш временной без TS значительный.
По поводу рефакторить, если есть тенденция рефакторить по крупному, то это уже проблемы адские в архитектуре и таких рефакторингов будет много, опять же тут дело чисто в кривых ручках, а вообще я рефакторил дофига проектов раных рамерах, никаких проблем небыло, как бы опять же есть IDE, есть ты сам, который элементарно делает несколько кликов по проекту, есть тестировщики, есть другие разрабы… А TS все равно от косяков не спасет, только от банальных, которые сразу же видно в консоле и так. У меня было 2 крупных проекта на TS и того: профита 0, оверхед по временным затратам ощутимый, неоправданная головная боль и вынужденные костыли с типами для всех компонентов которые претендуют хоть на какую-то универсальность… Это самые явные пункты, после этого сдраво подумав головой, взвесив все за и против невольно приходишь к выводу, а нахрена оно вообще надо? На бэкенде это полезно и удобно, спору нет, сам писал бэки на ноде с TS, тут без нареканий, а вот на фронте… это мазахизм. Связка Devepors + QA и все, максимально возможная скорость и качество, а если вместо QA писать авто тесты, то это опять же идиотизм ничем не обоснованый в реальной жизни и программист становится тестировщиком ручным в том числе, потому что только ручное тестирование выявляет 99% багов и 1% выявят автотесты и то, потому что ты ещё просто не успел открыть страничку на которой есть этот баг.
ни разу не работал с теми кто может в момент написания кода нагенерировать кучи ошибок

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

тестирование выявляет 99% багов и 1% выявят автотесты

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

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

и юнит тесты значит тоже пустая трата времени, всё ясно

А какие есть настоящие аргументы в пользу unit тестов против тестировщиков на проекте?
в пользу unit тестов против тестировщиков на проекте

Э… что? С каких пор они «против»? Только вместе.
Уже давно против, сейчас тестировщик на проекте это редкость

Если уж и заменять труд тестировщика машинами, то это будут интеграционные тесты. Unit — они про другое

сейчас тестировщик на проекте это редкость

Может вам просто с проектами не очень везет?
Нет, это просто ситуация на рынке, с каждым годом встретить QA это редкость, из-за статей которые говорят что unit тесты и прочие автотесты это огонь, и люди это видят, которые вообще не шарят(менеджеры и т.п.) и у них сразу складывается идеальная картинка — тестировщикам платить не надо, шикардос, программисты и так сами все будут тестировать да ещё и быстрее и качественее, шикардос, более того, мы ещё читали что TS тема, шикардос, будет у нас все максимально быстро писаться и без багов, а потом волосы на голове рвут и банкротятся потому что, миллион багов оказывается, а по скорости разработки так это вообще труба, сделано только 30% от запланированного, и дальше все вытекающие. Либо должна быть оценка JS + QA x 3, тогда по срокам можно будет попасть более менее с TS + Unit тесты, но проблема того, что будет тонна багов и из-за этого сырой продукт так и останется, потому что настоящего тестировщика/ов на проекте нет.
я с 2015 года вообще ни разу не работал с теми кто может в момент написания кода нагенерировать кучи ошибок, даже если ошибки появляются, их тут же видит разработчик

У вас искаженное восприятие о своих коллегах, и о себе в том числе.
За прошедшие полгода я провел свыше 160 технических интервью, из которых взял каждого 4-го и лишь единицы отправили на первое ревью код, который не ломал обратной совместимости или не вызывал ошибок.
Если вы не видите своих ошибок — это не значит, что их нет.

А какие есть настоящие аргументы в пользу unit тестов против тестировщиков на проекте?

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

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

Начните писать тесты, чтобы было наоборот.

У меня было 2 крупных проекта на TS и того: профита 0, оверхед по временным затратам ощутимый, неоправданная головная боль и вынужденные костыли с типами для всех компонентов которые претендуют хоть на какую-то универсальность…

Если вы не справились с описанием типов для собственных же интерфейсов, то сложно представить, что вы там написали.
Я может быть открою для вас тайну, но тестирование фронта это не «жду 4, 2+2 вернуло 4, ура всё работает», на фронте юзкейсы растут с каждой строчкой кода в геометрической прогрессии, и по мимо функционала, там ещё тестируется верстка в разных браузерах, если вы будет по настоящему тестировать код, а не так, как это делают все и считают себя покрывателями кода тестами, то вы не будете писать фичи и фиксить баги, а будете только тесты писать. А ещё самое клевое, когда меняется бизнес логика и надо кучу тестов переписывать по новой, уххх сколько времени выброшено в мусор… А всего лишь, нужен хотя бы 1 тестировщик, а лучше несколько, и вот тогда будет по настоящему качество и скорость разработки и продукт будет выпускаться в срок, а не будет всю жизнь сырым, потому что «блин, ну мы не знали, у нас же все тесты прошли». Но конечно если заказчику пофигу что TS + Unit тесты замедляют работу над проектов в 3 раза, по сравнению с JS + QA, то на здоровье. Как известно самый худший тестировщик — это программист.
Если проект состоит из сайтика с двумя скриптиками, то может, без юнит-тестирования и можно обойтись.
Но у нас, например, если бы не было юнит-тестов, тестировщикам пришлось бы тратить три недели вместо одной на проверку каждой минорной версии.
Тестировщики должны юзеркейсы проверять, и случаи когда 2+2 не вернуло 4 — до них просто не должны доходить: они вообще не должны попадать в коммит (и не попадают).
Как известно самый худший тестировщик — это программист.

Кто Вам сказал такую ерунду?
Как бы в нормальных командах флоу такой: тестировщики тестируют только закрытые разабами баги и только новые фичи, в процессе естественно будут находится ещё баги, потом все это заливается на стейджинг, и только тогда уже происходит полный регрес и чисто стабилизация(фикс багов, без новых фичей), и уже после этого, когда все полностью протестировано и работает стабильно можно выкатываться на прод. Юнит тесты от полных регресов на стейджинге не освобождают это раз, юнит тесты от проверок тестировщиками всех багов и фичей не освобождают это два, если у вас есть проблемы, что разрабы сразу же не видят и/или не думают что их изменения что-то сломали и/или потенциально сломают, то у меня для вас плохие новости это три и архитектура вашего проекта в таком случае архитектурой называться и не может. Отсюда вывод, зачем тратить время на Unit тесты проверяя 2+2, если разрабы и так сами за собой проверяют и когда в любом случае тестировщики за ними перепроверяют? Полагаться на Unit тесты и думать, раз они прошли, то всё в порядке это же просто смешно, я надеюсь вы это понимаете?
Полагаться на Unit тесты и думать, раз они прошли, то всё в порядке это же просто смешно, я надеюсь вы это понимаете?


Разумеется. Я вообще не понимаю, с чем Вы спорите. Юнит-тесты это самое первичное тестирование, которое происходит при каждой сборке дев-версии системы и автоматически пинает разраба «чувак, ты накосячил, давай исправляй». И только если система нормально собирается и юнит-тесты не падают — её не стыдно показать тестировщику для тестирования закрытого бага или новой фичи.
Но конечно если заказчику пофигу что TS + Unit тесты замедляют работу над проектов в 3 раза, по сравнению с JS + QA

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

По поводу автокомплита да, это удобно, но не настолько, учитывая то, какие манипуляции ты должен делать чтобы этого автокомплита достичь. Это не TS подстраивается под тебя и под твой проект, а ты вынужден прогибаться и подстраиваться под TS. Замедляет когда ты описываешь типы, замедляет когда ты пытаешься пропихнуть что-то в компонент который принимает другой тип(вопрос универсальности) и тут уже либо ты убиваешь смысл TS и кастуешь as any или as другой тип, либо в том компоненте добавляешь | anouter interface и тут тоже спорное решение с точки зреня строгой типизации, или чтобы не нарушать ни одного «правильного» канона ты создаешь ещё один компонент который по сути клонирует функционал другого и убиваешь DRY. Мораль такова, каждое нажатие на клавишу занимает время, чем больше мы жмакаем на клавишы, думаем о 100% совподении типов, когда используем язык с димамической типизацией, а не строгой, тем больше мы утомляемся. Вообщем увы, если бы оверхеда по времени не было и не надо было бы постоянно идти на какие-то компромисы, то претензий к TS именно на рфонте у меня был не было. На бэке, я только за TS, вот так это реально нужно, а на фронте ну хз хз.
P.S. если тот, кто топит за TS хоть в каком-то месте использует any или as any, то грошь цена этому топильщику. Это автоматически сводит все типизацию в ноль.
По поводу автокомплита да, это удобно, но не настолько, учитывая то, какие манипуляции ты должен делать чтобы этого автокомплита достичь.

Какие?


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

Эм, каким образом? У вас же что с ТС, что без ТС, все ф-и имеют свои типы. ТС просто позволяет вам этот тип записать, ну как в документации. Только эта документация компактна, заведомо актуальна, проверяется компилятором и предоставляет доп. возможности тулинга.


Замедляет когда ты описываешь типы

Чем именно замедляет-то? Написание кода при программировании не является ограничителем скорости. С-но, то, что приходится писать на ~5-10% больше кода само по себе замедлить никак не может.


ты пытаешься пропихнуть что-то в компонент который принимает другой тип

Так это же ошибка, если вы в компонент суете то, чего туда совать не надо. ТС не дает вам написать некорректный код. Сэкономите время на дебаге этой ошибки. Что тут не так?


или чтобы не нарушать ни одного «правильного» канона ты создаешь ещё один компонент который по сути клонирует функционал другого и убиваешь DRY

Вот уже 4 год использую ТС и ни разу не встречался с таким. Можно пример?


думаем о 100% совподении типов, когда используем язык с димамической типизацией

Так со статической типизацией мы как раз о совпадении типов не думаем — за нас думает компилятор. А вот когда типизация динамическая — тут самый настоящий bondage and discipline, как раз ндао постоянно помнить о типах, держать их все в уме, постоянно перепроверять, в уме производить тайпчек и т.д…
Многие вещи на динамических ЯП вообще просто нельзя писать, т.к. слишком error prone. Куча ограничений, короче.


Это автоматически сводит все типизацию в ноль.

Каким образом-то? Тот факт что у вас, например, 5% кода не типизированы ничуть не мешает тому, что остальные 95% типизированы. И всем плюсам от типизированности этих 95% тоже не мешает.

Вопрос такой, зачем вам вообще JS? Он вообще не про типизацию
Ну так он и не про «не-типизацию». Он про платформу и про асинхронную парадигму.
На нем пишут не потому что 1 == '1', а вопреки этому.
Если бы 1 != '1', то он был бы изначально усложнен для простых задач, для которых он создан(если мы говорим только о клиентской стороне), прикол в том, что люди сами себе придумывают проблемы и усложняют жизнь, когда одни и те же вещи можно было бы решить значительно проще и быстрее и речь тут не о быстрых костылях, а о правильной архитектуре проекта для тех или иных задач, когда у тебя грамотная архитектура, то тебе не нужен TS, но по факту у подавляющего большенства почему-то проблемы с выстраивание архитектур и тут уже принимаются отчаяные меры чтобы немного сгладить эти фундаментальные косяки и просчеты в виде TS, кучей unit-тестов и т.п. Потому что проект настолько не структурирован и его поведение непредсказуемо из-за кривых ручек, что никто в команде не уверен, на что повлияет та или иная строка в коде. TS и unit тесты это просто попытка лечения симптомов, а не лечение болезни как таковой. У меня сейчас огромный и сложный проект, но грамотно спроектированный и структурированный изначально,
в него вливаются новые разработчики и в первый же день и начинают фиксить баги и делать новые фичи и мне даже вопросов не задают, а что да как и почему, потому что там и так все понятно, очевидно и предсказуемо написано и я за этим слежу в мердж реквестах, чтобы все так и писали понятно и очевидно. И без TS и unit тестов все прекрасно разрабатывается и поддерживается, причем с высокой скоростью. P.S. последние 4 месяца нас 7 разрабов на этом проекте (это чисто на фронте) и никто ни разу ничего не сломал случайно и не жаловался что боится что-то сломать.
Да, если на проекте сумасшедшая текучка, квалификация людей мутная, архитектура шаткая, то немного поможет TS и unit тесты, но это уже чисто от безисходности.
Вопрос такой, зачем вам вообще JS? Он вообще не про типизацию

Так мы не про js, а про ts. ts про типизацию :)


Если бы 1 != '1', то он был бы изначально усложнен для простых задач,

Только вот уже давно запрет на использование нестрогих сравнений во всех гайдлайнах по js'у :)


когда у тебя грамотная архитектура, то тебе не нужен TS

Вы как-то сравниваете теплое с мягким. Каким образом грамотная архитектура поможет решить проблемы, которые решает TS? Это совершенно ортогональные вещи. И как раз TS скорее поможет грамотной архитектуре, т.к. можно будет архитектурные инварианты фиксировать автоматически, типами (то, что в случае js вам приходится фиксировать административными мерами).


И без TS и unit тестов все прекрасно разрабатывается и поддерживается, причем с высокой скоростью.

Ну а с ними было бы с еще большей скоростью :)

JS очень даже про типизацию, там есть оператор typeof и несколько базовых типов. Только вот проверки проходят в рантайме, и вызывают ошибки "Cannot get property foo of undefined"


Отличие TS лишь в том, что он переносит эти проверки на этап компиляции, не более того.


Больше об этом написано здесь в треде: https://dev.to/stereobooster/comment/df11

спасибо, посмотрим
Если архитектура проекта грамотная, то вообще пофигу есть TS или нету, проект будет масштабироваться до бесконечности четко, а от кривых ручек извините, ничего не спасает.
Typescript не сильно отличается от последних стандартов ECMAScript. Я бы скорее предпочел kotlin или dart для трансляции в js
TypeScript это и есть JS, только с типизацией, с чего вдруг он должен отличаться?

Например, какие проекты не слишком большие и сложные, чтобы их записать в портфолио? А какие уже слишком сложные?

UFO just landed and posted this here
Спорт — это про состязания.

Состязания с собой — это спорт? Скажем, бег, с целью дойти до марафона.

Физкультура мне кажется ОФП. Спорт — это скорее про достижения, а не про состязания с кем-либо.
UFO just landed and posted this here
Семья и близкие — это важно. С головой погрузившись в изучение JavaScript и недооценивая важность своей психической и эмоциональной жизни, вы рискуете погрузиться в депрессию, стать раздражительным, перестать нормально спать и много чего еще.

Передайте автору, что не надо свои личные проблемы в жизни обобщать на всех.

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

Автомобили-роботы лишают работы водителей, кассы самообслуживания лишают работы кассиров… Вы вообще не задумывались, что тестировщики — одни из самых низкоквалифицированных работников IT и существуют лишь потому, что разработчикам самостоятельно заниматься тестированием было бы намного дороже?

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

Чтобы писать, к примеру, UI тесты, код знать не нужно, а вот чтобы писать юниты, его нужно знать и иногда реыакторить. Я бы тестировщики к такому не допустил. Юниты — отнюдь не чуть. Они могут проверить за несколько миллисекунд сложную логику, которую тестировщик может проверять целый час.

Например? что такого может выявить Unit тест, чего не может выявить автотест написанный автотестировщиком?

Я не говорил, что они могут выявить что-то особенное, хотя некоторые вещи куда проще проверить с помощью юнит тестов.
Дело в том, что есть пирамида тестирования и она появилась из практики. Она обусловлена тем, что юнит-тесты легче писать, они реже ломаются и, самое главное, проходят быстрее в несколько тысяч раз, чем UI-тесты. Так получилось, что на нашем проекте за стратегию автотестирования отвечают индусы и они заставляли писать селениумы на всё. В результате, за год время прогона тестов выросло в 3 раза и теперь при изменении в коде за день все тесты уже не прогнать. В то же время, юнит-тесты прогоняются всего за 15 минут. К тому же, UI-тесты часто требуют ещё и настройки среды, в отличие от юнитов.
На эту тему на хабре есть статья https://m.habr.com/ru/post/358950/. Сам прочитал по диагонали, но, вроде, неплохая.

за что же вам всем так не нравится jQuery? донельзя оптимизированная библиотека экономящая кучу времени при разработке. И я говорю даже не о встроенных возможностях поиска элементов или ajax и все вот это. А то что есть куча библиотек, зависящих от jQuery, которые делают твою жизнь сильно проще.
Отказ от unit тестирования, ИМХО было бы лучше если бы люди говоря о unit тестировании, поделились какими то своими болями настоящими, ну вот было так, затестировать забыли, или вообще без тестирования писали, потом случилось вот такое, и все упало.
Да я понимаю всевозрастающую необходимость в тестировании, потому что сейчас микросервисы, приложения пишут со встроенными серверами, ну например там NodeJS, пишем приложение, запускаем, вот нам и сервер. Или там на Python + Flask написали приложение, подняли, тоже отвечает на запросы и что-то делает. И в этом случае если приложение упадет с ошибкой, да, весь сервер перестанет работать. Но почему люди отходят от модели с тем же nginx+php-fpm где если что-то будет вылетать, будет вылетать только в конкретном месте и для конкретного пользователя никак не влияя на других и в целом все будет продолжать работать?!?!?

с остальными пунктами с автором согласен.
ИМХО было бы лучше если бы люди говоря о unit тестировании, поделились какими то своими болями настоящими, ну вот было так, затестировать забыли, или вообще без тестирования писали, потом случилось вот такое, и все упало

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

Но почему люди отходят от модели с тем же nginx+php-fpm где если что-то будет вылетать, будет вылетать только в конкретном месте и для конкретного пользователя никак не влияя на других и в целом все будет продолжать работать?!?!?

Кто вам сказал что «люди от этого отходят»? Наоборот в последнее время всякие балансировщики, прокси и прочие cloudflare набирают обороты. nginx точно так же используется с node/python. К тому же есть всякие докеры и кубернетисы. Да много всего…
Юнит тесты обычно пишутся для того, чтобы при внесении изменений в код, не сломать уже существующий.

ааа, ну вот реально действительно хороший кейс. Такое было да.
Я просто думал, ну пишешь ты код, ты все предусмотрел, все работает, зачем тесты то? Все же работает.
Т.е. получается мы пишем рабочий код, покрываем его тестами его текущего состояния, потом меняем что-то, и пропускаем уже через эти тесты чтобы понять что то что нам нужно было в предыдущем состоянии и то что еще нужно работало. Спасибо большое. Это действительно может быть полезным. Век живи, век учись.
Кто вам сказал что «люди от этого отходят»? Наоборот в последнее время всякие балансировщики, прокси и прочие cloudflare набирают обороты. nginx точно так же используется с node/python. К тому же есть всякие докеры и кубернетисы. Да много всего…

да, я просто наверное немного не то имел в виду. Вот nginx+php-fpm как работает, запрос, родился поток, отработал умер, не влияет на другие потоки, т.е. упал с ошибкой, рядом запрос с другими параметрами нормально продолжает работать.
А в модели когда ты пишешь например приложение на node или python+flask и запускаешь его. И если у тебя что-то случится и программа упадет, упадут все запросы, которые параллельно обрабатывались с тем, который привел к фатальной ошибке.
Да, можно запустить какой нибудь наверное монитор, который бы следил, чтобы процесс был всегда запущенным и будет перезапускать его. И вот для таких приложений я хотел сказать что нужно писать тесты и тестировать до продакшена.
Т.е. получается мы пишем рабочий код, покрываем его тестами его текущего состояния, потом меняем что-то, и пропускаем уже через эти тесты

Ну это только основная, «практическая» причина написания юнит тестов.
Еще их можно использовать как документацию/спецификацию (ТДД и т.п.), ну и плюс просто как доказательство работы кода (например на ревью)

А в модели когда ты пишешь например приложение на node или python+flask и запускаешь его. И если у тебя что-то случится и программа упадет, упадут все запросы, которые параллельно обрабатывались с тем, который привел к фатальной ошибке.

Это не так, Flask работает через wsgi, что по сути то же самое что php-fpm. На ноде вообще другая модель, там и так все запросы асинхронно обрабатываются через event loop, и если что-то в отдельном запросе упадет — это вам не уронит главный процесс. К тому же и python и node сервера обычно так же ставятся за nginx/apache proxy-pass.
Ну это только основная, «практическая» причина написания юнит тестов.

да уж, сколько открытий чудных ) спасибо.
Это не так, Flask работает через wsgi, что по сути то же самое что php-fpm. На ноде вообще другая модель, там и так все запросы асинхронно обрабатываются через event loop, и если что-то в отдельном запросе упадет — это вам не уронит главный процесс. К тому же и python и node сервера обычно так же ставятся за nginx/apache proxy-pass.

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

Смешно
«Быть JavaScript-разработчиком круто, поскольку на рынке труда постоянно растет нужда в хороших JS-программистах.» пойду пройду какие-нить курсы с гарантированным трудоустройством…
Sign up to leave a comment.