Cross Join - канал о разработке – Telegram
Cross Join - канал о разработке
3.69K subscribers
91 photos
8 videos
3 files
286 links
Канал о разработке Антона Околелова. Тимлид Go, живу в Чехии. Мысли, новости, вопросы.

По вопросам рекламы @antonokolelov
Download Telegram
Forwarded from Shit books (Maxi Frolof)
#непрокниги

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

Эти вопросы я собрал при помощи коллег, когда проходил интервью в Яндекс 360. Дополняйте своими вопросами в комментариях.
👍27🔥5👎2💩2🤮1
Давайте пофантазируем.

Что, если сделать свой отдельный Go, который бы транспилировался в обычный? как TS -> JS

Я бы добавил туда как минимум две вещи, которые точно никогда не появятся в Go, и половине людей там и не нужны:

1. Сахар для обработки ошибок (как-нибудь как в Расте, чтобы обработка была всё еще явной, но синтаксически попроще). Плюс синтаксис для ловли паник тоже попроще.

2. Добавил бы немного structured concurrency: запретил бы голый вызов команды go. Синтаксически заставить дожидаться завершения горутины в той же функции, где она была запущена.

Может, еще с каналами что-то намутить, чтобы заставить их закрывать примерно там же, где в них шла запись (в том же пакете?)

Тогда это получится язык в 10 раз более читаемый и в 10 раз менее запутанный в вопросах concurrency
👍13🥱4👎3🌚1
Очень интересный документ на github, который на различных примерах утверждает, что при программировании во главу угла нужно ставить когнитивную нагрузку от твоего кода и всегда это держать в голове.

Как делить на модули, когда нужно или не нужно использовать микросервисы, гексагональную архитектуру и т.д. Что важнее: гибкость/универсальность кода или простота.

TLDR: используйте сложные трюки только там, где они действительно нужны.

https://github.com/zakirullin/cognitive-load
👍40🔥9👏21
В догонку к предыдущему посту про гибкость vs простота. В языке Go очень интересно сделаны интерфейсы.

Например, есть какой-то класс (точнее структура с методами) с методом getWeather(city), который является обёрткой над внешним сервисом погоды.



type WeatherService struct {
apiKey string
}

func (w *WeatherService) GetWeather(city string) (string, error) {
// http вызов внешнего API
return "Sunny", nil
}


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



type WeatherAnalyzer struct {
weatherService *WeatherService // конкретный класс
}

func (wa *WeatherAnalyzer) AnalyzeWeather(city string) string {
weather, err := wa.weatherService.GetWeather(city)
if err != nil {
return "Unable to analyze weather"
}
if weather == "Sunny" {
return "Great day for a picnic!"
}
return "Maybe stay indoors"
}

// Использование
func main() {
ws := &WeatherService{apiKey: "some-api-key"}
wa := &WeatherAnalyzer{weatherService: ws}
result := wa.AnalyzeWeather("New York")
fmt.Println(result)
}


И тут мы ВНЕЗАПНО поняли, что покрывать тестами это неудобно (ибо внешние вызовы), и лучше бы написать интерфейс, чтобы потом его замокать. Или у нас вдруг появился еще один сервис погоды, и нужен интерфейс. Так вот, в Go достаточно просто ПО МЕСТУ добавить интерфейс с описанием нужных в этом месте методов, а сам класс погоды останется неизменным.

Вот как это будет выглядеть:


// WeatherService остается без изменений

type WeatherProvider interface {
GetWeather(city string) (string, error)
}

type WeatherAnalyzer struct {
weatherProvider WeatherProvider
}

func (wa *WeatherAnalyzer) AnalyzeWeather(city string) string {
weather, err := wa.weatherProvider.GetWeather(city)
if err != nil {
return "Unable to analyze weather"
}
if weather == "Sunny" {
return "Great day for a picnic!"
}
return "Maybe stay indoors"
}


Потому что в отличие от Java/PHP/etc не нужно писать что класс имплементирует что-то там. Если у класса есть методы такие же как в интерфейсе, то он подходит под сигнатуру

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

Теперь мы можем легко создать мок для тестирования (упрощенный пример)



type MockWeatherProvider struct {
MockWeather string
}

func (m *MockWeatherProvider) GetWeather(city string) (string, error) {
return m.MockWeather, nil
}

func TestWeatherAnalyzer(t *testing.T) {
mockProvider := &MockWeatherProvider{MockWeather: "Sunny"}
analyzer := &WeatherAnalyzer{weatherProvider: mockProvider}

result := analyzer.AnalyzeWeather("Test City")
expected := "Great day for a picnic!"

if result != expected {
t.Errorf("Expected %s, but got %s", expected, result)
}
}


У этого конечно есть и недостатки.
👍19🌚5👎1
Ну и неустаревающая классика. Для тех, кто любит делать код максимально гибким на всякий случай под неизвестные требования:

FizzBuzz Enterprise Edition

Думаю, все знают задачку Fizz Buzz (выведи Fizz, если число делится на 3, Buzz, если на 5, FizzBuzz если на 3 и на 5). Посмотрите, как делают эту задачу серьёзные люди. Для серьёзного бизнеса. Какие стратегии, фабрики, интерфейсы и всё такое.

Это настоящее пособие по паттернам, а паттерны - это язык, облегчающий общение разработчиков
😁29🥴2🔥1
Гоферы, пройдите опрос 2024

Прошлогодний опрос показал, что гошники в основном бывшие пыхари, и от языка хотят они одного: улучшения обработки ошибок :)
😁9👍4🤯1
иногда комментарии в коде очень важны
😁58👍3
Devjobscanner пропарсил 12 миллионов вакансий (за 1.5 года) и составил топ самых востребованных языков. Из интересного - Ruby и PHP, про смерть которых я слышу уже лет 10, по прежнему хорошо себя чувствуют и всех нас еще переживут. С++ че-то немного пошел вниз
🔥14
Если нужно с помощью ChatGPT сделать сразу несколько файлов с кодом, например целый проект, то это неудобно, надо копировать каждый файл отдельно и хз как это организовать, в общем тупо как-то. Вчера я увидел интересный лайфхак (здесь): можно гопчат попросить сделать bash-файл, который создаст тебе проект со всеми файлами, env переменными и т.д.

Например, такой промт:

"Создай проект на Go 1.23, который делает API для todo list. Данные хранить в Postgres. Создай проект со всеми необходимыми файлами, docker-compose и env переменными. Сделай это в виде bash файла, который сразу всё правильно создаст. Проект назови proverka"

в итоге реально был создан bash файл, который при запуске создал проект. Этот проект сбилдился (я сделал только одну правочку в импортах), запустился через docker-compose, всё ок. Правда, версия Go была не такая, зачем-то туда приделался Gorm, но не суть, это мелочи и можно поиграться с промтом
🔥39👍12💩21👏1🌚1
React Native полностью переделан

После 6 лет разработки команда React Native представила полностью переписанную архитектуру фреймворка (0.76) – самое значительное обновление с момента создания React Native. Это результат масштабной работы над улучшением производительности, стабильности и возможностей платформы.

Ключевые изменения

Новая версия обеспечивает полную поддержку современных возможностей React, включая Suspense, Transitions и автоматический батчинг. В React Native наконец появился полноценный useLayoutEffect – теперь работа с лейаутом стала синхронной и предсказуемой. Это позволяет корректно позиционировать элементы интерфейса без промежуточных состояний и визуальных артефактов.

Улучшение производительности

Мост между JavaScript и нативным кодом полностью удален. Коммуникация теперь происходит напрямую через JavaScript Interface (JSI), что существенно ускоряет работу приложения и его запуск. Новый рендерер может обрабатывать несколько деревьев компонентов одновременно в разных потоках с разными приоритетами. Это позволяет прерывать низкоприоритетные обновления для обработки пользовательского ввода, обеспечивая отзывчивость интерфейса даже при сложных вычислениях.

Технические улучшения

Система нативных модулей была полностью переработана. Теперь доступен синхронный доступ к нативным интерфейсам с полной типобезопасностью между JavaScript и нативным кодом. Появилась возможность писать кроссплатформенный код на C++, который работает на всех поддерживаемых платформах: iOS, Android, Windows и macOS. Модули загружаются лениво, что значительно сокращает время запуска приложения и потребление памяти.

View Flattening, ранее доступный только на Android, теперь работает и на iOS благодаря общему C++ рендереру. Эта оптимизация автоматически упрощает глубокие деревья компонентов, улучшая производительность рендеринга.

Проверено в продакшене

Новая архитектура уже активно используется в крупных приложениях: Facebook, Instagram, Expensify, Kraken и BlueSky. Facebook и Instagram для Meta Quest также построены на новой архитектуре. Это демонстрирует её готовность к применению в проектах любого масштаба и сложности.

Процесс миграции

Большинство приложений смогут обновиться с тем же уровнем усилий, как и при обычном релизе. Более 850 популярных библиотек уже поддерживают новую архитектуру, включая все библиотеки с более чем 200 тысячами еженедельных загрузок. Благодаря автоматическому слою совместимости со старой архитектурой, миграция может быть постепенной – нет необходимости переписывать всё приложение одновременно.

Популярные библиотеки, такие как react-native-mmkv и Reanimated, уже получили значительные улучшения от перехода на новую архитектуру. MMKV стал полностью кроссплатформенным C++ модулем с улучшенной типобезопасностью, а Reanimated 4 получил возможность управлять анимациями и лейаутом в разных потоках.

Дальнейшее развитие

В планах команды React Native – улучшение встроенных компонентов и расширение поддержки современных веб-стандартов. Event Loop теперь работает в соответствии с веб-спецификациями HTML Standard, что в будущем позволит использовать такие API как microtasks, MutationObserver и IntersectionObserver.

Практическая информация

Совместимость используемых библиотек можно проверить на reactnative.directory. Официальная документация содержит подробное руководство по миграции. При возникновении проблем всегда есть возможность отключить новую архитектуру через конфигурацию проекта.
1🔥21🤔7💩5👍1🤬1
API хочется создавать, начиная со спецификации, а потом генерить по ней код "контроллеров", тогда код и дока всегда будут актуальны. Для описания http API есть стандарт OpenAPI (бывший swagger), но он довольно многословный, создавать эти огромные yaml неудобно.

Ну так вот, я недавно узнал, что у Майкрософт есть свой стандарт typespec, который можно сконвертить в те же километровые емлы.

Выглядит миленько
21👍8🔥5🤮4
Пора заводить рубрику "слоупок".

Бесит, когда запускаешь терминал, в терминале набираешь что-то частое, например docker, жмешь стрелку вверх (zsh), а там в истории какой-то мусор от других проектов, которые ты недавно пощупал.

Ну так вот, нашёл классный плагин для zsh - per-directory-history. Он запоминает команды отдельно для каждой папки.

Ctrl+G переключает между локальной и глобальной историей.

Включается просто - добавить в список плагинов per-directory-history

Чума просто
🔥45👍14
ахаха, сегодня я узнал, что в JavaScript обдумывают завезти оператор ?=, который делает обработку ошибок в Гошном стиле. Т.е. натурально, проверку ошибки на nil null


const [error, result] ?= await fetch("https://example.com/data");

if (error) {
// do something
}


правильно, пусть все страдают, а то чё только гошники
😁30👍10🔥2🥰2