работа программист python с обучением

Говорят, выучить Python и стать программистом легко. Правда?

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

Мы запускаем цикл статей в которых подробно расскажем о каждой профессии через опыт людей. В первом выпуске обсуждаем Python-разработчиков. Свои истории рассказали Артем Сухаренко и Данила Лобанов. Они пришли в профессию совсем недавно, но успели набраться опыта в других сферах. А экспертом выступил Алексей Петренко — декан факультета Python в Geekbrains.

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

Для чего учить Python

Артем Сухаренко учился в СибГИУ на кафедре автоматики и информатики. Его специальность была инженерной, но не связанной с программированием. После выпуска Артем устроился работать на завод ЗСМК — один из самых крупных металлургических комбинатов в России.

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

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

«Может быть, я не туда совался, но развития для себя не нашел. Пять лет вуза — просто чтобы крутить провода. Это было так обидно».

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

В 36 лет Артем пошел на курсы Python-разработчика.

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

«Зная Пайтон можно делать много всего — от простейших скриптов до анализа данных и построения нейронных сетей. Но конкретно разработка на Пайтоне — это бэкенд для веб-серверов, разработка скрытой части интернета — той, которую не видят обычные пользователи. Сервер, его логику, взаимодействие с базами данных», говорит Алексей Петренко, декан факультета Python в Geekbrains.

«Думаю, это хороший выбор в качестве первого языка. У него простой синтаксис. Он прощает мелкие ошибки разработчика. У Пайтона низкий порог вхождения, на нем очень легко освоить азы программирования. У него очень большая аудитория и обширная библиотека, плюс много внешних библиотек, которые делают разработчики со всего мира. За счет этого он становится языком, который подойдет для чего угодно».

«Хоть Python и пропагандируется как язык для всего, по факту у него только две сферы применения: всякие data science, ML и прочая математика — и веб-разработка. В этом он меня немного разочаровал», — говорит Данила Лобанов, бывший сисадмин, который недавно стал Python-разработчиком.

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

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

«Я попытался изучать С, PHP, Java еще какие-то языки, но не заходило — начинал и бросал. Не мог писать даже простейшие скрипты. Когда я ходил на курсы по С, у меня получалось читать код, но не получалось его писать. Мне давали задачу, я смотрел на нее и не представлял, как делать. Преподаватель садился рядом, писал построчно, объяснял, и я понимал, что именно так и надо было делать. Но мне давали аналогичную задачу, и я снова был в ступоре».

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

«Новичку лучше первым делом разобраться в синтаксисе», — считает Алексей Петренко, — «Только потом стоит думать, куда хочется идти дальше. Чем больше ты учишься, тем больше уходишь от синтаксиса к библиотекам, паттернам проектирования, отдельным шаблонам».

Данила все-таки выбрал Python потому, что язык считался легким. «Синтаксис реально оказался простым», — говорит он, — «Как писать текст на английском языке. Сначала я изучал его самостоятельно по видеоматериалам на Ютубе, по статьям, решал задачи на pythontutor.ru. Но потом понял, что ресурсы в интернете — это только основы и азы. Они доступны всем и везде, и не помогут научиться программированию основательно. Я понял, что надо искать курсы, которые дадут все то же самое, только систематизировано, а потом поведут меня дальше».

Что надо знать перед началом обучения

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

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

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

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

Артем продолжал работать электриком днем, а вечерами начал учиться на курсах, несмотря на усталость. «Как и у всех наивных людей, у меня было ожидание магии от курсов. Я пришел не совсем нулевым. В багаже было несколько книг и даже простых сайтиков, в том числе на PHP (грешен, признаю). Я ждал, что на курсах надмозги меня выдрессируют, и я стану волшебником. Реалии оказались другими — там такие же люди, которые просто знают чуть больше».

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

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

«Все признавали, в том числе сотрудники Geekbrains, что уровни 2 и 3 в программе по Python были одними из самых сложных курсов в университете. Очень много информации в слишком сжатые сроки, очень большие домашние задания. Многие усваивали только часть материала. Я лично два раза переводился в следующий поток. Мы просили облегчить программу, нас спрашивали как, и я предлагал разбить два курса на три. Что-то из этого приняли во внимание и сейчас реализовали».

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

«Преподавать программирование тоже очень сложно. Всем кажется, что раз человек может писать программы, значит может и научить. Это не так. Когда мышление перестроено, и знаешь много всего — уже не можешь вспомнить, каково это — не понимать».

Алексей предупреждает, что Python легкий только в начале. А после легкой базы придется приложить усилия, чтобы освоить более серьезные аспекты — библиотеки и фреймворки. «Если сравнить язык программирования с водоемом, то, например, язык С — это океан. Ты ныряешь с обрыва на огромную глубину, и либо плывешь, либо тонешь. Язык Пайтон — это пляж с чистым песком, где ты можешь далеко зайти, спокойно поплавать, и если понял, что хочешь двигаться дальше — то за красивым пляжем есть огромная впадина, по глубине сопоставимая с С и Java».

«Асинхронное программирование в Python — это мозгодробительная штука», вспоминает Артем. «Мы проходили это как-то поверхностно, и потом даже на собеседованиях, когда по нему спрашивали, я чувствовал, что плыл.

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

Данила же вспоминает модуль select как самое трудное: «Все три потока помнят мою боль с селектами. Есть такой модуль, и он мне прямо очень не давался в свое время. Сейчас-то он для меня простой — я теперь не понимаю, как его можно не понять».

«В базовой конфигурации Python лежит около 70 функций и несколько десятков зарезервированных слов, но даже крутой программист не обязательно использует их все. То есть, чтобы выучить сотню слов и понять, что они делают, можно потратить одну-три недели при желании и активной работе», говорит Алексей.

Читайте также:  Stinger или stels что лучше

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

Чтобы в будущем работать в команде и показывать код кому-то еще, надо знать общепринятые стандарты стиля. В Python они называются «Пепы» (Peps). Я бы советовал читать Pep8 параллельно с изучением синтаксиса. Это соглашение программистов, которые пишут на Пайтоне. Оно рекомендует как правильно писать, а как неправильно.

Несколько лет назад в Python произошло разделение. Был Python 2.7, а потом вышла версия 3. Вторая версия все еще используется, но только в старых фирмах для поддержания легаси-кода. Если устроиться в такую фирму, то изучать Python 2 придется, но я бы рекомендовал учить третью версию. Все современные проекты и сторонние библиотеки пишутся под нее».

Как выдержать первые собеседования

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

«Проект назвался GoLiving. Это что-то вроде AirBnb, только задумка такая: в Америке есть люди, которые часто ездят работать в разные города на непродолжительный период. И они могут между собой меняться жильем с гарантированной страховкой, чтобы точно быть уверенным, что не вернешься в разгромленную квартиру. Сейчас я не знаю, насколько далеко пошел этот ресурс, кажется финансирование приостановили. Но тогда у нас даже были инвесторы».

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

«Под новый год я написал в компанию, которая просто находилась рядом с моим домом. Зашел к ним на сайт, увидел вакансию бэкенд-разработчика и написал им письмо. Говорю, хотел бы у вас поработать, хоть и учился, но знаю немного. Очень интересуюсь и буду развиваться. И меня позвали на собеседование».

«Мой опыт в Geekbrains показывает, что некоторые студенты находят работу, до того как они заканчивают годовой курс обучения», говорит Алексей. «Работодатель хочет видеть у серверного разработчика элементарное умение работать с синтаксисом, знание как работают сайты, как устроен бэкенд, тот же самый набирающий популярность Django. Я бы сюда ещё добавил работу в команде и знания баз данных, потому что любой бэкенд любого сайта неразрывно связан с хранением информации.

Ежемесячно на «Моём круге» открывается порядка 200 вакансий python-разработчиков, вы можете посмотреть самые свежие и подписаться на рассылку о новых вакансиях.

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

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

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

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

«Я считаю, не спрашивать технические вещи — это правильный подход», говорит Данила. «Очень известный в Python-сообществе Григорий Петров тоже говорит, что скилы по программированию (хард скилы) подтянуть всегда можно. Главное сойтись во взглядах на жизнь, чтобы было комфортно вместе работать. Я с ним согласен.

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

«Собеседование, которое проходил я, расплавило мне мозг еще как», вспоминает Артем. «Когда я вышел, состояние было, как будто иду на автопилоте — так сильно продолжали жужжать мысли».

Проходило оно так: сидели два эйчара и два технаря. Один питонист и фулстек, который занимался вебом — куда пробовался и я. Второй — судя по вопросам — совершенный надмозг. У него такой был сильный матан, что просто ого-го!

Сначала пошли житейские вопросы, все эти «как себя видишь, как себя чувствуешь». Потом за меня принялся фулстек, погонял меня по Python, по Django. Он прямо на бумаге накидывал примеры и спрашивал по ним. Не сложные, но с подковырками.

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

Честно, даже не ожидал, что мне перезвонят. Тем не менее — получил оффер. Через несколько дней будет первый рабочий день».

На какие деньги стоит рассчитывать

Люди идут в ИТ не только по зову души. Это индустрия с одними из самых быстро растущих зарплат в России. И иногда кажется, что зарплаты программистов по сравнению со среднестатистическими профессиями отличаются как зарплаты в Москве и в регионах. Тем не менее, ни Артем, ни Данила не шли в эту профессию за богатством. Больше того — они его пока так и не нашли.

«Даже в Москве на начальных позициях программистам предлагают 40-50 тысяч, может даже меньше. В регионах 20 тысяч для джуниора тоже не редкость. Это не такая уж высокооплачиваемая работа, как все утверждают. Да, когда достигаешь уровня синьора, зарплаты могут переваливать за 200-300 тысяч. Но где таких зарплат нет? Недавно одна такси-компания показала доходы таксистов, которые больше всех заработали. Там 230, 240 тысяч.

На диаграмме зарплат python-разработчиков с разбивкой по квалификациям видно, что медиана для джуна составляет почти 60 000 рублей, тогда как мидл получает уже в среднем чуть больше 100 000 рублей. Зато разница между показателями медиан для сеньора и лида совсем небольшая — 151 000 рублей и 167 000 рублей соответственно.

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

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

«Зарплаты зависят от региона», говорит Алексей, «Кто-то устроится за 40 тысяч как начинающий, кто-то может и сразу на 100 тысяч. Смотря как себя проявить. Если покажешь, что можешь писать не только код, но и разбираешься в архитектуре, можешь набросать схему проекта целиком, всех модулей, сервисов, связей между ними».

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

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

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

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

Источник

Как быстро стать программистом на Питон. Путь автотестировщика

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

Для начала несколько общих вопросов про тестирование на Python:

Что делает тестировщик?

Сколько получает тестировщик?

А есть ли куда расти?

“Вот я нихрена не умею, пойду в тестирование, хотя бы ручное, а там и дальше как-то пойдет.”

Итак, каков же путь тестировщика на Питоне.

1. Пройти базовый курс по python и полностью разобраться в каждой задаче. Мы предлагаем для начала бесплатный и общедоступный курс pythontutor.ru. Есть еще курсы с нуля:

2. Пройти продвинутые курсы по python и программному обеспечению. Вот некоторые из них:

3. Изучить технологии тестирования: юнит-тесты, функциональные тесты, регрессионное тестирование, интеграционное тестирование

4. Изучить инструменты тестирования: Selenium, Jenkins, Jmeter, SoapUI, Postman

и изучить сопутствующие технологии:

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

Эти две технологии будут использоваться в большинстве мест. Вот ещё немного:

тысячи их, гуглите и обрящете 😉

Читайте также:  закон о едином федеральном информационном регистре что это значит

Крайне желательно изучить основные алгоритмы и структуры данных:

и дополнительные возможности питона:

ВАЖНО! Вы должны уметь постоянно учиться (при этом самостоятельно), быстро находить нужную информацию и разбираться в ней. В работе это требуется постоянно. Причем это происходит не только при смене работы. Регулярно появляются новые технологии и инструменты, использовав которые, можно повысить удобство и эффективность работы. Цитата к месту:

“Ну, а здесь, знаешь ли, приходится бежать со всех ног, чтобы только остаться на том же месте, а чтобы попасть в другое место, нужно бежать вдвое быстрее.” Алиса в Зазеркалье, Льюис Кэрролл

А теперь вопрос: сколько надо работать, чтобы стать программистом на Python?

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

Это нормально, когда не получается ни с первого ни с десятого раза. Это нормально, постоянно гуглить, втуплять в документацию и дебажить снова и снова. Это нормально когда вроде это на курсе было легко, а потом тебя настигает ПРАКТИКА и начинается настоящее самообучение через страдания. Зато потом разбираешься как следует и понимаешь, что на самом деле после курса было лишь смутное представление.

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

Питон действительно более читаемый чем многие другие языки и его сравнительно легко освоить на начальном(!!) уровне. Однако сложные алгоритмы или сложные системы будет трудно писать на любом языке.

Как видите, вряд ли получится освоить python за 21 день и начать зарабатывать десятки тысяч долларов в месяц. Учиться будет очень трудно. Но поверьте, если у вас есть желание программировать и создавать, то все эти сложности преодолимы.

Программирование на python

217 постов 7.5K подписчиков

Правила сообщества

Публиковать могут пользователи с любым рейтингом. Однако!

• уважение к читателям и авторам

• простота и информативность повествования

• тег python2 или python3, если актуально

• код публиковать в виде цитаты, либо ссылкой на специализированный сайт

• допускать оскорбления и провокации

• распространять вредоносное ПО

• просить решить вашу полноценную задачу за вас

Ну наконец-то кто-то пишет правду: долго, сложно. И обучение никогда не заканчивается.

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

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

Каким счастьем Jenkins инструмент тестирования?)

плюс за степик, отличный ресурс

@embden, а не предполагается ли создать подобный roadmap для машинного обучения?

Наткнулся на этот пост. Как я стал пайтон разрабом? Ответ: совершенно случайно. (но был бэкграуд из js, java, c# и даже Assembler). Программирование, со школы, всегда было было моим, исключительно, хобби. Сейчас мне почти 30, и я джун. Если кому интересна эта история напишу пост)

А где же лига тестировщиков?

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

Вторая без первой не заведётся

Если бы программист создавал Землю

[Не]эффективный алгоритм прохождения лабиринта

Ответ на пост «Перевел интерактивные уроки «Базовый курс CSS» и «Базовый курс JavaScript»»

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

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

В планах сделать интерактивные курсы по питону.
Что из недостатков по сайту вижу сейчас:

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

— не весь функционал реализован до конца

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

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

Да прибудут с Вами знания

Перевел интерактивные уроки «Базовый курс CSS» и «Базовый курс JavaScript»

Предыдущий топик Перевел интерактивные уроки «Базовый курс HTML» оказался довольно положительно воспринят пикабушниками (на самом деле сильно положительней, чем я ожидал), и это меня довольно сильно простимулировало на скорейший перевод еще двух курсов: Базовый CSS (44 урока) и Базовый JavaScript (107 уроков). Работы оказалось сильно больше, чем я предполагал, но и ценность материала на выходе сильно больше (не только исправил множество неточностей, но и дополнил своими комментариями).

Осталось перевести курс по ECMAScript 6 и можно будет перейти к самому главному: курс по React. Планирую сделать это на следующей неделе.

Всем приятной бесплатной учебы!

Как на самом деле работает заимствование чужого кода.

Вот уже на протяжении нескольких лет Тимофей, преподаватель кафедры информатики МФТИ, выкладывает свои лекции по программированию на своём Youtube канале с открытым доступом.

Перевел интерактивные уроки «Базовый курс HTML»

Материал для новичков, кто хочет освоить HTML. Здесь есть около 30 интерактивных уроков, переведенных на русский: https://freecode.academy/learn/sections/ck4h36qjt0hoq0782jj6.

То есть это не просто теория, но и сразу выполнение заданий.

Не заметил подвоха

Разработка системы заметок с нуля. Часть 2: REST API для RESTful API Service + JWT + Swagger

Продолжаем серию материалов про создание системы заметок. В этой части мы спроектируем и разработаем RESTful API Service на Go cо Swagger и авторизацией. Будет много кода, ещё больше рефакторинга и даже немного интеграционных тестов.

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

Подробности в видео и текстовой расшифровке под ним.

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

Страницу регистрации сделаем простую, с четырьмя полями: Name, Email, Password и Repeat Password. Лейблы делать не будем, обойдемся плейсходерами. Авторизацию сделаем по юзернейму и паролю.

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

Интерфейс, который будет у нашего веб-приложения:

— Слева — список категорий любой вложенности.

— Справа — список заметок в виде карточек, который делится на два списка: прикреплённые и обычные карточки.

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

— Справа указано, сколько секунд/минут/часов/дней назад была создана заметка.

— Тело заголовка — отрендеренный Markdown.

— Панель инструментов. Через неё можно изменить цвет, прикрепить или удалить заметку.

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

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

Так будет выглядеть открытая заметка

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

Для страниц авторизации и регистрации нам нужны эндпоинты аутентификации и регистрации соответственно. В качестве аутентификации и сессий пользователя мы будем использовать JWT. Что это такое и как работает, разберём чуть позднее. Пока просто запомните эти 3 буквы.

Для страницы списка заметок нам нужны эндпоинты /api/categories для получения древовидного списка категорий и /api/notes?category_id=? для получения списка заметок текущей категории. Перемещаясь по другим категориям, мы будем отдельно запрашивать заметки для выбранной категории, а на фронтенде сделаем кэш на клиенте. В ходе работы с заметками нам нужно уметь создавать новую категорию. Это будет метод POST на URL /api/categories. Также мы будем создавать новый тег при помощи метода POST на URL /api/tags.

Чтобы обновить заметку, используем метод PATCH на URL /api/notes/:uuid с измененными полями. Делаем PATCH, а не PUT, потому что PUT требует отправки всех полей сущности по спецификации HTTP, а PATCH как раз нужен для частичного обновления. Для отображения заметки нам ещё нужен эндпоинт /api/notes/:uuid/files с методами POST и GET. Также нам нужно скачивать файл, поэтому сделаем метод GET на URL /api/files/:uuid.

Структура репозитория системы

Ещё немного общей информации. Структура репозитория всей системы будет выглядеть следующим образом:

В директории app будет исходный код сервиса (если он будет). На уровне с app будут другие директории других продуктов, которые используются с этим сервисом, например, MongoDB или ELK. Продукты, которые будут использоваться на уровне всей системы, например, Consul, будут в отдельных директориях на уровне с сервисами.

Писать будем на Go

— Идём на официальный сайт.

— Копируем ссылку до архива, скачиваем, проверяем хеш-сумму.

— Распаковываем и добавляем в переменную PATH путь до бинарников Go

— Пишем небольшой тест проверки работоспособности, собираем бинарник и запускаем.

Установка завершена, всё работает

Теперь создаём проект. Структура стандартная:

— cmd — точка входа в приложение,

— internal — внутренняя бизнес-логика приложения,

— pkg — для кода, который можно переиспользовать из проекта в проект.

Я очень люблю логировать ход работы приложения, поэтому перенесу свою обёртку над логером logrus из другого проекта. Основная функция здесь Init, которая создает логер, папку logs и в ней файл all.log со всеми логами. Кроме файла логи будут выводиться в STDOUT. Также в пакете реализована поддержка логирования в разные файлы с разным уровнем логирования, но в текущем проекте мы это использовать не будем.

Читайте также:  Что чувствует человек после чистки

APIService будет работать на сокете. Создаём роутер, затем файл с сокетом и начинаем его слушать. Также мы хотим перехватывать от системы сигналы завершения работы. Например, если кто-то пошлёт приложению сигнал SIGHUP, приложение должно корректно завершиться, закрыв все текущие соединения и сессии. Хотел перехватывать все сигналы, но линтер предупреждает, что os.Kill и SIGSTOP перехватить не получится, поэтому их удаляем из этого списка.

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

Далее создаём точку входа в приложение. В директории cmd создаём директорию main, а в ней — файл app.go. В нём мы создаём функцию main, в которой инициализируем и создаём логер. Роутер создаём через ключевое слово defer, чтобы метод Init у роутера вызвался только тогда, когда завершится функция main. Таким образом можно выполнять очистку ресурсов, закрытие контекстов и отложенный запуск методов. Запускаем, проверяем логи и сокет, всё работает.

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

Создадим для приложения контекст. Сделаем его синглтоном при помощи механизма sync.Once. Пока что в нём будет только конфиг. Контекст в виде синглтона создаю исключительно в учебных целях, впоследствии он будет выпилен. В большинстве случаев синглтоны — необходимое зло, в нашем проекте они не нужны. Далее создаём конфиг. Это будет YAML-файл, который мы будем парсить в структуру.

В роутере мы вытаскиваем из контекста конфиг и на основании listen.type либо создаем сокет, либо вешаем приложение на порт. Код graceful shutdown выделяем в отдельный пакет и передаём на вход список сигналов и список интерфейсов io.Close, которые надо закрывать. Запускаем приложение и проверяем наш эндпоинт heartbeat. Всё работает. Давайте и конфиг сделаем синглтоном через механизм sync.Once, чтобы потом безболезненно удалить контекст, который создавался в учебных целях.

Теперь переходим к API. Создаём эндпоинты, полученные при анализе прототипов интерфейса. Тут важно отметить, что у нас все данные привязаны к пользователю. На первый взгляд, все ручки должны начинаться с пользователя и его идентификатора /api/users/:uuid. Но у нас будет авторизация, иначе любой пользователь сможет программно запросить заметки любого другого пользователя. Авторизацию можно сделать следующим образом: Basic Auth, Digest Auth, JSON Web Token, сессии и OAuth2. У всех способов есть свои плюсы и минусы. Для этого проекта мы возьмём JSON Web Token.

Работа с JSON Web Token

JSON Web Token (JWT) — это JSON-объект, который определён в открытом стандарте RFC 7519. Он считается одним из безопасных способов передачи информации между двумя участниками. Для его создания необходимо определить заголовок (header) с общей информацией по токену, полезные данные (payload), такие как id пользователя, его роль и т.д., а также подписи (signature).

JWT использует преимущества подхода цифровой подписи JWS (Signature) и кодирования JWE (Encrypting). Подпись не даёт кому-то подделать токен без информации о секретном ключе, а кодирование защищает от прочтения данных третьими лицами. Давайте разберёмся, как они могут нам помочь для аутентификации и авторизации пользователя.

Аутентификация — процедура проверки подлинности. Мы проверяем, есть ли пользователь с полученной связкой логин-пароль в нашей системе.

Авторизация — предоставление пользователю прав на выполнение определённых действий, а также процесс проверки (подтверждения) данных прав при попытке выполнения этих действий.

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

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

Реализация JWT в нашем APIService:

— Создаём директории middleware и jwt, а также файл jwt.go.

— Описываем кастомные UserClaims и сам middlware.

— Получаем заголовок Authorization, оттуда берём токен.

— Берём секрет из конфига.

— Создаём верификатор HMAC.

— Парсим и проверяем токен.

— Анмаршалим полученные данные в модель UserClaims.

— Проверяем, что токен валидный на текущий момент.

При любой ошибке отдаём ответ с кодом 401 Unauthorized. Если ошибок не было, в контекст сохраняем ID пользователя в параметр user_id, чтобы во всех хендлерах его можно было получить. Теперь надо этот токен сгенерировать. Это будет делать хендлер авторизации с методом POST и эндпоинтом /api/auth. Он получает входные данные в виде полей username и password, которые мы описываем отдельной структурой user. Здесь также будет взаимодействие с UserService, нам надо там искать пользователя по полученным данным. Если такой пользователь есть, то создаём для него UserClaims, в которых указываем все нужные для нас данные. Определяем время жизни токена при помощи переменной ExpiresAt — берём текущее время и добавляем 15 секунд. Билдим токен и отдаём в виде JSON в параметре token. Клиента к UserService у нас пока нет, поэтому делаем заглушку.

Добавим в хендлер с heartbeat еще один тестовый хендлер, чтобы проверить работу аутентификации. Пишем небольшой тест. Для этого используем инструмент sketch, встроенный в IDE. Делаем POST-запрос на /api/auth, получаем токен и подставляем его в следующий запрос. Получаем ответ от эндпоинта /api/heartbeat, по истечении 5 секунд мы начнём получать ошибку с кодом 401 Unauthorized.

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

Чтобы этого избежать, прикрутим refresh-токен. Он позволит пересоздать основной токен доступа без запроса данных авторизации пользователя. Такие токены живут очень долго или вообще бессрочно. После того как только старый JWT истекает мы больше не можем обратиться к API. Тогда отправляем refresh-токен. Нам приходит новая пара токена доступа и refresh-токена.

Хранить refresh-токены на сервере мы будем в кэше. В качестве реализации возьмём FreeCache. Я использую свою обёртку над кэшем из другого проекта, которая позволяет заменить реализацию FreeCache на любую другую, так как отдает интерфейс Repository с методами, которые никак не связаны с библиотекой.

Пока рассуждал про кэш, решил зарефакторить существующий код, чтобы было удобней прокидывать объекты без dependency injection и синглтонов. Обернул хендлеры и роутер в структуры. В хендлерах сделал интерфейс с методом Register, которые регистрируют его в роутере. Все объекты теперь инициализируются в main, весь роутер переехал в мейн. Старт приложения выделили в отдельную функцию также в main-файле. Теперь, если хендлеру нужен какой-то объект, я его просто буду добавлять в конструктор структуры хендлера, а инициализировать в main. Плюс появилась возможность прокидывать всем хендлерам свой логер. Это будет удобно когда надо будет добавлять поле trace_id от Zipkin в строчку лога.

Вернемся к refresh_token. Теперь при создании токена доступа создадим refresh_token и отдадим его вместе с основным. Сделаем обработку метода PUT для эндпоинта /api/auth, а в теле запроса будем ожидать параметр refresh_token, чтобы сгенерировать новую пару токена доступа и refresh-токена. Refresh-токен мы кладём в кэш в качестве ключа. Значением будет user_id, чтобы по нему можно было запросить данные пользователя у UserService и сгенерировать новый токен доступа. Refresh-токен одноразовый, поэтому сразу после получения токена из кэша удаляем его.

Для описания нашего API будем использовать спецификацию OpenAPI 3.0 и Swagger — YAML-файл, который описывает все схемы данных и все эндпоинты. По нему очень легко ориентироваться, у него приятный интерфейс. Но описывать вручную всё очень муторно, поэтому лучше генерировать его кодом.

— Создаём эндпоинты /api/auth с методами POST и PUT для получения токена по юзернейму и паролю и по Refresh-токену соответственно.

— Добавляем схемы объектов Token и User.

— Создаём эндпоинты /api/users с методом POST для регистрации нового пользователя. Для него создаём схему CreateUser.

Понимаем, что забыли сделать хендлер для регистрации пользователя. Создаём метод Signup у хенлера Auth и структуру newUser со всеми полями для регистрации. Генерацию JWT выделяем в отдельный метод, чтобы можно было его вызывать как в Auth, так и в Signup-хендлерах. У нас всё еще нет UserService, поэтому проставляем TODO. Нам надо будет провалидировать полученные данные от пользователя и потом отправить их в UserService, чтобы он уже создал пользователя и ответил нам об успехе. Далее вызываем функцию создания пары токена доступа и refresh-токена и отдаём с кодом 201.

У нас есть подсказка в виде Swagger-файла. На его основе создаём все нужные хендлеры. Там, где вызов микросервисов, будем проставлять комментарий с TODO.

Создаём хендлер для категорий, определяем URL в константах. Далее создаём структуры. Опираемся на Swagger-файл, который создали ранее. Далее создаём сам хендлер и реализуем метод Register, который регистрирует его в роутере. Затем создаём методы с логикой работы и сразу пишем тест API на этот метод. Проверяем, находим ошибки в сваггере. Таким образом мы создаём все методы по работе с категориями: получение и создание.

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

Здесь надо обратить внимание на то, что методы создания сущности возвращают код ответа 201 и заголовок Location, в котором находится URL для получения сущности. Оттуда можно вытащить идентификатор созданной сущности.

В третьей части мы познакомимся с графовой базой данных Neo4j, а также будем работать над микросервисами CategoryService и APIService.

Источник

Образовательный портал