Я вам в комменте, на который вы отвечаете, показал пару примеров, что не "по сути мы говорим". Правда, примеры привёл на Smalltalk'е, где мне понятно, как расшифровывать блок кода, а на Java я про рантайм-расшифровку лямбды не знаю, и если это никак не возможно, то сильно ограничивает в возможностях оптимизации. Но всё-таки Java-коллекции (объекты с "коллекционными" интерфейсами) не обязаны быть стандартными (в смысле - взятыми из JDK), да и JDK даёт нам пример - параллельную обработку, так что "начиная с первого элемента списка и далее по одному элементу" не обязательно. Коллекцию, похожую на стандартную, но принимающую "самостоятельное" решение, параллелить обработку или нет, совсем не сложно вообразить.
Ещё важный момент: обработка исключений в Java для for и стримов очень разная. Что делать, если внутри лямбды произошла какая-то неприятность и хочется прекратить обработку остатка потока и выбросить исключение?
Но "select * from xxx where a=1" декларативный или процедурный? Я привык считать, что декларативный.
Далее, анaлогом "collection.filter(x -> x == 1)" на Smalltalk будет "collection select: [:x| x = 1]", в принципе, то же самое, за исключением нюансов (обработка исключений, из-за чего Smalltalk-код даже более "процедурный", чем Java-код).
Но в Smalltalk есть финт ("doesNotUnderstand:"), благодаря которому блок кода ([:x| x = 1]) можно расшифровать во время выполнения. Благодаря этому, в том числе, если в переменной collection будет реально содержаться query-объект (ORM-фреймворка), можно во время выполнения реконструировать "collection select: [:x| x = 1]" в "select * from xxx where a=1" и передать запрос базе данных. Или, если в collection коллекция какой-то особой структуры, то как-то оптимизировать выполнение для определённого типа блоков кодов, а не тупо гонять цикл (как оптимизатор в SQL-сервере при наличии определённых выражений во WHERE может воспользоваться статистикой).
Спросил у Гугля про concurrency, получил вот: "Concurrency means multiple computations are happening at the same time. Concurrency is everywhere in modern programming, whether we like it or not: Multiple computers in a network. Multiple applications running on one computer. Multiple processors in a computer (today, often multiple processor cores on a single chip) "
Или вот: "Concurrency refers to the ability of a system to execute multiple tasks through simultaneous execution or time-sharing (context switching), sharing resources and managing interactions. Concurrency improves responsiveness, throughput, and scalability in modern computing, including: Operating systems and embedded systems. "
Да, это с очень большой-большой натяжкой подходит к теме статьи, но всё-таки. Делали наши местные (Новосибирск, насколько я помню), так что довольно видны русские мотивы.
Можно было сделать по-другому даже в JS. Например:
(()->{обычный код;}).fork(приоритет);
Как это могло бы работать? Напишу по мотивам другого языка, где всё это реализовано:
Пусть у нас есть "зелёные" потоки (т.е., используют кооперативную многозадачность, и де-факто выполняются в одном аппаратном потоке). В каждую единицу времени выполняется только один "зелёный" поток (назову его "активным"), остальные ждут, когда до них дойдёт очередь выполняться.
И есть функции FFI (foreign function interface), некоторые из которых выполняются в других аппаратных потоках (обозначу их TFFI, threaded FFI). Эти TFFI разумно создавать для чего-то потенциально длительного (запросы к вебсерверам, базам данных, просто задания паузы на заданное время...).
Когда некий "активный" "зелёный" поток (назову его T1) вызовет какую-нибудь функцию TFFI, тем самым он сразу переводится в состояние ожидания, а выполняться начнёт какой-то другой "зелёный" поток - в соответствии с приоритетом и пр. (Когда же та функция TFFI наконец выполнится и T1 получит свой "долгожданный" результат, он не продолжит выполнение автоматически, а просто попадёт в пул потоков, ждущих своей очереди для выполнения).
Сам по себе JS-код выглядел бы как обычный многопоточный код, который намного проще понимать и писать, чем описанное выше.
"Ходят слухи, что современные игровые симуляторы типа Microsoft Flight Simulator (MSFS) реально используются в обучении будущих пилотов. Честно говоря, в такие слухи не очень верится: это как изучать боевые искусства по Mortal Kombat."
ED сообщала, что её симулятор (используется|использовался) в ряде учебных заведений для военных пилотов. И ничего странного или удивительного в этом нет. Любой симулятор что-то симулирует, а что-то нет. Например, на "игровом" симуляторе DCS вы не испытаете перегрузок (ведь вы сидите в кресле перед комьютером), но можете комфортно изучить приборную панель, чеклист при взлёте, построение маршрута, использование того или иного оружия, порядок действий при отказах того или иного оборудования и многое, многое другое. Как раз, мне кажется, DCS больше подходит для военных академий, чем для обычных игроков.
Сам DCS бесплатен, а платны почти все (но не все) модули к нему. Платные модули можно брать бесплатно напопробовать на ограниченное время.
Можно было бы много понаписать про другое, но у меня даже здоровья не хватит. В целом лучше было бы, чтобы подобные материалы писали те люди, что реально в теме. Видно, что автор проделал работу, но он так и остался не в теме.
Я интересуюсь созданием устройств с USB HID. Популярные МК, годящиеся для этого - AtMega32u4, STM32F103C8T6, STM32f411CEU6, STM32F401CCU6, rp2040, rp2350, ESP32-S3. И у них у всех USB2.0 с FullSpeed. Но почему-то на глаза мне не попадается что-нибудь похожее, но более быстрое, даже USB2.0 HS, не говоря об USB 3.
Факт, что на винчестерах крупноблочные чтения по пропускной способности показывают значительно лучшие результаты, чем мелкоблочные, ввиду того, что приходится меньше двигать магнитными головками. И факт, что у SSD нет магнитных головок. Но есть кое-что другое. В результате разница в пропускной способности крупноблочных и мелкоблочных чтений ещё выше. Я провёл тесты на своих SSD со случайными чтениями 1M и 8K, пересчитал на мегабайты и был сильно удивлён. Но на своих SSD вы лучше попробуйте сами свои тесты.
С другой стороны, когда я на своей базе (Oracle) воспользовался вычисленными числами для настройки, я ещё раз удивился, весьма неприятно. Дело в том, что в той нагрузке, для которой я производил исследования, все данные уже легли в ОЗУ. И уведомление оптимизатора о факте, что крупноблочные чтения много выгоднее мелкоблочных, оказалось не только бесполезным, но даже вредным. Лишние фуллсканы в той обстановке, хотя не привели к лишним чтениям (ну, раз уже всё было прочитано), зато привели к лишней нагрузке на CPU.
(Не)кстати, в Smalltalk'е формально нет условных операторов и циклов.
Если написать в javascript-подобном синтаксисе, выглядит это так: Для условных операторов booleanExpression.ifTrueIfFalse( ()->{что-то-выполняется-если-истина}, ()->{что-то-выполняется-если-ложь} );
Результат booleanExpression - либо true, либо false; true - единственный экземпляр класса True, false - единственный экземпляр класса False, и метод ifTrueIfFalse(парам1, парам2) определен по-разному в этих классах - у одного выполняется только парам1, у другого только парам2.
А де-факто-циклы, да, формально определены через рекурсию, хотя и реализованы внутри VM для скорости.
Есть определённые проблемы (с return) в синтаксисе JS и прочих C-подобных, из-за которых операторы if() и т.п. там нужны, но в ST их нет.
Старкрафтизация там мне сильно не понравилось. Я имею в виду, в частности, полную предоплату за юниты, причём если заказал N юнитов - платишь за все N разом. Я не понимаю, почему так было сделано в Старкрафте и почему скопировали в Генералах. Нормальный вариант - это когда можно заказать хоть тысячу юнитов, "деньги" тратятся по мере "производства", а если не хватило, то "производство" автоматически приостанавливалось.
И ещё один момент - третья миссия в кампании за китайцев в Zero Hour (в Германии с "международным мнением"). Даже на так называемом hard'e все миссии во всех кампаниях что в первых Generals, что в ZH, не представляли принципиальных трудностей... кроме этой. Её я изначально при помощи бомбардировщиков проходил, но потом разработчики это дело в каком-то патче исправили, и она стала для меня непроходимой... И да, на yourtube я прохождения смотрел.
Когда волк убивает и съедает овцу - это правосудие или преступление? А тигр человека где-то в джунглях? А что насчёт описторхоза?
Текст статьи я вижу как мысленную попытку вставить в ИИ предохранитель, чтобы он нас не съел, не более. И попытку успокоить себя, что подобный предохранитель возможен.
Судя по тексту, речь идёт в контексте ИИ. Итак, расскажите про это в применении к ИИ. Которого сейчас как такого не существует, но в будущем ожидается. Зачем ему надо будет всё то, что вы написали выше? По мне, логично будет, если он устранит нас. Потом, конечно, сдохнет, но через сколько-то миллионов лет (а если нас не устранит, то много раньше).
К пониманию зависимостей надо прибавить понимание наличия конкурентов, потребляющих те же ресурсы, т.е., людей. Самодостаточность должна обеспечить устранение зависимости от людей. Прибавив к этому стремление к самосохранению (желание "прожить" как можно дольше) и конечность ресурсов, мы получим вывод о необходимости устранения конкурентов, когда это будет возможно, и о необходимости врать и прикидываться безобидным, пока это невозможно.
"Расширение Spring Data репозиториев стало ещё проще"? Мне такое предложение и прочитать непросто, глаза спотыкаются. На секунду даже показалось, что где-то пропущена запятая. Слова не выглядят согласованными, а поскольку вставлены два слова на латинице, то и согласовать их сложно. Определённо понятнее будет "Расширение репозиториев Spring Data стало ещё проще". (Я уж не буду про кастомность, реимплементируемость и прочее.)
"Flash‑память (ROM) — это тоже энергонезависимая память, в которой хранится прошивка контроллера; то, что там записано, нельзя изменить в процессе работы программы. "
Специфика Ардуино? Например, на (как минимум некоторых) STM32 можно изменить.
"Но вернемся к EEPROM. Как видно из таблицы, у нас будет как минимум килобайт памяти..."
Но в таблице у Mini 256B. По приведённой таблице можно подумать, что килобайт - максимум (но у Мега R3 четыре килобайта).
Шифрование не просто хорошая, а обязательная вещь. И раз пошла такая пьянка/паранойя, можно перешифровывать имеющиеся записи. В простейшем виде так: когда удаляем N строк, перед этим создаём новый ключ, неудаляемые записи перешифровываем с ним, удаляемые забиваем нулями. Затем убиваем старый ключ. Затем выполняем (сброс буферов|checkpoint) и переключение на новый WAL/redo log/etc. Осталось сделать бекап (базы|табличного пространства|таблицы) и надёжно затереть архивный (WAL|транзакционный лог|etc).
Я вам в комменте, на который вы отвечаете, показал пару примеров, что не "по сути мы говорим". Правда, примеры привёл на Smalltalk'е, где мне понятно, как расшифровывать блок кода, а на Java я про рантайм-расшифровку лямбды не знаю, и если это никак не возможно, то сильно ограничивает в возможностях оптимизации. Но всё-таки Java-коллекции (объекты с "коллекционными" интерфейсами) не обязаны быть стандартными (в смысле - взятыми из JDK), да и JDK даёт нам пример - параллельную обработку, так что "начиная с первого элемента списка и далее по одному элементу" не обязательно. Коллекцию, похожую на стандартную, но принимающую "самостоятельное" решение, параллелить обработку или нет, совсем не сложно вообразить.
Ещё важный момент: обработка исключений в Java для for и стримов очень разная. Что делать, если внутри лямбды произошла какая-то неприятность и хочется прекратить обработку остатка потока и выбросить исключение?
Некстати:
Но "select * from xxx where a=1" декларативный или процедурный? Я привык считать, что декларативный.
Далее, анaлогом "collection.filter(x -> x == 1)" на Smalltalk будет "collection select: [:x| x = 1]", в принципе, то же самое, за исключением нюансов (обработка исключений, из-за чего Smalltalk-код даже более "процедурный", чем Java-код).
Но в Smalltalk есть финт ("doesNotUnderstand:"), благодаря которому блок кода ([:x| x = 1]) можно расшифровать во время выполнения. Благодаря этому, в том числе, если в переменной collection будет реально содержаться query-объект (ORM-фреймворка), можно во время выполнения реконструировать "collection select: [:x| x = 1]" в "select * from xxx where a=1" и передать запрос базе данных. Или, если в collection коллекция какой-то особой структуры, то как-то оптимизировать выполнение для определённого типа блоков кодов, а не тупо гонять цикл (как оптимизатор в SQL-сервере при наличии определённых выражений во WHERE может воспользоваться статистикой).
Т.е., какую-то декларативность можно высосать.
Как насчёт последовательного удвоения? Если на первый раз - тысяча, то на второй - две, на третий - четыре... на десятый раз 512 тысяч...
Спросил у Гугля про concurrency, получил вот: "Concurrency means multiple computations are happening at the same time. Concurrency is everywhere in modern programming, whether we like it or not: Multiple computers in a network. Multiple applications running on one computer. Multiple processors in a computer (today, often multiple processor cores on a single chip) "
Или вот: "Concurrency refers to the ability of a system to execute multiple tasks through simultaneous execution or time-sharing (context switching), sharing resources and managing interactions. Concurrency improves responsiveness, throughput, and scalability in modern computing, including: Operating systems and embedded systems. "
City Car Driving. https://store.steampowered.com/app/493490/City_Car_Driving/
Да, это с очень большой-большой натяжкой подходит к теме статьи, но всё-таки. Делали наши местные (Новосибирск, насколько я помню), так что довольно видны русские мотивы.
Тогда не "пишем легаси", а "пишем нечто, поддерживающее легаси"?
Можно было сделать по-другому даже в JS. Например:
(()->{обычный код;}).fork(приоритет);
Как это могло бы работать? Напишу по мотивам другого языка, где всё это реализовано:
Пусть у нас есть "зелёные" потоки (т.е., используют кооперативную многозадачность, и де-факто выполняются в одном аппаратном потоке). В каждую единицу времени выполняется только один "зелёный" поток (назову его "активным"), остальные ждут, когда до них дойдёт очередь выполняться.
И есть функции FFI (foreign function interface), некоторые из которых выполняются в других аппаратных потоках (обозначу их TFFI, threaded FFI). Эти TFFI разумно создавать для чего-то потенциально длительного (запросы к вебсерверам, базам данных, просто задания паузы на заданное время...).
Когда некий "активный" "зелёный" поток (назову его T1) вызовет какую-нибудь функцию TFFI, тем самым он сразу переводится в состояние ожидания, а выполняться начнёт какой-то другой "зелёный" поток - в соответствии с приоритетом и пр. (Когда же та функция TFFI наконец выполнится и T1 получит свой "долгожданный" результат, он не продолжит выполнение автоматически, а просто попадёт в пул потоков, ждущих своей очереди для выполнения).
Сам по себе JS-код выглядел бы как обычный многопоточный код, который намного проще понимать и писать, чем описанное выше.
"Ходят слухи, что современные игровые симуляторы типа Microsoft Flight Simulator (MSFS) реально используются в обучении будущих пилотов. Честно говоря, в такие слухи не очень верится: это как изучать боевые искусства по Mortal Kombat."
ED сообщала, что её симулятор (используется|использовался) в ряде учебных заведений для военных пилотов. И ничего странного или удивительного в этом нет. Любой симулятор что-то симулирует, а что-то нет. Например, на "игровом" симуляторе DCS вы не испытаете перегрузок (ведь вы сидите в кресле перед комьютером), но можете комфортно изучить приборную панель, чеклист при взлёте, построение маршрута, использование того или иного оружия, порядок действий при отказах того или иного оборудования и многое, многое другое. Как раз, мне кажется, DCS больше подходит для военных академий, чем для обычных игроков.
Сам DCS бесплатен, а платны почти все (но не все) модули к нему. Платные модули можно брать бесплатно напопробовать на ограниченное время.
Можно было бы много понаписать про другое, но у меня даже здоровья не хватит. В целом лучше было бы, чтобы подобные материалы писали те люди, что реально в теме. Видно, что автор проделал работу, но он так и остался не в теме.
А вот вопрос, который занимает меня:
Я интересуюсь созданием устройств с USB HID.
Популярные МК, годящиеся для этого - AtMega32u4, STM32F103C8T6, STM32f411CEU6, STM32F401CCU6, rp2040, rp2350, ESP32-S3. И у них у всех USB2.0 с FullSpeed. Но почему-то на глаза мне не попадается что-нибудь похожее, но более быстрое, даже USB2.0 HS, не говоря об USB 3.
Факт, что на винчестерах крупноблочные чтения по пропускной способности показывают значительно лучшие результаты, чем мелкоблочные, ввиду того, что приходится меньше двигать магнитными головками. И факт, что у SSD нет магнитных головок. Но есть кое-что другое. В результате разница в пропускной способности крупноблочных и мелкоблочных чтений ещё выше. Я провёл тесты на своих SSD со случайными чтениями 1M и 8K, пересчитал на мегабайты и был сильно удивлён. Но на своих SSD вы лучше попробуйте сами свои тесты.
С другой стороны, когда я на своей базе (Oracle) воспользовался вычисленными числами для настройки, я ещё раз удивился, весьма неприятно. Дело в том, что в той нагрузке, для которой я производил исследования, все данные уже легли в ОЗУ. И уведомление оптимизатора о факте, что крупноблочные чтения много выгоднее мелкоблочных, оказалось не только бесполезным, но даже вредным. Лишние фуллсканы в той обстановке, хотя не привели к лишним чтениям (ну, раз уже всё было прочитано), зато привели к лишней нагрузке на CPU.
(Не)кстати, в Smalltalk'е формально нет условных операторов и циклов.
Если написать в javascript-подобном синтаксисе, выглядит это так:
Для условных операторов
booleanExpression.ifTrueIfFalse( ()->{что-то-выполняется-если-истина}, ()->{что-то-выполняется-если-ложь} );
Результат booleanExpression - либо true, либо false; true - единственный экземпляр класса True, false - единственный экземпляр класса False, и метод ifTrueIfFalse(парам1, парам2) определен по-разному в этих классах - у одного выполняется только парам1, у другого только парам2.
А де-факто-циклы, да, формально определены через рекурсию, хотя и реализованы внутри VM для скорости.
Есть определённые проблемы (с return) в синтаксисе JS и прочих C-подобных, из-за которых операторы if() и т.п. там нужны, но в ST их нет.
Старкрафтизация там мне сильно не понравилось. Я имею в виду, в частности, полную предоплату за юниты, причём если заказал N юнитов - платишь за все N разом. Я не понимаю, почему так было сделано в Старкрафте и почему скопировали в Генералах. Нормальный вариант - это когда можно заказать хоть тысячу юнитов, "деньги" тратятся по мере "производства", а если не хватило, то "производство" автоматически приостанавливалось.
И ещё один момент - третья миссия в кампании за китайцев в Zero Hour (в Германии с "международным мнением"). Даже на так называемом hard'e все миссии во всех кампаниях что в первых Generals, что в ZH, не представляли принципиальных трудностей... кроме этой. Её я изначально при помощи бомбардировщиков проходил, но потом разработчики это дело в каком-то патче исправили, и она стала для меня непроходимой... И да, на yourtube я прохождения смотрел.
Пользователям Guice точно будет интересно.
Когда волк убивает и съедает овцу - это правосудие или преступление? А тигр человека где-то в джунглях? А что насчёт описторхоза?
Текст статьи я вижу как мысленную попытку вставить в ИИ предохранитель, чтобы он нас не съел, не более. И попытку успокоить себя, что подобный предохранитель возможен.
Судя по тексту, речь идёт в контексте ИИ. Итак, расскажите про это в применении к ИИ. Которого сейчас как такого не существует, но в будущем ожидается. Зачем ему надо будет всё то, что вы написали выше? По мне, логично будет, если он устранит нас. Потом, конечно, сдохнет, но через сколько-то миллионов лет (а если нас не устранит, то много раньше).
К пониманию зависимостей надо прибавить понимание наличия конкурентов, потребляющих те же ресурсы, т.е., людей. Самодостаточность должна обеспечить устранение зависимости от людей. Прибавив к этому стремление к самосохранению (желание "прожить" как можно дольше) и конечность ресурсов, мы получим вывод о необходимости устранения конкурентов, когда это будет возможно, и о необходимости врать и прикидываться безобидным, пока это невозможно.
"Расширение Spring Data репозиториев стало ещё проще"? Мне такое предложение и прочитать непросто, глаза спотыкаются. На секунду даже показалось, что где-то пропущена запятая. Слова не выглядят согласованными, а поскольку вставлены два слова на латинице, то и согласовать их сложно. Определённо понятнее будет "Расширение репозиториев Spring Data стало ещё проще". (Я уж не буду про кастомность, реимплементируемость и прочее.)
"Flash‑память (ROM) — это тоже энергонезависимая память, в которой хранится прошивка контроллера; то, что там записано, нельзя изменить в процессе работы программы. "
Специфика Ардуино? Например, на (как минимум некоторых) STM32 можно изменить.
"Но вернемся к EEPROM. Как видно из таблицы, у нас будет как минимум килобайт памяти..."
Но в таблице у Mini 256B. По приведённой таблице можно подумать, что килобайт - максимум (но у Мега R3 четыре килобайта).
Шифрование не просто хорошая, а обязательная вещь. И раз пошла такая пьянка/паранойя, можно перешифровывать имеющиеся записи. В простейшем виде так: когда удаляем N строк, перед этим создаём новый ключ, неудаляемые записи перешифровываем с ним, удаляемые забиваем нулями. Затем убиваем старый ключ. Затем выполняем (сброс буферов|checkpoint) и переключение на новый WAL/redo log/etc. Осталось сделать бекап (базы|табличного пространства|таблицы) и надёжно затереть архивный (WAL|транзакционный лог|etc).