Coding: архитектура, программирование и разработка, подходы, best practices, devops, containers (k8s, docker, nomad, mesos), releases, waterfall/agile, scrum, sprints, CI/CD, Serverless computing, Microservice Architecture

 Программирование Best Practices
  • Соответствие кода best practice (code style, security и проч) могут проверять как IDE, так и отдельные мощные продукты типа SonarQube.
  • Code review/document review – крайне важный аспект в программировании в каких-либо командах, помимо покрытия этого вопроса инструментами вроде git/tfs есть отдельные инструменты типо smartbear Collaborator
  • Стараться не повторять код, Code reuse – критичный аспект в программировании сейчас.
    • использовать функции
    • использовать чужой код (библиотеки и проч)
  • Стараться делить большой/сложный код на отдельные простые функции
  • Даже если язык case-sensitive (переменная Var != var), не стоит это использовать
  • Даже если в языке не задано ограничение по неймингу переменных/функций/классов, стоит использовать стандарты
  • Даже если язык позволяет назвать одинаково переменную и функцию/метод, не стоит это использовать
  • Страуструп “язык программирования c++” считается очень сильной книгой для программистов, которую мало кто может полностью прочитать и понять
  • Идеология PHP от создателя Rasmus Lerdord:
    • лучше иметь плохо работающий в каких то условиях функционал/библиотеку, но который позволяет решить задачи, чем не иметь функционала вообще. Если вы спорите без предложения альтернативной реализации (просто ноете) – вы скорей всего проиграете спор.

 

    • я изначально не интересовался программированием – для меня это было средство решения моих задач и программирование было дотошным/скучным. Я старался минимизировать время, которое посвещаю программированию, отсюда появился PHP – его первая версия позволяла мне очень быстро реализовывать проекты клиентам)))) уже потом люди начали интересоваться и привносить свою лепту и я поделился своим проектом – я продавал услуги решения проблем, не инструмент (мой “hammer”). И люди сдавали мне баги, а я их фиксил у клиентов, которые удивлялись моей продуктивности)) Это был 1994, до того как термин open source еще появился. В 1997 я передал права на CVS репозиторий, чтобы любой мог вносить свою лепту в язык и считать его своим (это легко и сейчас, таких аккаунтов более 1000, где-то половина из которых что-то коммитила за последний год). Я старался сделать максимально простым как сам язык, так и возможность его совершенствовать – я лучше помогу новому контрибьютору и укажу на его ошибки, чтобы он стал более продуктивен, чем буду орать на него и отпугну его от проекта.

             

  • Не нужно учить синтаксис, будь то программирование или работа с устройствами. Намного важнее понимать технологии и принципы. Синтаксис на практике натаскается или за’tab’ится (в IDE/CLI).
  • Нет самых лучших языков во всем, так же как и самых худших. Нужно рассматривать язык как инструмент для достижения цели, какие то языки могут решать задачу быстрее/качественнее/надежнее. Знание одного языка существенно облегчает изучение другого (SRE Google).
You should think about any given programming language as being just one of the potential tools in the IT support specialist toolbox. From traditionally platform specific scripting languages like PowerShell for Windows and Bash for Linux, to more general purpose scripting languages, similar to Ruby, like Python and Pearl. There are many options available to the IT support specialist who is interested in automation. If you want, there's also a whole world of more traditionally compiled languages like C, C++, Java, and Go to Explorer. One nice feature of learning the basics of programming in one language is that the concepts you learn can generally be applied to other languages. This transferability means that becoming familiar with a language like Ruby will help you pick up new languages in the future, because you'll be able to spot similarities between them and understand their differences.
  • Документация, исправление багов и работа с community зачастую важнее самого кода – создатель JQuery пишет, что это была единственная среди конкурентов библиотека с документацией (причем актуальной и на весь функционал) и во многом из-за этого она выстрелила.
  • Крупные релизы ПО обычно выходят раз в месяц/два. Реже раз в неделю-две.
  • Высшая математика и алгоритмы редко нужны в программировании. Важнее знать существующие инструменты/библиотеки/умение писать. Сложной математики не много в бизнес задачах.
  • Митапы по IT (coding, devops, bigdata, AI, etc) круты тем, что инфа с них хорошо усваивается и зачастую уникальна. 
  • На stackoverflow для популярных языков есть почти все. Поэтому есть термин stackoverflow coding.
  • Классы – спорно.
    • Есть мнение, что классы следует использовать уже при 100-300 строках кода.
    • Но есть и оппоненты этому мнению с справедливыми аргументами, которые говорят на основе практики, что создавать классы без большой reusability и продуманной архитектуры/структуры является, зачастую, вредным мероприятием. Это не редко усложнение структуры кода, кроме того, многие отказываются от классов ООП (напр. сделанных в C++ в пользу “плоского” C) из-за проблем с производительностью. В классах, при их использовании, наследование следует исключать или избегать – классы общаться между собой должны.
  • Текущий фронтент сложен. После базого курса по js bootstrap (хорошая тема для backend в том числе) все намного сложнее (dom model, flow, rendering и прочее).
  • Nested conditions (напр. вложенные if) лучше максимально избегать т.к. их сложно читать и менять. Лучше их заменять, например, логическими операциями.
Although the indentation of the statements makes the structure apparent, nested conditionals become difficult to read very quickly. In general, it is a good idea to avoid them when you can. Logical operators often provide a way to simplify nested conditional statements.
  • Есть такая общая концепция что explicit лучше чем implicit, но в контексте завершения каждого кода exit или в результате метода выдавать return (в случае с Ruby не обязательно) – это не тот кейс. 
You will notice that there was no need to have quit() at the end of the Python program in the file. When Python is reading your source code from a file, it knows to stop when it reaches the end of the file.
Whitespace errors can be tricky because spaces and tabs are invisible and we are used to ignoring them.
  • Раньше была концепция наличия единой точки выхода (exit point) в коде – сейчас это скорее не актуально
https://stackoverflow.com/questions/4838828/why-should-a-function-have-only-one-exit-point
There are different schools of thought, and it largely comes down to personal preference.
- One is that it is less confusing if there is only a single exit point - you have a single path through the method and you know where to look for the exit. On the minus side if you use indentation to represent nesting, your code ends up massively indented to the right, and it becomes very difficult to follow all the nested scopes.
- Another is that you can check preconditions and exit early at the start of a method, so that you know in the body of the method that certain conditions are true, without the entire body of the method being indented 5 miles off to the right. This usually minimises the number of scopes you have to worry about, which makes code much easier to follow.
- A third is that you can exit anywhere you please. This used to be more confusing in the old days, but now that we have syntax-colouring editors and compilers that detect unreachable code, it's a lot easier to deal with.
I'm squarely in the middle camp. Enforcing a single exit point is a pointless or even counterproductive restriction IMHO, while exiting at random all over a method can sometimes lead to messy difficult to follow logic, where it becomes difficult to see if a given bit of code will or won't be executed. But "gating" your method makes it possible to significantly simplify the body of the method.

 

 

Стилистика

В разных ЯП может различаться, в среднем (pep8 python):

A blank line at the end of a block of statements is not necessary when writing and executing a script, but it may improve readability of your code.
https://pypi.org/project/pep8-naming/
code    sample message
N801   class names should use CapWords convention
N802   function name should be lowercase
N803   argument name should be lowercase
N804   first argument of a classmethod should be named ‘cls’
N805   first argument of a method should be named ‘self’
N806   variable in function should be lowercase

 

 

Комменты
  • Комментировать в целом хорошо, но избыточное комментирование, как и полное его отсутствие, тоже порок, потому что отвлекает
  • Нужно комментировать в первую очередь ЗАЧЕМ код это делает, а не КАК. Потому что КАК описано в коде.
  • Большую часть комментариев можно избежать если правильно, по смыслу ( “mnemonic variable names”), называть переменные (не слишком длинно). Подробно о важности naming переменных/функций тут.
Good variable names can reduce the need for comments, but long names can make complex expressions hard to read, so there is a trade-off.
We often give variables mnemonic names to help us remember what is stored in the variable.
  • Однозначно комментируются неочевидные (со стороны) вещи
Comments are most useful when they document non-obvious features of the code.

 

short-circuiting evaluation

short-circuiting evaluation – это когда при анализе логического выражения интерпретатор (Python, Ruby, snort content + pcre) заранее знает результат и перестает исполнять его дальше – например:

    • один из элементов TRUE в выражении состоящем из OR
    • один из элементов FALSE в конструкции состоящем из AND
Поэтому сначала зачастую используют наиболее широкие/наименее затратные критерии по оценке (опять же, snort content + pcre), а уже в конце выражения самые узкие/наиболее вычислительно-затратные. 
When Python detects that there is nothing to be gained by evaluating the rest of a logical expression, it stops its evaluation and does not do the computations in the rest of the logical expression. When the evaluation of a logical expression stops because the overall value is already known, it is called short-circuiting the evaluation.
Эта концепция так же используется для защиты от “опасных” операций с проверкой переменных (напр. деление на ноль) в отдельном if: мы создаем перед потенциально опасным логическим выражением guard, который проверяет переменную, которая используется в потенциально опасном логическом выражении. Это называется guardian pattern. 
x >= 2 and (x/y) > 2 % # without guard crashes when devision on zero

The short-circuit behavior leads to a clever technique called the guardian pattern. We can construct the logical expression to strategically place a guard evaluation just before the evaluation that might cause an error as follows:

x >= 2 and y != 0 and (x/y) > 2 % # with guard

 

Этапы разработки ПО

Этапы разработки (кратко):

    • анализ потребностей (требований), возможностей реализации
    • алгоритмизация
    • программирование
    • тестирование
Правильное тестирование: dev -> test -> pre prod -> prod
SAP: D/q/p - development/quality/production servers
  • написание документации
  • написание инструкций по работе

 

Devops и архитектура

Devops включает в себя лучшие практики архитектуры, разработки и эксплуатации, объединяет множество технический и управленческих (project management) актуальных практик.

На основе данных курса Azure Fundamentals.

Software developers and operations professionals strive to create working software systems that satisfy the needs of the organization. However, sometimes their short-term objectives are at cross-purposes, which can result in technical issues, delays, and downtime.

DevOps is a new approach that helps to align technical teams as they work toward common goals. To accomplish this alignment, organizations employ practices and processes that seek to automate the ongoing development, maintenance, and deployment of software systems. Their aim is to expedite the release of software changes, ensure the ongoing deployability of the system, and ensure that all changes meet a high quality bar.

When done correctly, DevOps practices and processes touch nearly every aspect of the company, not to mention the software development lifecycle, including planning, project management, and the collaboration of software developers with each other and with operations and quality assurance teams. Tooling automates and enforces most of the practices and processes, making it both difficult and unnecessary to work around.

DevOps requires a fundamental mindset change from the top down. Organizations can't merely install software tools or adopt services and hope to get all of the benefits promised by DevOps.

Три основных концепций/философии (ways) DevOps:

    • Systems and flow – организация потока работы, работа становится более видимой за счет уменьшения размера работ – большая работа разделяется на ряд мелких с небольшими интервалами между ними (sprints); защита от дефектов реализуется с помощью реализации QA процесса повсеместно (throughout a process)
    • Feedback loop – замыкаем обратную связь из эксплуатации в разработку, защита от того, что проблема произойдет еще раз. Позволяет быстрее обнаруживать проблемы и быстрее их устранять за счет этого. Обучаться на ошибках.
    • Continuous Experimentation and Learning – постоянные эксперименты и обучение, разрешено экспериментировать с рисками, при этом выделяется время на то, чтобы исправлять ошибки и сделать систему лучше; использование shared/central repositories (github, gitlab)

CSIT (Continuous System Integration Testing)пример CI процесса функционального и нагрузочного тестирования Cisco VPP, страница команды (публичная с указанием участников) и можно даже почитать их обсуждения (не перебор ли)

DEVSECOPS

Devsecops – концепт, используемый в последнее время, который описывает, как перенести активности по безопасности к началу цикла разработки. Подразумевает при разработке ПО:

    • внедрение практик по безопасности в CI/CD pipeline; CSIT (Continuous System Integration Testing)
    • внедрение Secure Development Lifecycle (SDLC/SDL)
DevSecOps enables integration of security testing earlier in the software development lifecycle (SDLC). DevSecOps enables seamless application security earlier in the software development lifecycle, rather than at the end when vulnerability findings requiring mitigation are more difficult and costly to implement.

Практики devsecops & SDLC используются многими современными организациями, особенно теми, кто разобрался с devops и реализовал CI/CD.

Примером того, на что будет опираться devsecops/программист SDLC может быть Top 10 owasp proactive control – это набор безопасных практик разработки и руководств которые любой разработчик должен следовать для создания безопасных приложений. Все эти практики помогают перенести безопасность в самые ранние стадии разработки, такие как требования и дизайн, программирование и тестирования.

Top 10 owasp proactive control:

    • Define security requirements
    • Leverage security frameworks and libraries – не переизобретайте колесо (reinvent the wheel), иначе можете наступить на грабли, которые учли в фреймворках
    • Secure database access
    • Encode and escape data
    • Validate all inputs – до сих пор актуальная серьзная проблема многих приложений
    • Implement digital identity
    • Enforce access controls
    • Protect data everywhere – без разницы в облаке или on premise
    • Implement security logging and monitoring
    • Handle all errors and exceptions

Инструментами devsecops могут быть software assurance инструменты. Есть проект на сайте devsecops.github.io, который включает большое количество инструментов и мануалов о Devsecops и практиках devsecops.

    • фаззеры (fuzzers) – Fuzzing позволяет выявить програмные ошибки/баги (связанные в основном с input validation и buffer overflow) в разном ПО за счет отправки рандомных данных на обьект тестирования. Fuzzers – инструменты для fuzzing. Примеры: 
      • radamsa
      • mutiny fuzzing framework (Cisco) – проигрывает packet capture файлы через мутационный фаззер.
    • средства статического тестирования приложений (SAST, static application security testing) – ПО, которое проводит анализ программы (исходных кодов) без ее выполнения.
    • средства динамического тестирования приложений (DAST, dynamic application security testing) – ПО, которое проводит анализ программы с ее выполнением.

 

Releases
Software releases were once scheduled in terms of months or even years. Today, teams release features in smaller batches that are often scheduled in days or weeks. Some teams even deliver software updates continuously--sometimes with multiple releases within the same day.

 

waterfall

В прошлом широко использовалась (а где то и продолжает) методология waterfall, которая представляла из себя подход к разработке ПО из 5 основных фаз (в некоторых интерпретациях 7). Фазы строго следовали друг за другом, фаза не могла начаться, если предыдущая не выполнена.

  • Требования (requirements) к продукту согласовываются на самой ранней стадии. Требования могут быть описаны конечным клиентом в виде user stories, которые описывают, какие проблемы продукт должен решать и как будет продукт использоваться в их среде. Такой подход:
    • позволяет легче разрабатывать архитектуру продукта и проще оценить результат реализованного продукта. Процесс разработки всем понятен и последователен и это основное достоинство.
    • с другой стороны часто все заинтересованные лица не могут определить все необходимые требования к продукту на данной фазе и это приводит к тому, что продукт доходит до фаз verification/maintenance и только на этих фазах выявляются принципиальные недостатки, которые может быть очень дорого исправить. Отсутствует гибкость и это основной недостаток.
  • Дизайн, архитектура (design, architecture)
  • Реализация, программирование (implementation)
  • Проверка, тестирование (verification/testing)
  • Поддержка (maintenance)
Agile

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

 

SCRUM, SPRINTS
  • Scrum.org имеет большое количество материалов, включая даже обучение и сертификацию.
  • Экспертами в scrum, agile, sprints, etc обычно являются project managers.

Scrum концепция используется многими организациями, работающими по Agile. Scrum по сути своей это framework, который позволяет командам организации работать вместе и способствует обучению команд через усвоение опыта за счет анализа (Continuous Experimentation and Learning) побед и поражений. Scrum описывает набор встреч, инструментов, ролей которые будут работать вместе для того чтобы команда структуировала и управляла своей работой.

Scrum методология использует концепцию spint’ов – это двухнедельные периоды, в которые команда работает для решения определенных ранее задач. Sprint’ы это одна из ключевых концепций scrum и agile методологий.

 

CI/CD PipeLines

CI/CD pipelines – процессы CI и CD, которые автоматизируют релиз софта. Поддерживается многими организациями сейчас и это огромное преимущество компаний, которые поддерживают этот процесс.

Каждое изменение кода по сути запускает процесс сборки и тестирования ПО с реализацией feedback (feedback loop) для программистов, которые сделали изменения и всей команды (логи).

  • Continuous Integration (CI) – практика разработки софта при которой программисты постоянно (on ongoing basis), несколько раз в день, merge’ат код в централизованном репозитории типа github/gitlab
  • Continuous Delivery (CD) – полагается на процесс CI, может подразумевать настройку/провиженинг облака под новую сборку софта, что раньше делалось вручную
Serverless computing

Serverless computing = PaaS cloud computing

With serverless applications, the cloud service provider automatically provisions, scales, and manages the infrastructure required to run the code. Serverless architectures are highly scalable and event-driven, only using resources when a specific function or trigger occurs.
  • Serverless – не означает, что вам не понадобится сервер вообще, это означает то, что вы используете облачную платформу (PaaS) для хостинга вашего кода и облачный провайдер, а не вы, отвечает за обслуживание и деплой серверов.
  • Serverless приложения обычно работают в stateless контейнерах, которые являются ephemeral и event trigger – по сути это означает, что они полностью управляются облачным провайдером. Пример такого serverless популярного сервиса – AWS Lambda, Azure Functions.
AWS Lambda – это бессерверный вычислительный сервис, который позволяет исполнять код без необходимости выделять серверы и управлять ими, создавать логику масштабирования кластера с учетом рабочих нагрузок, поддерживать интеграцию событий или управлять временем выполнения. Lambda позволяет выполнять код практически любого приложения или серверного сервиса без администрирования. Просто загрузите свой код в виде ZIP-файла или образа контейнера, и Lambda автоматически и точно выделит вычислительную мощность и запустит код на основе входящего запроса или события для любого масштаба трафика. Можно настроить автоматический запуск программного кода из более чем 200 сервисов AWS и приложений Saas или вызывать его непосредственно из любого мобильного или интернет‑приложения. Функции Lambda можно писать на своем любимом языке (Node.js, Python, Go, Java и др.) и использовать бессерверные и контейнерные инструменты, такие как AWS SAM или Docker CLI, для создания, тестирования и развертывания ваших функций.

 

Microservice architecture

Microservice – небольшая часть (кода) имеющего строгую функциональную задачу (single business capability) и мало связанная с какими то другими Web сервисами. Обычно такие сервисы объединяются в microservice architecture.

A miscroservice is a way to simplify an application erchitecture by focusing on creating smaller, more manageable, autonomous and independently deployed web services.

Команды по поддержке могут быть в рамках каждого сервиса и каждая команда в итоге может выбрать свой язык/среду для реализации сервиса. Упрощается релиз улучшений систем. Divide and conquer:

    • Чем меньше объем кода каждого сервиса, тем проще выпускать релизы и подключать новых людей для разработки (проще разобраться в работе).
    • Команда может обновить существующий сервис без пересборки/редеплоя всего приложения. Плюс упрощается откат (roll back), если что-то пойдет не так.
    • Тестирование упрощается, баги проще найти и устранить. В итоге релизы более управляемые и несут меньше рисков.
    • Scaling микросервисов зачастую проще – можно расширить конкретный проблемный компонент.

Взаимодействия между микросервисами часто реализуются посредством API, но часто используется и подход к созданию отдельного orchestration/management layer в приложении, которое координирует запросы к разным микросервисам и объединяет результат.

Требования к микросервисам: каждый микросервис должен быть автономен – должен сохранять свои данные и состояние, не полагаясь на общий репозиторий. Some microservice experts insist that each microservice should even have its own separate database (как по мне перегиб). This kind of freedom provides a layer of fault isolation. If a service goes down, it won’t necessarily take out the entire application.

Containers are often used to create solutions by using a microservice architecture. This architecture is where you break solutions into smaller, independent pieces. For example, you might split a website into a container hosting your front end, another hosting your back end, and a third for storage. 
This split allows you to separate portions of your app into logical sections that can be maintained, scaled, or updated independently.

 

Инструменты DEVOPS
Сборка ПО

TeamCity

Серверное программное обеспечение от компании JetBrains, написанное на языке Java, билд-сервер для обеспечения непрерывной интеграции. Первый релиз состоялся 2 октября 2006 года.

Оркестрация контейнеров

Оркестрация подразумевает деплоймент, управление, удаление контейнеров. Инструментов разных много, например:

    • Kubernates (k8s) – самый популярный инструмент/фреймворк управления контейнерами. Изначально разработан Google. В github находится как код k8s, так и в h4cker.org/github есть ресурсы для изучения и старта работы с k8s. Подробнее.
    • Nomad (hashicorp) – другой оркестратор контейнеров.
    • Mesos (apache) – включен в ядро Linux (another distributed linux kernel), позволяет работать с контейнерами docker, apc images.
    • Docker swarm – для управления докерами от создателей докера. Подробнее в статье про Docker.

 

Leave a Reply