за сколько лет работы ни разу не приходилось объясняться терминами SOLID с непрогоаммистами. зачем вы вообще кому-то не коллеге рассказываете что-то подобное?
Начальство разное бывает.
а можете показать проект, который не использует эти принципы, поддерживается и развивается достаточно долго вменяемым количеством разработчиков, при этом каждое изменение это не переписать 70% кода.
Да половина FOSS мира такая. GCC. Linux (как минимум ядро). FreeBSD, NetBSD, OpenBSD (полный комплект). Причём я не говорю о специфически ассемблерных компонентах или тому подобном - а исключительно о центральной логике. Или вот загляните в .NET runtime. Код gc это полтора мегабайта плетёной логики только в одном центральном файле. И работает же, неплохо работает. У меня есть примеры и пожёстче, но я отложу их для подходящего случая.
На самом деле и в них полно случаев принципов из SOLID. Single responsibility - контролирует, чтобы не было посторонней функциональности там, где она не нужна и мешает гибкости. Liskov substitution principle - например, работа с файлами в ядре через вызов функций в softc-структурах - полный аналог полиморфизма на виртуальных функциях с выполнением контракта для каждого вызова (грубо говоря, read() не выполняет запись). Аналогично для VFS и массы других уровней. Open/close выражается в требованиях стабильности API ядра и системных библиотек. И так далее. Но главное то, что они не циклятся на этих принципах! Где они нужны - они соблюдаются. Где нет - их игнорируют. Если они мешают эффективности - принципы идут нафиг. Базовые требования там совсем другие.
Обратите внимание на исходный комментарий - [q]если надо исполнять код напрямую из флеш памяти[/q]. Это однозначно означает, что в RAM будет readonly-копия содержимого flash ROM. При пропадании питания это значит, что потребуется ещё раз сделать такую же подготовку на следующем старте. Вроде очевидно? В чём ваш вопрос?
SOLID, точнее, идеология Дяди Боба - это практически, промышленный стандарт организации кода.
Удивительно, что в 2024 ещё находятся люди, которые этому верят, несмотря на всю практику и множество обоснованных (в отличие от) критических статей; несмотря на то, что Clean Code противоречит сама себе и предлагает ужасный код; несмотря на то, что есть множество более внятно формулированных и потому более реальных методик... которые ещё и работают.
SOLID же в основе неконкретен настолько, насколько это вообще может быть. 'S' просто непонятно в отрыве от любой реальности, и становится понятным только через конкретные требования вроде Information Expert из GRASP (более внятный набор принципов) и реалии конкретного требования к гибкости и тестировании - но "дядя Боб" об этом не скажет, напустив туману. 'O' вообще не имеет отношения к проектированию, оно про жизненный цикл с развитием. 'L' про стабильность интерфейсов (в самом широком смысле) и контрактов. Остальные два имеют смысл только в одной конкретной объектной модели и теряются при выходе за её пределы.
На самом деле смысл этого симулякра совсем другой: это выдача - для внешнего потребителя, которыми являются непрограммирующие менеджеры и прочее начальство - hard skills за soft skills. Используя стандартизованные термины из SOLID или паттернов GoF, программист может объяснять начальству проблемы на стандартизованном языке, который, благодаря шуму, оно уже знает и предполагает его услышать. Но это же загоняет программиста в прокрустово ложе разработки именно в этих понятиях - которое работает, в основном, в домене "внутреннего софта" по Спольски, где и сконцентрировано основное начальственное невежество. Так что в целом оно скорее позитивно. Но - именно для программистов я бы желал, чтобы они понимали, насколько всё это чистейший симулякр.
давно есть аппаратные контроллеры, на лету читающие SPI flash / NAND / eMMC
Но это будет медленно. Ещё начиная с 80-х использовался метод shadow RAM - один раз содержимое ROM вычитывается в оперативку, переключается отображение, и дальше работает из RAM. Сейчас ценность этого метода только повысилась - процессор может использовать нормальные скорости, а не ждать тысячи тактов на каждый байт.
Они накрутили с пул-реквестами, на каждый из которых создаётся скрытая ветка, или что-то такое.
И что? Ну пусть невыдаленный пулл-реквест хранит ветку. Там только изменения для этого PR и он виден в списке.
Gerrit вон вообще хранит каждую версию каждого коммита на ревью (хотя можно грубой силой зачистить старые).
В результате эффективный GC там сделать толком не получается.
Это всё не помешает. Список существующих голов плюс инкрементальная сборка, которая медленно в фоне хрустит по объектам. Специфика Git меняет только способ доступа к объектам (хэши вместо указателей в памяти), но не остальное, и все методы, наработанные десятилетиями для объектов в памяти в языках с AutoMM (LISP, Java, C#, JavaScript, Lua, тысячи их) - будут работать без принципиальных изменений. (Хм, разве что систему поколений придётся убрать... и то не уверен.)
С проектами типа https://github.com/presslabs/gitfs - может и 1% "репозитория" не влезть.
А ведь есть те, кто реально это начал использовать. Ограничения на размер приватного репозитория до сих пор нет, насколько мне известно - только на количество пользователей.
Вы продолжаете в упор не понимать то, о чём я говорю, хотя я сказал это открытым текстом.
Да, может быть, что внутри github один репозиторий на всех. Может, там что-то вроде, например, 2^16 репозиториев, хэшированных по микросекунде создания первого оригинала, и клоны включаются к оригиналам. Это всё неважно. Важно то, что это хранилище должно периодически чиститься, иначе в нём будет накапливаться то, что никто никогда использовать не будет - убитые репозитории, целые удалённые юзеры, выброшенные ветки, выброшенные ошибочные коммиты (включая те, где случайно вкоммитили пару десятков гигов промежуточных файлов), и прочая и прочая.
Я не верю, что там вообще нет очистки. Иначе бы оно давно разрослось до объёмов, которые не выдержит ни одно хранилище в мире. Я думаю, что очистка есть. Когда, как она проводится - их внутреннее дело. Может, они раз в год чистят, или когда вырастет от предыдущего в два раза. Для GC существуют много алгоритмов и критериев. Но хоть когда-то это должно делаться.
Прежде чем продолжать дискуссию, прошу вас оценить самому необходимость чисток, её периодичность и типовые подходы. Можете начать с реализации команд prune, gc, repack в каноническом клиенте git. Только после этого будет смысл продолжать обсуждение.
Не только. reflog как пример. Головы удалённых веток и всё, на что они ссылаются, хранятся до ближайшей большой сборки. Я не верю, что на github нет периодического запуска аналога `git gc`.
Он не имеет к проблеме никакого отношения, здесь доступ к коммитам выполняется по хешам коммитов
Для того, чтобы коммиты были в репозитории, нужно, чтобы они остались доступны. И вот почему они доступны, когда на них ничего не ссылается уже долгое время - сомнительно. Даже ответ с самого github тут может быть некорректным.
По-нормальному таки надо сделать тест с проверкой после большой паузы.
Вопрос - сколько времени удалённые данные будут доступны? Я про "вечно" не совсем верю. Больше похоже на умолчание Git - 90 дней. Тогда это даже разумно.
Есть ли средства рефакторить форматирование между этими стилями? Чтобы само умело переделывать по запросу, например, `"%s %r" % (x, y)` в `"{} {!r}".format(x, y)` и далее в `f"{x} {y!r}"`, или наоборот. И какие их достоинства и недостатки. Без этого рассказ неполон.
Так оно тоже достаточно часто отвечает. Но если "думает", что знает ответ, то начинает писать абстрактное кэпство.
Подозреваю, что какой-то следующий круг усилий по совершенствованию этих моделей будет направлен как раз на улучшение качества самопонимания... и это как раз то, что приблизит реально к человеческому уровню (ну, имеющего образование в данной области).
Если в интернете нет описания чего-то, то шанс на генерацию полезного ответа - минимален. Собственно, по этому часто и видно, что данных нет, или надо менять формулировку.
Итого, все ваши высказывания про гуманитариев противоречат общеизвестным фактам. Это лично вы не способны на физику, а не гуманитарии.
А может, это физик оказался способен ещё и картины рисовать, а не наоборот? ;)
По-моему, ваш оппонент говорил о статистической закономерности - а один пример одного великого художника её не опровергает, подчёркивая, наоборот, её наличие.
Я бы сказал, основная проблема в том, что любая IT технология в период бурного развития даёт 99% шума-хайпа и только 1% того, что станет полезным. Это касается не только IT, а значительной части прогресса в целом, но в IT за счёт общих темпов это выражено значительно острее. Автор вспоминает ML/DS, но ML/DS десять лет назад были примерно таким же по шуму, а до этого были другие, включая компьютеры в целом.
Так что ещё 10 лет и мы сможем понять, что же реально выжило и стало полезным, а рядом будет что-то ещё хайповать.
Если бы автор не матерился, я бы подумал, что это James Mickens. Но хорошо, что остались ещё авторы хороших сатирических проездов. Они пользительны и прельстивы.
ни на одном языке вообще нельзя сравнивать дробные числа на равенство!
Можно и нужно - но, понимая, что именно делаешь и почему. И имея в виду возможные проблемы от реализации. А вот если не понимать... вот тут целое собачье кладбище зарыто.
В обсуждаемом случае сравнение int и float - это не сравнение двух float. Это отдельный вариант (хоть внутри и получается конверсия к float (double), но она замаскирована видом констант). И последствия от него примерно такие же, как в JS ситуация типа "ваш номер карточки 4.1492103e+15". Это больше проблема типизации, чем собственно сравнение floatʼов.
Сравнение floatʼов на равенство вредно тогда, когда мы говорим о результатах вычислений с заведомо приближёнными значениями (типично для прикладной математики всех видов выше, чем 4 арифметические операции). Вот там появляется правило про корректный выбор относительной погрешности (каковой выбор ещё надо осилить, не всегда сразу получается адекватная погрешность).
А вот если значения по каким-то причинам точные (или гарантированно точные, или результат однозначно определённых операций типа i*0.01), тогда и точное сравнение возможно. Также есть случаи сравнения с нулём, как признак полной потери значения (даже не денормализованные). Но очень часто само по себе такое сравнение подсказывает, что выбрана неверная модель представления числа.
В финансовых расчётах точное сравнение возможно и нужно. Но тут вопрос, с какого момента может начаться недопустимое округление. Всякие Decimal из С# маскируют проблему до предела, давая аж до 28 знаков точности... обычно хватает. Но с фиксированной точкой таки честнее (и проблема, если что, выскочит явно).
Но попросту, конечно, можно сказать "нельзя!" и это будет как деление на ноль ;)
База данных является краеугольным камнем любого проекта.
Посмотрел на несколько последних проектов, в которых участвовал.
SIP софтсвич. Общается с чем-то, представляющим себя как биллинг, по кастомному протоколу (RADIUS с вендорскими расширениями). Ну база тоже есть, но очень вспомогательная.
Компонент радиосоты, управление локальной конфигурацией, которая задаёт направление потоков данных через кастомизированное железо. О "базе данных" можно говорить только в плане состояния этой конфигурации в памяти между ребутами. Есть, конечно, центральная база (на всяких etcd), но это конфигурация, которую в основном правят руками.
Можно продолжать...
Я не против статьи в целом, но слишком много упрощений. И почему мне кажется, что вся статья была написана ради одного слова "Swagger"? И чем же он так хорош, что использовать его, а не 100500 аналогов? "Тема <xxx> не раскрыта" (c).
Начальство разное бывает.
Да половина FOSS мира такая. GCC. Linux (как минимум ядро). FreeBSD, NetBSD, OpenBSD (полный комплект). Причём я не говорю о специфически ассемблерных компонентах или тому подобном - а исключительно о центральной логике. Или вот загляните в .NET runtime. Код gc это полтора мегабайта плетёной логики только в одном центральном файле. И работает же, неплохо работает. У меня есть примеры и пожёстче, но я отложу их для подходящего случая.
На самом деле и в них полно случаев принципов из SOLID. Single responsibility - контролирует, чтобы не было посторонней функциональности там, где она не нужна и мешает гибкости. Liskov substitution principle - например, работа с файлами в ядре через вызов функций в softc-структурах - полный аналог полиморфизма на виртуальных функциях с выполнением контракта для каждого вызова (грубо говоря, read() не выполняет запись). Аналогично для VFS и массы других уровней. Open/close выражается в требованиях стабильности API ядра и системных библиотек. И так далее. Но главное то, что они не циклятся на этих принципах! Где они нужны - они соблюдаются. Где нет - их игнорируют. Если они мешают эффективности - принципы идут нафиг. Базовые требования там совсем другие.
С какими именно данными?
Обратите внимание на исходный комментарий - [q]если надо исполнять код напрямую из флеш памяти[/q]. Это однозначно означает, что в RAM будет readonly-копия содержимого flash ROM. При пропадании питания это значит, что потребуется ещё раз сделать такую же подготовку на следующем старте. Вроде очевидно? В чём ваш вопрос?
Удивительно, что в 2024 ещё находятся люди, которые этому верят, несмотря на всю практику и множество обоснованных (в отличие от) критических статей; несмотря на то, что Clean Code противоречит сама себе и предлагает ужасный код; несмотря на то, что есть множество более внятно формулированных и потому более реальных методик... которые ещё и работают.
SOLID же в основе неконкретен настолько, насколько это вообще может быть. 'S' просто непонятно в отрыве от любой реальности, и становится понятным только через конкретные требования вроде Information Expert из GRASP (более внятный набор принципов) и реалии конкретного требования к гибкости и тестировании - но "дядя Боб" об этом не скажет, напустив туману. 'O' вообще не имеет отношения к проектированию, оно про жизненный цикл с развитием. 'L' про стабильность интерфейсов (в самом широком смысле) и контрактов. Остальные два имеют смысл только в одной конкретной объектной модели и теряются при выходе за её пределы.
На самом деле смысл этого симулякра совсем другой: это выдача - для внешнего потребителя, которыми являются непрограммирующие менеджеры и прочее начальство - hard skills за soft skills. Используя стандартизованные термины из SOLID или паттернов GoF, программист может объяснять начальству проблемы на стандартизованном языке, который, благодаря шуму, оно уже знает и предполагает его услышать. Но это же загоняет программиста в прокрустово ложе разработки именно в этих понятиях - которое работает, в основном, в домене "внутреннего софта" по Спольски, где и сконцентрировано основное начальственное невежество. Так что в целом оно скорее позитивно. Но - именно для программистов я бы желал, чтобы они понимали, насколько всё это чистейший симулякр.
Но это будет медленно. Ещё начиная с 80-х использовался метод shadow RAM - один раз содержимое ROM вычитывается в оперативку, переключается отображение, и дальше работает из RAM. Сейчас ценность этого метода только повысилась - процессор может использовать нормальные скорости, а не ждать тысячи тактов на каждый байт.
И что? Ну пусть невыдаленный пулл-реквест хранит ветку. Там только изменения для этого PR и он виден в списке.
Gerrit вон вообще хранит каждую версию каждого коммита на ревью (хотя можно грубой силой зачистить старые).
Это всё не помешает. Список существующих голов плюс инкрементальная сборка, которая медленно в фоне хрустит по объектам. Специфика Git меняет только способ доступа к объектам (хэши вместо указателей в памяти), но не остальное, и все методы, наработанные десятилетиями для объектов в памяти в языках с AutoMM (LISP, Java, C#, JavaScript, Lua, тысячи их) - будут работать без принципиальных изменений. (Хм, разве что систему поколений придётся убрать... и то не уверен.)
С проектами типа https://github.com/presslabs/gitfs - может и 1% "репозитория" не влезть.
А ведь есть те, кто реально это начал использовать. Ограничения на размер приватного репозитория до сих пор нет, насколько мне известно - только на количество пользователей.
Вы продолжаете в упор не понимать то, о чём я говорю, хотя я сказал это открытым текстом.
Да, может быть, что внутри github один репозиторий на всех. Может, там что-то вроде, например, 2^16 репозиториев, хэшированных по микросекунде создания первого оригинала, и клоны включаются к оригиналам. Это всё неважно. Важно то, что это хранилище должно периодически чиститься, иначе в нём будет накапливаться то, что никто никогда использовать не будет - убитые репозитории, целые удалённые юзеры, выброшенные ветки, выброшенные ошибочные коммиты (включая те, где случайно вкоммитили пару десятков гигов промежуточных файлов), и прочая и прочая.
Я не верю, что там вообще нет очистки. Иначе бы оно давно разрослось до объёмов, которые не выдержит ни одно хранилище в мире. Я думаю, что очистка есть. Когда, как она проводится - их внутреннее дело. Может, они раз в год чистят, или когда вырастет от предыдущего в два раза. Для GC существуют много алгоритмов и критериев. Но хоть когда-то это должно делаться.
Прежде чем продолжать дискуссию, прошу вас оценить самому необходимость чисток, её периодичность и типовые подходы. Можете начать с реализации команд prune, gc, repack в каноническом клиенте git. Только после этого будет смысл продолжать обсуждение.
Не только. reflog как пример. Головы удалённых веток и всё, на что они ссылаются, хранятся до ближайшей большой сборки. Я не верю, что на github нет периодического запуска аналога `git gc`.
Для того, чтобы коммиты были в репозитории, нужно, чтобы они остались доступны. И вот почему они доступны, когда на них ничего не ссылается уже долгое время - сомнительно. Даже ответ с самого github тут может быть некорректным.
По-нормальному таки надо сделать тест с проверкой после большой паузы.
Вопрос - сколько времени удалённые данные будут доступны? Я про "вечно" не совсем верю. Больше похоже на умолчание Git - 90 дней. Тогда это даже разумно.
И ещё одно...
Есть ли средства рефакторить форматирование между этими стилями? Чтобы само умело переделывать по запросу, например, `"%s %r" % (x, y)` в `"{} {!r}".format(x, y)` и далее в `f"{x} {y!r}"`, или наоборот. И какие их достоинства и недостатки. Без этого рассказ неполон.
Самый старый вариант с %s по-прежнему рекомендуется для модуля logging, чтобы не форматировать, если не включено по уровню.
В примеры надо бы добавить, что bool('0') is True, и то же для bool('0.0')... Есть виды опыта, после которого это не совсем очевидно.
Так оно тоже достаточно часто отвечает. Но если "думает", что знает ответ, то начинает писать абстрактное кэпство.
Подозреваю, что какой-то следующий круг усилий по совершенствованию этих моделей будет направлен как раз на улучшение качества самопонимания... и это как раз то, что приблизит реально к человеческому уровню (ну, имеющего образование в данной области).
Если в интернете нет описания чего-то, то шанс на генерацию полезного ответа - минимален. Собственно, по этому часто и видно, что данных нет, или надо менять формулировку.
А может, это физик оказался способен ещё и картины рисовать, а не наоборот? ;)
По-моему, ваш оппонент говорил о статистической закономерности - а один пример одного великого художника её не опровергает, подчёркивая, наоборот, её наличие.
Простите, а какая именно версия GPT написала этот комментарий?
Я бы сказал, основная проблема в том, что любая IT технология в период бурного развития даёт 99% шума-хайпа и только 1% того, что станет полезным. Это касается не только IT, а значительной части прогресса в целом, но в IT за счёт общих темпов это выражено значительно острее. Автор вспоминает ML/DS, но ML/DS десять лет назад были примерно таким же по шуму, а до этого были другие, включая компьютеры в целом.
Так что ещё 10 лет и мы сможем понять, что же реально выжило и стало полезным, а рядом будет что-то ещё хайповать.
Если бы автор не матерился, я бы подумал, что это James Mickens. Но хорошо, что остались ещё авторы хороших сатирических проездов. Они пользительны и прельстивы.
Можно и нужно - но, понимая, что именно делаешь и почему. И имея в виду возможные проблемы от реализации. А вот если не понимать... вот тут целое собачье кладбище зарыто.
В обсуждаемом случае сравнение int и float - это не сравнение двух float. Это отдельный вариант (хоть внутри и получается конверсия к float (double), но она замаскирована видом констант). И последствия от него примерно такие же, как в JS ситуация типа "ваш номер карточки 4.1492103e+15". Это больше проблема типизации, чем собственно сравнение floatʼов.
Сравнение floatʼов на равенство вредно тогда, когда мы говорим о результатах вычислений с заведомо приближёнными значениями (типично для прикладной математики всех видов выше, чем 4 арифметические операции). Вот там появляется правило про корректный выбор относительной погрешности (каковой выбор ещё надо осилить, не всегда сразу получается адекватная погрешность).
А вот если значения по каким-то причинам точные (или гарантированно точные, или результат однозначно определённых операций типа i*0.01), тогда и точное сравнение возможно. Также есть случаи сравнения с нулём, как признак полной потери значения (даже не денормализованные). Но очень часто само по себе такое сравнение подсказывает, что выбрана неверная модель представления числа.
В финансовых расчётах точное сравнение возможно и нужно. Но тут вопрос, с какого момента может начаться недопустимое округление. Всякие Decimal из С# маскируют проблему до предела, давая аж до 28 знаков точности... обычно хватает. Но с фиксированной точкой таки честнее (и проблема, если что, выскочит явно).
Но попросту, конечно, можно сказать "нельзя!" и это будет как деление на ноль ;)
Посмотрел на несколько последних проектов, в которых участвовал.
SIP софтсвич. Общается с чем-то, представляющим себя как биллинг, по кастомному протоколу (RADIUS с вендорскими расширениями). Ну база тоже есть, но очень вспомогательная.
Компонент радиосоты, управление локальной конфигурацией, которая задаёт направление потоков данных через кастомизированное железо. О "базе данных" можно говорить только в плане состояния этой конфигурации в памяти между ребутами. Есть, конечно, центральная база (на всяких etcd), но это конфигурация, которую в основном правят руками.
Можно продолжать...
Я не против статьи в целом, но слишком много упрощений. И почему мне кажется, что вся статья была написана ради одного слова "Swagger"? И чем же он так хорош, что использовать его, а не 100500 аналогов? "Тема <xxx> не раскрыта" (c).