История разработки Total Reload
12 постов
12 постов
39 постов
1 пост
5 постов
Где-то тут был пост, про то, что любого человека можно завалить на собеседовании. Да, не переживайте, почти любого можно укатать, если экзаменатор "правильно" психологически подходит к этому.
Вспомнилось несколько интересных историй о собеседованиях в которых если я и не принимал участие, то как минимум стоял рядом.
История 1: IT-фирма ищет программиста
Заходит человек, которого будут собеседовать на должность то ли мидл, то ли джуниор (С++ разработчик). До этого он уже прошел какие-то ступени, но не суть. Сходу, ему задают простой вопрос: какое максимальное количество переменных можно обьявить в теле функции 😂
Ну и все на этом как бы. Что с него дальше спрашивать? 😂😂😂
История 2: та же IT-фирма ищет программиста
Снова заходит человек, должность тоже вроде джун-мидл, С++. Тестирующий - уже другой специалист.
Здрасьте-здрасьте. Вопрос: смотрите, у нас точка входа - это void main, это всем известно, но нам нужно запустить процедуру до вызова void main. Опишите процесс запуска программы и как можно бы осуществить этот вызов, вот бумажка, можете на ней писать код\рисовать.
Первые две истории - это то, что меня тогда очень удивило 😂
История 3: собеседование в Газпром (вроде на должность в гостиницу)
Человек прошел все ступени, осталось поговорить с интервьюером по видео и продемонстрировать знание английского. Вопрос, который задал интервьюер: переведите, пожалуйста, стихотворение Пушкина "У Лукоморья дуб зеленый" 😂
Человек как-то перевел 😂 После этого был только 1 вопрос : "а почему нескладно-то получилось?"
--
По вечерам разрабатываю сервис для общения. Кому интересено, можете подписаться куда-нибудь на меня, попробуете его в числе первых.
Постепенно буду продолжать делиться успехами разработки сервиса.
Привет всем!
Ранее поделился видео, где была видна скорость загрузки истории переписки. Задержка загрузки составляла примерно пол секунды. Достаточно много 😒
Также проблемные моменты в видео были видны (передерги поля ввода при открытии чата). Можете посмотреть еще раз:
На выходных поработал над этим. Было немного интересно это исправить. У меня есть понимание как можно "ускорить" подгрузку данных, но как оно будет работать на самом деле - это нужно звать блогера-Конора или провести свой эксперимент.
В первую очередь добавил возможность отображения миниатюр медиа в истории переписки:
Да, не божественно, не круто, но как заглушка эта часть готова. Наличие медиа отображается в окне чатов 😀
А вот и улучшенный интерфейс:
Убрал артефакты в поле ввода: оно меняет размер, опускает текст вниз и расширяется при открытии чата
Немного доработал анимацию кнопок в правом нижнем углу окна переписки
Научил отображать историю переписки и подгружать черновики максимально быстро
Как работает быстрая подгрузка черновиков?
В первое время я полагал, что из SQLite данные будут прилетать моментально. По этой причине перенес логику получения готовых данных из базы данных. То есть SQLite возвращает все отсортировано и как надо, мне только нужно вывести на экран.
Как результат - заметные задержки. Как ни пытался ускорить, задержки есть. Похоже просто так брать и подгружать данные из БД - это неправильный путь.
Как реализовал у себя: при открытии списка чатов происходит подгрузка историй переписки. Делается это в фоне и в то время, когда пользователь видит окно чатов. По сути, при открытии чатов происходит визуализация предзагруженных данных. Для пользователя это выглядит как моментальное открытие чата. Все довольны :)
--
По вечерам разрабатываю сервис для общения. Кому интересено, можете подписаться куда-нибудь на меня, попробуете его в числе первых.
Постепенно буду продолжать делиться успехами разработки сервиса.
Мне потребовалось приобрести шлифмашинку. В какой-то момент пришел к тому, что щеточный инструмент меня больше не устраивает по очевидным причинам: стирание щеток, шум из-за трения щеток, относительно короткий срок службы двигателя. Не на всех инструментах это острая проблема, но так как шлифую часто, то коллекторный двигатель будет доставлять проблемы. А еще у меня есть ЧПУ-станок с шпинделем 0.5 кВт... На нем коллекторный китайский шпиндель оказался расходником.
Какую шлифмашинку выбрал
Обзоры на разные машинки можете посмотреть в сети, но я остановился на DeWalt по паре причин:
- у меня уже есть их инструмент и аккумуляторы
- инструмент надежный
Интересный момент, всегда думал что DeWalt - это немецкая фирма. Оказалась американской 👀
Итого выбирать пришлось среди проводного и беспроводного инструмента их фирмы:
- Беспроводной DeWalt dcw210 - бесколекторная, аккумуляторная -~8500 руб минимальная стоимость на момент покупки + аккумулятор 20В 5Ач ~3500 руб (сообщите в коментах, если завысил цену). Итого: 12000 руб
Вы уже наверно догадались. Беспроводной вариант машинки достаточно дорогой, с бесколлекторным двигателем и с дорогим аккумулятором. Проводной вариант дешевый, но с коллекторным двигателем.
Короче, каптиалисты из DeWalt предлагают богатый выбор того как поставят тебя на деньги:
- будешь докупать запчасти для ремонта коллекторного двигателя
- будешь докупать аккумуляторы для работы бесколлекторного варианта ¯\_(ツ)_/¯
Варианта запитать аккумуляторный двигатель от сети, конечно же, отсутствует 😂
Ну и что делать? Конечно, сейчас мы все сделаем как надо:
Будем делать беспроводной инструмент сетевым!
Берем аккумулятор DeWalt (у меня их много) и разбираем его:
Думал что все просто: на машинку подается +18В и все запускается. Но разбор аккумулятора показал, что схема аккумулятора выглядит как-то так:
Аккумулятор представляет из себя последовательно соединенные 5 банок аккумуляторов. Каждая банка состоит из 2-х параллельно соединенных аккумулятора. Между красным проводом (+) и черным (-) все 20В.
Что-что? На этикетке написано 18В? А, ну написат и не такое можно. На самом деле напряжение около 20В.
Изменеие напряжения между каждой следующей параллельно подключенной банкой - 4В (см рисунок выше). Максимальный ток, который выдает аккумулятор под нагрузкой (зажатый шлифдиск) составляет 10А. Это ток, который течет по крайним контактам шлифмашинки.
На машинке всего 4 контакт. Два крайних - плюс и минус. Два средних - непонятно для чего.
Ток на средних контактах всегда 0А.
Ну что, все просто? Беру свой источник питания, задаю 20В, подаю питание на соответствующие контакты на шлифмашинке, запускаю... И машинка не включается 😂 А вы думали будет все просто? Так бы каждый подключал машинку и все бы работало 😂 А нет, кто убийца, садовник? Что происходит? Это предстоит расследовать.
Ладно, разбираем шлифмашинку и смотрим что же там внутри:
А внутри хорошая сборка, бесколлекторный двигатель, залитая эпоксидкой микросхема... Эпоксидка так и шепчет: "ну давай-давай, иди сюда, рискни отковырнуть меня".
В общем черный ящик, непонятно как оно работает. Разбор машинки не дал понимания. А, ну и противокражная метка есть прямо внутри машинки. Для нее даже специальное место имеется:
На данный момент экспериментирую, пытаюсь понять как запустить машинку. В планах приобрести блок питания с нужными параметрами и размерами, подходящими для размещения в корпусе аккумулятора:
Недешевые источники питания. Возможно соберу свой или закажу этот. Поставил задачу разработать универсальный проводной источник питания для устройств DeWalt. Нужно чтобы этот источник можно было подключить ко всем устройствам DeWalt и чтобы они работали.
Рассказал коллеге, оказалось что у него тоже есть DeWalt и нет аккумулятора. В общем попросил меня изготовить для него такое устройство 😂😂😂 Потом еще один знакомый прознал, тоже заказал 😂 Стоимость одного устройства составит 5500 руб.
Временное заключение
Для работы устройства требуется источник питания на 20В 10А.
Да, я не рассказал как запустить устройство, пока сам не разобрался. Но верю что это возможно. Показал внутренности и предоставил "схему аккумулятора". После того как закончу работу, обязательно поделюсь здесь информацией о том как оно работает, чтобы каждый мог нанести свой сокрушительный удар по капитализму, сделав беспроводной DeWalt проводным 😂 Или на худой конец можете заказать у меня (если у меня все получится).
--
По вечерам разрабатываю сервис для общения. Кому интересено, можете подписаться куда-нибудь на меня, попробуете его в числе первых.
Постепенно буду продолжать делиться успехами разработки сервиса.
Вернулся к работе над списком чатов:
Да-да, нужно работать над отправкой сообщений, но я нашел места, которые еще совсем сырые и не хотелось бы их забрасывать. Потому вернулся к работе над списком чатов.
- добавил отображение иконок отключения оповещения и звуков для чатов
- доработал механизм обновления списка чатов
- доработал систему черновиков
- доработал поле воода текста и анимации кнопок отправки сообщения, записи голосовых, вложения медиа, изменения размреа поля ввода
Черновики - это неотправленные сообщения. Они не сохраняются на сервере (только локально), отображаются в списке чатов красным цветом с иконкой карандашика.
Кнопку возврата назад разместил в левом нижнем углу (в видео видно). Обычно пишу сообщения одной рукой, да и вообще одной рукой все делаю. Когда нужно переключаться между вкладками, то это вызывает неудобство, приходится звать на помощь вторую руку так как нопка "назад" находится в верхней части экрана. Ну или можно рисковать, тянуться все той же рукой и выронить телефон.
Мои ошибки
Ошибка №1: сюрпризы платформ.
Работа идет сразу в нескольких направлениях, забегая наперед скажу, что работал над системой подгрузки изображений и медиа. Для оптимизации сетевого трафика, все файлы дико сжимаются и за это отвыечают отдельные библиотеки.
Тут я немного сел в лужу из-за неосведомленности относительно требований, которые предьявляются к мобильным платформам. Когда разрабатывал головоломку Total Reload, то очень многие части системы выносил в отдельные библиотеки. В общем-то это обычная практика, когда разработчики не копилируют весь код в один большой кусок исполняемого файла, а бьют на разные заменяемые модули:
В разных операционных системах динамические библиотеки собираются немного по-разному, но суть примерно одна: они нормально работают и их можно использовать и я их собирал для видеоигры для Windows, Linux, OSX. Претензий к ним не было.
А вот для мобильных платформ, здравствуйте, дело обстоит иначе. Поправьте если не прав. На многих форумах пишут, что из-за проблем с безопасностью (даже для IOS, где разработчик предоставляет вообще все данные чтобы исключить угрозу вредоносного кода), использование динамических библиотек нежелательно или запрещено. Тем не менее собирать их можно, что я и делал пока не обнаружил информацию о том, что из-за этого приложение может не пройти проверку. Однозначного запрета я не нашел, но вот что говорит Google:
Услуги ВПН продавать разрешено, но рекламировать - нельзя. Собственно тут, на мой взгляд, +/- лапоть ситуация, когда можно нарваться на сюрприз. Потому пришлось прилинковать все файлы статически.
Ошибка №2: UTC0 и точность времени
Видимо я был очень уверен в том, что лучше рассчитывать время на сервере относительно локального часового пояса. Не знаю как я дошел до этой дурацкой идеи, возможно головой стукнулся. Это доставило много головной боли и проблем на абсолютно ровном месте. Не делайте так 😂
Но это еще не все. В перове время не утвердил точность времени на сервер и клиенте. В итоге из-за этого начались проблемы связанные с получением последних обновлений с сервера. Этот момент был поправлен достаточно быстро.
Надо заметить, на клиенте время хранится в INTEGER а на сервере в Timestamp-формате базы данных. Нужно учесть этот важный момент, иначе сюрпризов не избежать.
Ошибка №3: context на сервере
Ну, тут все просто, сервер работает и без контекста хорошо. Зачем разбираться что это такое, сделаем сервер без него, а там посмотрим нужен он вообще или нет. Вроде все работает:
А потом прилетает куча проблем с висячими процессами, невозможностью отменить задачу и непонимание почему вообще этот контекст пытаются прикрутить чуть ли не к 99% операций на сервере. Контекст - важная штука, если сюрпризы не нужны, то лучше вникнуть 😂 Иначе все будет очень плохо.
Пожалуй это самые серьезные мои промахи. Ну, кроме криво спроектированной серверной системы рассылки сообщений (уже переделал).
Сейчас дорабатываю окно чатов. Выводится последнее сообщение или черновик. Помимо сообщений отправлять можно будет еще и файлы. Нужно бы научить визуализировать отправленные файлы. Этим займусь в ближайшее время.
--
По вечерам разрабатываю сервис для общения. Кому интересено, можете подписаться куда-нибудь на меня, попробуете его в числе первых.
Постепенно буду продолжать делиться успехами разработки.
Немного исправил шапку окна чатов:
- добавил прозрачность по градиенту в верхней и нижней областях окна чатов
- растянул список сообщений во весь экран
- кнопкам задал стандартный стиль, который разрабатываю для приложения (сейчас он выглядит неочень так как не до подбора цветов и анимаций, в основном над формами работаю)
Хорошо когда есть режим отладки, можно проинспектировать поведение виджетов:
Плохо только то, что приходится перезапускать приложение для переключения визуализации режима отладки. Смена состояния визуализации отладки задается так:
debugPaintSizeEnabled = Config.debugUI_Debug;
Flutter перестраивает виджеты быстро, на лету. Но так как мне приходится работать не только над виджетами, то иногда приходится перезапускать Flutter полностью. А это долго. Кстати, еще константы, кажется, он не умеет обновлять если поменять их значения. Приходится перезапускать приложение или менять имена переменных констант (то, что сейчас называют "лайф-хак").
Тут видно размытие и плашку с названием чата:
А тут плашка с эмодзи и профилем собеседника (персональный чат):
Еще добавил интерактивную анимашку в окно пустого чата (в качестве заглушки, потом нужно будет подобрать нужную анимацию). Анимашка скачана из сети, не моя. Пока показывать не буду. Неплохо получается, даже замечательно, вроде, не тормозит 😂.
Также вынес некоторый код темы в отдельные компоненты, унифицировал это дело.
Сейчас работаю над областью ввода и отправки сообщения. Покажу что получилось. Клиентское приложение получается собирать быстрее так как серверная логика продумана, основные механизмы сделаны. Просто сиди и собирай как конструктор, ну и редактируй потихоньку, если что-то новое добавляешь.
--
По вечерам разрабатываю сервис для общения. Кому интересено, можете подписаться куда-нибудь на меня, попробуете его в числе первых.
Постепенно буду продолжать делиться успехами разработки.
Вчера немного "причесал" профили собеседников и механизм их синхронизации/отображения. На самом деле не все продумал, но "как-то оно уже работает" и оображается в групповом чате:
Создал "шапку/header" для окна с чатами. Туда добавил информацию/статус о собеседнике или чате. Также добавил иконки-кнопки аудио и видео-звонков. Звонки пока не работают, просто метсо для иконок выделил чтобы оценить как оно смотрится, оценить функциональность этих элементов. У пользователей также имеется статус состояния в сети и иконка эмоджи. В планах добавить возможность видеть:
1) заряд аккумулятора собеседника (полезно для понимания состояния собеседника)
2) Через что пользователь вышел в интернет: Wi-Fi или мобильная сеть
У групп тоже есть аватарка и название:
Также добавлено отображение измененных/отредактированных сообщений :
Из текущих недочетов (помимо красивого внешнего вида):
- пока не оптимизировано переключение на окно переписки, из-за этого имеются задержки в начале отображения окна и элементы появляются как в старых браузерах: сперва одни элементы, потом другие. Не сразу все вместе отрисовывается.
- не добавлено поле ввода.
Над отображением и порядком загрузки элементов будем работать позже, это некритично. А вот поле ввода нужно бы сделать как можно быстрее и научить приложение обмениваться сообщениями.
Также прокинул "Fingerprint" с клиентов на сервер. Сервер их получает и сейчас технически можно начать работать над разпознаванием разных устройств. Это необходимо для синхронизации данных между устройствами, которые подключены к одному аккаунту. То есть чтобы на телефоне и планшете у пользователя, условно, история переписки была всегда синхронизирована.
Текущая ближайшая задача - организовать обмен сообщениями.
--
По вечерам разрабатываю сервис для общения. Кому интересен сервис для общения, можете подписаться куда-нибудь на меня, попробуете его в числе первых.
Постепенно буду продолжать делиться успехами разработки.
Как-то так получилось, очень много времени потратил на разбор ошибки, которая потом самоликвидировалась:
Надеюсь ликвидировалась с концами. В чем была проблема: нужно получить из локальной базы данных переписку пользователя. Эта база синхронизируется с сервером, приложение использует ее для вывода сообщений на экран.
Взять из БД и вывести все сообщения - это легко. Но мы же знаем к чему это может привести, когда сообщений тысячи. Так что просто брать и грузить все что есть в память - это тупиковый путь. Хотя... Если ты хомяк, у тебя нет конечной цели, есть только путь... то почему бы не заниматься абсолютно бесперспективной и бесцельной ерундой 😂
В итоге брал из БД сообщения и подгружал по мере необходимости. И так пока пользователь не доберется до начала переписки.
Проблемы были в момент подгрузки:
1) ListView.builder дергался
2) В момент подгрузки скрол терял каcание экрана
В итоге как-то само собой разрешилось. Нужно было всего лишь выставить reverse: true и еще какие-то мелочи специфичные сделать. Так и не понял что за "магия", но ладно.
Дело в том, что многие компоненты достаточно навороченные и под капотом много чего сами по себе делают. А еще сверху машина Flutter производит свои манипуляции. В общем, тонкостей хватает. Вот первый вариант сообщений в истории переписки:
Да-да, знаю что так себе выглядит. Внешний вид буду дорабатывать позже. Главное вынес все компоненты в разные классы, раскидал их на основе функций. Таким образом можно будет работать с каждым компонентом отдельно.
Нужны эмоджи? Пожалуйста, их тоже добавил и продумал задолго до работы над чатом 😂
Вот они:
Сообщения представляют из себя числа. Почему числа? Чтобы было проще видеть порядок и отследить ошибки.
Сдается мне я как всегда что-то не продумал и узнаю об этом в конце и это приведет к тому, что всю работу придется поставить с ног на голову. Но увидим, пока, вроде, получается.
Забыл добавить курсорную синхронизацию сообщений и эмоджи. Так что сообщения прилетели не с сервера, а пока из локальной БД (телефона) в которой их создал ручками.
Слева находится аватарка собеседника. Ее нужно подгрузить с профилем, сторис и прочим. Еще не сделал, но это следующая задача. В списке чатов эти данные подгружаются. Нужно бы и в переписку подобным образом грузить. А вообще, хорошо бы доработать сущность модели профиля пользователя, сейчас она немного аморфная.
А медиа можно передавать?
Вот медиа из БД в переписке, их тоже заранее продумал:
Да, да, сам в шоке от того как это выглядит, но и TotalReload ближе к началу выглядел так:
К концу вот так:
Так что не переживайте, все будет 😀
На ближайшее время запланирована работа над отображением профиля собеседника, синхронизация переписки и эмоджи.
Что с синхронизацией
Вообще, меня терзают смутные сомнения. Дело в том, что на форуме подсказали "просто синхронизируй". Но сдается мне что нужно "батчить". Из геймдева мне известно, что есть такие вещи как Пулинг и Батчинг. И это прям катастрофически важные механизмы, которые позволяют оптимизировать производительность. Пулинг - это, условно, умное хранение данных в ОЗУ. Устройства не любят постоянно обращаться к жесткому диску (или еще куда-то) для доступа к данным. Для этого используется пулинг.
А батчинг - это в основном про GPU (про видеокарту). Обьекты в сцене обьединяются в пачки и пачками подаются видеокарте для обработки. Видеокрты очень любят работать с "однородными" данными (пачками) и с радостью обрабатывают их всеми своими ядрами. За счет этого можно, условно, отрисовать 1000 сфер и иметь 30 ФПС. Без батчинга на той же карте можно, условно, отрисовать 50 сфер с тем же ФПС.
Разницу улавливаете, имеет смысл вникнуть в тему поглубже? Думаю ответ очевиден.
Так вот, пробегусь по вопросу насчет того как батчинг сказывается на производительности. Сдается мне что передавать данные по сети лучше пачками.
Пока на этом все. Если появятся новости, то обязательно сообщу.
--
По вечерам разрабатываю сервис для общения. Кому интересен сервис для общения, можете подписаться куда-нибудь на меня, попробуете его в числе первых.
Постепенно буду продолжать делиться успехами разработки.
После доработки серверного микросервиса по рассылке сообщений вернулся к клиентскому приложению, а если точнее - к чатам.
Как-то так получилось, после правок серверной части, клиентское приложение немного развалилась. Пришлось доработать интерфейс взаимодействия и это повлекло доработку клиента.
Приступил к работе над созданием чатов. Вообще, технически все сделано, но оказалось что клиенту нужно добавить систему черновиков. Зачем нужны черновики?
Конечно, хорошо бы закругляться и быстрее выпускать упрощенную первую версию приложения, где доступен только режим личной переписки. Групповые чаты и каналы добавим позже.
Но черновики нужны, лучше их не пропускать. Вообще, лучше ничего не пропускать, как-то уже пробовал халтурить и из этого получались катастрофы:
- не стал дотошно прорабатывать сервис по доставке сообщений - всплыли сюрпризы с идемпотентностью, а это равносильно тому, что сервис будет присылать сообщения "как попало" 😂
- не стал разбираться с context на сервере и когда-то заключил "как-нибудь потом разберусь с ним", пришлось весь сервер ревизировать 😂
- не строил логику приложения / схемы, в результате пришлось строить 😂
- не закладывал в архитектуру softDelete. Просто удалял все с диска. Решил исправить момент и пришлось неплохо так поработать чтобы удаление происходило как надо 😂
Зачем нужны черновики?
Человек начинает писать сообщение в чате, выходит из переписки не отправив сообщение. Это сообщение нужно сохранить в черновик (не зря же человек писал).
Есть еще одна ситуация: человек пишет первое личное сообщение, не отправляет его. Это сообщение сохраняется в черновик и переписка с этим черновиком появляется в общем списке чатов. Например на фото видно эту ситуацию. Начал писать человеку, стер сообщение, вышел в список чатов и в общем списке чатов появился личный чат без сообщений:
Далее нужно будет отправлять команды создания и удаления чатов, обрабатывать удаленные и созданые чаты с учетом черновиков.
Примерно одновременно с созданием и удалением чатов начну работу над экраном переписок. Вообще-то эту работу начал давно, но более плотно к ней приступлю в ближайшее время.
Что крутого в этом сервисе, почему он выстрелит, зачем ты его делаешь, на что рассчитываешь?
Эти вопросы прилетают и в личные и сюда. Ни на что не рассчитываю, ни на какое "выстрелит". В первую очередь собираю платформу как минимум для возможности общения между семьей и друзьями. Этот проект - это в какой-то степени мой "Hello World".
В отличии от конкурентов не планирую использовать дорогие сервисы по доставке сообщений, хранилища и тп. Все планирую поставить у себя и на поддержание работоспособности системы настраиваюсь тратить МИНИМУМ усилий. Частично для этого встраиваю систему защиты и балансировки нагрузки на сервер, чтобы оно работало "без меня".
Хотя, писал ранее что законы меняются, все крутится-вертится и мне придется крутить головой как танк башней, чтобы куда-нибудь не вляпаться. С этим пока не знаю что делать и как быть.
Пока на этом все, обязательно поделюсь следующей порцией успехов.
--
По вечерам разрабатываю сервис для общения. Кому интересен сервис для общения, можете подписаться куда-нибудь на меня, попробуете его в числе первых.
Постепенно буду продолжать делиться успехами разработки.