Все потоки
Поиск
Написать публикацию
Обновить
1028.98

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

Искусство создания компьютерных программ

Сначала показывать
Порог рейтинга

Хотите опубликовать свой продукт или сервис? Тогда присоединяйтесь к вебинару про Маркетплейс Cloud.ru.

📆 Когда: 17 апреля в 11:00 мск

📍 Где: онлайн

Какие продукты можно опубликовать на Маркетплейсе Cloud.ru, кто может стать вендором и какие это дает преимущества, а также, как устроен процесс публикации продуктов на витрине, расскажет Бузулуцкова Юлия — ведущий аналитик.

В программе:

  • что такое Маркетплейс Cloud.ru и какие решения мы уже предлагаем клиентам;

  • типы продуктов на витрине и особенности их использования;

  • публикация продукта на витрине: условия, этапы, сопровождение;

  • преимущества партнерства с Маркетплейс Cloud.ru в качестве вендора;

  • демо: как заполнить анкету продукта и опубликовать его.

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

Зарегистрироваться 👈

Теги:
Рейтинг0
Комментарии0

📢 Почему устаревшие библиотеки всё ещё используются? Взгляд на Log4j 1.x 📊

Несмотря на то, что поддержка Log4j 1.x завершилась ещё в 2015 году, исследование показывает удивительную тенденцию:

  • 33.81% проектов продолжают использовать устаревшую версию Log4j 1.x.

  • Лишь 10.89% проектов перешли на современную Log4j-Core 2.x.
    Что ещё более удивительно, даже новые проекты выбирают устаревшую версию, что подчёркивает сложности в управлении зависимостями.

🔍 Почему это происходит?
1️⃣ Недостаточная осведомлённость о безопасности: Разработчики могут недооценивать риски использования уязвимых библиотек.
2️⃣ Высокая стоимость миграции: Переход на новые версии часто воспринимается как сложный и дорогостоящий процесс.
3️⃣ Зависимость от легаси-систем: Многие проекты связаны с устаревшими системами, что делает обновление крайне затруднительным.

⚠️ Риски использования Log4j 1.x
Продолжение работы с этой библиотекой подвергает системы серьёзным угрозам, включая возможность удалённого выполнения кода (например, уязвимость CVE-2019-17571).

💡 Следующие шаги для сообщества

  • Повышать осведомлённость о рисках использования устаревших библиотек.

  • Предоставлять инструменты и ресурсы для упрощения процесса миграции.

  • Рассмотреть временные решения, такие как Reload4j, для быстрого устранения критических проблем.

https://arxiv.org/pdf/2504.03167

Теги:
Рейтинг0
Комментарии0

LLM в разработке: Практические вопросы к сообществу

Привет, Хабр!

LLM уже не просто стучатся — они локтями расталкивают наши привычные рабочие процессы. За последний год я много экспериментировал c LLM в разработке, пытаясь найти эффективный и осознанный способ применения, который я для себя назвал «выращиванием кода». Это подход, основанный на декомпозиции, качественном контексте и итеративной доработке, как антидот слепой генерации или «вайб‑кодингу».

Но теория — это одно, а реальность у всех разная. Хочется сверить часы с сообществом и обсудить конкретные методики и наблюдения. Вместо утверждений — задам вопросы, которые возникли у меня (и в ходе недавних обсуждений):

  1. Как вы используете LLM в своей работе? Только для автодополнения и поиска решений, или пробовали полноценно «выращивать» компоненты и модули? Какие модели дают лучший результат для вашего стека?

  2. Насколько важен контекст при работе с LLM? Замечали ли вы разницу между запросами типа «напиши X» и «вот существующий код, создай Y, который интегрируется с ним»? Как вы подбираете релевантный контекст?

  3. Трансформировалась ли ваша роль как разработчика? Заметили ли вы изменение в процессе работы — больше времени на архитектуру и меньше на написание кода? Или LLM пока остается вспомогательным инструментом?

  4. Какие новые навыки потребовались? Как вы формулируете запросы? Разрабатывали ли особые техники промпт‑инжиниринга для программирования? Какие приемы повышают качество генерируемого кода?

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

  6. Как вы проверяете сгенерированный код? Какие методы и практики помогают выявлять потенциальные проблемы? Меняется ли подход к ревью LLM‑кода по сравнению с человеческим? Приходилось ли сталкиваться со специфическим «LLM‑долгом»?

  7. Как LLM влияет на вашу продуктивность? Замечаете ли реальное ускорение разработки? В каких типах задач выигрыш наиболее заметен? Изменилось ли качество конечного продукта?

  8. Как вы решаете проблему «разрыва интерпретаций» между нечеткими человеческими намерениями и точными машинными инструкциями при работе с LLM? Какие техники помогают сузить пространство возможных интерпретаций в промптах?

  9. Какие техники декомпозиции задач вы используете при работе с LLM? Отличаются ли они от «классической» декомпозиции при ручном программировании (например, в части подготовки контекста для каждого шага)?

  10. Как вы видите будущее этой практики? Считаете ли «выращивание кода» (или похожие осознанные подходы) временным трендом или фундаментальным изменением в разработке программного обеспечения?

Буду рад услышать ваши мнения, опыт и конкретные примеры из практики!

Теги:
Всего голосов 4: ↑2 и ↓2+1
Комментарии5

Индексация массивов (портал в ад).

Как известно, иногда массивы индексируют с нуля, а иногда с единицы, и это часто вызывает споры.

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

  1. Массивы индексируются с 0.

  2. Массивы индексируются с 1.

  3. Массивы индексируются с 0, но можно указать другое начало.

  4. Массивы индексируются с 1, но можно указать другое начало.

  5. Массивы индексируются только с явно указанного начала.

  6. Массивов в языке нет.

Языков явно выраженного типа (3) мне сходу не удаётся припомнить (хотя в Delphi и C++ есть некоторые движения в этом направлении), а в остальном известные мне языки довольно равномерно распределены между типами.

Нумерация с 0 упрощает индексную арифметику.

Нумерация с 1 соответствует естественному натуральному счёту и математической нотации.

В связи с этим, к нумерации с 1 тяготеют в основном языки для вычислительного применения (Фортран, Матлаб, Джулия). Страшно представить, сколько проклятий получили авторы NumPy от людей, переводящих алгоритмы с Фортрана.

Теги:
Всего голосов 2: ↑1 и ↓10
Комментарии14

Пошла мода писать манифесты, напишу и я что-нибудь эдакое.

Система не сводится к сумме своих частей.

Поэтому декомпозиция, как метод проектирования, ущербна.

Встаёт вопрос, как же тогда нам просто описывать сложное? Здесь скрывается некоторая смысловая тонкость. Мы можем просто описывать сложное сложными словами. А дальше настоящее наше дело – представить эти сложные слова другими, простыми словами, которыми описать сложное сложно, но технически возможно.

То есть метаязыковая абстракция решает, и DSL – наше всё.

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

Теги:
Всего голосов 6: ↑5 и ↓1+5
Комментарии2

Нельзя использовать goto

Часто говорят, что goto плох. А собственно, почему?

В ассемблерном коде на машинном уровне все управляющие конструкции (if, while, for и другие) преобразуются в набор команд с безусловным переходом jmp (UPD: меня поправили, с безусловным или условным переходом, но по указанному адресу, то есть куда угодно).. А такой переход — самый настоящий goto. То есть ты весь такой изящный во фраке пишешь циклы, а наглый компилятор/интерпретатор выкидывает всю красоту и делает goto.

Так почему же сам goto является признаком плохого кода, если он на самом деле везде?

Ответ кроется в умении сохранять контекст. Человек может в голове держать 5-9 сущностей, больше не получается. Поэтому придумали функции, и придумали держать их небольшими — для снижения когнитивной сложности. Конструкция if переведёт тебя в одну из веток ниже, циклы for и while выполнят тело цикла или выбросят за его пределы. Команда goto сложность привносит — прыжок может быть куда угодно. А повышение сложности всегда приводит к росту числа ошибок.

Ну а ещё из-за goto может напасть велоцираптор
Ну а ещё из-за goto может напасть велоцираптор

Теги:
Всего голосов 4: ↑3 и ↓1+2
Комментарии6

MTS AI выпустила Kodify 2 — второе поколение ИИ-ассистента для разработчиков:

  • 7 млрд параметров, 

  • контекст до 32 тыс. токенов, 

  • поддержка 90 языков программирования,

  • OpenAI-совместимый API для простой интеграции с другими системами. 

В отличие от первого поколения Kodify, использующегося c 2024 года лишь в компаниях, входящих в ПАО «МТС», Kodify 2 станет доступен внешним заказчикам.

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

Подробнее на сайте разработчика. Демо на Java и Python здесь.

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии4

Нормальный ли у меня код?

Разработчики часто задаются таким вопросом. Давайте подумаем, как оценить "нормальность" кода. На мой взгляд, важны следующие аспекты:

Код решает поставленную задачу. Самым важным является достижение цели. Код, который работает неверно, однозначно не нормальный. Пусть криво и косо, но нужный результат должен быть получен.

Код легко читается. Правильная архитектура, понятное именование переменных, достаточные комментарии, короткие функции. Это целый набор плохо формализованных требований к коду. Сможете ли вы спустя год понять, что происходит в коде? Сможет ли код разобрать ваш коллега? Сколько времени займут изменения вашего кода?

Быстрый по скорости и компактный по данным. Другими словами, код должен быть нормальной вычислительной и пространственной сложности. Тут помогают и интуитивные представления (что-то тормозит), и теория вычислительной сложности (О-нотация). Если вы сортируете записи за O(n^3) и требуете O(n^5) оперативной памяти, то вы делаете что-то не так.

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

Если, конечно, не горят сроки

Теги:
Всего голосов 4: ↑4 и ↓0+4
Комментарии1

Определение переменных и вызов функций в Rust

Взглянем на код:

fn main() {
	let a = 10;
	let b: i32 = 20;
	let c = 30i32;
	let d = 30_i32;
	let e = add(add(a, b), add(c, d));

	println!("(a + b) + (c + d) = {}", e);
}

fn add(i: i32, j: i32) -> i32 {
	i + j;
}

Определение функции начинается с ключевого слова fn. Точка входа в Rust-программы - это функция main. Она не получает никаких аргументов и не возвращает никаких значений.

В следующих строках let используется для привязки переменной. По умолчанию переменные неизменяемые, то есть предназначены только для чтения, а не для чтения-записи.

Также можно указывать конкретный тип данных разными способами:

  1. Через двоеточие

  2. Числовые литералы могут включать аннотации типов

В последней строке вызывается макрос println! для вывода текста.

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

И наконец, функция add имеет аргументы с указанными типами данных и возвращает нужный тип данных. Как вы видите, возврат значения происходит автоматически, для этого не используются ключевые слова по типу return.

Поговорим о создании переменных. В Rust они бывают мутабельными (mutable) или немутабельными (unmutable), то есть изменяемые и неизменяемые. Неизменяемые переменные можно сравнить с константами.

Разберем пример:

fn main() {
	let a = 10;
	a = 15;
}

Если мы скомпилируем данную программу, то получим ошибку:

error[E0384]: cannot assign twice to immutable variable `a`
  --> src\main.rs:25:5
   |
24 |     let a = 10;
   |         - first assignment to `a`
25 |     a = 2;
   |     ^^^^^ cannot assign twice to immutable variable
   |
help: consider making this binding mutable
   |
24 |     let mut a = 10;
   |         +++

Т.к. все переменные в rust изначально неизменяемые, то мы не можем изменить переменную. Компилятор нам подсказывает, что для изменения значений надо добавить ключевое слово mut.

Добавим:

fn main() {
	let mut a = 10;
	a = 15;
	println!(a);
}

Программа успешно скомпилируется и мы получим 15.

Но также существуют константы. Подобно неизменяемым переменным, константы — это значения, которые связаны с именем и не могут изменяться, но между константами и переменными есть несколько различий. Во-первых, нельзя использовать mut с константами. Константы не просто неизменяемы по умолчанию — они неизменяемы всегда. Для объявления констант используется ключевое слово const вместо let, а также тип значения должен быть указан в аннотации.

fn main() {
	const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;
}

Имя константы - THREE_HOURS_IN_SECONDS, а её значение устанавливается как результат умножения 60 (количество секунд в минуте) на 60 (количество минут в часе) на 3 (количество часов, которые нужно посчитать в этой программе). Соглашение Rust для именования констант требует использования всех заглавных букв с подчёркиванием между словами. Компилятор может вычислять ограниченный набор операций во время компиляции, позволяющий записать это значение более понятным и простым для проверки способом, чем установка этой константы в значение 10 800.

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

Еще момент - в листингах выше мы не декларировали тип данных переменных.

Вообще, типизация в Rust несет полу строгий характер. Разработчик может не указывать тип данных. Это может укоротить код, если сама программа небольшая. Но всегда рекомендуется описывать тип данных, иначе могут возникнуть ошибки. Например:

fn main() {
	let mut a = 10;
	a = "hello"; // возникнет ошибка
}

Мы не можем поменять тип данных, которые хранятся в переменной. Обычно типы данных указывают так:

fn main() {
	let mut a: i32 = 10;
	a = 15;
}
Теги:
Всего голосов 2: ↑1 и ↓10
Комментарии1

Область видимости и затенение переменных в Rust

Затенение переменных

В Rust, также как и в большинстве ЯВУ, можно "затенять переменные", то есть создавать вторую переменную с таким же именем, используя значение первой переменной:

fn main() {
    let x = 5;

    let x = x + 1;

    {
        let x = x * 2;
        println!("The value of x in the inner scope is: {x}");
    }

    println!("The value of x is: {x}");
}

Эта программа сначала привязывает x к значению 5. Затем она создаёт новую переменную x, повторяя let x =, беря исходное значение и добавляя 1, чтобы значение x стало равным 6. Затем во внутренней области видимости, созданной с помощью фигурных скобок, третий оператор let также затеняет x и создаёт новую переменную, умножая предыдущее значение на 2, чтобы дать x значение 12. Когда эта область заканчивается, внутреннее затенение заканчивается, и x возвращается к значению 6. Запустив эту программу, она выведет следующее:

The value of x in the inner scope is: 12
The value of x is: 6

Область видимости

Связывание переменных происходит в локальной области видимости — они ограничены существованием внутри блока. Блок — это набор инструкций, заключённый между фигурными скобками {}.

fn main() {
    // Эта переменная живёт в функции main
	let long_lived_binding = 1;  
	let shadowed_variable = 1;  
	  
	// Это блок, он имеет меньшую область видимости, чем функция main  
	{  
	    // Эта переменная существует только в этом блоке  
	    let short_lived_binding = 2;  
	    let shadowed_variable = 2;  
	  
	    println!("shadowed variable: {}", shadowed_variable);  
	  
	    println!("inner short: {}", short_lived_binding);  
	}  
	// Конец блока  
	println!("shadowed variable: {}", shadowed_variable);  
	  
	println!("outer long: {}", long_lived_binding);
}

Теги:
Рейтинг0
Комментарии0

Как писать REST API — 9 правил

REST API (Representational State Transfer Application Programming Interface) — это архитектурный стиль взаимодействия между клиентом и сервером через HTTP. Он определяет принципы построения API, обеспечивая стандартизированный и эффективный обмен данными между различными системами.

  1. GET-запросы не должны что-то сохранять, удалять или изменять. Нельзя менять какие-либо данные на стороне сервера при GET-запросе. Почему? GET-запросы часто кешируются на стороне клиента.

  2. POST запросы для загрузки/создания сущностей, PUT для изменения в сущности, а PATCH - для мелких изменений в сущности.

  3. Наименование эндпоинтов. Должен присутствовать единый стиль, и желательно во множественном числе, ибо это более лаконичнее. Например, эндпоинт /users. Можно и единственное число использовать, но обосновано.

  4. Иерархия. Нужно соблюдать единую иерархию для построения запросов. Конструкции /users/1/friends/3/items/4 будет неудобно использовать разработчикам клиентских приложений. Нужно избегать такую иерархию, нужно конкретно указывать что нам нужно, не перезагружать данными.

  5. Соблюдайте версионирование API. Допустим: /api/v1/get_all_users и /api/v2/get_all_users. При выходе новой версии не всегда разработчики готовы переписать логику клиентских приложений, и для этого нам нужно разделять версии API

  6. Чувствительные данные. Очень важный момент. Например, передача различных паролей в Query-параметрах запрещено, только в теле запроса.

  7. Из 6 вытекает 7е правило: не логируйте персональные и прочие секретные данные. Было несколько случаев, когда из-за логирования параметров утекали данные пользователей.

  8. Расширение ответов. Во-первых, не передавайте массивы в самом верхнем уровне ответа. JSON-ответ от сервера не должен быть массивом, только словарь (ключ-значение). Если мы будем возвращать список, в будущем нам будет неудобно расширить ответ сервера, добавив дополнительные параметры. А также иногда в API разработчики делают обязательные параметры, например помимо самих данных параметр success и error, чтобы клиентское приложение могло понять, что произошла ошибка, или наоборот, успешно выполнилось.

  9. Работа с датой и временем. Есть два метода - использование Unix Timestamp (количество секунд прошедших с 1 января 1970 года). Это в какой-то степени более удобно для машины, но менее удобно для клиентского разработчика. И второй метод как раз делает формат даты и времени более понятным - это ISO 8601 (2025-04-05T12:00:00.100Z). Этот метод более удобный, т.к. мы понимаем дату и часовой пояс, точное время.

  10. Бонусное правило, лично мое. Относится не только к REST API, но и в принципе к программированию. Пишите код так, как будто эта поэма, книга. Попробуйте сами поработать со своим API, будто вы его не писали. Разделение ответственности, единая точка отказа, Don't Repeat Yourself и даже Keep It Simple, Stupid. Все это конечно-же вариативно.

Теги:
Всего голосов 4: ↑4 и ↓0+4
Комментарии5

Напоминаем, что в Академии Selectel можно пройти бесплатный курс «Изучаем Python: теория, практика, настройка инструментов».

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

Что будем делать:

✅ настроим инструменты разработчика — уделим внимание связке IDE и Python;

✅ поработаем с базами данных и брокерами сообщений — будем писать запросы SQL;

✅ создадим приложения с графическим интерфейсом — нарисуем виджеты, выведем диалоговые окна;

✅ научимся автоматизировать получение данных — попрактикуемся и с Request, и с Selenium.

Без задач для практики тоже не останетесь!

Но и это не все! Поделимся записями докладов Python Meetup. Дадим подборку для дальнейшего изучения.

Все материалы бесплатные. Не требуется даже регистрация.

Изучить курс в Академии Selectel

Теги:
Всего голосов 1: ↑1 и ↓0+2
Комментарии0

Последние месяцы изучаю функциональное программирование. И я не понимаю, почему любой доклад по ФП начинается с того, что докладчик пол часа рассказывает, почему не стоит использовать ООП. И при этом приводит в пример структурный код!

Если в языке есть управляющие конструкции, по типу if/else, то это НЕ объектно-ориентированный язык. И не важно какие свойства ему приписываются в Wikipedia. В ООП работа с булевыми выражениями выглядит так:

result = request->validate(rules);
result
    ->ifTrue(useCase->execute())
    ->ifFalse(response->unprocessable())

Вот вам и посылка сообщений, и "Tell, don't ask".

Я вижу ситуацию с языками так. На данный момент используется 3 высокоуровневых парадигмы: объектная, функциональная и реляционная. Объектная подходит для передачи данных, функциональная для их обработки, а реляционная для хранения. Все парадигмы хороши по своему и эффективно работают в своей области.

Вы выстрелите себе в ногу, если попытаетесь смоделировать развёртку docker-контейнеров или взаимодействие между web-компонентами с помощью ФП. И вам будет так же трудно обработать данные запроса на сервере с помощью ООП. Все парадигмы имеют свои преимущества и недостатки, и используются как инструменты для разных задач.

Слушая доклады по ФП, лично я хотел бы слышать что-то типа: "Смотрите, мы сейчас будем заниматься обработкой данных. У ФП есть для этого отличные механизмы, и работают они вот так..."

Призываю всех улучшать своё понимание парадигм и использовать их по назначению. (b.t.w. нативный "Railway programming" в ФП - это круто)

Теги:
Всего голосов 2: ↑1 и ↓10
Комментарии10

Ближайшие события

Привет, Habr!

Уже завтра увидимся на JPoint в Москве, где на стенде Explyt представим новую версию Explyt Test плагина, разыграем весеннюю коллекцию мерча и на вечернем докладе обсудим, что болит и где подгорает у разработчика и тестировщика.

В этом релизе killer фичи Explyt Test плагина – интеграция тестов в существующую кодовую базу и подражание стилю проекта – усилены:

  • возможностями для увеличения тестового покрытия кода

  • генерацией интеграционных тестов для Spring разных видов: MockMVC, Spring Boot

  • анализом моргающих тестов (Flaky tests)

  • генерацией кода в строке редактора (Inline code generation)

  • объяснением ошибок, возникших в консоли

В Explyt Test мы поддержали современные языковые модели от провайдеров OpenAI, Anthropic, DeepSeek, Google Gemini, Cerebras, Groq, Ollama, в том числе:

  • Claude 3.7 Sonnet

  • OpenAI o3-mini

  • DeepSeek R1

  • OpenAI GPT-4.5

Возможности генерации тестов:

  • расширение тестового класса новыми тестовыми методами

  • автоматическая генерация тестов

  • исправление ошибок компиляции и runtime-ошибок в любом тестовом классе

  • использование существующего тестового класса в качестве примера для генерации тестов

  • подготовка проекта для интеграции сгенерированных тестов в существующую кодовую базу 

  • генерация тестового кода по пользовательскому тестовому сценарию 

  • автоматическое исправление ошибок компиляции и runtime-ошибок

Возможности интегрированного ассистента:

  • чат с LLM с поддержкой вложений

  • анализ кода на предмет потенциальных ошибок в реализации (Analyze for bugs)

  • объяснение работы кода и нюансов его использования (Explain code fragment)

  • использование локальной модели для генерации тестов и общения с ассистентом

Поддержка совместимости:

  • IntelliJ IDEA 2024.1+

  • Kotlin K2 

  • Android Studio Koala, Ladybug, Meercat

Поддерживаем тестовые фреймворки: JUnit 5, JUnit 4, TestNG, kotlin-test, фреймворки мокирования: Mockito, Mockito-Kotlin, MockK, SpringMockK, системы сборки: Maven, Gradle, IntelliJ Build System.

Вы можете обращаться к языковым моделям как через серверы Explyt, так и с использованием собственных API-ключей.

В личном кабинете добавлена возможность выбирать между Personal и Enterprise версиями.

Explyt Enterprise можно развернуть в виртуальном частном облаке (VPC) или в контуре компании (self-hosting). Код компании не отправляется в интернет и не используется для обучения модели.

Мы очень ценим обратную связь от комьюнити и будем рады пообщаться с вами на стенде Explyt на JPoint и почитать ваши комментарии на Хабре. Скачивайте плагин на сайте, багрепорты и фичреквесты добавляйте в GitHub Issues, узнавать новое – в нашем телеграм.

Теги:
Всего голосов 4: ↑4 и ↓0+4
Комментарии0

Анализируем размер проекта

Среди метрик качества проекта теоретики выделяют число LOC == lines of code, измеряемое обычно в тысячах.

Для измерения размера проекта в строках кода есть интересный проект cloc, запускаемый в том числе в docker (зачем docker?).

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

Пример для одного легаси проекта
Пример для одного легаси проекта

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

DevFM

Теги:
Всего голосов 5: ↑3 и ↓2+2
Комментарии7

Попробуйте себя в роли этичного хакера на T-CTF 2025

19—20 апреля встречаемся на T-CTF — соревнованиях по кибербезопасности. Вас ждут увлекательные задачи из мира информационной безопасности. Лучшие игроки получат шанс выиграть призы — до 420 000 ₽ на команду.

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

  • Приглашаем скилловых ИТ-специалистов из разных сфер. На соревнованиях будет две лиги: Лига безопасности для опытных игроков и Лига разработки для тех, кто еще ни разу не участвовал в СTF. Ждем backend- и frontend-разработчиков, аналитиков, SRE- и QA-инженеров и других специалистов, которые хорошо разбираются в коде.

  • Участвуйте онлайн или приходите на офлайн-площадки в шести городах России. Для тех, кто хочет погрузиться в атмосферу ИТ-хабов Т-Банка, мы подготовили площадки в Москве, Санкт-Петербурге, Казани, Иннополисе, Екатеринбурге и Новосибирске. На них вас будут ждать рабочие места для выполнения заданий, зоны для отдыха и нетворкинга, вкусная еда и напитки. 

  • В T-CTF участвуют командами — если у вас ее нет, мы поможем найти. После регистрации присоединяйтесь к чату в Телеграме: в нем будут единомышленники, которые тоже ищут команду. Еще есть телеграм-бот, где можно посмотреть анкеты участников и объединиться с желающими. В одной команде может быть от одного до трех человек. Чем больше команда, тем выше шансы на победу.

Выбирайте лигу по скиллам, отправляйте заявку и собирайте команду! Регистрация открыта до 18 апреля 23:59.

Зарегистрироваться

Теги:
Всего голосов 1: ↑1 и ↓0+3
Комментарии0

Конкурентность в Go: просто запустить — сложнее управлять

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

Полезные материалы о конкурентности в Go можно найти в блоге Дейва Чени. Он рассматривает различные решения в Go, объясняя их происхождение и способы использования. В своих статьях он также подробно разбирает тему конкурентности.

Например, в статье Curious Channels Дейв Чени описывает два важных свойства каналов в Go:

  1. Закрытый канал не блокируется. После закрытия в него нельзя отправлять данные, но можно читать. Если данных нет, возвращается нулевое значение. Это удобно при использовании range, который автоматически завершает цикл.

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

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

Владислав Белогрудов, эксперт по разработке ПО в YADRO, собрал полезные материалы про конкурентность в Go. В статье — блоги, выступления и книги, которые помогут разобраться, как в Go работать с горутинами и каналами без хаоса и дедлоков.

Теги:
Всего голосов 4: ↑4 и ↓0+6
Комментарии0

Напиши мне программу богатства

С выходных каждый день программирую новый сервис для студентов.
Программист я никакой, но очень нравится.
Сидишь, смотришь, как нейронка пишет код за тебя. А ты ей: «Просто хочу быть богатым, напиши мне программу». Магия какая-то.
Так думают все, кто первый раз пробует с нейронкой написать код. А потом, спустя первые 20 минут, чёт, ошибка какая-то, и потом 4 часа пробуешь её поправить с помощью нейронки.

Вторая стадия — это когда ты пишешь ей уже матом, чтобы выплеснуть всю ненависть к роботу, и он извиняется: «Мол, прости брат, не бей, ошибся» — и вроде легче на душе. И ошибается снова и снова.
Моя стадия — 4 нейронки, которые правят ошибки друг друга, долго, муторно, но двигаешься, чуть быстрее, чем сам.

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

Перешли этот пост тому, кто думает, что быстро напишет программу с помощью ИИ.

Теги:
Всего голосов 5: ↑3 и ↓2+1
Комментарии2

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

Вот продукт готов, покупатели и менеджеры довольны... Они твои пользователи.

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

Да, да.... это я, твой коллега, твой первый пользователь, твой продукт - это код, я им пользуюсь.

Почему ты не подумал обо мне: не написал README, не оставил инструкций, не озвучил подводные камни? Почему мне нужно провести реверс-инжинириг, просто что бы запустить или задеплоить проект?

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

Почему ты злишься, когда я комментирую код на ревью? Почему ты отвечаешь - "мне так удобно"? Почему... почему... почему?

После этого, ты удивляешься тому, что я не хочу иметь ничего общего с твоим продуктом и с тобой. Почему?

Теги:
Всего голосов 6: ↑5 и ↓1+5
Комментарии4

Полезные ссылки и новости в дайджесте за февраль🌨️

📢 Анонсировали программу главной конференцию про облачные технологии и искусственный интеллект — GoCloud 2025. Хотите узнать про глобальные тренды в AI, пополнить список инструментов и сценариев работы в облаке, обменяться опытом с коллегами-экспертами, а также увидеть, какой простор открывают облачные и AI-технологии для ваших IT-проектов? Тогда мы ждем вас 10 апреля онлайн и офлайн в Москве в Цифровом деловом пространстве (ЦДП). Посмотреть программу и зарегистрироваться.

🚀 Запустили Cloud․ru Evolution Stack — платформу для создания частных и гибридных облаков в IT-ландшафте компании. Платформа позволяет построить частное облако в собственном дата-центре, а также развернуть гибридную инфраструктуру, объединяя возможности публичного облака Cloud․ru Evolution, сторонние облачные сервисы на базе OpenStack и виртуализацию VMware vSphere. Узнать больше.

☁️ Расширили возможности облака Cloud.ru Evolution:

  • добавили поддержку Kubernetes версии 1.29

  • в личном кабинете добавили возможность указывать публичную часть SSH-ключа из сервиса SSH-ключи для аутентификации на рабочем узле.

  • добавили поддержку Apache Iceberg в Evolution Managed Trino

  • опубликовали UserGate NGFW в виде образа виртуальной машины по модели BYOL — подробности на странице образа.

  • опубликовали инструкцию — как развернуть UserGate NGFW.

  • добавили ресурсы в Evolution Bare Metal — доступно более 40 мощных серверов в двух зонах доступности.

🦾 Обновили наши облачные платформы — об этом подробно рассказали в дайджесте на сайте

💰 Обновили реферальную программу, чтобы вы могли с большей выгодой рекомендовать сервисы Cloud.ru клиентам, коллегам или друзьям. Теперь можно получить 20% от суммы чеков приведенных пользователей в первый год и 15% — в последующие годы. Регистрируйтесь в программе до 31 мая и приводите новых пользователей в течение трех месяцев. Участвовать могут самозанятые, ИП и юридические лица. Присоединиться.

🧊 Заморозили цены на облачные услуги для новых клиентов на три года. Вы можете выбрать виртуальные машины, GPU-ресурсы, объектные хранилища, базы данных и другие облачные сервисы — тарифы останутся неизменными в течение трех лет. Предложение действует до 31 марта 2025 для юрлиц и индивидуальных предпринимателей. Оставить заявку.

📺 Провели вебинары, и их можно посмотреть в записи:

А также приглашаем на ближайшие вебинары: 

До встречи в следующем выпуске!

Теги:
Рейтинг0
Комментарии0

Вклад авторов