Как быть эффективным x2
Нас окружает множество бытовых или семейных дел, которые со временем превращаются в рутину. Такие дела требуют нашего ресурса и внимания, что порой нас сильно утомляет и даже иногда злит. Начинают появляться мысли, что это время проходит впустую и ты мог бы найти для него лучшее применение...
Расскажу что работает для меня.
Возьмем, к примеру, любой тайм-консьюмер: поездка в транспорте, пешая прогулка до работы, уборка дома или квартиры, прогулка с собакой (к сожалению, иногда это тоже становится рутиной) и пр.
Итак, у нас есть деятельность, которая требует от нас какого-то физического усилия, но мозг в этот момент праздно блуждает по мыслям, прокручивая рабочие задачи или планируя следующий день. Как же подкинуть для себя какую-нибудь интеллектуальную деятельность в этот момент?
Подкасты
При этом, я уверен, что немало людей такой рецепт уже используют. Но как же из него получить в 2 раза больше пользы?
Так как я относительно активно учу английский язык, то решил, что подкасты у меня тоже должны быть на английском.
И вот тут появляется большая вариативность по увеличению эффективности.
Например, я беру английский подкаст, в котором общаются программисты о своей профессии, технологиях и лайфхаках.
Так как подкасты зачастую ведут люди с хорошим произношением, то таким образом я могу улучшать свое понимание английской речи, а также еще получаю полезную информацию в IT.
Конечно, тут есть нюанс. Для понимания подобных подкастов и максимальной пользы у вас должен быть уровень владения иностранным языком не менее среднего. Мне хватает B1 в английском, чтобы без особого напряжения слушать и понимать некоторые подкасты.
При этом я:
- фиксирую и разбираю незнакомые слова после прослушивания или находу
- делаю полезные заметки, связанные с программированием (лайфхаки или просто записываю свои мысли)
Крайне важно найти интересный и полезный для вас подкаст.
Попробуйте начать с 15 минут в день. И со временем, это станет еще одной полезной привычкой!
Нас окружает множество бытовых или семейных дел, которые со временем превращаются в рутину. Такие дела требуют нашего ресурса и внимания, что порой нас сильно утомляет и даже иногда злит. Начинают появляться мысли, что это время проходит впустую и ты мог бы найти для него лучшее применение...
Расскажу что работает для меня.
Возьмем, к примеру, любой тайм-консьюмер: поездка в транспорте, пешая прогулка до работы, уборка дома или квартиры, прогулка с собакой (к сожалению, иногда это тоже становится рутиной) и пр.
Итак, у нас есть деятельность, которая требует от нас какого-то физического усилия, но мозг в этот момент праздно блуждает по мыслям, прокручивая рабочие задачи или планируя следующий день. Как же подкинуть для себя какую-нибудь интеллектуальную деятельность в этот момент?
При этом, я уверен, что немало людей такой рецепт уже используют. Но как же из него получить в 2 раза больше пользы?
Так как я относительно активно учу английский язык, то решил, что подкасты у меня тоже должны быть на английском.
И вот тут появляется большая вариативность по увеличению эффективности.
Например, я беру английский подкаст, в котором общаются программисты о своей профессии, технологиях и лайфхаках.
Так как подкасты зачастую ведут люди с хорошим произношением, то таким образом я могу улучшать свое понимание английской речи, а также еще получаю полезную информацию в IT.
Конечно, тут есть нюанс. Для понимания подобных подкастов и максимальной пользы у вас должен быть уровень владения иностранным языком не менее среднего. Мне хватает B1 в английском, чтобы без особого напряжения слушать и понимать некоторые подкасты.
При этом я:
- фиксирую и разбираю незнакомые слова после прослушивания или находу
- делаю полезные заметки, связанные с программированием (лайфхаки или просто записываю свои мысли)
Крайне важно найти интересный и полезный для вас подкаст.
Попробуйте начать с 15 минут в день. И со временем, это станет еще одной полезной привычкой!
👍3
За 6 месяцев в IBM на позицию фулстек разработчика
"Develop Yourself" - подкаст, который я слушаю последние несколько месяцев. При этом, часто подобные подкасты представляют собой фасад, за которым вас ожидают курсы от автора, а повествование строится вокруг истории гостя - успешного разработчика, который раньше работал в другой сфере, но через труд и дисциплину стал программистом.
Всегда важно критически оценивать ту информацию, которую слышите. У каждого свой путь, свои уникальные навыки и обстоятельства, которые будут вас сопровождать.
История тренера по кроссфиту, которая с нуля устроилась в крупнейшую мировую компанию на полную ставку разработчика, для меня выглядит удивительно. Даже, если человек упорно трудился, скорее всего, в истории опущены важные детали и мы видим то, что нам позволяют видеть.
Конечно, хорошо, когда есть такие вдохновляющие истории. Но, чтобы не потерять мотивацию и не строить ложных ожиданий, не сравнивайте себя с 1%, которым это удалось. Крайне вероятно, что это "выжившие".
"Develop Yourself" - подкаст, который я слушаю последние несколько месяцев. При этом, часто подобные подкасты представляют собой фасад, за которым вас ожидают курсы от автора, а повествование строится вокруг истории гостя - успешного разработчика, который раньше работал в другой сфере, но через труд и дисциплину стал программистом.
Всегда важно критически оценивать ту информацию, которую слышите. У каждого свой путь, свои уникальные навыки и обстоятельства, которые будут вас сопровождать.
История тренера по кроссфиту, которая с нуля устроилась в крупнейшую мировую компанию на полную ставку разработчика, для меня выглядит удивительно. Даже, если человек упорно трудился, скорее всего, в истории опущены важные детали и мы видим то, что нам позволяют видеть.
Конечно, хорошо, когда есть такие вдохновляющие истории. Но, чтобы не потерять мотивацию и не строить ложных ожиданий, не сравнивайте себя с 1%, которым это удалось. Крайне вероятно, что это "выжившие".
В ближайшие месяцы планирую взять на себя роль Security Champion нашей продуктовой команды.
Это поможет улучшить свои знания в кибер-безопасности, а также усилить свою команду экспертизой в этом направлении.
Если совсем кратко, то секьюрити чемпион предупреждает любые риски связанные с уязвимостью поставляемых фич или новых сервисов.
Чтобы перенять эту роль, существует роадмап. Приведу основные пункты из него:
1. Пройти security gym на одном из основных языков программирования (go, php, js) - это тренажер, состоящий из 12-ти заданий, в каждом из которых разбираются основные уязвимости в формате задач.
2. Пройти несколько воркшопов по моделированию угроз, пентесту и криптографии.
3. Провести сессию по моделированию угроз для команды.
В связи с этим планирую выпустить цикл постов, где разберу основные уязвимости веб-разработки и приведу примеры как их избежать в Go.
Это поможет улучшить свои знания в кибер-безопасности, а также усилить свою команду экспертизой в этом направлении.
Если совсем кратко, то секьюрити чемпион предупреждает любые риски связанные с уязвимостью поставляемых фич или новых сервисов.
Чтобы перенять эту роль, существует роадмап. Приведу основные пункты из него:
1. Пройти security gym на одном из основных языков программирования (go, php, js) - это тренажер, состоящий из 12-ти заданий, в каждом из которых разбираются основные уязвимости в формате задач.
2. Пройти несколько воркшопов по моделированию угроз, пентесту и криптографии.
3. Провести сессию по моделированию угроз для команды.
В связи с этим планирую выпустить цикл постов, где разберу основные уязвимости веб-разработки и приведу примеры как их избежать в Go.
owasp.org
OWASP Security Culture | OWASP Foundation
OWASP Security Culture on the main website for The OWASP Foundation. OWASP is a nonprofit foundation that works to improve the security of software.
👍6🔥5
Межсайтовый скриптинг (XSS) в HTML
XSS - одна из разновидность инъекций в уязвимости веб-приложений. Если форма ввода никак не валидируется, то очень легко вместо ожидаемого значения подложить вредоносный скрипт.
Предлагаю ознакомиться с лучшими практиками по предотвращению подобной атаки и применить полученные знания.
Задание: Как сделать код ниже более безопасным?
Код написан на Go. Если раньше с языком не работали, для сборки проекта можно использовать инструкцию.
0) Создайте файлик main.go и поместите туда код из задания
1) Соберите и запустите проект (
2) Перейдите на
3) Попробуйте ввести ожидаемый ввод, например:
4) А теперь попробуйте подложить вредоносный скрипт в другой запрос, например:
5) У нас выполнился безобидный скрипт с простым алертом. А, если можно выполнить его, то можно выполнить что угодно таким способом, не так ли?
6) Исправьте уязвимость
Исправленный код
#безопасность
XSS - одна из разновидность инъекций в уязвимости веб-приложений. Если форма ввода никак не валидируется, то очень легко вместо ожидаемого значения подложить вредоносный скрипт.
Предлагаю ознакомиться с лучшими практиками по предотвращению подобной атаки и применить полученные знания.
Задание: Как сделать код ниже более безопасным?
Код написан на Go. Если раньше с языком не работали, для сборки проекта можно использовать инструкцию.
0) Создайте файлик main.go и поместите туда код из задания
1) Соберите и запустите проект (
go run main.go)2) Перейдите на
http://localhost:4000/3) Попробуйте ввести ожидаемый ввод, например:
?name=Alexander4) А теперь попробуйте подложить вредоносный скрипт в другой запрос, например:
?name=</div><noscript>alert(document.cookie)</noscript><div>5) У нас выполнился безобидный скрипт с простым алертом. А, если можно выполнить его, то можно выполнить что угодно таким способом, не так ли?
6) Исправьте уязвимость
#безопасность
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", HelloHandler)
err := http.ListenAndServe(":4000", mux)
log.Fatal(err)
}
func HelloHandler(w http.ResponseWriter, req *http.Request) {
http.SetCookie(w, &http.Cookie{Name: "user", Value: "guest"})
http.SetCookie(w, &http.Cookie{Name: "password", Value: "qwerty123"})
helloTemplate := `
<html>
<head></head>
<body>
<p>Hello, <b>%s</b></p>
</body>
</html>
`
name := req.URL.Query().Get("name")
fmt.Fprintf(w, helloTemplate, name)
}
owasp.org
Cross Site Scripting (XSS) | OWASP Foundation
Cross Site Scripting (XSS) on the main website for The OWASP Foundation. OWASP is a nonprofit foundation that works to improve the security of software.
👍2
Межсайтовый скриптинг (XSS) в ответах API
XSS атаки бывают не только в HTML, но и в серверных ответах API.
И если в прошлый раз мы закрывали уязвимость заменой 5 основных символов: <, >, &, ' и " - то теперь используем другой подход.
В некоторых библиотеках для работы с HTML (для Go это text/template и net/http) заголовок Content-Type проставляется автоматически в зависимости от содержимого. И, если в коде ответа будут обнаружены html-тэги, то может проставиться заголовок подразумевающий выполнение кода браузером.
Таким образом, явная установка нужного хэдера, отмечающего за Content-Type, также позволяет избежать XSS.
Прикладываю код с уязвимостью, который нужно обезопасить.
Исправленный код
#безопасность
XSS атаки бывают не только в HTML, но и в серверных ответах API.
И если в прошлый раз мы закрывали уязвимость заменой 5 основных символов: <, >, &, ' и " - то теперь используем другой подход.
В некоторых библиотеках для работы с HTML (для Go это text/template и net/http) заголовок Content-Type проставляется автоматически в зависимости от содержимого. И, если в коде ответа будут обнаружены html-тэги, то может проставиться заголовок подразумевающий выполнение кода браузером.
Таким образом, явная установка нужного хэдера, отмечающего за Content-Type, также позволяет избежать XSS.
Прикладываю код с уязвимостью, который нужно обезопасить.
#безопасность
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", HelloHandler)
err := http.ListenAndServe(":4000", mux)
log.Fatal(err)
}
func HelloHandler(w http.ResponseWriter, req *http.Request) {
helloTemplate := `{{.}}`
tmpl := template.New("hello")
tmpl, _ = tmpl.Parse(helloTemplate)
name := req.URL.Query().Get("name")
_ = tmpl.Execute(w, name)
}
IDE делает вас глупее [1/2]
Каждый ли помнит как написать простейший цикл на своем языке или слово
3 года назад я купил IDE Rider от компании JetBrains для разработки на платформе .NET, а также призывал инвестировать в свой комфорт.
В тот момент я не понимал как можно вести разработку под .NET без одной из IDE: MS Visual Studio или JetBrains Rider. Я использовал обе и это было очень удобно, но я совершенно не задумывался, что происходит внутри: когда я создавал новый консольный, веб или WPF-проект или когда запускал дебагер. Это просто работало и я мог писать свой код.
Когда я перешел на Go, то IDE Goland от JetBrains - была самым очевидным выбором. Я слышал, что это лучшее решение на рынке и мне очень оно нравилось. Тем более, сперва у меня была бесплатная версия для учебных целей, а потом компания предоставила лицензию для работы.
Такой мультитул сильно повышает скорость и удобство. Но многие ли задумываются о том, что скрывает внутри себя любимая интегрированная среда разработки, предлагая нам тот комфорт, к которому мы привыкли? 🤔
...
В первую очередь,редактор текста .
У меня есть коллега, который до сих пор принципиально использует Vim. Ему так удобнее и быстрее. Пару недель назад он давал мастер-класс по своему инструментарию для разработки и это действительно поражает, как быстро и эффективно можно работать без мыши и без классических тяжеловесных IDE.
Про удобство Vim слышу от многих разработчиков, в особенности про Neovim. Но порог вхождения очень высокий, особенно, если начинали свой путь с популярных IDE, которые все делают за вас.
IDE - это не только текстовый редактор, но она также включает SDK выбранного языка, а это компилятор (если язык компилируемый), стандартные библиотеки, дебагер, LSP для автокомплита и множество других фич.
Очевидно, возникает вопрос: зачем отказываться от IDE, которая максимально облегчает твою жизнь в разработке?
Ответить можно по-разному, но вот несколько моих причин:
1. В РФ JetBrains прекратила поддержку своих продуктов, а значит их стало сложнее купить для личного использования, а "белым" компаниям практически невозможно.
2. Отсутствие поддержки = отсутствие обновлений, а это чревато комфортом в работе. Например, полгода назад мне пришлось самостоятельно разбираться в версиях дебагера, которую использовала IDE и вручную переопределять его конфигурацию, скачивая самую актуальную сборку Delve.
3. Некорректная работа IDE при отладке больших проектов. Пару раз Goland вводила меня в заблуждение своим поведением и все, что помогало - перезагрузка среды или ПК (да, пару раз было и такое).
4. Я время от времени балуюсь C#, а для разработки под него нужна отдельная IDE.
5. Все, что описал выше, уже с лихвой оправдывало переход на другой инструмент, но сюда еще и добавилось мое любопытство к тому, что именно заменяет IDE, когда стал отказываться от нее.
Так можно ли жить без IDE совсем? Каждый решаем сам, но для себя я решил однозначно: да.
В четверг расскажу о своем сетапе для разработки (где пишу код и какие еще использую инструменты).
Каждый ли помнит как написать простейший цикл на своем языке или слово
for и двойная команда TAB делает это за нас? Способны ли вы, смерджив несколько веток в мастер и разрешив при этом конфликты, собрать свой проект используя только консоль?3 года назад я купил IDE Rider от компании JetBrains для разработки на платформе .NET, а также призывал инвестировать в свой комфорт.
В тот момент я не понимал как можно вести разработку под .NET без одной из IDE: MS Visual Studio или JetBrains Rider. Я использовал обе и это было очень удобно, но я совершенно не задумывался, что происходит внутри: когда я создавал новый консольный, веб или WPF-проект или когда запускал дебагер. Это просто работало и я мог писать свой код.
Когда я перешел на Go, то IDE Goland от JetBrains - была самым очевидным выбором. Я слышал, что это лучшее решение на рынке и мне очень оно нравилось. Тем более, сперва у меня была бесплатная версия для учебных целей, а потом компания предоставила лицензию для работы.
Такой мультитул сильно повышает скорость и удобство. Но многие ли задумываются о том, что скрывает внутри себя любимая интегрированная среда разработки, предлагая нам тот комфорт, к которому мы привыкли? 🤔
...
В первую очередь,
У меня есть коллега, который до сих пор принципиально использует Vim. Ему так удобнее и быстрее. Пару недель назад он давал мастер-класс по своему инструментарию для разработки и это действительно поражает, как быстро и эффективно можно работать без мыши и без классических тяжеловесных IDE.
Про удобство Vim слышу от многих разработчиков, в особенности про Neovim. Но порог вхождения очень высокий, особенно, если начинали свой путь с популярных IDE, которые все делают за вас.
IDE - это не только текстовый редактор, но она также включает SDK выбранного языка, а это компилятор (если язык компилируемый), стандартные библиотеки, дебагер, LSP для автокомплита и множество других фич.
Очевидно, возникает вопрос: зачем отказываться от IDE, которая максимально облегчает твою жизнь в разработке?
Ответить можно по-разному, но вот несколько моих причин:
1. В РФ JetBrains прекратила поддержку своих продуктов, а значит их стало сложнее купить для личного использования, а "белым" компаниям практически невозможно.
2. Отсутствие поддержки = отсутствие обновлений, а это чревато комфортом в работе. Например, полгода назад мне пришлось самостоятельно разбираться в версиях дебагера, которую использовала IDE и вручную переопределять его конфигурацию, скачивая самую актуальную сборку Delve.
3. Некорректная работа IDE при отладке больших проектов. Пару раз Goland вводила меня в заблуждение своим поведением и все, что помогало - перезагрузка среды или ПК (да, пару раз было и такое).
4. Я время от времени балуюсь C#, а для разработки под него нужна отдельная IDE.
5. Все, что описал выше, уже с лихвой оправдывало переход на другой инструмент, но сюда еще и добавилось мое любопытство к тому, что именно заменяет IDE, когда стал отказываться от нее.
Так можно ли жить без IDE совсем? Каждый решаем сам, но для себя я решил однозначно: да.
В четверг расскажу о своем сетапе для разработки (где пишу код и какие еще использую инструменты).
🔥4
IDE делает вас глупее [2/2]
Я полностью отказался от классической IDE и теперь счастлив. Ежедневно я использую 3 инструмента: редактор текста (кода), инструменты для работы с запросами API и проксированием трафика.
3 инструмента, которые покрывают полный цикл разработки и тестирования на всех платформах
📝 1. Редактор кода
С конца февраля весь код пишу только в Visual Studio Code. Это легковесный (по сравнению с IDE) редактор исходного кода.
При этом создал себе комфорт, который был в IDE, добавив следующие плагины:
1. Go для разработки под Go, предлагающий дебагер delve, Go LSP - gopls и пр.)
2. GitLens для просмотра истории коммитов прямо в коде (использую только 1 функцию - превью последнего коммита с автором на выбранной строке)
3. GitHub Theme для пестрой раскраски кода
Есть еще плагины для сторонних проектов, но их использование оцениваю как 5% от всего остального:
// 4. C# Dev Kit (плагин для разработки под .NET)
// 5. Julia (плагин для разработки на Julia)
При этом, я уверен, что можно ограничиться еще большим минимумом плагинов (или вообще обойтись без них), но пока у меня такой сетап.
Предостережение, если смотрите в эту сторону: не увлекайтесь установкой множества плагинов, а то на выходе можно получить более неповоротливое решение, чем коммерческие популярные IDE. Фактически, когда вы к редактору кода добавляете плагины, то на выходе получается интегрированная среда разработки :)
🚀 2. Запросы к API
Все запросы организую в коллекции с помощью Postman: <название сервиса> / <ендпоинты> / <платформы> и т.д. Когда работаешь с десятками, а то и сотнями микросервисов - это просто необходимо для удобной разработки и тестировании фич.
👨🚀 3. Проксирование запросов
Проксирую запросы (трафик) для отладки с помощью Proxyman. Это полезно для тестирования мобильных клиентов: iOS и Android. Очевидно, что это работа для QA, но я убежден, что в тестирование нужно отдавать полностью проверенный код. И, если я могу самостоятельно поднять тестовую среду и проверить несколько кейсов на каждой из платформ, то это сильно сократит время тестирования и, следовательно, Time to Market. На этом этапе можно отловить большинство глупых ошибок - лучше узнать про них первым, чем их потом принесет QA.
Выводы
VS Code + плагины полностью развязали мне руки:
1. Убрал зависимость от конкретного коммерческого продукта (VS Code - это опен-сорс), при этом экономлю еще (100-200)$ каждый год.
2. Получил полное осознание того, что скрывает IDE под капотом и за что мы платим.
3. Стал меньше бояться Vim'а, с легкостью из него выхожу и даже активно использую, когда появляется необходимость править ридми или конфиг файлы на удаленном сервере, где под рукой только консоль.
4. Нашел новые крутые фишки, которые ускоряют работу.
5. Чувствую себя более уверенным :)
Возможно, со временем стану еще более аскетичным и перейду на Neovim, но пока понимаю, что слишком мало времени, чтобы привыкать к этому инструменту.
Если готовы поделиться, то интересно, что используете вы в своей работе/учебе? Удобно ли вам или тоже иногда задумываетесь о переходе на что-то другое?
Я полностью отказался от классической IDE и теперь счастлив. Ежедневно я использую 3 инструмента: редактор текста (кода), инструменты для работы с запросами API и проксированием трафика.
3 инструмента, которые покрывают полный цикл разработки и тестирования на всех платформах
📝 1. Редактор кода
С конца февраля весь код пишу только в Visual Studio Code. Это легковесный (по сравнению с IDE) редактор исходного кода.
При этом создал себе комфорт, который был в IDE, добавив следующие плагины:
1. Go для разработки под Go, предлагающий дебагер delve, Go LSP - gopls и пр.)
2. GitLens для просмотра истории коммитов прямо в коде (использую только 1 функцию - превью последнего коммита с автором на выбранной строке)
3. GitHub Theme для пестрой раскраски кода
Есть еще плагины для сторонних проектов, но их использование оцениваю как 5% от всего остального:
// 4. C# Dev Kit (плагин для разработки под .NET)
// 5. Julia (плагин для разработки на Julia)
При этом, я уверен, что можно ограничиться еще большим минимумом плагинов (или вообще обойтись без них), но пока у меня такой сетап.
Предостережение, если смотрите в эту сторону: не увлекайтесь установкой множества плагинов, а то на выходе можно получить более неповоротливое решение, чем коммерческие популярные IDE. Фактически, когда вы к редактору кода добавляете плагины, то на выходе получается интегрированная среда разработки :)
🚀 2. Запросы к API
Все запросы организую в коллекции с помощью Postman: <название сервиса> / <ендпоинты> / <платформы> и т.д. Когда работаешь с десятками, а то и сотнями микросервисов - это просто необходимо для удобной разработки и тестировании фич.
👨🚀 3. Проксирование запросов
Проксирую запросы (трафик) для отладки с помощью Proxyman. Это полезно для тестирования мобильных клиентов: iOS и Android. Очевидно, что это работа для QA, но я убежден, что в тестирование нужно отдавать полностью проверенный код. И, если я могу самостоятельно поднять тестовую среду и проверить несколько кейсов на каждой из платформ, то это сильно сократит время тестирования и, следовательно, Time to Market. На этом этапе можно отловить большинство глупых ошибок - лучше узнать про них первым, чем их потом принесет QA.
Выводы
VS Code + плагины полностью развязали мне руки:
1. Убрал зависимость от конкретного коммерческого продукта (VS Code - это опен-сорс), при этом экономлю еще (100-200)$ каждый год.
2. Получил полное осознание того, что скрывает IDE под капотом и за что мы платим.
3. Стал меньше бояться Vim'а, с легкостью из него выхожу и даже активно использую, когда появляется необходимость править ридми или конфиг файлы на удаленном сервере, где под рукой только консоль.
4. Нашел новые крутые фишки, которые ускоряют работу.
5. Чувствую себя более уверенным :)
Возможно, со временем стану еще более аскетичным и перейду на Neovim, но пока понимаю, что слишком мало времени, чтобы привыкать к этому инструменту.
Если готовы поделиться, то интересно, что используете вы в своей работе/учебе? Удобно ли вам или тоже иногда задумываетесь о переходе на что-то другое?
🔥6
Февраль 2024:
навыки
✔️ Потренировался очередной раз написать разные имплементации FizzBuzz'а. Одна из реализаций без единого if'а!
✔️ Погружаюсь глубже в Low Level Design и то как проектировать системы любой сложности с помощью ООП. Практикуюсь на C#, так как (в отличие от Go) язык обладает полной поддержкой основных парадигм ООП.
✔️ Познакомился с Фаззинг-тестированием и попрактиковался его применять с помощью стандартных пакетов тестирования в Go.
✔️ Начал изучать основные веб-уязвимости, рассмотрел 2 вида XSS-атак.
✔️ Написал проект с помощью TDD.
канал
✔️ Наладил регулярный темп выпуска новых постов: 2 раза в неделю
✔️ За февраль вышло 8 постов (2 из которых практические - по предотвращению XSS-уязвимостей)
прочее
✔️ Полностью отказался от IDE JetBrains Goland и перешел на опенс-сорсный редактор VS Code
#результаты
навыки
✔️ Потренировался очередной раз написать разные имплементации FizzBuzz'а. Одна из реализаций без единого if'а!
✔️ Погружаюсь глубже в Low Level Design и то как проектировать системы любой сложности с помощью ООП. Практикуюсь на C#, так как (в отличие от Go) язык обладает полной поддержкой основных парадигм ООП.
✔️ Познакомился с Фаззинг-тестированием и попрактиковался его применять с помощью стандартных пакетов тестирования в Go.
✔️ Начал изучать основные веб-уязвимости, рассмотрел 2 вида XSS-атак.
✔️ Написал проект с помощью TDD.
канал
✔️ Наладил регулярный темп выпуска новых постов: 2 раза в неделю
✔️ За февраль вышло 8 постов (2 из которых практические - по предотвращению XSS-уязвимостей)
прочее
✔️ Полностью отказался от IDE JetBrains Goland и перешел на опенс-сорсный редактор VS Code
#результаты
👍6
Межсайтовый скриптинг (XSS) в атрибутах HTML
Мы рассмотрели XSS атаки в серверных ответах API и затронули общий случай инъекции в HTML. Но еще важно упомянуть, что HTML-атрибуты часто становятся мишенью для XSS-атак.
На примере атрибута
Прикладываю код с уязвимостью, который нужно обезопасить.
В завершение цикла постов про XSS предлагаю ряд бытовых советов, которых следует придерживаться, чтобы не допускать уязвимостей в своем коде:
1. Всегда обрабатывайте (валидируйте) пользовательский ввод перед отображением на странице и энкодьте вывод. Используйте готовые библиотеки.
2. Устанавливайте явно заголовки, с которыми должен отвечать сервер.
3. Установите CSP.
Очевидно, это далеко не исчерпывающее руководство, но, если начать делать хотя бы это, то обезопасите себя от уязвимостей, про которые не все задумываются. Хабр в 2013 году, например, про это явно не думал :)
Исправленный код
#безопасность
Мы рассмотрели XSS атаки в серверных ответах API и затронули общий случай инъекции в HTML. Но еще важно упомянуть, что HTML-атрибуты часто становятся мишенью для XSS-атак.
На примере атрибута
href научимся обрабатывать и такие случаи. Прикладываю код с уязвимостью, который нужно обезопасить.
В завершение цикла постов про XSS предлагаю ряд бытовых советов, которых следует придерживаться, чтобы не допускать уязвимостей в своем коде:
1. Всегда обрабатывайте (валидируйте) пользовательский ввод перед отображением на странице и энкодьте вывод. Используйте готовые библиотеки.
2. Устанавливайте явно заголовки, с которыми должен отвечать сервер.
3. Установите CSP.
Очевидно, это далеко не исчерпывающее руководство, но, если начать делать хотя бы это, то обезопасите себя от уязвимостей, про которые не все задумываются. Хабр в 2013 году, например, про это явно не думал :)
#безопасность
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", HelloHandler)
err := http.ListenAndServe(":4000", mux)
log.Fatal(err)
}
func HelloHandler(w http.ResponseWriter, req *http.Request) {
http.SetCookie(w, &http.Cookie{Name: "user", Value: "guest"})
http.SetCookie(w, &http.Cookie{Name: "password", Value: "qwerty123"})
helloTemplate := `
<html>
<head></head>
<body>
<p><a href="%s">Go back</a></p>
</body>
</html>
`
returnUrl := req.URL.Query().Get("return_url")
fmt.Fprintf(w, helloTemplate, returnUrl)
}
You are gonna need it (YAGNI v2.0)
Когда я только оказался в большой компании, помимо классического пакета встреч: ежедневные стендапы, несколько грумингов в неделю и ретро в конце спринта - я получил еще одну регулярную встречу, которой сперва не придал большого значения, - 1-1 со своим руководителем.
Мой тимлид сразу обозначил, что подобные встречи у нас будут 1 раз в 2 недели, то есть 1 раз за спринт. Что оказалось удобно: не слишком часто, не слишком редко.
Встречи 1-1 (англ. one to one) проводятся с довольно прагматичной целью: узнать как у тебя дела, какие есть трудности и с каким настроением работаешь.
Для меня такие встречи полезны следующим:
- могу получить обратную связь касательно своей работы (что было хорошо, а что можно улучшить)
- могу транслировать свои опасения касательно процессов или других вещей (важно говорить о том, что тебя беспокоит или мешает работе)
- могу обсудить свое развитие: цели и планы - и как их достичь, учитывая интересы бизнеса
Также они повышают чувство внутренного комфорта: я знаю, что 1 раз в 2 недели у меня есть законные 30 минут для обсуждение любых тем, которые меня беспокоят. И это действительно помогает.
Лирическое отступление: я такой человек, что, когда достигаю определенного уровня (как правило, "выше среднего, но еще не профи") в чем бы то ни было, то мне становится скучно. Это и преимущество (я начинаю искать новые пути для развития), но и недостаток (мне очень сложно в чем-то по-настоящему преуспеть).
На прошлом 1-1 с тимлидом я решил признаться и сказать, что немного заскучал с продуктовыми задачами, что мне не хватает новых вызовов. Я не ожидал никакой реакции, у меня не было плана, просто хотел поделиться своим эмоциональным состоянием с руководителем...
Но его реакция меня приятно удивила своей честностью и желанием помочь: он тоже стал замечать, что я как будто выгораю, поэтому предложил себя поменьше загружать при планировании спринта, а также подумать над технически сложными задачами, на которых я могу вырасти и которые будут интересны конкретно мне.
Удивительно, но мы нашли такую задачу, которая требует глубокого погружения, серьезной работы над архитектурой сервиса, а также очень важна для нашей команды и будет полезна компании, в целом.
Теперь у меня появилось четкое понимание, чем я хочу, а главное могу заниматься на работе. Мы обозначили квартал этого года, чтобы зафиксировать задачу в дорожной карте по разработке, а я, в свою очередь, уже начал готовиться к полноценному оунерству нового проекта, улучшая свои навыки в проектировании нагруженных сервисов.
Если бы не такие встречи, то, вероятно, рано или поздно, я сам бы пришел с таким запросом. Но мне было бы гораздо сложнее на это решиться, при этом я могу назвать себя решительным человеком.
А как много существует скромных специалистов, кто не решается на подобные шаги и может многие годы сидеть над одними и теми же задачами, ставшими рутиной, пока не перегорит окончательно со всеми последствиями для себя и других?
Поэтому, если чувствуете, что заскучали или устали, то обязательно поговорите со своим руководителем. Хороший менеджер знает, что счастливый сотрудник принесет ему гораздо больше денег, а значит, будет вкладываться в вас и будет полностью на вашей стороне.
Когда я только оказался в большой компании, помимо классического пакета встреч: ежедневные стендапы, несколько грумингов в неделю и ретро в конце спринта - я получил еще одну регулярную встречу, которой сперва не придал большого значения, - 1-1 со своим руководителем.
Мой тимлид сразу обозначил, что подобные встречи у нас будут 1 раз в 2 недели, то есть 1 раз за спринт. Что оказалось удобно: не слишком часто, не слишком редко.
Встречи 1-1 (англ. one to one) проводятся с довольно прагматичной целью: узнать как у тебя дела, какие есть трудности и с каким настроением работаешь.
Для меня такие встречи полезны следующим:
- могу получить обратную связь касательно своей работы (что было хорошо, а что можно улучшить)
- могу транслировать свои опасения касательно процессов или других вещей (важно говорить о том, что тебя беспокоит или мешает работе)
- могу обсудить свое развитие: цели и планы - и как их достичь, учитывая интересы бизнеса
Также они повышают чувство внутренного комфорта: я знаю, что 1 раз в 2 недели у меня есть законные 30 минут для обсуждение любых тем, которые меня беспокоят. И это действительно помогает.
Лирическое отступление: я такой человек, что, когда достигаю определенного уровня (как правило, "выше среднего, но еще не профи") в чем бы то ни было, то мне становится скучно. Это и преимущество (я начинаю искать новые пути для развития), но и недостаток (мне очень сложно в чем-то по-настоящему преуспеть).
На прошлом 1-1 с тимлидом я решил признаться и сказать, что немного заскучал с продуктовыми задачами, что мне не хватает новых вызовов. Я не ожидал никакой реакции, у меня не было плана, просто хотел поделиться своим эмоциональным состоянием с руководителем...
Но его реакция меня приятно удивила своей честностью и желанием помочь: он тоже стал замечать, что я как будто выгораю, поэтому предложил себя поменьше загружать при планировании спринта, а также подумать над технически сложными задачами, на которых я могу вырасти и которые будут интересны конкретно мне.
Удивительно, но мы нашли такую задачу, которая требует глубокого погружения, серьезной работы над архитектурой сервиса, а также очень важна для нашей команды и будет полезна компании, в целом.
Теперь у меня появилось четкое понимание, чем я хочу, а главное могу заниматься на работе. Мы обозначили квартал этого года, чтобы зафиксировать задачу в дорожной карте по разработке, а я, в свою очередь, уже начал готовиться к полноценному оунерству нового проекта, улучшая свои навыки в проектировании нагруженных сервисов.
Если бы не такие встречи, то, вероятно, рано или поздно, я сам бы пришел с таким запросом. Но мне было бы гораздо сложнее на это решиться, при этом я могу назвать себя решительным человеком.
А как много существует скромных специалистов, кто не решается на подобные шаги и может многие годы сидеть над одними и теми же задачами, ставшими рутиной, пока не перегорит окончательно со всеми последствиями для себя и других?
Поэтому, если чувствуете, что заскучали или устали, то обязательно поговорите со своим руководителем. Хороший менеджер знает, что счастливый сотрудник принесет ему гораздо больше денег, а значит, будет вкладываться в вас и будет полностью на вашей стороне.
👍10
Феномен Баадера-Майнхоф в действии и при чем здесь Фаззинг
Случалось ли с вами такое, что совершенно новая информация (с которой раньше вы никогда не сталкивались) начинает появляться в вашей жизни все чаще и чаще, как только вы про нее узнали?
Проще всего про это думать в разрезе автомобилей. Вы никогда раньше не видели Volkswagen Beetle в своем городе, но как только 1 раз заметили, то на следующий день можете встретить не один, а уже целую серию. Как будто они начали преследовать вас.
…
Во вторник сходил на митап местного Go-сообщества.
Обсудили 2 темы:
- фаззинг тестирование
- альтернативу buf в условиях импортозамещения и санкций
Несмотря на важность второй темы (многие компании уже оценили преимущества опен-сорса над проприетарными решениями, от которых целиком и полностью зависели), меня зацепила тема именно фаззинга.
Фаззинг - вид тестирования, с которым я познакомился лишь в феврале. Что это такое и как его использовать в Go также описывал.
Удивительно, но мое поверхностное знакомство с темой заполнило секцию вопросов и ответов после доклада спикера. Оказалось, что из 40 человек в зале знакомых с темой было всего 3-4.
Еще я узнал, что:
- компания, которая выпускает свое железо, может испытывать с ним трудности при фаззинге
- фаззинг не самый популярный вид тестирования, поэтому многие библиотеки для работы с ним заброшены или обладают скудным функционалом; компаниям, которые заинтересованы в этом, приходится выделять отдельных людей для разработки своих решений (в частности, организатор митапа направил на создание фаззинг-инструмента junior-разработчика, который уже полгода этим занимается)
- 1 прогон теста для разработанного компонента занимает не менее 1-1.5 часа
- сейчас готовится стандарт, где будут закреплены требования к фаззинг тестированию проекта
Очевидно, что фаззинг необходим для ответственных проектов, где безопасность/отказоустойчивость превыше всего. При этом многие продуктовые компании могут неплохо обходиться без него, так как для них зачастую важнее Time To Market. И одно дело - запускать минутные юнит-тесты или даже e2e (которые могут занимать время на порядок дольше) и совсем другое - идти в фаззинг, который в разы может замедлить поставку новых фичей, требует мощного железа и разработчиков для его отдельной поддержки.
Случалось ли с вами такое, что совершенно новая информация (с которой раньше вы никогда не сталкивались) начинает появляться в вашей жизни все чаще и чаще, как только вы про нее узнали?
Проще всего про это думать в разрезе автомобилей. Вы никогда раньше не видели Volkswagen Beetle в своем городе, но как только 1 раз заметили, то на следующий день можете встретить не один, а уже целую серию. Как будто они начали преследовать вас.
…
Во вторник сходил на митап местного Go-сообщества.
Обсудили 2 темы:
- фаззинг тестирование
- альтернативу buf в условиях импортозамещения и санкций
Несмотря на важность второй темы (многие компании уже оценили преимущества опен-сорса над проприетарными решениями, от которых целиком и полностью зависели), меня зацепила тема именно фаззинга.
Фаззинг - вид тестирования, с которым я познакомился лишь в феврале. Что это такое и как его использовать в Go также описывал.
Удивительно, но мое поверхностное знакомство с темой заполнило секцию вопросов и ответов после доклада спикера. Оказалось, что из 40 человек в зале знакомых с темой было всего 3-4.
Еще я узнал, что:
- компания, которая выпускает свое железо, может испытывать с ним трудности при фаззинге
- фаззинг не самый популярный вид тестирования, поэтому многие библиотеки для работы с ним заброшены или обладают скудным функционалом; компаниям, которые заинтересованы в этом, приходится выделять отдельных людей для разработки своих решений (в частности, организатор митапа направил на создание фаззинг-инструмента junior-разработчика, который уже полгода этим занимается)
- 1 прогон теста для разработанного компонента занимает не менее 1-1.5 часа
- сейчас готовится стандарт, где будут закреплены требования к фаззинг тестированию проекта
Очевидно, что фаззинг необходим для ответственных проектов, где безопасность/отказоустойчивость превыше всего. При этом многие продуктовые компании могут неплохо обходиться без него, так как для них зачастую важнее Time To Market. И одно дело - запускать минутные юнит-тесты или даже e2e (которые могут занимать время на порядок дольше) и совсем другое - идти в фаззинг, который в разы может замедлить поставку новых фичей, требует мощного железа и разработчиков для его отдельной поддержки.
👍5
Межсервисная авторизация (Inter-Service authorization)
Каждый знает, что нужно обезопасить систему от проникновений извне, но каждый ли задумывается, что защита нужна также и на локальном уровне?
Когда сервисов становится много, то межсервисная авторизация становится необходимостью для обеспечения безопасности, целостности и отказоустойчивости распределенной системы.
Реализация может быть разная: middleware, решения на Service Mesh и др. Многое будет зависеть от архитектуры приложения, ресурсов компании и команды разработки. Поэтому важно выбирать не самое лучшее/популярное, а то, что будет хорошо работать именно у вас.
Например, в Авито инфраструктурная команда это реализовала на базе Service Mesh. Как это устроено и почему сделано именно так рассказывали здесь.
В посте прикрепляю примитивный код с хэндлером, проверяющий наличие "авторизации" и прерывающий выполнение при ее отсутствии. Решения могут быть самые разные, но крайне важно про это думать во время разработки и, если нет ресурсов сразу на хорошее решение, то начать с чего-нибудь простого и впоследствии докручивать его при появлении возможностей.
Подробнее про то, на что обращать внимание при работе с веб-сервисами в частности с аутентификацией и авторизацией можно найти в шпаргалке.
#безопасность
Каждый знает, что нужно обезопасить систему от проникновений извне, но каждый ли задумывается, что защита нужна также и на локальном уровне?
Когда сервисов становится много, то межсервисная авторизация становится необходимостью для обеспечения безопасности, целостности и отказоустойчивости распределенной системы.
Реализация может быть разная: middleware, решения на Service Mesh и др. Многое будет зависеть от архитектуры приложения, ресурсов компании и команды разработки. Поэтому важно выбирать не самое лучшее/популярное, а то, что будет хорошо работать именно у вас.
Например, в Авито инфраструктурная команда это реализовала на базе Service Mesh. Как это устроено и почему сделано именно так рассказывали здесь.
В посте прикрепляю примитивный код с хэндлером, проверяющий наличие "авторизации" и прерывающий выполнение при ее отсутствии. Решения могут быть самые разные, но крайне важно про это думать во время разработки и, если нет ресурсов сразу на хорошее решение, то начать с чего-нибудь простого и впоследствии докручивать его при появлении возможностей.
Подробнее про то, на что обращать внимание при работе с веб-сервисами в частности с аутентификацией и авторизацией можно найти в шпаргалке.
package main
import (
"html/template"
"log"
"net/http"
"os"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", HelloHandler)
err := http.ListenAndServe(":4000", mux)
log.Fatal(err)
}
func HelloHandler(w http.ResponseWriter, req *http.Request) {
secret := os.Getenv("SERVICES_SECRET")
if secret == "" {
return
}
if secret != req.Header.Get("Authorization") {
return
}
helloTemplate := `
<html>
<head></head>
<body>
<p>Some secret data</p>
</body>
</html>
`
tmpl, err := template.New("name").Parse(helloTemplate)
if err != nil {
log.Fatal(err)
}
err = tmpl.Execute(w, "")
}
#безопасность
👍1
Паттерны проектирования
Когда я только начинал писать на С#, мне повсеместно попадались советы о том как важна эта тема и я тщетно пытался запомнить все сниппеты с кодом, которые реализовывали отдельные идеи.
Но паттерны - это не что-то необходимое в работе, а лишь инструмент, который позволит вам видеть закономерности, легче читать чужой код и реализовывать свои решения.
Поэтому изучать их лучше после нескольких лет в профессии, чтобы возникло понимание как их правильно использовать.
Пару дней назад приступил к книге Head First Design Patterns (Eric Freeman, Elisabeth Robson).
Авторы явно знакомы с тем, как человек усваивает информацию: нас активно вовлекают в тему лирическими отступлениями, юмором и картинками, закрепляя прочитанное аналогиями из жизни.
Хорошая проработка такой книги на 99% закроет потребность в паттернах и переведет вас на другой уровень абстракции, который позволит проектировать систему с использованием подходов, давно оправдавших себя на практике.
Когда я только начинал писать на С#, мне повсеместно попадались советы о том как важна эта тема и я тщетно пытался запомнить все сниппеты с кодом, которые реализовывали отдельные идеи.
Но паттерны - это не что-то необходимое в работе, а лишь инструмент, который позволит вам видеть закономерности, легче читать чужой код и реализовывать свои решения.
Поэтому изучать их лучше после нескольких лет в профессии, чтобы возникло понимание как их правильно использовать.
Пару дней назад приступил к книге Head First Design Patterns (Eric Freeman, Elisabeth Robson).
Авторы явно знакомы с тем, как человек усваивает информацию: нас активно вовлекают в тему лирическими отступлениями, юмором и картинками, закрепляя прочитанное аналогиями из жизни.
Хорошая проработка такой книги на 99% закроет потребность в паттернах и переведет вас на другой уровень абстракции, который позволит проектировать систему с использованием подходов, давно оправдавших себя на практике.
👍6
Cross-Site Request Forgery (CSRF)
Межсайтовая подделка запроса - разновидность атак, заставляющая авторизированного пользователя совершить нежелательное действие по изменению данных.
🕵️♂️ Веб-приложение уязвимо к CSRF-атакам, если обнаружено:
1. Отсутствие или ненадежная реализация CSRF-токена.
2. Наличие повторяющихся запросов на изменение данных без дополнительной проверки подлинности.
3. Автоматическое выполнение действий без подтверждения со стороны пользователя.
🔧 Обеспечить безопасность вашего приложения помогут:
1. Внедрение CSRF-токен в формы и проверка их на сервере перед выполнением действия.
2. Использование сессионных токенов для подтверждения подлинности пользователя.
3. Ограничение привилегий доступа к функциями изменения данных.
В общем случае, основным способом защиты является CSRF-токен, который добавляется к запросам и проверяется на сервере, чтобы удостовериться, что действия совершает пользователь, а не злоумышленник.
Для обеспечения максимальной безопасности токен должен быть:
- уникальным для каждой сессии (чтобы предотвратить повторное использование)
- зашифрованным (чтобы предотвратить возможность изменения токена злоумышленником)
- непредсказуемым (сгенерирован с использованием криптографически безопасного генератора по надежному алгоритму)
Подробнее о данном виде атак и методах защиты можно найти в шпаргалке OWASP.
Применяя данные советы, вы добавите еще один слой защиты к своим приложениям.
#безопасность
Межсайтовая подделка запроса - разновидность атак, заставляющая авторизированного пользователя совершить нежелательное действие по изменению данных.
🕵️♂️ Веб-приложение уязвимо к CSRF-атакам, если обнаружено:
1. Отсутствие или ненадежная реализация CSRF-токена.
2. Наличие повторяющихся запросов на изменение данных без дополнительной проверки подлинности.
3. Автоматическое выполнение действий без подтверждения со стороны пользователя.
🔧 Обеспечить безопасность вашего приложения помогут:
1. Внедрение CSRF-токен в формы и проверка их на сервере перед выполнением действия.
2. Использование сессионных токенов для подтверждения подлинности пользователя.
3. Ограничение привилегий доступа к функциями изменения данных.
В общем случае, основным способом защиты является CSRF-токен, который добавляется к запросам и проверяется на сервере, чтобы удостовериться, что действия совершает пользователь, а не злоумышленник.
Для обеспечения максимальной безопасности токен должен быть:
- уникальным для каждой сессии (чтобы предотвратить повторное использование)
- зашифрованным (чтобы предотвратить возможность изменения токена злоумышленником)
- непредсказуемым (сгенерирован с использованием криптографически безопасного генератора по надежному алгоритму)
Подробнее о данном виде атак и методах защиты можно найти в шпаргалке OWASP.
Применяя данные советы, вы добавите еще один слой защиты к своим приложениям.
#безопасность
Март 2024:
навыки
✔️ Завершил практикум по безопасной разработке. Со всеми задачами можно познакомиться здесь. Планирую еще выпустить несколько постов по темам: IDOR, Path Traversal и SQL Injection.
✔️ Поучаствовал в оффлайн митапе Go-сообщества. Послушал про фаззинг и альтернативу buf.
✔️ Приступил к книге Head First Design Patterns, изучил 2 паттерна и реализовал их на Go
✔️ Продолжаю изучать ООП. Нравится, что эта парадигма заставляет думать иначе, нежели чем функциональный подход, однако, общие принципы к проектированию программы схожи.
✔️ Поделился рефлексией о том, как писать комментарии к своему коду.
✔️ Рефлексия о важности атомарных изменений. Частые коммиты лучше, чем редкие и большие.
карьера
✔️ Обсудил с тим-лидом возможности роста и будущий проект, который позволит перейти на следующий уровень экспертизы. Написал пост о важности коммуникации со своим руководителем.
прочее
✔️ Не открывал прошлую IDE (Goland) более месяца. Отлично справляюсь с VS Code. Можно сказать, что переход прошел легко.
#результаты
навыки
✔️ Завершил практикум по безопасной разработке. Со всеми задачами можно познакомиться здесь. Планирую еще выпустить несколько постов по темам: IDOR, Path Traversal и SQL Injection.
✔️ Поучаствовал в оффлайн митапе Go-сообщества. Послушал про фаззинг и альтернативу buf.
✔️ Приступил к книге Head First Design Patterns, изучил 2 паттерна и реализовал их на Go
✔️ Продолжаю изучать ООП. Нравится, что эта парадигма заставляет думать иначе, нежели чем функциональный подход, однако, общие принципы к проектированию программы схожи.
✔️ Поделился рефлексией о том, как писать комментарии к своему коду.
✔️ Рефлексия о важности атомарных изменений. Частые коммиты лучше, чем редкие и большие.
карьера
✔️ Обсудил с тим-лидом возможности роста и будущий проект, который позволит перейти на следующий уровень экспертизы. Написал пост о важности коммуникации со своим руководителем.
прочее
✔️ Не открывал прошлую IDE (Goland) более месяца. Отлично справляюсь с VS Code. Можно сказать, что переход прошел легко.
#результаты
🔥3
Как хорошо вы знаете свой язык программирования? [1/2]
Речь не про знание исходного кода (про что очень любят спрашивать на собеседованиях, например, по Go: "как устроена мапа"), а про то, что есть неочевидные вещи, которые вынуждают вас ошибаться.
Сможете правильно сказать что выведет код представленный ниже?
Выберите свой ЯП и, не раздумывая, попробуйте ответить. Затем проверьте себя.
Ответы:
C#, Julia, Swift: 100
Go, Java, Javanoscript, PHP: 98
Kotlin, Python: ERROR!
Речь не про знание исходного кода (про что очень любят спрашивать на собеседованиях, например, по Go: "как устроена мапа"), а про то, что есть неочевидные вещи, которые вынуждают вас ошибаться.
Сможете правильно сказать что выведет код представленный ниже?
Выберите свой ЯП и, не раздумывая, попробуйте ответить. Затем проверьте себя.
var sum = 90 + 010;
System.Console.WriteLine(sum);
func main() {
sum := 90 + 010
fmt.Println(sum)
}
sum = 90 + 010
print(sum)
public class Main
{
public static void main(String[] args) {
var sum = 90 + 010;
System.out.println(sum);
}
}
var sum = 90 + 010
console.log(sum)
fun main() {
var sum = 90 + 010
println(sum)
}
<?php
$sum = 90 + 010;
echo $sum;
sum = 90 + 010
print(sum)
var sum = 90 + 010
print(sum)
Ответы:
Go, Java, Javanoscript, PHP: 98
Kotlin, Python: ERROR!
🔥3
Как хорошо вы знаете свой язык программирования? [2/2]
"SyntaxError: leading zeros in decimal integer literals are not permitted; use an 0o prefix for octal integers". - С такой ошибкой ругнется интерпретатор Python, если выполните код, предложенный выше.
Из 9 представленных языков синтаксис также не устроит и компилятор Kotlin. А остальные? :)
Ответ
Извини JavaScript, но когда вижу, что
Go солидарен с Python, но при этом допускает оба написания:
Очевидно, что нужно всегда предпочитать второй вариант (если возможно), чтобы исключить ложные интерпретации результата.
Кстати говоря, Go также позволяет следующие префиксы:
Для чего вообще такой трюк с восьмеричной системой нужен? Например, для задания прав доступа в Unix при работе с файлами: 0777 (но лучше, конечно, 0o777).
Если знаете другое применение или причину почему так сделано в языке, обязательно делитесь в комментариях.
Настоящая экспертиза в использовании определенного ЯП проявляется именно в нюансах: написание выразительного кода, правильная работа со структурами данных не допускающая утечек памяти и пр.
Присмотритесь к книгам издательства Manning. У них есть серия
Найдите книгу, где собраны ошибки и рекомендации по использованию вашего языка, изучите вдумчиво (рефлексия очень важна) и вы почувствуете как сильно увеличили свой уровень.
"SyntaxError: leading zeros in decimal integer literals are not permitted; use an 0o prefix for octal integers". - С такой ошибкой ругнется интерпретатор Python, если выполните код, предложенный выше.
Из 9 представленных языков синтаксис также не устроит и компилятор Kotlin. А остальные? :)
Ответ
100 кажется интуитивный, поэтому к C#, Julia и Swift вопросов нет, но почему другие допускают такую вольность или это чем-то обусловлено? 98 мы получаем, когда появляются ведущие нули перед числом и (!) оно представлено в восьмеричной системе счисления (все цифры меньше 8), то есть на 090 + 010 нормальный язык уже заругается, что, конечно, разумно. Извини JavaScript, но когда вижу, что
console.log(090 + 010) все также выведет 98 , мой мир логики рушится. Очень уважаю людей, кто не путается со всеми подобными особенностями JS. Go солидарен с Python, но при этом допускает оба написания:
90 + 010 <=> 90 + 0o10Очевидно, что нужно всегда предпочитать второй вариант (если возможно), чтобы исключить ложные интерпретации результата.
Кстати говоря, Go также позволяет следующие префиксы:
0b, 0o, 0x - подробнее их описывал здесь.Для чего вообще такой трюк с восьмеричной системой нужен? Например, для задания прав доступа в Unix при работе с файлами: 0777 (но лучше, конечно, 0o777).
Если знаете другое применение или причину почему так сделано в языке, обязательно делитесь в комментариях.
Настоящая экспертиза в использовании определенного ЯП проявляется именно в нюансах: написание выразительного кода, правильная работа со структурами данных не допускающая утечек памяти и пр.
Присмотритесь к книгам издательства Manning. У них есть серия
100 {Language} Mistakes and How To Avoid Them. Я сейчас дочитываю "100 Go Mistakes and How to Avoid Them" и это must have для всех, кто изучает Go, в связке с какой-нибудь базовой книгой или гайда, как, например, A Tour of Go. Найдите книгу, где собраны ошибки и рекомендации по использованию вашего языка, изучите вдумчиво (рефлексия очень важна) и вы почувствуете как сильно увеличили свой уровень.
Как проходить технические собеседования?
Тренироваться.
С одной стороны это может показаться странным, ведь собеседование - всего лишь проверка твоих знаний и навыков: ты либо знаешь, либо нет.
Но не все так просто. Одно дело рассказывать про то, чем ты занимался прошлые годы и совсем другое - показывать свои способности вживую на время. И речь сейчас пойдет про лайвкодинг.
Представьте: есть ваша ежедневная задача на полспринта и декомпозируйте ее на подзадачи. А теперь пригласите 2-х старших разработчиков, поставьте себе таймер на 30 минут, возьмите одну из подзадач и с уверенностью попробуйте решить.
Если получилось, то у вас никаких проблем нет и вы легко пройдете в любую компанию при наличии опыта. Но, если это стало испытанием для вас, то нужно тренироваться проходить собеседования, даже если не собираетесь менять работу.
. . .
В прошлом месяце меня заинтересовал один стартап. Я написал рекрутеру, и текущее место работы без проблем мне обеспечило скрининг-интервью, где я рассказал про свой опыт и узнал про компанию больше.
Меня пригласили на второй этап - техническое интервью. Я попросил неделю времени, чтобы подготовиться, так как 2 года не было опыта прохождения тех. этапов.
Настал день интервью, где в течение 1.5 часов мы общались про Go, базы данных и немного про брокеров сообщений (в частности Kafka). Хочется отдать компании должное: собеседование на 90% состояло из практических задач, а я, к своей неудачи, всю прошлую неделю готовился к теории...
Мы хорошо поговорили, но уверенности в моих ответах не было и, вероятно, сказывалось волнение, поэтому делал невынужденные ошибки.
На следующий этап меня не пригласили, но дали очень хорошую обратную связь (что очередной раз подтверждает здоровый процесс найма в компании) и предложили попробовать через полгода, так как я им понравился.
. . .
Зачем проходить собеседования в другие компании, если полностью доволен текущим местом? Подсознательно я чувствовал, что это может быть полезно и это действительно было по нескольким причинам:
0️⃣ Когда работаешь в крупной компании, то в какой-то момент начинает казаться, что все по плечу и ты с легкостью найдешь работу. Такие ситуации тебя приземляют и ты вспоминаешь, что нужно тренироваться, чтобы проходить технические секции. 1 неделя для тренировки - очень мало, комфортный темп 2-4 недели (зависит от класса компании, в FAANG могут уйти месяцы).
1️⃣ Даже легкое волнение влияет на внимательность. Пример с собеседования: инициализация слайса
2️⃣ Я понял, что сильно погружен в продуктовую / бизнес разработку, из-за чего отлично разбираюсь в продуктовых контекстах, запусках и сетапах AB-экспериментов, но могу быть неуверенным при работе с транзакциями, написании SQL-запросов или траблшутингом сервисов, так как работаю с этим мало.
3️⃣ За время, что я готовился к собеседованию, значительно увеличил свои знания в Go и Kafka, изучая лучшие практики и особенности работы.
4️⃣ Лучше узнал себя. Когда тебя спрашивает интервьюер о мотивации для смены работы, то пытаешься найти честный ответ и ты его действительно можешь найти. У меня теперь такой ответ есть, он и до этого был, но сейчас я его достаточно точно формализовал, чтобы стратегически с ним более плотно работать.
В марте рассказывал о том, что можно сделать прямо сейчас, если заскучали на текущем месте с задачами.
P.S.: Если будет интерес, то обязательно разберу задачи с собеседования, они довольно легкие, но по-своему полезные.
С одной стороны это может показаться странным, ведь собеседование - всего лишь проверка твоих знаний и навыков: ты либо знаешь, либо нет.
Но не все так просто. Одно дело рассказывать про то, чем ты занимался прошлые годы и совсем другое - показывать свои способности вживую на время. И речь сейчас пойдет про лайвкодинг.
Представьте: есть ваша ежедневная задача на полспринта и декомпозируйте ее на подзадачи. А теперь пригласите 2-х старших разработчиков, поставьте себе таймер на 30 минут, возьмите одну из подзадач и с уверенностью попробуйте решить.
Если получилось, то у вас никаких проблем нет и вы легко пройдете в любую компанию при наличии опыта. Но, если это стало испытанием для вас, то нужно тренироваться проходить собеседования, даже если не собираетесь менять работу.
. . .
В прошлом месяце меня заинтересовал один стартап. Я написал рекрутеру, и текущее место работы без проблем мне обеспечило скрининг-интервью, где я рассказал про свой опыт и узнал про компанию больше.
Меня пригласили на второй этап - техническое интервью. Я попросил неделю времени, чтобы подготовиться, так как 2 года не было опыта прохождения тех. этапов.
Настал день интервью, где в течение 1.5 часов мы общались про Go, базы данных и немного про брокеров сообщений (в частности Kafka). Хочется отдать компании должное: собеседование на 90% состояло из практических задач, а я, к своей неудачи, всю прошлую неделю готовился к теории...
Мы хорошо поговорили, но уверенности в моих ответах не было и, вероятно, сказывалось волнение, поэтому делал невынужденные ошибки.
На следующий этап меня не пригласили, но дали очень хорошую обратную связь (что очередной раз подтверждает здоровый процесс найма в компании) и предложили попробовать через полгода, так как я им понравился.
. . .
Зачем проходить собеседования в другие компании, если полностью доволен текущим местом? Подсознательно я чувствовал, что это может быть полезно и это действительно было по нескольким причинам:
0️⃣ Когда работаешь в крупной компании, то в какой-то момент начинает казаться, что все по плечу и ты с легкостью найдешь работу. Такие ситуации тебя приземляют и ты вспоминаешь, что нужно тренироваться, чтобы проходить технические секции. 1 неделя для тренировки - очень мало, комфортный темп 2-4 недели (зависит от класса компании, в FAANG могут уйти месяцы).
1️⃣ Даже легкое волнение влияет на внимательность. Пример с собеседования: инициализация слайса
make([]int, 4) дает cap=4, len=4, но я почему-то воспринял это как cap=4, len=0, прочитав make([]int, 0, 4), несмотря на то, что я проговорил правило вслух. Такие вещи должны тренироваться до автоматизма, чтобы не совершать глупых ошибок. 2️⃣ Я понял, что сильно погружен в продуктовую / бизнес разработку, из-за чего отлично разбираюсь в продуктовых контекстах, запусках и сетапах AB-экспериментов, но могу быть неуверенным при работе с транзакциями, написании SQL-запросов или траблшутингом сервисов, так как работаю с этим мало.
3️⃣ За время, что я готовился к собеседованию, значительно увеличил свои знания в Go и Kafka, изучая лучшие практики и особенности работы.
4️⃣ Лучше узнал себя. Когда тебя спрашивает интервьюер о мотивации для смены работы, то пытаешься найти честный ответ и ты его действительно можешь найти. У меня теперь такой ответ есть, он и до этого был, но сейчас я его достаточно точно формализовал, чтобы стратегически с ним более плотно работать.
В марте рассказывал о том, что можно сделать прямо сейчас, если заскучали на текущем месте с задачами.
P.S.: Если будет интерес, то обязательно разберу задачи с собеседования, они довольно легкие, но по-своему полезные.
🔥6
Разбираем задачи с технической секции (платформа Go)
Решил остановиться на 3-х задачах, так как они довольно показательные, несмотря на простоту. Интервью еще включало задание на код-ревью готового пул-реквеста, написание SQL-запросов и сопутствующие вопросы про БД, транзакции и Kafka.
Так как стандартных средств форматирования для такого лонгрида мне не хватило, то тестирую telegraph.
Решил остановиться на 3-х задачах, так как они довольно показательные, несмотря на простоту. Интервью еще включало задание на код-ревью готового пул-реквеста, написание SQL-запросов и сопутствующие вопросы про БД, транзакции и Kafka.
Так как стандартных средств форматирования для такого лонгрида мне не хватило, то тестирую telegraph.
Telegraph
Разбор задач на позицию Go developer (Middle+ / Senior)
Чтобы успешно проходить собеседования, нужно практиковаться. Особенно важно - уделять внимание психологической подготовке, чтобы не волноваться и показывать весь свой потенциал. Недавно рассказывал свою историю собеседования в один интересный стартап. В этой…
С чего начинать код-ревью? [1/2]
ℹ️ Дисклеймер. Как именно давать обратную связь мы не затронем, но это очень важная тема, про которую нельзя забывать. Рекомендую материал по теме.
Код-ревью - неотъемлемая часть работы программиста любого уровня. И крайне полезный навык - уметь это делать быстро, так как иначе у вас не останется времени на свои задачи, и, конечно, качественно.
На собеседованиях также любят про это спрашивать. Задание может выглядеть так: "Представь, что этот код тебе пришел на код-ревью, как ты его прокомментируешь, апрувнишь ли"?
Для себя я выработал некоторый алгоритм, к которому обращаюсь каждый раз, когда от меня запрашивается ревью.
Алгоритм (1/2):
0️⃣ Погружаюсь в контекст. Для этого достаточно прочитать описание задачи, по которой выполнен данный пул-реквест (далее ПР). Хорошая практика - линковать к ПР номер таски Джиры или другой системы учета тасок. В Авито, например, название git-ветки начинается с номера Jira issue (иначе линтер не пропустит), а Bitbucket это распознает и делает кликабельную ссылку, поэтому легко можно навигироваться к задаче.
1️⃣ В первом приближении сравниваю описание задачи с фактической реализацией: смотрю в какой сервис или библиотеку сделан ПР, пытаюсь сопоставить критерии приемки с кодом, если они написаны и это вообще применимо. Часто бывает так, что по описанию задачи можно ничего не понять о том, что должно быть сделано, если, например, это задача другой команды или незнакомого домена.
2️⃣ Если после п.1 вопросов не возникло, то ревью начинаем с первой измененной строчки, в нашем случае с обозначения пакета, обращаем внимание на нейминг. Очевидно, что название domain никак не характеризует свое содержание, поэтому первым предложением может стать переименование пакета в соответствии с назначением добавляемого функционала: storage - лучше.
3️⃣ Далее импорты. Часто проблемой может быть их сортировка. Хотя настроенный CI/CD, конечно, не пропустит здесь вольность, но, если он вдруг не настроен и мы видим, что разработчик устроил беспорядок, то лучше ему порекомендовать исправить: например, использовать goimports или другие инструменты для форматирования, чтобы соблюсти код-стайл.
4️⃣ Пока далеко не ушли, то следует обратить внимание на нейминг. Некорректный алиас в импортах хоть и не является блокером, но лучше также соблюдать стиль языка (рекомендации); спойлер - стараться делать кратко, используя одно существительное, если говорим про Go.
5️⃣ И снова про нейминг. Важно обращать внимание на именование переменных, функций и пр. Применительно к нашему примеру, если мы пакет рекомендовали переименовать в storage, то большинство названий можно упростить:
6️⃣ Лучшие практики. Тут многое еще зависит от специфики проекта, но применительно к нашему случаю можно предположить, что напрямую использовать db sql.DB - не очень хорошо, а лучше работать с соединениями или их пуллом, который будет инициироваться при старте приложения.
И это далеко не все. Мы рассмотрели лишь одну часть, которая носит больше рекомендательный характер на реальном ревью.
🤔 Возможно я что-то упустил из опциональных комментариев к ПР и, если вы это заметили, то обязательно делитесь опытом и пишите в тред - вместе соберем ультимативный список-шпаргалку по проведению код-ревью.
В следующем посте обсудим основные блокеры, без исправления которых ваш код не пропустят в прод 🚫
ℹ️ Дисклеймер. Как именно давать обратную связь мы не затронем, но это очень важная тема, про которую нельзя забывать. Рекомендую материал по теме.
Код-ревью - неотъемлемая часть работы программиста любого уровня. И крайне полезный навык - уметь это делать быстро, так как иначе у вас не останется времени на свои задачи, и, конечно, качественно.
На собеседованиях также любят про это спрашивать. Задание может выглядеть так: "Представь, что этот код тебе пришел на код-ревью, как ты его прокомментируешь, апрувнишь ли"?
package domain
import (
"database/sql"
"fmt"
"time"
)
type UserStatusHistoryStore struct {
db *sql.DB
}
func New() UserStatusHistoryStore {
db, err := sql.Open("mysql", "username:password@tcp(127.0.0.1:3306)/jazzrecords")
if err != nil {
panic(err)
}
return UserStatusHistoryStore{
db: db,
}
}
func (s *UserStatusHistoryStore) Save(userID, partition, status string) {
query := fmt.Sprintf("insert into userstatushistory (user_id, status, inserted_at) values (%v, %v, %v, %v)", userID, partition, status, time.Now())
s.db.Exec(query)
}
Для себя я выработал некоторый алгоритм, к которому обращаюсь каждый раз, когда от меня запрашивается ревью.
Алгоритм (1/2):
0️⃣ Погружаюсь в контекст. Для этого достаточно прочитать описание задачи, по которой выполнен данный пул-реквест (далее ПР). Хорошая практика - линковать к ПР номер таски Джиры или другой системы учета тасок. В Авито, например, название git-ветки начинается с номера Jira issue (иначе линтер не пропустит), а Bitbucket это распознает и делает кликабельную ссылку, поэтому легко можно навигироваться к задаче.
1️⃣ В первом приближении сравниваю описание задачи с фактической реализацией: смотрю в какой сервис или библиотеку сделан ПР, пытаюсь сопоставить критерии приемки с кодом, если они написаны и это вообще применимо. Часто бывает так, что по описанию задачи можно ничего не понять о том, что должно быть сделано, если, например, это задача другой команды или незнакомого домена.
2️⃣ Если после п.1 вопросов не возникло, то ревью начинаем с первой измененной строчки, в нашем случае с обозначения пакета, обращаем внимание на нейминг. Очевидно, что название domain никак не характеризует свое содержание, поэтому первым предложением может стать переименование пакета в соответствии с назначением добавляемого функционала: storage - лучше.
3️⃣ Далее импорты. Часто проблемой может быть их сортировка. Хотя настроенный CI/CD, конечно, не пропустит здесь вольность, но, если он вдруг не настроен и мы видим, что разработчик устроил беспорядок, то лучше ему порекомендовать исправить: например, использовать goimports или другие инструменты для форматирования, чтобы соблюсти код-стайл.
4️⃣ Пока далеко не ушли, то следует обратить внимание на нейминг. Некорректный алиас в импортах хоть и не является блокером, но лучше также соблюдать стиль языка (рекомендации); спойлер - стараться делать кратко, используя одно существительное, если говорим про Go.
5️⃣ И снова про нейминг. Важно обращать внимание на именование переменных, функций и пр. Применительно к нашему примеру, если мы пакет рекомендовали переименовать в storage, то большинство названий можно упростить:
UserStatusHistoryStore -> UserStatusHistory и т.д. 6️⃣ Лучшие практики. Тут многое еще зависит от специфики проекта, но применительно к нашему случаю можно предположить, что напрямую использовать db sql.DB - не очень хорошо, а лучше работать с соединениями или их пуллом, который будет инициироваться при старте приложения.
И это далеко не все. Мы рассмотрели лишь одну часть, которая носит больше рекомендательный характер на реальном ревью.
🤔 Возможно я что-то упустил из опциональных комментариев к ПР и, если вы это заметили, то обязательно делитесь опытом и пишите в тред - вместе соберем ультимативный список-шпаргалку по проведению код-ревью.
В следующем посте обсудим основные блокеры, без исправления которых ваш код не пропустят в прод 🚫
👍2
С чего начинать код-ревью? [2/2]
В первой части мы рассмотрели опциональные комментарии, а сегодня поговорим про возможные блокеры на код-ревью. Код будем использовать тот же (см. в первом посте).
Алгоритм (2/2):
7️⃣ Тесты. Вся логика должна быть покрыта тестами. Обязательно. В крайних случаях, если может сорваться запуск эксперимента или нужен срочный хот фикс, допускается завести задачу на написание тестов и положить ее в будущий спринт. На интервью, если показывают только один файл, как на нашем примере, то обязательно проговорить, что должны быть тесты на новую логику.
8️⃣ Общая архитектура (в т.ч. организация директорий в проекте). Свое ли место занимает код, правильно лил организован в пакетах, доступен ли для расширения другими командами и пр. Тема очень обширная. В чужом сервисе иногда сложно понять общую концепцию, посмотрев всего несколько файлов, но при наличии опыта плохую архитектуру видно сразу.
9️⃣ Принципиальным моментом может стать сигнатура функции. Важно обращать внимание на то, что мы передаем (и как) и что возвращаем. В нашем примере можно заметить 2 вещи: 1) Мы работаем с базой данных, но не передаем контекст (ctx.Context) а значит теряем гибкость и другие полезные возможности; 2) Передаем партицию БД в функцию, чего мы делать явно не должны на этом уровне (c партициями работаем снаружи).
1️⃣0️⃣ Нагрузка. Если у вас высоконагруженное приложение, то крайне важно обратить внимание на создаваемую вашими изменениями нагрузку. Согласована ли она с оунерами сервиса и готовы ли мы к ней? Отсюда вытекают всевозможные оптимизации, такие как использование горутин (если возможно делать несколько действий асинхроонно) и работа с ними. Частая ошибка - пересоздавать какой-нибудь объект в цикле в то время, когда он не меняется при итерациях и есть удобная возможность объявить его до.
1️⃣1️⃣ Работа с секретами. Обращайте внимание на то, как организована работа с переменными среды и различными секретами. Очевидно, что:
sql.Open("mysql", "username:password@tcp(127.0.0.1:3306)/jazzrecords") - недопустимо. Чувствительную информацию нужно получать из окружения или защищенного хранилища.
1️⃣2️⃣ Наличие уязвимостей. Так как мы работаем с БД, то важно проверить код на наличие инъекции. Подобный запрос уязвим:
query := fmt.Sprintf("insert into userstatushistory (user_id, status, inserted_at) values (?, ?, ?, ?)", userID, partition, status, time.Now())
Пользовательский ввод важно валидировать. Можно использовать различные средства предоставляемые библиотеками:
После всех исправлений финальный код может выглядеть так:
При этом важно акцентировать внимание на наличии тестов, согласование нагрузки, правильности архитектуры, а также читаемости и простоты поддержки кода.
Если вы учли все вышеописанное, то с большой долей вероятности пройдете очередное код-ревью.
В первой части мы рассмотрели опциональные комментарии, а сегодня поговорим про возможные блокеры на код-ревью. Код будем использовать тот же (см. в первом посте).
Алгоритм (2/2):
7️⃣ Тесты. Вся логика должна быть покрыта тестами. Обязательно. В крайних случаях, если может сорваться запуск эксперимента или нужен срочный хот фикс, допускается завести задачу на написание тестов и положить ее в будущий спринт. На интервью, если показывают только один файл, как на нашем примере, то обязательно проговорить, что должны быть тесты на новую логику.
8️⃣ Общая архитектура (в т.ч. организация директорий в проекте). Свое ли место занимает код, правильно лил организован в пакетах, доступен ли для расширения другими командами и пр. Тема очень обширная. В чужом сервисе иногда сложно понять общую концепцию, посмотрев всего несколько файлов, но при наличии опыта плохую архитектуру видно сразу.
9️⃣ Принципиальным моментом может стать сигнатура функции. Важно обращать внимание на то, что мы передаем (и как) и что возвращаем. В нашем примере можно заметить 2 вещи: 1) Мы работаем с базой данных, но не передаем контекст (ctx.Context) а значит теряем гибкость и другие полезные возможности; 2) Передаем партицию БД в функцию, чего мы делать явно не должны на этом уровне (c партициями работаем снаружи).
1️⃣0️⃣ Нагрузка. Если у вас высоконагруженное приложение, то крайне важно обратить внимание на создаваемую вашими изменениями нагрузку. Согласована ли она с оунерами сервиса и готовы ли мы к ней? Отсюда вытекают всевозможные оптимизации, такие как использование горутин (если возможно делать несколько действий асинхроонно) и работа с ними. Частая ошибка - пересоздавать какой-нибудь объект в цикле в то время, когда он не меняется при итерациях и есть удобная возможность объявить его до.
1️⃣1️⃣ Работа с секретами. Обращайте внимание на то, как организована работа с переменными среды и различными секретами. Очевидно, что:
sql.Open("mysql", "username:password@tcp(127.0.0.1:3306)/jazzrecords") - недопустимо. Чувствительную информацию нужно получать из окружения или защищенного хранилища.
1️⃣2️⃣ Наличие уязвимостей. Так как мы работаем с БД, то важно проверить код на наличие инъекции. Подобный запрос уязвим:
query := fmt.Sprintf("insert into userstatushistory (user_id, status, inserted_at) values (?, ?, ?, ?)", userID, partition, status, time.Now())
Пользовательский ввод важно валидировать. Можно использовать различные средства предоставляемые библиотеками:
rows, err := db.Query("insert into userstatushistory (user_id, status, inserted_at) values (%v, %v, %v, %v)", user_id, status_ inserted_at)
После всех исправлений финальный код может выглядеть так:
// package domain
package storage
import (
"context"
"database/sql"
"fmt"
"os"
"time"
)
// type UserStatusHistoryStore struct {
type UserStatusHistory struct {
db *sql.DB
}
// func New() UserStatusHistoryStore {
func New() UserStatusHistory {
// db, err := sql.Open("mysql", "username:password@tcp(127.0.0.1:3306)/jazzrecords")
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/jazzrecords", os.Getenv("user"), os.Getenv("password"), os.Getenv("ip")))
if err != nil {
panic(err)
}
// return UserStatusHistoryStore{
return UserStatusHistory{
db: db,
}
}
// func (s *UserStatusHistoryStore) Save(userID, partition, status string) {
func (s *UserStatusHistory) Save(ctx context.Context, userID, status string) error {
// query := fmt.Sprintf("insert into userstatushistory (user_id, status, inserted_at) values (%v, %v, %v, %v)", userID, partition, status, time.Now())
// s.db.Exec(query)
_, err := s.db.Query("insert into userstatushistory (user_id, status, inserted_at) values (%v, %v, %v)", userID, status, time.Now())
if err != nil {
return err
}
// ...
return nil
}
При этом важно акцентировать внимание на наличии тестов, согласование нагрузки, правильности архитектуры, а также читаемости и простоты поддержки кода.
Если вы учли все вышеописанное, то с большой долей вероятности пройдете очередное код-ревью.
Telegram
Новиков > путь в Big Tech
С чего начинать код-ревью? [1/2]
ℹ️ Дисклеймер. Как именно давать обратную связь мы не затронем, но это очень важная тема, про которую нельзя забывать. Рекомендую материал по теме.
Код-ревью - неотъемлемая часть работы программиста любого уровня. И крайне…
ℹ️ Дисклеймер. Как именно давать обратную связь мы не затронем, но это очень важная тема, про которую нельзя забывать. Рекомендую материал по теме.
Код-ревью - неотъемлемая часть работы программиста любого уровня. И крайне…
👍2