Pull to refresh
8K+
45
Валерий@mvv-rus

Ненастоящий программист

4,4
Rating
34
Subscribers
Send message
Но способа выполнять таски не на тредпуле а на current thread например я не знаю.

TaskScheduler.FromCurrentSynchronizationContext() (в ContinueWith, в конструкторе TaskFactory) — не оно?
Правда, для этого упомянутый SynchronizationContext должен быть. Впрочем, там где это очень важно (в GUI к примеру, где все обращение к GUI должно быть в выделенном для этого потоке) MS уже изначально об этом позаботилась, а для желающих странного есть возможность реализовать SynchronizationContext самостоятельно.
В результате вы сами себе противоречите — с одной стороны, что любой программист должен считать SQL самым лучшим языком для работы с БД, с другой внезапно большинство программистов внезапно вместо SQL используют совсем другие средства в качестве обертки над SQL

Противоречия нет — есть нюанс: не только лишь все программисты умеют в SQL.
Конечно, сферический программист в вакууме, в совершенстве знающий все языки, чаще (значительно чаще IMHO) будет использовать SQL для доступа к данным в базе. Но вот реальный программист, которого удалось нанять на проект за разумные(на самом деле — не совсем, потому что «всем нужен программист») деньги, от SQL с немалой вероятностью окажется далек — чисто потому, что SQL не похож на его основной рабочий язык. И вот потому применение всяких средств уклонения от написания кода на SQL — от ORM до конструкторов запросов (которые в GIU мышкой) оказывается более чем оправданным.
Но у этой опраданности есть и другая, тёмная сторона. В качестве примера её расскажу историю. Я как-то (в довольно давние уже времена, впрочем) был привлечен к выяснению вопроса, почему так тормозит свежеразработанный местными веб-программистами сайт. Недолгое колдунство с SQL Profiler однажды вечером, когда число запросов на сайт было далеко от пика, но общее торможение оставалось, позволило найти дивные SQL-запросы, выполнявшиеся по 15 секунд — причем это были не отчеты и не поиск по БД, а обычная генерация страниц квазистатического контента. Тем не менее, планировщику СУБД от этих запросов конкретно плохело — и не зря: просмотр текста запроса — крайне сложного и запутанного — ввел меня в глубокую задумчивость, как такое можно вообще написать? Вопрос этот (с примерами) я резонно переадресовал команде веб-программистов — на что получил честный ответ типа «А мы сами не знаем, оно автоматически создается» (потом они, правда, зная, где именно творится безобразие, все же что-то с ним сделали). Короче, думаю, мораль понятна.
SQL, повторяю, на мой взгляд, сложен для привыкших к императивному программированию (коих среди программистов большинство) своей непривычностью — и уж никоим образом не многословностью и необходимостью учитывать множество мелочей, как ассемблер. Мне, например, не приходилось писать действительно огромные простыни именно на SQL (а не на каком-нибудь расширении его для создания хранимых процедур): всё самое сложное, что было нужно, укладывалось в несколько (всяко меньше десятка) связанных друг с другом подзапросов. Правда нередко сразу было не очевидно, как их писать, и приходилось писать код не с начала, а буквально с середины. Но в итоге код запроса получался довольно компактным.
А вот в защиту бизнес-логики на хранимых процедурах у меня слов мало найдется. По-моему это — пережиток той уже давней эпохи, когда приложения были чисто клиент-серверные, с «толстым клиентом» (иными словами — «тощим» сервером, который был по сути СУБД), а удобных технологий вынесения бизнес-логики на сервер («трехзвенные приложения») ещё не существовало. Вот тогда, с теми ограничениями, бизнес-логика на PL-SQL и ему подобных была как-то оправдана. Сейчас же оправдание такой архитектуры для новых проектов я найти не могу.
Не всегда. Конечно, с помощью SQL нельзя сделать всё. Но очень многое можно сделать куда проще, чем расписывая вручную выполнение запроса циклом(ами) в императивном языке.
За стандартный SQL не скажу (стандартов не читал давно), но вот в Transact-SQL для MS SQL Server рекурсивное получение данных из таблицы с id и parent_id, хранящей дерево (или даже целый лес), в виде набора записей, содержащих и вычисленную длину от корня дерева, вполне возможно и в чисто декларативном стиле — через использование Common Table Expresions (CTE) и UNION ALL. Как-то, типа (синтаксическую проверку не делал) так:
WITH Nodes(parent_id, id, node_level) AS (
  SELECT parent_id, id, 0 as node_level FROM tree_table WHERE parent_id IS NULL
  UNION ALL
    SELECT t.parent_id, t.id, node_level+1 FROM tree_table t
    INNER JOIN Nodes n ON t.parent_id = n.id
)
SELECT * FROM Nodes

Ну, а в оконечном SELECT (который я в простейшем виде записал) можно уже делать что нужно — например отсортировать записи в порядке убывания node_level и взять верхнюю.

Да, средства построения запросов SQL разной степени навороченности существуют, естественно: иначе бы программистам, которые обучены обычному императивному программирванию (а таких, наверное, большинство) было бы совсем грустно писать свои программы, которым по жизни часто с БД работать приходится.
Про Java и БД.
Что-то мне подсказывает, что автор статьи записал в функциональные языки ещё и SQL.
Участовать в споре функциональный ли язык SQL или нет, я не собираюсь, но, вообще-то, нечто общее у SQL с ФП есть — и уж, по-любому, в SQL реализована никак не императивная парадигма программирования.
А то, что SQL в качестве языка доступа к данным в БД (DML) сильно лучше императивных языков — это, думаю, ощутил на своей шкуре всякий достаточно опытный программист, которому приходилось в качестве DML где-нибудь в 1-й половине 90-х помучаться с чем-нибудь из серии Clipper/FoxPro/Paradox для написания запросов на получение данных из нескольких таблиц, да ещё и с фильтрами по значениям полей — тем, что в SQL делается в одну строчку.
Это — «best practices», связанные, например, с такими метриками, как «полнота покрытия кода юнит-тестами». И если вам какую-нибудь такую метрику воткнут в KPI — таки придется ей следовать.
Язык не имеет особого значения: как написано в той же самой статье по ссылке «закоренелый настоящий программист может написать фортрановскую про-
грамму на любом языке.»
Да, он наверняка помнил. А если что и не помнил — то смотрел в коде: «настоящие программисты не нуждаются в комментариях: текст программы все объясняет»
Вопрос в том, как он это поддерживал.
Возможно, он был настоящим программистом, неведомо какими ветрами занесенным в этот банк.
Тут надо было конкретно смотреть отдаваемый сервером дескриптор безопасности для политик. Кое-какие изменения, связанные с бюллетенем MS16-072 с безопасностью дл яполитик были (а в Win2019 они вошли изначально, естественно) — но они, вроде как, были для всех ОС, на которые обновления ставились.
Но раз уже пересоздали — это не актуально.
После этого слетела часть политик gpo.

Странно мне это. Политики применяются исключительно клиентом, контроллер домена служит всего лишь их хранилищем (в общей папке и в каталоге LDAP), достаточно пассивным.
Если окинуть всю картину общим взглядом, то становится понятным, откуда что и для чего появляется.
Ну, интерфейсы в качестве параметров конструкторов — это, понятно, буква «D» в cлове SOLID. В это слово сейчас положено верить, и на это вроде бы даже есть основания, которые я сейчас совсем не хочу рассматривать по существу. Примем на веру: SOLID рулит.
Отдельная подсистема, которая порождает все классы, реализующие интерфейсы — это, конечно, Abstract Factory pattern. Следовать ли ему? Если реализации разных интерфейсов внутри могут быть довольно сильно связаны (к примеру — использовать общее хранилище), и если есть большое подозрение, что реализации будут меняться(а в больших проектах такое надо подозревать IMHO всегда), то Abstract Factory pattern — это практически неизбежность. Вот если реализации разных интерфейсов друг от друга зависят слабо — тогда можно попробовать обойтись и без этой подсистемы.
Ну, и последний вопрос — зачем подсистему создания реализаций интерфейсов делать сложной и таинственной, наполненной нетривиальным внутренним сожержимым. И ответ здесь — соблазн декларативности. Каждому человеку (и программисту тоже) хочется просто указать компьютеру, что надо делать — и пусть он решит, как именно сделать. Оборотная сторона тут тоже есть: компьютер сделает ровно то, что вы ему приказали, а как и почему он сделал это — придется выяснять, и это может быть дольше, чем искать ошибку в собственном коде. И да, автор прав: выясниться это может в самый неподходящий момент. Но не все эту оборотную сторону видят, особенно — теоретики от программирования из Computer Science: это же не им приходится отлавливать ошибки.
Как к этому относиться — зависит от конкретных условий. Если архитектуру определяете вы самостоятельно — можно попробовать подумать и оценить. Но для этого нужен опыт, и что делать, если опыта нет — не знаю. Навереное, в этом случае лучше все же следовать моде, делать как все делают. Если же вам поставлено условие типа «используем DI-контейнер X» то тут можно только соглаисться на это условие. Или — не согласиться, со всеми вытекающими.
«Не понимаю этой любви разработчиков с к базам данных. Получить ошибку соединения ....»

Пишите тогда уж точнее, что ли: «Не понимаю этой любви рахработчиков к выделенным серверам баз данных». Потому как это — про другой уровень абстракции и другой уровень разделения обязанностей: между разными единицами аппаратуры по сети. То есть, в вашей аналогии на самом деле оказывается, что речь идет примерно о той же разнице, как разница между модульной и микросервисной архитектурой.
Потому как вообще-то базы данных могут быть и встренные (например Embedded SQL) — исторически на мейнфреймах, где они появились, примерно так и было, и там не было места ошибкам сетевого соединения.
Собственно, давным-давно существует (существовала) методология того, как из представлений информации, используемых разными компонентами информационной системы, синтезировать общую схему БД для этой системы. Называлась она IDEF1 (или «сущность-связь» — entity-relationship, ER). Описана она была ещё в древних книгах 30-летней давности, лет двадцать назад совершенно точно существовали программы (из числа средств CASE), которые автоматизировали построение и модификацию схемы БД (вплоть до написания скриптов генерации/модификации под конкретную промышленую БД). Одной такой программой — ERwin — я сам довольно активно в то время пользовался.
Есть ли подобные программы сейчас, модифицированы ли они под новомодные схемы хранения XML/JSON и прочего No-SQL (потому что тогда они строили схему БД в 3-й нормальной форме реляционной модели) — я даже не знаю.
Но это хорошо, что древнее знание не забывается (хотя, может быть — и переоткрывается).
У меня есть более рациональное объяснение.

Я, наверное, испорчен жизнью в 90-х, но для меня слово «рациональное» имеет однозначно другое значение: оно (если не про угрозы жизни и здоровью) — чисто про бабло.
И, насколько я знаю, типичные менеджеры корпораций рациональность понимают точно так же, меркантильно: больше доходов, меньше расходов.
И в таком понимании ваше объяснение сложно назвать рациональным. Но я на совещаниях тогдашних менеджеров IBM не присутсвовал, так что всё может быть: не исключено — значит, возможно.
Ну, товарищ Ленин левизну тоже не сильно уважал. Даже работу про нее написал под говорящим названием «Детская болезнь левизны в коммунизме».
Отсуствие структуры и возможность написания лапшевидного кода — это была только одна из претензий (в равной мере относившейся и к Фортрану). Но была и другая — отсутствие (или, по крайней мере, необязательность) типизации данных. И это никуда не делась ни в QB, ни в VB. И в JS эта, свойственная скриптовым языкам, особенность тоже есть.
Дошло до смешного, в одном проекте нужна была интеграция с Active Directory, так вот для Node.js нашлась готовая библиотека, с которой можно было тестировать приложение без поднятия отдельного контроллера домена. А для .NET, как нетрудно догадаться, не нашлась…

Так как я программист ненастоящий, то средства доступа к каталогу LDAP из .NET мне использовать не довелось. Но мне, ныне как специалисту именно по AD, странно это, что не нашлось библиотеки. Потому что у MS кроме AD Directory Services (AD DS), с доменами и аутентификацией, есть ещё и отдельный AD Lightwait Directory Services (AD LDS), который — просто сервер LDAP, ко всем заморочкам с доменами отношения не имеющий. И основной протокол доступа к содержимому каталога что AD DS, что AD LDS — один и тот же: LDAP (вряд ли кто-то в разработке для Интернет/интранет использует специфические именно для AD DS вещи на базе RPC (более строго — DCE RPC), типа API репликации). По крайней мере, средства доступа через LDAP — что древнее средство доступа к AD на базе COM Automation — ADSI, что современный модуль доступа в Powershell — ActiveDirectory называется (и который наверняка работает через стандартную библиотеку .NET Framework) — совершенно одинаково позволяют работать как с AD DS, так и с AD LDS, только сервер с портом им правильный указать надо.
Единственно, что я слышал в минус .NET в плане LDAP — что в .NET Framework нет интеграции LDAP с ADO.NET, т.е. возможности обращения к содержимому каталога с использованием SQL (но это не точно), а вот в ADSI, с ADO — была, сам использовал.
У VB нет концептуальных противоречий с Windows.

Как так — нет? Разве программа в Windows состоит из иерархически организованных компонентов (т.е. объектов, имеющих внутреннее состояние в виде полей), получающих события через свои обработчики, которые вызываются в соответствии с этой иерархией? А не из оконных процедур (т.е. ни разу не объектов, т.к. все состояние у них — доступное Get/SetWindowLong некоторое количество неструктурированной памяти окна), которым направляются сообщения (весьма низкоуровневые причем)? И это ещё не всё: часть компонентов вообще не имеют в системе связанного именно с ними окна, получающего сообщения от ОС, они реализуются на базе оконной процедуры того окна-контейнера, в котором они содержатся, т.е. их обработчики событий должен вызывать этот контейнер.
То есть, чтобы получить концептуальную модель, которую использовал VB, требовалось довольно много дополнительного кода — не зря же программа на VB требовала таскать вместе с ней ещё и DLL.

Когда я говорил про концептуальную противоестественность, подразумевал замену естественной для web'а модели запрос-ответ циклом событий.

А так ли уж естественна для web именно модель запрос-ответ?
Web — он очень разный.
К примеру, взять SPA: там как раз самый что ни на есть цикл событий. И — иерархия компонентов-элементов DOM, каждый из которых является объектом. И — погружение/всплывание событий по этой иерархии изначально организованное самой средой выполнения (браузером), а не как в в Windows — в лучшем случае прилепленное сбоку через управляющие сообщения дочерних окон элементов управления (совсем других, чем сообщения, которые получают эти элементы), а то и вообще — прописанное в коде оконной процедуры контейнера. И взаимодействие с сервером — не через запрос/ответ с полной заменой содержимого окна, а через API, полученные от которого данные потом обрабатываются самим SPA-приложением.
Или SPA — это не web?

PS Мое мнение, почему все пошло не так: MS придумала Web Forms и придумала XHR, но не додумалась совместить их друг с другом.

PPS В те далекие времена, когда я писал программы под Windows, я любил Delhi. Сейчас мне нечего любить.
WebForms был хорош для упрощения перехода в web-программирование windows-разработчиков. Но он же концептуально противоестественен для веба ¯\_(ツ)_/¯

Ну, я бы сказал, что и VB в 90-х не менее «концептуально противоестественным» для Windows: знал немало программистов, которые тогда от него плевались («как это — программировать мышкой?!»). Но (до выхода Delphi и Borlad C++ Builder) особого выбора средств быстрой разработки у них не было — разве что Powerbuilder или, там, Paradox for Windows, что тоже было не труъ. А то, что считалось труъ, «концептуально естественным» — типа Visual C++ с MFC или же Borland C++ с OWL (и все это с ODBC для работы с БД), — для типичной задачи «легко и быстро сляпать приложение» подходило весьма посредственно.
Но сейчас, конечно, Web Forms уже не поможет: это раньше формошлепы сидели на VB, а теперь они сидят на React/Angular/View и прочих фреймворках, и JS им вполне заменяет Basic — благо «бейсиковский» безалаберный стиль (по поводу которого некогда ругался ещё Никлаус Вирт) и для JS вполне своественен.
Читаю я этот текст, и мне в голову мысль приходит: зря, наверное, MS забросила Web Forms и Visual Basic. Или там решили, что на таких вот проектах они денег не подымут…

Information

Rating
1,286-th
Registered
Activity