Но вопрос-то остается открытым — вы бы взяли себе такого кандидата?
Вопрос взять или нет кандидата определяет собеседование а не строчки в резюме/сопроводительном письме и если бы он (кандидат) его прошел и показал требуемый набор знаний то я бы его взял. Выше Вы пишете "Но самое интересное в конце в блоке «О себе» — готов бить лица за критику. Мы правильно поняли?" а если Вы все же неправильно поняли?
По крайней мере профессионализм по одной строчке в статье мы точно не определяем.
Простите но из Вашей статьи непонятно этот кандидат был отсеян на этапе чтения сопроводительного письма или уже после/перед прохождения собеседования? Дальше идет скриншот примера где сложно сказать в чем проблема и кто кому пишет? И самое главное непонятно в чем суть - начальник написал двум исполнителям которые что-то одно делают(или разное?) о проблеме и каждый из них написал что это не его ответственность? Это может быть как проблемой начальника и организации в целом так и проблемой исполнителей. Начальник вместо того чтобы разбираться просто матом послал первого из них разбираться, это может говорить и о том что исполнитель плохой и футболит и о том что начальник вместо того чтобы разобраться "кто виноват и что делать" просто ставит ультиматумы первому попавшемуся исполнителю. Я к тому что пример не коррелирует или слабо коррелирует с указание строчки в сопроводительном письме и определении кого то как нестабильного, нестабильность <> неисполнительность. Более того определить будет ли человек футболить или нет на работе невозможно просто читая резюме, да даже на собеседовании это вряд ли получиться определить, только когда он начнет работать это выясниться и то это может проявиться через время когда он успокоиться что не потеряет место или например если выгорит.
Я говорил о Вашем утверждении из статьи где Вы говорите что не будете менять стек. Не очень понятно причем здесь мое желание? Моя мысль в комментарии выше как бы намекает что если завтра измениться востребованность Вашего стека на рынке то с наибольшей вероятность Вам также придется переобуться на актуальную технологию просто чтобы быть востребованным на рынке.
Я уже не поменяю стек, ибо понимаю, что частые переключения стека могут привести к деградации опыта и обесценению навыков. В результате я могу оказаться менее востребованным на рынке труда, и потребуются годы, чтобы достичь того уровня, который у был до изменений.
Просиживание штанов в одном стеке наоборот приводит к "деградации" опыта и в один прекрасный момент этот самый стек может стать не актуальным что уже ударит по востребованности на рынке труда поэтому не все так однозначно.
Ну допустим мы используем голый SQL. Завтра меняется структура и что требуется сделать? Найти по поиску все места где использовались измененные таблицы и поменять заменой или руками и так каждый раз, так удобней работать?
Хорошо исключим из CRUD операцию R, выборка действительно может быть сложной. CUD у Вас как-то по особенному работает? Вы не через INSERT, UPDATE, DELETE его выполняете?
При использовании ORM мы обычно прописываем в коде сущности и их взаимосвязи, и по сути это — проектирование БД ещё раз (дублирование логики!) прямо в коде.
Очень странная логика. Вот Вы например когда хотите передать сложный JSON объект наверно создаете набор классов/структур которые его описывают, создаете его экземпляр, заполняете поля значениями а потом скармливаете сериализатору который из Вашего сложного объекта превратит в строку. Бесспорно Вы можете сформировать JSON в виде строки без использования всего этого но согласитесь что поддерживать первый вариант будет намного проще как Вам так и людям после Вас. Тоже самое и с ORM, по факту он обычный (де)сериализатор неких объектов в запрос и обратно. Вы можете использовать например odbc или драйвер базы напрямую но удобно ли это поддерживать? ORM это больше про удобство поддержки кода чем про удобство работы с базой. А если Вам не хочется ручками в базе что-то делать то как вариант можно использовать тулинг миграций например такой https://github.com/davedevelopment/phpmig
Борьба с проблемами производительности никуда не денется всё равно, как ни абстрагируй. Ты просто не можешь не знать, что у тебя под капотом происходит. Какие там делаются джойны и группировки.
Странно но это относиться к абсолютно любой вещи в разработке, просто замените заголовок на любой другой. Обычно ORM позволяет использовать сырые запросы на манер odbc, да даже просто никто не мешает использовать odbc в местах где требуется работать с сырыми запросами. Т.е. вполне можно комбинировать для простых CRUD-ов использовать ORM для всего остального сырые запросы. Если сырые запросы сложные то да библиотеки для генерации sql помогают.
Есть ещё такое мнение, что ORM — это слой, абстрагирующий от способа хранения. Мол, сегодня ты пишешь на MySQL, завтра на Postgres, после завтра вообще в файлах хранишь — и тебе пофиг, код остаётся тем же. Чистая архитектура.
Это слой абстрагирующий от использования драйвера базы данных или odbc напрямую. И да он полностью решает эту задачу. Способность перехода с базы на базу зависит не от ORM а от Вашего проекта и его потребностей, например использовали Вы gis модуль в бд а потом попытались перейти на другую бд в которой этого модуля нет или он работает как-то не так.
А почему он ищет записи там, если изначально знает что репорт может быть в разных таймзонах? ну то есть камон время на экране != время на сервере/в базе/логах/журналах.
Тут разница не в том где он ищет а в том что время которое он видит у себя на экране (в своей таймзоне) не равно времени которое на самом деле записано в базе (в UTC). И когда он хочет поискать по времени, например колонка с датой < конкретная дате и время, ему надо из времени которое он видит у себя на экране в уме перевести в UTC либо явно указать перевод в UTC используя сессию или прописать в запросе иначе он либо не найдет того что ищет либо найдет что-то другое.
Интересное исследование и интересные выводы но спешу Вас отговорить от поспешных переделок всех полей c timestamp на timestampz. Тип timestampz предназначен для случаев когда Вам надо видеть (именно видеть!) дату+время в какой-то часовой зоне (обычно своей но это не важно). И это как раз узкий кейс в то время как тип timestamp предназначен для всех остальных случаев когда нам нужна просто гипотетическая дата+время. Если Вам требуется точная система которая обеспечивает гарантии на что бы то ни было связанное с временными зонами то ни timestamp ни timestampz Вам это не обеспечат. По Вашей логике клиент не несет ответственности за ту таймзону которую он настроил в сессии, но это не корректное утверждение. Каждый клиент ответственен за то какую таймзону он настроил. Условный дядя не устанавливает же время на Ваших часах, да Вы можете подключить службу по синхронизации времени но опять же это будет Ваше осознанное решение. К тому же замена типов порождает уже другую проблему, как я и сказал выше тип timestampz предназначен чтобы видеть дату+время в каком-то конкретном часовом поясе. Дак вот предположим ситуацию: есть 5 сотрудников работающих с базой каждый работает в своей часовой зоне (или как мы выяснили из статьи даже просто в разных клиентах). Один из них тестер который нашел багу в двух полях с датами в мобильном приложении и снял скриншот в зоне -5 с ошибкой и зарепортил баг. Разработчик в зоне +5 получив баг решил воспроизвести проблему у себя и попытался найти записи с датами как на скриншоте но он их не нашел а чтобы найти их ему надо было бы выполнить пересчет дат из -5 в utc и написать field = utc_date но результат запроса он увидит в +5. Т.е. все операции такие как больше, меньше равно и т.п выполняются не по той дате которую ты видишь а по utc что требует от пользователя выполнения операций в уме. Я уж не говорю сколько будет матов сложены администратором который в зоне -10 когда ему потребуется выбрать всех пользователей которые что-то когда то сделали и выгрузить в отчет. Другая проблема приведение к какому-то часовому поясу может давать другую дату что может еще больше повысить когнитивный диссонанс. Что подводит нас к одной простой мысли, установка таймзоны это обязанность клиента а если это так то Ваш главный аргумент в пользу незамедлительного уничтожения полей с типом timestamp уже не выглядит таким уж весомым.
"Нет. GeForce now — скорее да, и то с некоторой натяжкой. MMORPG всё-таки позволяют кнопки в меню нажимать локальным кодом, а не вызовом сервера. "
Т.е. Backend-Driven UI это когда клиент просто "удаленный рабочий столприложение" который картинку приезжающую с сервера показывает? С клиента только точки где мышка проезжает отсылаются и какие кнопки на ней (мышке) нажимаются? Я все верно понял?
То есть вместо получения машиночитаемых результатов поиска, мы получаем с сервера их готовое представление в виде кода на HTML
Это очень хорошая идея но ровно до того момента когда появится интерактивность внутри этого представления.
В этом примере подразумевается, что SearchBox не содержит вообще никакой другой логики, кроме отсылки на сервер событий, с ним произошедших (действий пользователя или разработчика) и показа присланного с сервера контента.
Решив проблему с универсальным UI на каждых чих приезжающий с сервера возникнет совсем другой класс проблем. Сетевых проблем, результатом которых будет либо недогруженный UI или несоответствие версий UI, измененные пути ведущие в 404 и т.п.
Тем не менее, мы не можем не отметить: при том, что любая крупная IT-компания проходит через эту фазу — разработки Backend-Driven UI (они же — «тонкие клиенты») для своих приложений или своих публичных SDK — мы не знаем ни одного заметного на рынке продукта, разработанного в этой парадигме (кроме, разве что, протоколов удалённых терминалов)
Тут очень важно понимать что такое "тонкий клиент" по Вашему а то таких технологий может оказаться очень много, например бутстрапер любой MMORPG это тонкий клиент или нет? А если мы говорим о вебе то нет ни одного заметного продукта потому что фаза эта закончилась провалом для таких технологий как Flash, Silverlight, Java Applet и других. Вместо этого усилия сообщества были направлены на то чтобы все что было в этих технологиях появилось и в web браузере и не надо было кучу тонких клиентов ставить заходя на рандомный сайт. Сейчас никто этим не занят потому что в этом просто нет никакого смысла. Уже даже десктопные приложения делают на технологиях вроде Electron которые по сути web браузер с щепоткой клиентского кода.
разработать серверный код управления UI ничуть не проще, нежели клиентский;
Возможно Вы имели ввиду "разрабатывать клиентское приложение работающее не на клиенте а по факту работающее на сервере сложнее"?
следует различать Backend-Driven UI и технологию серверного рендеринга (SSR). Второе подразумевает, что одно и то же состояние UI (как правило, в виде HTML-разметки или аналогичного декларативного описания) может быть сгенерировано как сервером, так и клиентом. В SSR, однако, подразумевается, что клиент может интерпретировать ответ сервера и извлекать из него семантические данные.
И чем плох вариант с генерация клиентом?
Когда соединение с сервером нестабильно или теряется Во что превратится UI? Одно дело UI "на клиенте" он просто покажет крутилку или что-то в таком духе но сам по себе продолжит быть отзывчивым, весь оффлайн функционал продолжит работу. Но в случае с Backend-Driven UI не получиться поставить даже крутилку потому что связь просто пропадет. Сетевые проблемы также могут сильно подпортить UX пользователю он будет либо часто видеть крутилку, либо нажимать на кнопки и другие интерактивные элементы а интеракции не будут происходить.
Можно но это сильно зависит от того сколько событий Вы собрались отправлять и их размер. Трафик от всех вкладок может быть большим и тогда один вебсокет будет не самой хорошей идеей особенно если его сеансы влияют на интерактивность UI. Т.е. я нажал на кнопку и ничего не произошло либо включилась крутилка и зависла.
Я имел ввиду когда два приложения могут делиться какими-то знаниями уникальными для друг друга. Т.е. есть два приложения - приложение с заказом карт и приложение с подарками. Допустим при заказе карты я получаю подарок и бизнес кейс что я перехожу с одного приложения на другое но при этом они вполне могут обменяться данными. Приложение подарков может получить информацию о карте (название например) и отобразить название карты и еще что-то плюс подарок. Простите если пример странный, пытался придумать что-то по Вашему профилю.
Шина да самый верный вариант, моя мысль была в том чтобы не изобретать велосипед беря какую-то библиотеку для шины а использовать DOM events в котором нет всех проблем которые я выше описал.
Если каждое приложение будет устанавливать веб-сокет то сервер очень легко может прилечь а если открыть пару тройку вкладок одного и того же сайта где такое решение реализовано то проблема увеличиться как n*k где n это количество вкладок а k это количество приложений внутри каждой вкладки.
"Более общим решением будет связать микрофронтенды через хост-приложение, например создав сервис, где мы опишем, какие МФ есть в приложении, и их API. Так сами микрофронтенды не будут знать о существовании друг друга, но хост-приложение должно уметь обрабатывать их запросы." мне кажется или это противоречит идее микрофронтендов? У Вас получается god-object "хост-приложение" которое обо всех все знает хотя по факту должно быть наоборот. "Хост-приложение" в теории вообще не должно ничего знать а просто загружать требуемые модули.
"В микрофронтенде мы используем метод отправки события и саму шину берем из хост-приложения через синглтон InjectionToken" начнем с того что браузер уже из коробки имеет реализацию событийно-ориентированного подхода. Также шина добавляет целый кластер новых проблем. Как понять что произошла ошибка в action-е и вообще он выполнился? Если не выполнился стоит ли попробовать повторить? Что если ошибка произошла в самой шине? Что если нужно не просто кейс по типу "кликнули на что-то и надо что-то выполнить" а сложнее по типу "дай мне информацию о то то о чем знаешь только ты"? Что если надо выполнять по цепочке несколько вызовов?
"Связанность в некотором смысле является платой за связность" - может быть все же поискать более разные слова для определения этих терминов потому что очень сильно сливаются в тексте.
Вопрос взять или нет кандидата определяет собеседование а не строчки в резюме/сопроводительном письме и если бы он (кандидат) его прошел и показал требуемый набор знаний то я бы его взял. Выше Вы пишете "Но самое интересное в конце в блоке «О себе» — готов бить лица за критику. Мы правильно поняли?" а если Вы все же неправильно поняли?
Простите но из Вашей статьи непонятно этот кандидат был отсеян на этапе чтения сопроводительного письма или уже после/перед прохождения собеседования? Дальше идет скриншот примера где сложно сказать в чем проблема и кто кому пишет? И самое главное непонятно в чем суть - начальник написал двум исполнителям которые что-то одно делают(или разное?) о проблеме и каждый из них написал что это не его ответственность? Это может быть как проблемой начальника и организации в целом так и проблемой исполнителей. Начальник вместо того чтобы разбираться просто матом послал первого из них разбираться, это может говорить и о том что исполнитель плохой и футболит и о том что начальник вместо того чтобы разобраться "кто виноват и что делать" просто ставит ультиматумы первому попавшемуся исполнителю. Я к тому что пример не коррелирует или слабо коррелирует с указание строчки в сопроводительном письме и определении кого то как нестабильного, нестабильность <> неисполнительность. Более того определить будет ли человек футболить или нет на работе невозможно просто читая резюме, да даже на собеседовании это вряд ли получиться определить, только когда он начнет работать это выясниться и то это может проявиться через время когда он успокоиться что не потеряет место или например если выгорит.
Определение что человек нестабильный по одной строчке в резюме это признак профессионализма. Какие еще заболевания можно определить таким образом?
Я говорил о Вашем утверждении из статьи где Вы говорите что не будете менять стек. Не очень понятно причем здесь мое желание? Моя мысль в комментарии выше как бы намекает что если завтра измениться востребованность Вашего стека на рынке то с наибольшей вероятность Вам также придется переобуться на актуальную технологию просто чтобы быть востребованным на рынке.
Просиживание штанов в одном стеке наоборот приводит к "деградации" опыта и в один прекрасный момент этот самый стек может стать не актуальным что уже ударит по востребованности на рынке труда поэтому не все так однозначно.
Ну допустим мы используем голый SQL. Завтра меняется структура и что требуется сделать? Найти по поиску все места где использовались измененные таблицы и поменять заменой или руками и так каждый раз, так удобней работать?
Хорошо исключим из CRUD операцию R, выборка действительно может быть сложной. CUD у Вас как-то по особенному работает? Вы не через INSERT, UPDATE, DELETE его выполняете?
Просветите нас какой же способ не "панихида продуктивности"?
Очень странная логика. Вот Вы например когда хотите передать сложный JSON объект наверно создаете набор классов/структур которые его описывают, создаете его экземпляр, заполняете поля значениями а потом скармливаете сериализатору который из Вашего сложного объекта превратит в строку. Бесспорно Вы можете сформировать JSON в виде строки без использования всего этого но согласитесь что поддерживать первый вариант будет намного проще как Вам так и людям после Вас. Тоже самое и с ORM, по факту он обычный (де)сериализатор неких объектов в запрос и обратно. Вы можете использовать например odbc или драйвер базы напрямую но удобно ли это поддерживать? ORM это больше про удобство поддержки кода чем про удобство работы с базой. А если Вам не хочется ручками в базе что-то делать то как вариант можно использовать тулинг миграций например такой https://github.com/davedevelopment/phpmig
Странно но это относиться к абсолютно любой вещи в разработке, просто замените заголовок на любой другой. Обычно ORM позволяет использовать сырые запросы на манер odbc, да даже просто никто не мешает использовать odbc в местах где требуется работать с сырыми запросами. Т.е. вполне можно комбинировать для простых CRUD-ов использовать ORM для всего остального сырые запросы. Если сырые запросы сложные то да библиотеки для генерации sql помогают.
Это слой абстрагирующий от использования драйвера базы данных или odbc напрямую. И да он полностью решает эту задачу. Способность перехода с базы на базу зависит не от ORM а от Вашего проекта и его потребностей, например использовали Вы gis модуль в бд а потом попытались перейти на другую бд в которой этого модуля нет или он работает как-то не так.
Тут разница не в том где он ищет а в том что время которое он видит у себя на экране (в своей таймзоне) не равно времени которое на самом деле записано в базе (в UTC). И когда он хочет поискать по времени, например колонка с датой < конкретная дате и время, ему надо из времени которое он видит у себя на экране в уме перевести в UTC либо явно указать перевод в UTC используя сессию или прописать в запросе иначе он либо не найдет того что ищет либо найдет что-то другое.
Интересное исследование и интересные выводы но спешу Вас отговорить от поспешных переделок всех полей c timestamp на timestampz.
Тип timestampz предназначен для случаев когда Вам надо видеть (именно видеть!) дату+время в какой-то часовой зоне (обычно своей но это не важно).
И это как раз узкий кейс в то время как тип timestamp предназначен для всех остальных случаев когда нам нужна просто гипотетическая дата+время. Если Вам требуется точная система которая обеспечивает гарантии на что бы то ни было связанное с временными зонами то ни timestamp ни timestampz Вам это не обеспечат. По Вашей логике клиент не несет ответственности за ту таймзону которую он настроил в сессии, но это не корректное утверждение. Каждый клиент ответственен за то какую таймзону он настроил. Условный дядя не устанавливает же время на Ваших часах, да Вы можете подключить службу по синхронизации времени но опять же это будет Ваше осознанное решение. К тому же замена типов порождает уже другую проблему, как я и сказал выше тип timestampz предназначен чтобы видеть дату+время в каком-то конкретном часовом поясе. Дак вот предположим ситуацию: есть 5 сотрудников работающих с базой каждый работает в своей часовой зоне (или как мы выяснили из статьи даже просто в разных клиентах). Один из них тестер который нашел багу в двух полях с датами в мобильном приложении и снял скриншот в зоне -5 с ошибкой и зарепортил баг. Разработчик в зоне +5 получив баг решил воспроизвести проблему у себя и попытался найти записи с датами как на скриншоте но он их не нашел а чтобы найти их ему надо было бы выполнить пересчет дат из -5 в utc и написать field = utc_date но результат запроса он увидит в +5. Т.е. все операции такие как больше, меньше равно и т.п выполняются не по той дате которую ты видишь а по utc что требует от пользователя выполнения операций в уме. Я уж не говорю сколько будет матов сложены администратором который в зоне -10 когда ему потребуется выбрать всех пользователей которые что-то когда то сделали и выгрузить в отчет. Другая проблема приведение к какому-то часовому поясу может давать другую дату что может еще больше повысить когнитивный диссонанс. Что подводит нас к одной простой мысли, установка таймзоны это обязанность клиента а если это так то Ваш главный аргумент в пользу незамедлительного уничтожения полей с типом timestamp уже не выглядит таким уж весомым.
Спасибо за разъяснение. Я думаю за пределами Web такое проворачивать без изобретения своего HTML аналога крайне затруднительно.
Объясните пожалуйста отличие "представления для рендеринга" от "семантических данных" пожалуйста.
"Нет. GeForce now — скорее да, и то с некоторой натяжкой. MMORPG всё-таки позволяют кнопки в меню нажимать локальным кодом, а не вызовом сервера. "
Т.е. Backend-Driven UI это когда клиент просто "удаленный рабочий
столприложение" который картинку приезжающую с сервера показывает? С клиента только точки где мышка проезжает отсылаются и какие кнопки на ней (мышке) нажимаются? Я все верно понял?Это очень хорошая идея но ровно до того момента когда появится интерактивность внутри этого представления.
Решив проблему с универсальным UI на каждых чих приезжающий с сервера возникнет совсем другой класс проблем. Сетевых проблем, результатом которых будет либо недогруженный UI или несоответствие версий UI, измененные пути ведущие в 404 и т.п.
Тут очень важно понимать что такое "тонкий клиент" по Вашему а то таких технологий может оказаться очень много, например бутстрапер любой MMORPG это тонкий клиент или нет?
А если мы говорим о вебе то нет ни одного заметного продукта потому что фаза эта закончилась провалом для таких технологий как Flash, Silverlight, Java Applet и других.
Вместо этого усилия сообщества были направлены на то чтобы все что было в этих технологиях появилось и в web браузере и не надо было кучу тонких клиентов ставить заходя на рандомный сайт. Сейчас никто этим не занят потому что в этом просто нет никакого смысла. Уже даже десктопные приложения делают на технологиях вроде Electron которые по сути web браузер с щепоткой клиентского кода.
Возможно Вы имели ввиду "разрабатывать клиентское приложение работающее не на клиенте а по факту работающее на сервере сложнее"?
И чем плох вариант с генерация клиентом?
Когда соединение с сервером нестабильно или теряется Во что превратится UI? Одно дело UI "на клиенте" он просто покажет крутилку или что-то в таком духе но сам по себе продолжит быть отзывчивым, весь оффлайн функционал продолжит работу. Но в случае с Backend-Driven UI не получиться поставить даже крутилку потому что связь просто пропадет. Сетевые проблемы также могут сильно подпортить UX пользователю он будет либо часто видеть крутилку, либо нажимать на кнопки и другие интерактивные элементы а интеракции не будут происходить.
Можно но это сильно зависит от того сколько событий Вы собрались отправлять и их размер. Трафик от всех вкладок может быть большим и тогда один вебсокет будет не самой хорошей идеей особенно если его сеансы влияют на интерактивность UI. Т.е. я нажал на кнопку и ничего не произошло либо включилась крутилка и зависла.
Я имел ввиду когда два приложения могут делиться какими-то знаниями уникальными для друг друга. Т.е. есть два приложения - приложение с заказом карт и приложение с подарками. Допустим при заказе карты я получаю подарок и бизнес кейс что я перехожу с одного приложения на другое но при этом они вполне могут обменяться данными. Приложение подарков может получить информацию о карте (название например) и отобразить название карты и еще что-то плюс подарок. Простите если пример странный, пытался придумать что-то по Вашему профилю.
Шина да самый верный вариант, моя мысль была в том чтобы не изобретать велосипед беря какую-то библиотеку для шины а использовать DOM events в котором нет всех проблем которые я выше описал.
Если каждое приложение будет устанавливать веб-сокет то сервер очень легко может прилечь а если открыть пару тройку вкладок одного и того же сайта где такое решение реализовано то проблема увеличиться как n*k где n это количество вкладок а k это количество приложений внутри каждой вкладки.
"Более общим решением будет связать микрофронтенды через хост-приложение, например создав сервис, где мы опишем, какие МФ есть в приложении, и их API. Так сами микрофронтенды не будут знать о существовании друг друга, но хост-приложение должно уметь обрабатывать их запросы." мне кажется или это противоречит идее микрофронтендов? У Вас получается god-object "хост-приложение" которое обо всех все знает хотя по факту должно быть наоборот. "Хост-приложение" в теории вообще не должно ничего знать а просто загружать требуемые модули.
"В микрофронтенде мы используем метод отправки события и саму шину берем из хост-приложения через синглтон InjectionToken" начнем с того что браузер уже из коробки имеет реализацию событийно-ориентированного подхода. Также шина добавляет целый кластер новых проблем. Как понять что произошла ошибка в action-е и вообще он выполнился? Если не выполнился стоит ли попробовать повторить? Что если ошибка произошла в самой шине? Что если нужно не просто кейс по типу "кликнули на что-то и надо что-то выполнить" а сложнее по типу "дай мне информацию о то то о чем знаешь только ты"? Что если надо выполнять по цепочке несколько вызовов?
"Связанность в некотором смысле является платой за связность" - может быть все же поискать более разные слова для определения этих терминов потому что очень сильно сливаются в тексте.