Forwarded from Прямоугольники и стрелочки (Maxim Yunusov)
ScyllaDB | Thank You
https://lp.scylladb.com/designing-data-intensive-apps-book-thanks
https://lp.scylladb.com/designing-data-intensive-apps-book-thanks
https://www.scylladb.com
ScyllaDB | Thank You
In this practical and comprehensive guide, Martin Kleppmann helps you navigate the diverse and fast-changing landscape of approaches to processing and storing data for data-intensive applications.
❤1👍1
Виртуальная машина СPython позволяет легко менять значения даже у литералов.
Например, мы легко можем заменить значение литерала
Например, мы легко можем заменить значение литерала
a в нашей виртуальной машине. После замены a на z в нашей программе больше не осталось первой буквы алфавита, теперь в a лежит “z”from ctypes import c_byte
from sys import getsizeof
def set_value(old: object, new: object) -> None:
src_s, des_s = getsizeof(new), getsizeof(old)
src_arr = (c_byte * src_s).from_address(id(new))
des_arr = (c_byte * des_s).from_address(id(old))
des_arr[:] = src_arr[:]
set_value('a', 'z')
assert 'a' == 'z'
🤬3❤2😁1
Forwarded from Wazowski Recommends
Попав в Яндекс, мы получили проект от Ильи Сегаловича. Илья умел очень классно делиться идеями и объяснять суть. Он нам рассказал, что на самом деле Гугл в своё время выиграл у всех предыдущих поисковиков за счёт хорошо сделанных сниппетов. А теперь для нас самое главное — сделать так, чтобы поисковые результаты не были сплошь одинаковыми. Надо бороться с полу-дублями.
Только сделать это у нас не удалось. Зато мне удалось получить свою первую психологическую травму на работе.
В Яндексе тогда не было почти никакой документации. Даже как собирать проект — было тайным знанием, передающимся из уст в уста.
Когда нужно было разобраться в каком-то куске поискового кода, Макс сказал:
— Ну давай посмотрим, кто автор этого кода... Ага, некий Антон с ником pg@. Просто сходи и спроси у него, что здесь происходит.
Я сходил и спросил. Антон с ником pg@ ответил мне, чтобы я просто прочитал код.
Прочитать и понять код у меня не получилось. А так как работали мы на четверть ставки, то в следующий раз мы с Максом встретились примерно через неделю. Узнав, что прогресса особо нет, Макс сказал:
— Нет, ну так дело не пойдёт. Пойдём вместе сходим и спросим.
Сходили и спросили. На что Антон с ником pg@ просто накричал на нас обоих: какого чёрта какие-то стажёры его отвлекают и не могут даже за неделю самостоятельно прочитать код?!
С тех пор ни я, ни Макс уже больше никогда не хотели работать в Яндекс.Поиске.
#lifestories
Только сделать это у нас не удалось. Зато мне удалось получить свою первую психологическую травму на работе.
В Яндексе тогда не было почти никакой документации. Даже как собирать проект — было тайным знанием, передающимся из уст в уста.
Когда нужно было разобраться в каком-то куске поискового кода, Макс сказал:
— Ну давай посмотрим, кто автор этого кода... Ага, некий Антон с ником pg@. Просто сходи и спроси у него, что здесь происходит.
Я сходил и спросил. Антон с ником pg@ ответил мне, чтобы я просто прочитал код.
Прочитать и понять код у меня не получилось. А так как работали мы на четверть ставки, то в следующий раз мы с Максом встретились примерно через неделю. Узнав, что прогресса особо нет, Макс сказал:
— Нет, ну так дело не пойдёт. Пойдём вместе сходим и спросим.
Сходили и спросили. На что Антон с ником pg@ просто накричал на нас обоих: какого чёрта какие-то стажёры его отвлекают и не могут даже за неделю самостоятельно прочитать код?!
С тех пор ни я, ни Макс уже больше никогда не хотели работать в Яндекс.Поиске.
#lifestories
❤5🦄1
В Python 3.12 подвезли события виртуальной машины и API для работы с ними. В PEP 669 – Low Impact Monitoring for CPython описываются эти события, главная мотивация их добавить — профилирование приложения на проде без влияния на производительность
API довольно низкоуровневый, но если поиграться, можно лучше понять исполнение python программ. Например, если прикрутить коллбеки на события
C++ and Java developers expect to be able to run a program at full speed (or very close to it) under a debugger. Python developers should expect that too.
API довольно низкоуровневый, но если поиграться, можно лучше понять исполнение python программ. Например, если прикрутить коллбеки на события
PY_YIELD и STOP_ITERATION, то можно понаблюдать за работой корутин:import sys
import random
import asyncio
from types import CodeType
from contextlib import contextmanager
@contextmanager
def log_cpython_vm_events(events_callbacks: dict):
if len(events_callbacks) > 5:
raise ValueError("Too many events callbacks")
try:
for tool_id, (event, callback) in enumerate(events_callbacks.items(), start=1):
sys.monitoring.use_tool_id(tool_id, "test")
sys.monitoring.register_callback(tool_id, event, callback)
sys.monitoring.set_events(tool_id, event)
yield
finally:
for tool_id, (event, callback) in enumerate(events_callbacks.items()):
sys.monitoring.register_callback(tool_id, event, None)
sys.monitoring.free_tool_id(tool_id)
def callback_on_yield(code: CodeType, instruction_offset: int, retval: object):
next_frame = sys._getframe(1)
print(
f'Yield from "{code.co_name}" with locals={next_frame.f_locals} witch return instance id={id(retval)} of type {type(retval).__name__}'
)
def callback_on_stop_iteration(
code: CodeType, instruction_offset: int, exception: object
):
next_frame = sys._getframe(1)
print(
f'Stop iteration from "{code.co_name}" with locals={next_frame.f_locals} witch raise exc "{type(exception).__name__}"'
)
EVENTS_CALLBACKS_MAPPING = {
sys.monitoring.events.PY_YIELD: callback_on_yield,
sys.monitoring.events.STOP_ITERATION: callback_on_stop_iteration,
}
async def run(idx: int):
await asyncio.sleep(random.random())
async def main():
await asyncio.gather(*map(run, range(2)))
with log_cpython_vm_events(EVENTS_CALLBACKS_MAPPING):
asyncio.run(main())
Python Enhancement Proposals (PEPs)
PEP 669 – Low Impact Monitoring for CPython | peps.python.org
Using a profiler or debugger in CPython can have a severe impact on performance. Slowdowns by an order of magnitude are common.
👍2❤1🤷♂1
Краем уха слышал про акторную модель в Erlang и в Akka (фреймворк на Scalla), но не понимал, как обстоят дела с гарантиями доставки. Если сообщения между акторами хранятся в памяти, то мы их потеряем при перезапуске/падении нашего приложения.
В Akka нашел возможность хранить сообщения в базе с помощью плагинов персистентного хранения. Как понимаю, работают на основе snapshot, и как с snapshot в Redis, некоторые данные можем потерять в случае перезапуска.
В докладе Никита Мельников рассказывает про альтернативный подход в построение акторной модели, который отчасти решает проблему потери сообщений при перезапусках. Вместо того, чтобы использовать готовую инфраструктуру, но не очень популярную, можно самим сварить на основе Kafka, Outbox и CDC. Минусы очевидны — велосипедостроение, из плюсов, что решение на Kafka масштабируется и лучше проверено сообществом.
Еще из доклада узнал неочевидный для меня плюс акторной модели — это уход от состояния гонок и явное описание состояний актора
В Akka нашел возможность хранить сообщения в базе с помощью плагинов персистентного хранения. Как понимаю, работают на основе snapshot, и как с snapshot в Redis, некоторые данные можем потерять в случае перезапуска.
В докладе Никита Мельников рассказывает про альтернативный подход в построение акторной модели, который отчасти решает проблему потери сообщений при перезапусках. Вместо того, чтобы использовать готовую инфраструктуру, но не очень популярную, можно самим сварить на основе Kafka, Outbox и CDC. Минусы очевидны — велосипедостроение, из плюсов, что решение на Kafka масштабируется и лучше проверено сообществом.
Еще из доклада узнал неочевидный для меня плюс акторной модели — это уход от состояния гонок и явное описание состояний актора
Akka Documentation
Akka Persistence :: Akka Guide
✍7
Глубинный котер
Краем уха слышал про акторную модель в Erlang и в Akka (фреймворк на Scalla), но не понимал, как обстоят дела с гарантиями доставки. Если сообщения между акторами хранятся в памяти, то мы их потеряем при перезапуске/падении нашего приложения. В Akka нашел…
Из той же области, выглядит интересным спецификация CloudEvents, которая должна стандартизировать формат сообщений между сервисами из различных экосистем
❤3
Приблизительно понимал, что такое каррирование, но не понимал связи с кортежем (tuple). Но теперь все стало на место.
Кортеж является типом-произведения, а его значения принадлежат уже к декартовому (?) произведению множеств значений. Соотвественно, мы можем всегда найти функцию, которая принимает один из множителей. Повторяя поиск такой функции для других множителей, мы сможем найти последовательность функций от одного типа эквивалентную функции от типа-произведения, то есть кортежа
Кортеж является типом-произведения, а его значения принадлежат уже к декартовому (?) произведению множеств значений. Соотвественно, мы можем всегда найти функцию, которая принимает один из множителей. Повторяя поиск такой функции для других множителей, мы сможем найти последовательность функций от одного типа эквивалентную функции от типа-произведения, то есть кортежа
❤3✍1👍1
Увидел красоту реактивного программирования в докладе Ахтяма Сакаева
Главный вывод: бизнес-процессы можно моделировать через стримы, ака стрелочки на диаграмме у архитекторов
Главный вывод: бизнес-процессы можно моделировать через стримы, ака стрелочки на диаграмме у архитекторов
❤4👎1
Ознакомился со статьей Understanding Real-World Concurrency Bugs in Go о которой узнал из Блог*. Главный вывод: добавление новых семантических конструкций в языке увеличивает количество багов.
Так одной из отличительных особенностей Go являются каналы, которые по результатам исследования стали причиной больше половины блокирующих багов. При этом встроенный детектор блоков толком не помогает найти эти баги.
Из статьи можно сделать вывод, что Go не обеспечивает достаточный уровень проверок на этапе компиляции. Как в том же Rust на уровне теории типов были выявлены и устранены баги в корутинах. Но статья была написана в 2019 году, на текущий момент многие примеры из статьи поднимают ошибки во время исполнения, что уже неплохо.
Так одной из отличительных особенностей Go являются каналы, которые по результатам исследования стали причиной больше половины блокирующих багов. При этом встроенный детектор блоков толком не помогает найти эти баги.
Из статьи можно сделать вывод, что Go не обеспечивает достаточный уровень проверок на этапе компиляции. Как в том же Rust на уровне теории типов были выявлены и устранены баги в корутинах. Но статья была написана в 2019 году, на текущий момент многие примеры из статьи поднимают ошибки во время исполнения, что уже неплохо.
ACM Conferences
Understanding Real-World Concurrency Bugs in Go | Proceedings of the Twenty-Fourth International Conference on Architectural Support…
✍2👍2
Forwarded from Алиса копается
package main
import "fmt"
type SelfReferential struct {
r *SelfReferential
field int
}
func make_self_referential() SelfReferential {
s := SelfReferential {
r: nil,
field: 1,
}
s.r = &s
return s
}
func main() {
s := make_self_referential()
s.r.field = 2
fmt.Println(s.field)
fmt.Println(s.r.field)
fmt.Println(s.r.r.field)
}
Ваши догадки, что случится при запуске этой программы:
1. (lawful good) Выведется
2 2 2 без UB (структура аллоцировалась на куче)2. (lawful evil) Произойдет UB или паника (структура аллоцируется на стеке, в
s.r окажется dangling pointer)3. (chaotic neutral) Выведется
1 2 2 без UB (#dev #go
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🥰2
This media is not supported in your browser
VIEW IN TELEGRAM
Автор Haskell in Depth про хаскелистов
👍3🤔1
Книга "Структурированный дизайн" Йордона и Константина, похоже, переживает настоящее переосмысление спустя более 50 лет после первого издания. На неё ссылались Влад Хононов и Кент Бек в своих новых книгах, а теперь на конференции Joker был доклад, посвящённый применению идей из этой книги в современной промышленной разработке. И знаете, что самое интересное? Эти идеи оказались удивительно злободневными, особенно в контексте функционального программирования.
Главная мысль доклада — это важность отделения эффектов от основного потока выполнения. Докладчик прямо говорит об этом и честно признаётся, что похожие идеи распространены в мире функционального программирования. Хотя в докладе рассматриваются только IO-эффекты, это делает идею ещё более наглядной. Например, когда запросы к базе данных смешиваются с бизнес-логикой, получается настоящий "ком грязи", который сложно поддерживать и тестировать. На таких простых примерах становится понятно, почему эффекты — это большая боль для разработчиков: они усложняют формализацию потока выполнения и делают код менее предсказуемым.
Тема эффектов, кстати, сейчас набирает популярность. Недавно вышла книга Effect Oriented Programming с примерами на ZIO, которая тоже поднимает вопросы управления эффектами. Видимо, придётся погрузиться в современные практики приручения эффектов, так что Scala 3, до встречи
Главная мысль доклада — это важность отделения эффектов от основного потока выполнения. Докладчик прямо говорит об этом и честно признаётся, что похожие идеи распространены в мире функционального программирования. Хотя в докладе рассматриваются только IO-эффекты, это делает идею ещё более наглядной. Например, когда запросы к базе данных смешиваются с бизнес-логикой, получается настоящий "ком грязи", который сложно поддерживать и тестировать. На таких простых примерах становится понятно, почему эффекты — это большая боль для разработчиков: они усложняют формализацию потока выполнения и делают код менее предсказуемым.
Тема эффектов, кстати, сейчас набирает популярность. Недавно вышла книга Effect Oriented Programming с примерами на ZIO, которая тоже поднимает вопросы управления эффектами. Видимо, придётся погрузиться в современные практики приручения эффектов, так что Scala 3, до встречи
YouTube
Алексей Жидков — Структурный дизайн. Древний секрет простого и быстрого кода
Ближайшая конференция — JPoint 2025, 3–4 апреля (Москва + трансляция).
Подробности и билеты: https://jrg.su/T2zfbS
— —
Скачать презентацию с сайта Joker — https://jrg.su/TWOpZS
В докладе — краткий экскурс в структурный дизайн и, в частности, в понятие …
Подробности и билеты: https://jrg.su/T2zfbS
— —
Скачать презентацию с сайта Joker — https://jrg.su/TWOpZS
В докладе — краткий экскурс в структурный дизайн и, в частности, в понятие …
👍1🐳1
Глубинный котер
Книга "Структурированный дизайн" Йордона и Константина, похоже, переживает настоящее переосмысление спустя более 50 лет после первого издания. На неё ссылались Влад Хононов и Кент Бек в своих новых книгах, а теперь на конференции Joker был доклад, посвящённый…
В этом докладе я наткнулся на интересный и, казалось бы, очевидный критерий, который помогает оценить, насколько архитектура приложения находится в порядке. Если иерархия вызовов компонентов образует дерево — это хороший знак. Всё работает как надо, компоненты изолированы, и система остаётся поддерживаемой. Но если эта иерархия превращается в граф с множеством связей между компонентами — это явный сигнал, что что-то пошло не так.
Такой граф часто указывает на сильную связанность компонентов, что усложняет тестирование, рефакторинг и понимание кода в целом. Если вы видите, что компоненты начинают ссылаться друг на друга в произвольном порядке, это повод задуматься о реорганизации архитектуры. В идеале, поток вызовов должен быть направленным и предсказуемым, как в дереве, а не запутанным, как в графе.
Этот критерий — отличный способ быстро оценить состояние проекта и понять, где могут скрываться проблемы. Если вы видите "граф" вместо "дерева", возможно, пришло время для рефакторинга
Такой граф часто указывает на сильную связанность компонентов, что усложняет тестирование, рефакторинг и понимание кода в целом. Если вы видите, что компоненты начинают ссылаться друг на друга в произвольном порядке, это повод задуматься о реорганизации архитектуры. В идеале, поток вызовов должен быть направленным и предсказуемым, как в дереве, а не запутанным, как в графе.
Этот критерий — отличный способ быстро оценить состояние проекта и понять, где могут скрываться проблемы. Если вы видите "граф" вместо "дерева", возможно, пришло время для рефакторинга
❤4
Есть API, в который необходимо передавать ключ идемпотентности. На первый взгляд, всё кажется простым: можно использовать любой идентификатор или хэш в качестве ключа. Однако есть нюансы:
1. Нужно сделать N запросов на дочерние ресурсы
2. Ключ идемпотентности должен быть в формате UUID
Возникает вопрос: использовать ли идентификатор дочернего ресурса в качестве ключа или же родительского? Но здесь есть две проблемы:
1. Дочерние ресурсы не имеют UUID-идентификаторов
2. Использование родительского идентификатора не подходит, так как это сделает некорректными смежные запросы для других дочерних ресурсов
Решение сразу приходит на ум: можно склеить идентификаторы дочернего и родительского ресурсов. Но как превратить результат в UUID? Это довольно легко сделать, пример на Go:
Кажется, здесь есть проблема с уникальностью такого UUID, но вроде бы это не критично.
Альтернативное решение — честно генерировать UUID, сохранять его в базу данных и использовать до победного конца в ретраях запроса. Но это будет в разы сложней реализовать и тяжело поддерживать в будущем
1. Нужно сделать N запросов на дочерние ресурсы
2. Ключ идемпотентности должен быть в формате UUID
Возникает вопрос: использовать ли идентификатор дочернего ресурса в качестве ключа или же родительского? Но здесь есть две проблемы:
1. Дочерние ресурсы не имеют UUID-идентификаторов
2. Использование родительского идентификатора не подходит, так как это сделает некорректными смежные запросы для других дочерних ресурсов
Решение сразу приходит на ум: можно склеить идентификаторы дочернего и родительского ресурсов. Но как превратить результат в UUID? Это довольно легко сделать, пример на Go:
concatenated := []byte("<ParentID>/<DaughterID>")
result := uuid.NewSHA1(uuid.Nil, concatenated)
Кажется, здесь есть проблема с уникальностью такого UUID, но вроде бы это не критично.
Альтернативное решение — честно генерировать UUID, сохранять его в базу данных и использовать до победного конца в ретраях запроса. Но это будет в разы сложней реализовать и тяжело поддерживать в будущем
👍3❤1