Узнайте, как разработка в здравоохранении научила меня избегать скрытых сбоев и думать о пользователе. Примените эти принципы к своим проектам уже сегодня.
Я работал разработчиком в двух индустриях — телекоме и здравоохранении. Обе связаны с распределёнными системами, event-driven архитектурой и обработкой данных в реальном времени. Технические проблемы похожи, но мой подход к написанию кода изменился кардинально. И это заслуга здравоохранения. Если вы пишете код, который влияет на жизни людей, — эта статья для вас.
В телекоме я строил Kafka-пайплайны, обрабатывающие сотни миллионов событий в день. Инженерные проблемы были реальными и интересными: задержки, отказоустойчивость, эволюция схем, consumer lag. Когда что-то шло не так, падала пропускная способность, загорались красные дашборды, и дежурный инженер не спал ночью. Это стресс. Но худший сценарий большинства сбоев: некоторые события задерживались, некоторые метрики устаревали, очереди повторных попыток забивались. Вы фиксили проблему, писали пост-мортем и шли дальше. Пользователи системы — клиенты телекома — чаще всего даже не знали, что что-то случилось.
На первой неделе в моей нынешней организации меня провели по клиническому отделению. Я увидел реальные документы, которые мой код будет обрабатывать: направления пациентов, выписки, операционные заметки. Настоящие документы с реальными именами пациентов, диагнозами, списками лекарств. И я осознал нечто очевидное, но до этого не до конца понятное: результат моего кода влияет на чью-то жизнь. Неправильный URN пациента — это не просто проваленный unit-тест. Это документ, попавший не в ту запись. В лучшем случае кто-то заметит и исправит вручную. В худшем — врач примет решение на основе неполной или неверной информации. Я не драматизирую. Это действительно изменило то, как я пишу код.
1. Я перестал терпеть скрытые сбои
Во многих системах скрытые сбои приемлемы. Джоб упал, записал ошибку в лог, пошёл дальше. Вы заметите утром на ежедневном ревью. В здравоохранении я стал почти аллергичным к этому паттерну. Если что-то идёт не так, я хочу знать немедленно и точно, что пошло не так. Не общее исключение. Не null pointer, всплывший через три слоя. Конкретную причину сбоя, почему он произошёл и в каком состоянии остались данные. Это привело к тому, что я спроектировал OCR-сервис с явными режимами отказа. Если система не может уверенно извлечь URN пациента, она не угадывает — она помечает документ для ручной проверки. Это осознанное дизайнерское решение, а не запасной вариант. Неопределённость выводится на поверхность, а не прячется. Я перенёс этот подход во все системы, которые строю сейчас. Скрытые сбои — это технический долг, который вы платите доверием.
# Пример: явный режим отказа вместо угадывания
def extract_patient_urn(document_text: str) -> str:
"""Извлекает URN пациента из текста документа."""
# Используем регулярное выражение для поиска URN
match = re.search(r'URN:\s*([A-Z0-9]+)', document_text)
if match:
urn = match.group(1)
# Проверяем формат URN
if len(urn) == 10 and urn.isalnum():
return urn
else:
# Не уверены — помечаем для ручной проверки
raise ManualReviewRequired(f"Неверный формат URN: {urn}")
else:
# URN не найден — не угадываем
raise ManualReviewRequired("URN не найден в документе")
class ManualReviewRequired(Exception):
"""Исключение для запроса ручной проверки."""
pass2. Я начал думать о человеке в конце пайплайна
В телекоме я думал о пропускной способности, задержках и аптайме. Это правильные вещи. В здравоохранении я начал задавать другой вопрос перед проектированием любой фичи: кто будет это использовать и что они сделают с результатом? Для OCR-сервиса ответ был: член клинической административной команды, который возьмёт этот Excel-вывод и использует его для сопоставления документов с записями пациентов. Этот человек — не разработчик. Он не знает, что такое OCR. Ему плевать на мою архитектуру. Ему важно, корректен ли вывод и чётко ли помечены ошибки, чтобы он мог обработать исключения без вызова IT. Этот сдвиг перспективы — от «работает ли система» к «работает ли система для этого конкретного человека в этом конкретном контексте» — я теперь применяю везде.
# Пример: проектирование вывода с учётом пользователя
def generate_report(results: list) -> str:
"""Генерирует отчёт, понятный для администратора."""
report_lines = []
for result in results:
if result['status'] == 'success':
report_lines.append(f"OK: URN {result['urn']} — документ обработан")
elif result['status'] == 'manual_review':
report_lines.append(f"ВНИМАНИЕ: Документ {result['doc_id']} требует ручной проверки. Причина: {result['reason']}")
else:
report_lines.append(f"ОШИБКА: Документ {result['doc_id']} не обработан. Свяжитесь с IT.")
return '\n'.join(report_lines)3. Я стал больше спорить
Это меня удивило. Я всегда считал, что неплохо задаю вопросы о требованиях. Но здравоохранение дало мне гораздо меньшую толерантность к созданию того, в чём я не уверен. Цена создания неправильной штуки в клиническом контексте высока. Не только потраченное инженерное время — потенциально неверные данные в продакшене, процесс, который вносит ошибки, которые трудно найти позже. Поэтому я начал больше спорить на планерках. Не агрессивно, но настойчиво. «Что будет, если в документе нет метки в ожидаемой позиции?» «Что должна делать система, если confidence score ниже порога?» «Кто отвечает за проверку исключений?» Эти вопросы замедляют процесс в моменте. Они делают планерки длиннее. Но они делают софт гораздо надёжнее, потому что вы продумали крайние случаи до того, как написали строку кода.
Чего я не ожидал: писать код таким образом — более удовлетворяюще. Когда я запустил OCR-сервис в продакшен, я точно знал, что он делает, чего не делает, как он отказывает и кто отвечает за каждый режим отказа. Я знал, что клинический персонал, использующий его, участвовал в тестировании на реальных документах. Я знал, что обработка исключений соответствует их реальному рабочему процессу. Это другое чувство по сравнению с запуском того, что работает на демо, но имеет кучу крайних случаев, в которых вы не уверены. Думаю, большинство разработчиков хотят писать код, который имеет значение. Здравоохранение делает это очень конкретным и быстрым. Петля обратной связи между тем, что вы строите, и тем, помогает ли это кому-то, коротка и видна. Это привилегия, честно говоря.
Это не так недоступно, как кажется. Вам не нужно медицинское образование. Вам нужно то же, что и в любой другой области: любопытство к реальной проблеме, готовность задавать вопросы и дисциплина правильно обрабатывать крайние случаи. Взамен вы получаете ясность цели, которую труднее найти в других областях. Работа имеет значение в осязаемом смысле. И это обычно делает вас лучшим инженером.
Что делать прямо сейчас: возьмите одну свою текущую задачу и спросите себя: «Кто будет использовать результат моего кода? Что они будут с ним делать? Как они узнают, что что-то пошло не так?» Если вы не можете ответить на эти вопросы — начните задавать их на следующей планерке. Это изменит ваш код к лучшему.
Хочешь закрепить знания на практике?
Решай задачи на Algolit — интерактивная платформа для обучения
Начать бесплатно →