#balancing_coupling
Вот и ответ почему слоистая архитектура так хороша
Вот и ответ почему слоистая архитектура так хороша
Remember David L. Parnas’s saying that a module is an abstraction, and according to Edsger Dijkstra, the purpose of abstraction is to create a new semantic level in which one can be absolutely precise. Introducing an explicit integration contract takes this idea to the extreme. The integration contract can create a new language that focuses entirely on the tasks that can be carried out using the module, while completely abstracting how the tasks are implemented
❤2
#balancing_coupling
Честно про программную архитектуру от Влада Хононова:
Честно про программную архитектуру от Влада Хононова:
DISCLAIMER: THIS IS NOT AN EXACT SCIENCE
👍2🤨1
Всегда думал, что Java слишком вербозная, а Python такой выразительный и краткий.
Но вот в случае функционального стиля Python явно проигрывает API стримов в Java. Вместо лаконичного пайплайна, получаем скобочный ад
Но вот в случае функционального стиля Python явно проигрывает API стримов в Java. Вместо лаконичного пайплайна, получаем скобочный ад
👍3❤2
Прикольно автор книги с кабанчиком раздает бесплатно избранные главы на сайте, как понимаю, его NoSQL СУБД ScyllaDB
👍1
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