Обновить
@Scfread⁠-⁠only

Пользователь

10
Подписчики
Отправить сообщение

Только вдумайтесь, как звучит: "человек с высшим техническим образованием не может переставить винду".

Я считаю, в ВУЗах не нужно учить программировать, языки программирования и подходы меняются регулярно и ни одна учебная программа под них не подстроится. В ВУЗах нужно давать то, что человек самостоятельно изучать не будет — теорию.


Линейная албегра, матанализ, вычислительная математика, теория графов, моделирование, нейронные сети, конечные автоматы, исчисление предикатов, устройство процессоров и многопроцессорных систем — вот то, что мне уже пригодилось.
Чего не было, но что хотелось бы иметь: алгебра в конечных полях, теория параллельных программ, теория распределенных алгоритмов.

Музыкантам сложнее — сам ты придумал эту мелодию или слышал краем уха 5 лет назад?

Спасибо, что так хорошо расписали :-) По моему опыту, полный отказ от мутабельности в угоду математической чистоте — плохая идея, т.к. компиляторов, способых качественно реализовать эту математическую чистоту, нет.
Теперь о пользе:


  • иммутабельные структуры данных значительно упрощают синхронизацию в многопоточном окружении. Вместо мьютексов и т.п. часто можно обойтись CAS над одной переменной
  • передавать функции в качестве аргументов другие функции — удобная вещь, как для декомпозиции кода так и для тестирования.
  • map, flatMap и filter над коллекциями — очень полезные операции, позволяющие изящно выразить большинство распространенных преобразований коллекций
  • концепция "всё является выражением" в языке программирования позволяет писать более качественный код. К примеру, if в современных языках это expression, а не statement.
  • pattern matching — тоже очень удачная находка из мира ФП. switch на стероидах.
  • добавление к четырем китам ООП (наследование, полиморфизм, инкапсуляция, агрегация) композиции (операция соединения двух объектов, возвращающая третий объект того же типа) позволяет многие вещи делать проще и изящнее.
  • монада Option вместо null — must use в 21 веке, кроме самого оптимизированного кода
  • монада Either позволяет писать безопасный код, где компилятор проверит, что программист обработал все ошибки
  • монада Future/Promise — новый стандарт для асинхронного кода.

Я про то же — "совсем ФП" беспощаден, медленнен и бесполезен. И не очень хорошо работает с J2EE.

Академический ФП — академический и его надо оставить академикам. Но идеи из ФП вкупе с последними версиями популярных языков очень полезны. Вот пример java8 + spring после двух лет на скале. Ничего особо хитрого, но джавист так не напишет:


        long unsentEmailId = transactionTemplate.execute(status ->
                unsentEmailRepository.save(
                        new UnsentEmail()
                                .to(to)
                                .subject(subject)
                                .body(body)
                                .lastSent(new Date())
                ).getId()
        );

Проблема вашего решения в наличии связи между бизнес-требованиями и структурой базы. Это проблемно, т.к.


  • при изменении требований возможно придется делать несовместимую миграцию базы (долго и даунтайм)
  • может появиться рассинхрон между данными и производными полями. У поискового индекса такой проблемы нет, т.к. его можно быстро перестроить.
  • народ может повадиться делать селекты не по данным, а по производным полям, добавленным для поиска. Это значительно увеличит хрупкость системы.

Трудоемкость — это довод, если умеете лепить хитрые запросы и не умеете в индекс. Но на вашем месте я бы как минимум вынес производные поля как минимум в отдельные таблицы.

Я бы поднял Solr/ElasticSearch c денормализованными данными, оптимизированными под нужный вид поиска.
Быть может, это было бы больше кода, связанного с обновлением поискового индекса, но решение точно получилось бы проще и масштабировалось бы лучше.

Это сколько же человеко-клико-часов потрачено на покупку еды и браминов....

DI нужен, не нужна конфигурация через данные. Конфигурация кодом — лучше.

Лямбды и чистые функции позвляют значительно улучшать конфиги. В этом плане инновационные языки — Scala и Javascript. Вкратце, идея в том, что любой сетевой обработчик, фильтр и собственно сервер — это функция Request -> Response. Т.е. приложение можно собирать функциональной композицией индивидуальных обработчиков, фильтров и роутеров.

Хорошая попытка, Спринг, но нет, это плохая попытка. Получается, для того, чтобы вывести JSON вместо строки, нужно указать content-type:


.contentType(APPLICATION_JSON)

А дальше начинается счастье и проклятие спринга — спринговая магия. Какой сериализатор мы используем? Как его настроить? А если я хочу выдавать не json с content-type application/json? А если я хочу свой сериализатор вкрутить? И вообще зачем веб-серверу зависеть от спринга?


21 век на дворе, сейчас всем нужны:


  • http server, где спрингом бы и не пахло
  • сериализатор json, где спрингом бы и не пахло
  • возможность скомпоновать 1 и 2, вне зависмости от релиализации.

Guava Collections неплохи, и с лямбдами получается достаточно компактный код.

Пользоваться не запретили, до этого наши законодатели пока не додумались. Запретили предоставлять ВПН без фильтрации контента.

Можно поподробнее про вконтакте? Всегда думал, что они на сях и пхп с самодельным компилятором.

Я имел в виду сборку приложения типа


git clone myapp ; cd myapp # или git pull
docker run -it -v ./:/build  my-js-build-tools /build/build.sh
docker build -t myapp:42 .
docker push myapp:42

Получается, основное преимущество dapp — он умеет сохранять и восстанавливать предыдущее состояние сборки, чтобы делать инкрементальный билд вместо полного?


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

А можно как-то объяснить, зачем всё это нужно вообще?
Ну ок, решили собирать приложения не на хосте дженкинсом, а в контейнере.
Делаем отдельный образ с build environment, содержащий утилиты сборки без кода приложения.
На хосте тем же дженкинсом делаем чекаут и запускам образ сборки, примонтировав ему зачекаутенные исходники и папки с кешами (~/.m2 для мавена, node_modules для npm и т.п.)
Образ с приложением делаем банальным docker build в папке с артефактами, собранными системой сборки.


Хотим, чтобы npm install/composer install вызывался только при изменении соответствующих файлов, а не всегда? пишем простой Makefile, gnu make создавался специально для этой цели.

g++ -Wall -Wextra -O2 test.c -o test
test.c: In function ‘float FastInvSqrt(float)’:
test.c:5:19: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
   int i = *(int*)&x;
                   ^
test.c:7:17: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
   x = *(float*)&i;

Правда, скомпилировать код так, чтобы он сломался, я не смог.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609

Тогда a+b может быть больше 255, т.е. нужно оперировать словами и таблицу квадратов удваивать по размеру.

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность