Задать вопрос
  • Безопасно ли загружать docx файлы пользователей на сервер?

    @rPman
    Да, для сервера безопасно хранить документы и даже вирусы.

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

    p.s. что бы исключить запуск вируса по ошибке администратором сервера, файлы можно хранить на диске с 'техническими' именами (например числовой идентификатор из базы), так как подавляющее большинство приложений (файловые менеджеры, интерфейсы ОС и т.п.) ожидают нужное расширение (часть имени файла с конца с точкой, например ".exe" или в твоем случае ".docx") и/или атрибут файловой системы (linux "x" для скриптов и бинарных файлов)
    Ответ написан
  • Как узнать первые признаки, что ноутбук больше не включится?

    VoidVolker
    @VoidVolker Куратор тега Железо
    Dark side eye. А у нас печеньки! А у вас?
    Никак. ПК может проработать как пять минут и двинуть кони, так и запросто 10-20 лет без поломок. Надо просто периодически обслуживать (менять термопасту, чистить от грязи, пыли и т.п.), эксплуатировать в нормальных условиях, не допускать перегрева, следить за показаниями смарта дисков и прочее. Выход железа из строя практически всегда происходит внезапно. Да, бывают неисправности, которые приводят к частичному отказу - нестабильное поведение, перезагрузки, падение ПО и прочее. Но это тоже случается непредсказуемо.

    Не может что прям все идеально работает, а завтра не включится.

    Может и случается регулярно - это вполне обычное явление.
    Ответ написан
    Комментировать
  • ИИ на стадии обучения программированию. Стоит ли?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Обучение - это формирование связей в тканях мозга, поэтому оно больше похоже на накачивание мышц, а не на загрузку файлов на флешку. И происходит это, как и с накачиванием мышц, только под нагрузкой. Нельзя нарастить бицуху, если гантели будет тягать робот. Нельзя научиться программированию, если задачи решает ИИ.
    Ответ написан
    Комментировать
  • Как найти работу, если есть большой опыт, но всё равно не берут?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    У меня есть уже 6 лет опыта в программировании на Python, я самоучка с 13 лет (сейчас 19)

    Для компаний значение имеет только тот опыт, который в трудовую записан. Если у вас нет трудовой, то с позиции нанимателя и опыта у вас тоже нет.
    Ответ написан
    5 комментариев
  • Сервис для поиска заказов веб-разработчика?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Таких нет и быть не может. На фрилансе заказов сильно меньше, чем исполнителей, поэтому последним приходится активно конкурировать. Если хотите, чтобы заказчик выбирал вас, придётся сначала добиться высокой репутации и известности.
    Ответ написан
    2 комментария
  • Как создать свою библиотеку для Go?

    fenrir1121
    @fenrir1121
    Начни с документации
    Прочитать в документации.
    Ответ написан
    Комментировать
  • Есть ли какая то определенная причина почему стоит использовать Windows Server?

    VoidVolker
    @VoidVolker
    Dark side eye. А у нас печеньки! А у вас?
    Только для тех случаев, когда зависимости ПО работают только под виндой. Во всех остальных случаях удобнее и практичнее линукс. Сегодня dotNet спокойно ставится под линуксом из пакетов и отлично там работает как и любое другое ПО.

    Если Windows Server настолько проиграл Linux в серверных войнах, то почему Microsoft не закрывает этот отдел? Значит сервера на Windows, используются.

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

    Почему я задал этот вопрос, я как системный администратор, столкнулся с клиентом, с которым я сцепился из за того, что его разработчики и бывший сотрудник сисадмин решил установить .NET + C# + Mono + Nginx и все это на линукс.
    Естественно меня это взбесило, и я просто отказался все это поддерживать, потому что извините, но .NET проще поддерживать на Windows Server

    Единственная адекватная причина отказа от сопровождения серверов на линуксе - отсутствие знаний и умений по их сопровождению либо недостаточная квалификация в данной области. "Взбесило" - вот ту вы были не правы и вот это ваше "проще" просто свидетельствует о вашей недостаточной квалификации в данной области. Кроме того, в рамках диалога с клиентом можно было просто спросить о целях, причинах и задачах именно такого решения.
    Ответ написан
    9 комментариев
  • Как распарсить файл в табличной верстке через beatifulsoap?

    Maksim_64
    @Maksim_64
    Data Analyst
    У тебя всегда таблица в htnl используй подходящуюю структуру данных пандас датафрейм.

    import pandas as pd
    from io import StringIO  
    html = '''<!-- SW --><TABLE WIDTH=100%><TD CLASS=pt><A NAME="installed programs">Установленные программы</A><TR><TD><HR></TABLE><TABLE><TR><TD WIDTH=16>&nbsp;<TD WIDTH=16><TD><TD><TD><TD><TD><TD>
    <TR><TD><TD><TD><B>Программа</B>&nbsp;&nbsp;<TD CLASS=cr><B>Версия</B>&nbsp;&nbsp;<TD CLASS=cr><B>Размер</B>&nbsp;&nbsp;<TD><B>GUID</B>&nbsp;&nbsp;<TD><B>Издатель</B>&nbsp;&nbsp;<TD CLASS=cr><B>Дата</B>
    <TR><TD><TD><TD>64 Bit HP CIO Components Installer&nbsp;&nbsp;<TD CLASS=cr>16.2.1&nbsp;&nbsp;<TD CLASS=cr>Неизвестно&nbsp;&nbsp;<TD>{F8F948EA-5AEA-4158-8821-A2F788ECE936}&nbsp;&nbsp;<TD>Hewlett-Packard&nbsp;&nbsp;<TD CLASS=cr>2023-05-18
    <TR><TD><TD><TD>HP LaserJet Pro M201-M202&nbsp;&nbsp;<TD CLASS=cr>15.0.16064.399&nbsp;&nbsp;<TD CLASS=cr>Неизвестно&nbsp;&nbsp;<TD>{e71f6d30-080d-43ef-87e0-1ac4d7f8adfa}&nbsp;&nbsp;<TD>Hewlett-Packard&nbsp;&nbsp;<TD CLASS=cr>
    <TR><TD><TD><TD>HP Unified IO&nbsp;&nbsp;<TD CLASS=cr>2.0.0.434&nbsp;&nbsp;<TD CLASS=cr>Неизвестно&nbsp;&nbsp;<TD>{F1390872-2500-4408-A46C-CD16C960C661}&nbsp;&nbsp;<TD>HP&nbsp;&nbsp;<TD CLASS=cr>2023-05-18
    <TR><TD><TD><TD>HP Update&nbsp;&nbsp;<TD CLASS=cr>5.005.002.002&nbsp;&nbsp;<TD CLASS=cr>Неизвестно&nbsp;&nbsp;<TD>{912D30CF-F39E-4B31-AD9A-123C6B794EE2}&nbsp;&nbsp;<TD>Hewlett-Packard&nbsp;&nbsp;<TD CLASS=cr>2023-05-18
    <TR><TD><TD><TD>Mesh Agent&nbsp;&nbsp;<TD CLASS=cr>2022-12-02 22:42:16.000+03:00&nbsp;&nbsp;<TD CLASS=cr>Неизвестно&nbsp;&nbsp;<TD>Mesh Agent&nbsp;&nbsp;<TD>&nbsp;&nbsp;<TD CLASS=cr>
    <TR><TD><TD><TD>Microsoft Edge&nbsp;&nbsp;<TD CLASS=cr>132.0.2957.115&nbsp;&nbsp;<TD CLASS=cr>Неизвестно&nbsp;&nbsp;<TD>Microsoft Edge&nbsp;&nbsp;<TD>Корпорация Майкрософт&nbsp;&nbsp;<TD CLASS=cr>2025-01-20
    <TR><TD><TD><TD>Microsoft Office LTSC профессиональный плюс 2021 - ru-ru&nbsp;&nbsp;<TD CLASS=cr>16.0.14332.20345&nbsp;&nbsp;<TD CLASS=cr>Неизвестно&nbsp;&nbsp;<TD>ProPlus2021Volume - ru-ru&nbsp;&nbsp;<TD>Microsoft Corporation&nbsp;&nbsp;<TD CLASS=cr>
    <TR><TD><TD><TD>Microsoft Update Health Tools&nbsp;&nbsp;<TD CLASS=cr>3.74.0.0&nbsp;&nbsp;<TD CLASS=cr>Неизвестно&nbsp;&nbsp;<TD>{1FC1A6C2-576E-489A-9B4A-92D21F542136}&nbsp;&nbsp;<TD>Microsoft Corporation&nbsp;&nbsp;<TD CLASS=cr>2023-11-14
    <TR><TD><TD><TD>Mozilla Firefox (x64 ru)&nbsp;&nbsp;<TD CLASS=cr>134.0.1&nbsp;&nbsp;<TD CLASS=cr>Неизвестно&nbsp;&nbsp;<TD>Mozilla Firefox 134.0.1 (x64 ru)&nbsp;&nbsp;<TD>Mozilla&nbsp;&nbsp;<TD CLASS=cr>
    <TR><TD><TD><TD>Mozilla Maintenance Service&nbsp;&nbsp;<TD CLASS=cr>113.0.1&nbsp;&nbsp;<TD CLASS=cr>Неизвестно&nbsp;&nbsp;<TD>MozillaMaintenanceService&nbsp;&nbsp;<TD>Mozilla&nbsp;&nbsp;<TD CLASS=cr>
    <TR><TD><TD><TD>Office 16 Click-to-Run Extensibility Component&nbsp;&nbsp;<TD CLASS=cr>16.0.14332.20345&nbsp;&nbsp;<TD CLASS=cr>Неизвестно&nbsp;&nbsp;<TD>{90160000-008C-0000-1000-0000000FF1CE}&nbsp;&nbsp;<TD>Microsoft Corporation&nbsp;&nbsp;<TD CLASS=cr>2023-05-18
    <TR><TD><TD><TD>Office 16 Click-to-Run Licensing Component&nbsp;&nbsp;<TD CLASS=cr>16.0.14332.20345&nbsp;&nbsp;<TD CLASS=cr>Неизвестно&nbsp;&nbsp;<TD>{90160000-007E-0000-1000-0000000FF1CE}&nbsp;&nbsp;<TD>Microsoft Corporation&nbsp;&nbsp;<TD CLASS=cr>2023-05-18
    <TR><TD><TD><TD>Office 16 Click-to-Run Localization Component [Русский (Россия)]&nbsp;&nbsp;<TD CLASS=cr>16.0.14332.20281&nbsp;&nbsp;<TD CLASS=cr>Неизвестно&nbsp;&nbsp;<TD>{90160000-008C-0419-1000-0000000FF1CE}&nbsp;&nbsp;<TD>Microsoft Corporation&nbsp;&nbsp;<TD CLASS=cr>2023-05-18
    <TR><TD><TD><TD>STDU Viewer version 1.6.361.0&nbsp;&nbsp;<TD CLASS=cr>1.6.361.0&nbsp;&nbsp;<TD CLASS=cr>Неизвестно&nbsp;&nbsp;<TD>STDU Viewer_is1&nbsp;&nbsp;<TD>STDUtility&nbsp;&nbsp;<TD CLASS=cr>2023-05-18
    <TR><TD><TD><TD>Update for x64-based Windows Systems (KB5001716)&nbsp;&nbsp;<TD CLASS=cr>8.94.0.0&nbsp;&nbsp;<TD CLASS=cr>Неизвестно&nbsp;&nbsp;<TD>{DA80A019-4C3B-4DAA-ACA1-6937D7CAAF9E}&nbsp;&nbsp;<TD>Microsoft Corporation&nbsp;&nbsp;<TD CLASS=cr>2024-10-16
    <TR><TD><TD><TD>VixWin Platinum&nbsp;&nbsp;<TD CLASS=cr>3.50.000&nbsp;&nbsp;<TD CLASS=cr>Неизвестно&nbsp;&nbsp;<TD>{81695582-88F8-47A6-8431-C10617AF058A}&nbsp;&nbsp;<TD>Gendex&nbsp;&nbsp;<TD CLASS=cr>2023-05-19
    <TR><TD><TD><TD>WinRAR 6.21 (64-разрядная)&nbsp;&nbsp;<TD CLASS=cr>6.21.0&nbsp;&nbsp;<TD CLASS=cr>Неизвестно&nbsp;&nbsp;<TD>WinRAR archiver&nbsp;&nbsp;<TD>win.rar GmbH&nbsp;&nbsp;<TD CLASS=cr>
    <TR><TD><TD><TD>КриптоПро CSP&nbsp;&nbsp;<TD CLASS=cr>5.0.12330&nbsp;&nbsp;<TD CLASS=cr>Неизвестно&nbsp;&nbsp;<TD>{50F91F80-D397-437C-B0C8-62128DE3B55E}&nbsp;&nbsp;<TD>Компания КриптоПро&nbsp;&nbsp;<TD CLASS=cr>2023-05-18
    <TR><TD><TD><TD>КриптоПро ЭЦП Browser plug-in [Русский (Россия)]&nbsp;&nbsp;<TD CLASS=cr>2.0.14816&nbsp;&nbsp;<TD CLASS=cr>Неизвестно&nbsp;&nbsp;<TD>{E12CC7EE-36B7-4AAA-924E-2F5CD75BCECF}&nbsp;&nbsp;<TD>Компания КриптоПро&nbsp;&nbsp;<TD CLASS=cr>2023-05-18
    <TR><TD><TD><TD>Платные услуги К1-1&nbsp;&nbsp;<TD CLASS=cr>0.1&nbsp;&nbsp;<TD CLASS=cr>Неизвестно&nbsp;&nbsp;<TD>{E59C5221-50B3-420C-84C0-DF40A1AC280E}&nbsp;&nbsp;<TD>Maximus&nbsp;&nbsp;<TD CLASS=cr>2023-05-18
    <TR><TD><TD><TD>Среда выполнения Microsoft Edge WebView2 Runtime&nbsp;&nbsp;<TD CLASS=cr>131.0.2903.146&nbsp;&nbsp;<TD CLASS=cr>Неизвестно&nbsp;&nbsp;<TD>Microsoft EdgeWebView&nbsp;&nbsp;<TD>Корпорация Майкрософт&nbsp;&nbsp;<TD CLASS=cr>2025-01-16
    </TABLE><BR><BR>
    '''
    table = pd.read_html(StringIO(html),header=[1])[0]
    print(table)


    Все задача решается в одну строчку кода table = pd.read_html(StringIO(html),header=[1])[0]затем выбираешь нужные тебе колонки, параметр header это с какой строки считать имя колонок, на другом примере его значение может, отличатся, по этому можешь его опустить, а выяснить нужные локации колонок, уже после.
    Ответ написан
    3 комментария
  • Перенаправление с sait.ru/ на sait.ru/index.shtml Как сделать?

    @dodo512
    RewriteEngine On
    
    RewriteRule ^katalog/$ https://sait.ru/katalog/index.shtml  [R=301,L]


    RewriteEngine On
    
    RewriteRule ^$ https://sait.ru/index.shtml  [R=301,L]
    
    RewriteRule ^(.+)/$ https://sait.ru/$1/index.shtml [R=301,L]
    Ответ написан
    5 комментариев
  • Имеет смысл подключение через переходник HDMI в DisplayPort?

    ValdikSS
    @ValdikSS
    Одним кабелем не обойтись, нужен активный адаптер (с чипом, преобразующим протоколы/сигналы).

    Существуют адаптеры, поддерживающие 600 МГц Pixel Clock, с ними 1920×1080p будет работать на 240 Гц, 2560×1440 на 144 Гц.

    Вот пример (почему-то заявлено 165@1080p): https://www.amazon.com/gp/product/B0752D33PJ/
    Ответ написан
    3 комментария
  • Как получить айди по юзернейму?

    @kaka888
    C, C++, Qt, Python, Flask, aiogram, MySQL, Redis..
    Подсказка здесь: Как получить username пользователя в aiogram?

    При вызове команды /start записывайте в БД user_id и username пользователя.
    А при вызове команды /айди ищите в БД переданный в команде юзернейм.
    Всё просто =)
    Ответ написан
    Комментировать
  • Почему эмуляция кликов мыши через SendInput блокируется после трёх срабатываний?

    VoidVolker
    @VoidVolker Куратор тега Windows
    Dark side eye. А у нас печеньки! А у вас?
    Неужели для работы такого достаточно простенького кода придется обращаться к драйверам?

    В играх - да, ибо там своя атмосфера с античитами и банхаммерами. Вам нужен драйвер пользовательского ввода в ядре ОС (ring0). А туда пускают только с подписью (ну или ломать систему). Ищите на форумах автоита - там вроде был такой. Альтернативный вариант - свой контроллёр в USB порт, прикидывающийся мышкой/клавиатурой и которым можно рулить через драйвер уже в пользовательском пространстве.
    Ответ написан
    1 комментарий
  • Как оптимизировать цикл while?

    phaggi
    @phaggi Куратор тега Python
    лужу, паяю, ЭВМы починяю
    Если у вас в коде появились нумерованные переменные, вы точно что-то делаете не так.

    Кроме рекомендации Rsa97 вынести однотипные действия в функцию, можно однотипные данные вынести в структуру. Например, словарь, список или что-то такое. И в одном цикле по условию переходить к «следующему» элементу структуры.

    Можно вообще всё в класс объединить - однотипные данные и однотипные методы для работы с ними.
    Ответ написан
    Комментировать
  • Есть ли софт для программного брутфорса пинкода для расшифровки андроида?

    15432
    @15432
    Системный программист ^_^
    В современных смартфонах возможно расшифровать дамп только на этом же устройстве (ключ частично в процессоре).

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

    Вы также правильно предположили, что задержка введена искусственно. Поэтому если для вашей модели телефона/процессора существуют эксплоиты уровня бутрома или прелоадера (то есть можно исполнить произвольный код на вашем же телефоне с максимальными привилегиями, а в результате - запустить пропатченную систему), теоретически можно как отключить ограничения/задержки на ввод PIN, так и программно забрутфорсить пин-код на самом устройстве за секунды (непубличными forensic утилитами)

    Увы, поскольку это большая брешь в безопасности, позволяющая достать зашифрованные данные из любого устройства, производители стараются своевременно латать дыры и закрывать любые подобные баги, поэтому шансы, что вы достанете свои данные, довольно низкие
    Ответ написан
    Комментировать
  • Как при помощи GPO задать единые настройки "Программ по умолчанию" и точечных расширений?

    SignFinder
    @SignFinder
    Wintel\Unix Engineer\DevOps
    Я так понимаю, гугл все еще не осилили и ваша неспособность погуглить просто потрясает.
    И тем не менее - запрос в гугле "Set default File Associations using GPO".
    А путь здесь
    User Configuration -> Preferences -> Control Panel Settings -> Folder Options
    Ответ написан
    2 комментария
  • Как постепенно перекочевать из Web в Machine Learning максимально безболезненно?

    un1t
    @un1t
    Знакомый работал в стартапе когда его заинтересмовал ML, вобщем он предложил использовать какие-то штуки из ML для этого стартапа, заказчик согласился. И вот у него появилось несколько месяцев практического использования ML в продакшене. С точки зрения бизнеса я скажу, что идея была сомнительная, но кого это волнует)). Ну а знакомый продолжил дальше углубляться в эту тему и на следущую работу уже устроился как специалист по ML.

    Самый быстрый и безболезненный путь это начать применять ML на текущем месте. Придумай задачу, предложи заказчику, лучше начать с чего-то простого и нетрудозатратного.
    Ответ написан
    Комментировать
  • Как постепенно перекочевать из Web в Machine Learning максимально безболезненно?

    @asd111
    Из языков строго python. Он похож чем то на Golang и на javascript так что сложностей в использовании не возникнет. С++ и R сразу нет. Потому что на С++ пишут в основном только сами библиотеки для ML либо что то очень быстрое наподобие анализа видеопотока в автопилотах и даже тогда прототип пишут на python, а R практически не развивается по сравнению с python и имеет более узкую сферу применения чем python.
    В плане обучения можно сделать так:
    1. Прочесть хорошую книгу по теме, потому что нужно знать термины и основные алгоритмы. Ну или хотя бы посмотреть курсы Andrew Ng Machine Learning. Для применения чужих библиотек на простых задачах этого в принципе достаточно.
    2. Глянуть scipy, numpy и jupyter notebook. У scikit есть scikit learn, в котором реализованы некоторые популярные алгоритмы. Например SVM, decision trees и т.д. и есть доки под это дело для начинающих scikit-learn.org/stable
    3. Зарегистрироваться на kaggle.com и найти задачу про титаник. Вот она https://www.kaggle.com/c/titanic Делаете решение как умеете. Можно взять простой gradient boost. Yandex как раз недавно выложил либу под это дело называется cat boost https://tech.yandex.ru/catboost/ Банальное использование этой библиотеки может дать около 80% точности. Вот туториал https://github.com/catboost/catboost/blob/master/c...
    4. Прочитать про keras. Взять готовую модель для смешивания стилей изображений и сделать сайт наподобие ostagram.ru для смешивания изображений. https://github.com/fchollet/keras/blob/master/exam...

    5. Дальше всё зависит от вас, поскольку заработать в области ML непросто :) Когда прочтете хотя бы одну книгу по ML, регистрируйтесь здесь ods.ai - это сообщество русскоговорящих специалистов в данной области.
    Ответ написан
    Комментировать
  • Кто нибудь применял или видел generics в серьезных Go проектах?

    Одно из самых полезных применений дженериков, которое у меня было — это написание врапперов, которые добавляют строгую типизацию в обработку чего-либо и уменьшают бойлерплейт. Например, обработка http-запросов. Обычно используется роутер и в него регистрируются хендлеры для разных путей, например:
    router := httprouter.New()
    
    router.POST("/api/products", productsHandler.Handle)
    router.POST("/api/get_free_slots", getFreeTimeSlotsHandler.Handle)
    router.POST("/api/create_visit", createVisitHandler.Handle)


    При этом, функция Handle у каждого хендлера это обычно что-то типа func(w http.ResponseWriter, r *http.Request)
    Хендлер уже внутри себя сам читает тело, парсит его из json, потом формирует ответ, итд.

    Хотелось добавить сюда типизацию и какую-то структуру, поэтому я написал
    простой враппер

    type Validatable interface {
    	Validate() error
    }
    
    func Wrap[Req Validatable, Res any](fn func(ctx context.Context, req Req) (Res, error)) httprouter.Handle {
    	handler := func(writer http.ResponseWriter, request *http.Request, _ httprouter.Params) {
    		writeError := func(statusCode int, err error) {
    			writer.WriteHeader(statusCode)
    			_, _ = writer.Write([]byte(err.Error()))
    		}
    
    		var req Req
    
    		bytes, err := io.ReadAll(request.Body)
    		if err != nil {
    			writeError(http.StatusBadRequest, err)
    			return
    		}
    
    		if err := json.Unmarshal(bytes, &req); err != nil {
    			writeError(http.StatusBadRequest, err)
    			return
    		}
    
    		if err := req.Validate(); err != nil {
    			writeError(http.StatusBadRequest, err)
    			return
    		}
    
    		resp, err := fn(request.Context(), req)
    		if err != nil {
    			writeError(http.StatusInternalServerError, err)
    			return
    		}
    
    		respBytes, err := json.Marshal(resp)
    		if err != nil {
    			writeError(http.StatusInternalServerError, err)
    			return
    		}
    		writer.WriteHeader(http.StatusOK)
    		_, _ = writer.Write(respBytes)
    	}
    
    	return handler
    }



    Он берет на себя весь бойлерплейт по парсингу и валидации запроса, формированию ответа, работы с кодами, итд. Причем, через стандартный errors.Is иногда добавлял сюда еще возможность из хэндлера указать врапперу, какой http-код ответа отдавать. Обычно все функции враппера делал под конкретную задачу в конкретном проекте (можно, например, не только json тела парсить, но и урл и хедеры, итд).

    Использование враппера выглядит так.
    Мы пишем хэндлер, используя конкретные типы

    type Handler struct {
    	userService *usersvc.Service
    }
    
    type Request struct {
    	UserID int64 `json:"user_id"`
    }
    
    func (c Request) Validate() error {
    	if c.UserID == 0 {
    		return errors.New("empty user id")
    	}
    	return nil
    }
    
    type Response struct {
    	Name string `json:"name"`
    	Age  int    `json:"age"`
    }
    
    func New(userService *usersvc.Service) *Handler {
    	return &Handler{userService: userService}
    }
    
    func (h Handler) Handle(ctx context.Context, req *Request) (*Response, error) {
    	user, err := h.userService.UserByID(ctx, req.UserID)
    	if err != nil {
    		return nil, err
    	}
    
    	return &Response{
    		Name: user.Name,
    		Age:  user.Age,
    	}, nil
    }



    Через dependency injection даем хэндлеру все источники данных, изолируем хэндлер в отдельном пакете, четко прописываем ему типы Request и Response, пишем валидацию для запроса. Открыв хэндлер, разработчик сразу видит его контракты, весь бойлерплейт во враппере, остается написать только логику.

    В итоге использование такого хэндлера+враппер выглядит так:
    getUserHandler := getuser.New(userSvc)
    
    router := httprouter.New()
    
    router.POST("/api/get_user", wrapper.Wrap(productsHandler.getUserHandler))


    Причем, тут даже не видно, что Wrap() имеет дженерик-параметры, потому что гошка самостоятельно выводит эти параметры из типов Request и Response из хэндлера и проверяет, что у Request есть метод Validate.

    Подобные дженерик-врапперы применял в нескольких разных задачах. Кроме обработки запросов еще была система для запуска фоновых джоб по обработке данных, нужно было положить джобы в один слайс, но при этом, чтобы контракты джоб были типизированы. Поэтому враппером приводил конкретные типы структур из джоб к более универсальному виду с типами в interface{}. Получилось, что и типы все на компиляции проверяются и могу положить все джобы в одну коллекцию.
    Ответ написан
    Комментировать
  • Как обосновать применение реляционной БД на интервью по System Design?

    VoidVolker
    @VoidVolker
    Dark side eye. А у нас печеньки! А у вас?
    Обоснование в данном случае очень простое:
    • Данная БД позволяет решить задачу?
    • Она соответствует требованиям задачи?

    Положительный ответ на вот эти два вопроса в целом достаточное обоснование. Что-то более сложное - это надо проводить исследования, собрать прототип, провести тестирование решения, возможно даже для нескольких разных БД, сделать сводную таблицу результатов, подвести итоги исследований. Вот тогда да, будет "сильное" обоснование. "Сильное обоснование" входило в условия ТЗ? Если не входило и вы не делали - то в данном случае не вы "сели в лужу", а те, кто проводил интервью. Возможно, надо было уточнить, какое именно обоснование они хотят получить и сколько они готовы за это заплатить. ТЗ было какое? Решить конкретную задачу в определённых рамках. Вы её решили успешно? Значит, вы молодец и всё отлично.
    Ответ написан
    Комментировать
  • Как обосновать применение реляционной БД на интервью по System Design?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Реляционные СУБД способны решать наиболее широкий круг задач, при этом менее требовательны к ресурсам, чем noSQL, что делает их решением по умолчанию, пока нет специфических проблем, требующих поиска специфических решений. Кроме того, реляционки более распространены, так что компании легче будет нанять и программистов и DBA для работы с ними.
    Ответ написан
    Комментировать