Зависит от того, насколько важная операция делалась на верхнем уровне, и есть ли резервная система.
Ну и, если речь идёт о сервере, ответ "сервер сломался, ждите пока починят" тоже кто-то выдавать должен. Так что да, никакого аборта.
Ну ок, движок баз данных поймал панику, но мы продолжаем упорно делать вид, что если у нас микросхема памяти глюкнула или dangling pointer превратил всю память в кровавое месиво из мусора, то все нормас, т.к. нужно же дескать кому-то выдавать "сервер сломался, ждите пока починят". Кому же еще это делать, как не полуживому трупу с паникой. Про существование таких штук, как haproxy и прочие балансировщики и сервис мониторы - не, не слышали.
Но я так и так понял, что вы там точно не промышленным программированием занимаетесь. Забавны скорее плюсующие и минусующие, кто бы мог подумать, что это еще и массовое явление сейчас. Даже задумываться начинаешь, кого сейчас берут в IT по собеседованиям.
Вы каким-то удивительным образом разговариваете с голосами в своей голове, при этом цитируете мое сообщение.
Ок, контекст держать уже не можем? До чего людей ChatGPT доводит в наше время, страшно подумать :) Ну да ладно, пусть это будут голоса в голове виноваты.
Например, MDBX_PANIC - тут нам делать нечего и поправить мы не можем - бросаем исключение.
И дальше что? Бросили, заллогировали, далее работаем как ни чем не бывало? Тут вообще-то в abort() выпадать надо.
вы тут уже ничего не можете сделать, только рестарт процесса с исправлением конфига - т.е. читай выше про abort()
MDBX_NOTFOUND - тут мы можем что-то сделать в зависимости от нашей логики - заворачиваем в свой error codes и обрабатываем в моменте.
MDBX_NOTFOUND The specified database doesn't exist in the * environment and \ref MDBX_CREATE was not specified.
Тут тоже аборт и рестарт,
хотя вот тут да MDBX_NOTFOUND No matching key found.
Тут это просто даже не ошибка, а просто статус - нашли-не нашли, это не Exception ни разу, это банальное EXISTS() / NOT EXISTS(), просто Говарду Чу было проще это через код ошибки сделать, зачем-то.
MDBX_NOTFOUND - тут мы можем что-то сделать в зависимости от нашей логики - заворачиваем в свой error codes и обрабатываем в моменте.
Но забавно было конечно, вы там вообще чем занимаетесь? Точно программированием?
Дополню: Те ошибки, которые мы можем исправить в моменте или которые являются частью логики, конечно оставлены кодами ошибки (перекодированными).
В иронии выше про EAGAIN и EACCESS было просто два реальных сценария.
Первый - это вовсе не ошибка, а просто такой себе очень странный API в виде "ой, что-то пошло не так, попробуй еще раз тож самое повторить, на этот раз точно получится". Если подобное делать на Exceptions - то это лишь делает код нечитабельным, ну и может просадить производительность, хоть и не так чтоб сильно.
А второй класс ошибок это - "а блин, что-то в процессе пошло не так, шеф, все пропало, гипс снимает, клиент уезжает" - никакой дальнейшей обработки реально уже и не нужно предусматривать, нужно просто в scope текущего вызова управляемо освободить все внешние ресурсы, которые в процессе вызова были заимствованы (управляемо освободить менеджером внешних ресурсов, а никак не своим говнокодом), хендлы, аллокации памяти, вот это вот все, как-то оформить вызывающему сообщение о возникшей неожиданной проблеме, и на этом прекратить обработку вызова. Именно так себя ведут к примеру серверы баз данных внутри, и не только они.
И... и все.
Попытка же писать некую прикладную логику на exceptions - это просто закамуфлированное goto программирование, и не более того. В говнокоде допустимо, там не критично, в системах 24/7 (серверы баз данных, ядра ОС и т.п.) за подобный "стиль" - тебя просто не поймут.
Но в индустрии в какой-то момент что-то пошло не так, и уже вроде и 30 лет прошло, но нет, продолжают эти goto exceptions двигать в массы, и никакого Go с Дейкстрой и прочей функциональщиной на них не хватает. Настолько legacy изначально криво спроектированных прикладных сред придавило создание этих масс, что не видят очевидный обман и подмену понятий.
Что же до вашей программы - abort вызвать слишком просто, вы прокиньте код ошибки выше по стеку десяток раз, а потом рассказывайте как это "удобно".
Но зачем по стеку десяток раз передавать наверх код ошибки? Вот чтобы что?
Оно конечно понятно, что типовой Java и не только код stacktrace подразумевает от 70 уровней вложенности вызовов, если меньше - коллеги засмеют, но а вот если подумать? Взять реальный код, и посмотреть, на сколько уровней выше нужно к примеру передавать код ошибок EAGAIN или EACCES?
Но хоть кто-то решил немного подумать и сразу написать вопрос (про как десять раз передавать), вместо того чтобы молча минусы выставлять (как же так, бубубу, мне же говорили, что коды ошибок и goto это очень, очень плохо, а exceptions хорошо и я точно буду молодец, если буду их пытаться использовать, а сейчас, сейчас просто молча заминусую, выскажу тем самым свое мнение, в интернете кто-то не прав!).
Ну и макросы так писать нельзя, иначе потом безобидный код вроде вот такого будет содержать совершенно неочевидную ошибку:
Недолго музыка играла - мозг увидел макросы (аааа, макросы же это плохо, говорили мне умные книжки и старшие, более опытные товарищи), они дают НЕОЧЕВИДНЫЕ ошибки.
А то что ни один более менее большой и рабочий проект без макросов не обходится - ой, какая неудобная правда.
Ладно, весело тут с вами, но хоть бы что-то новое и свежее услышать, вместо молчаливо негодующей массы минусующей, впрочем, видимо и не в этот раз.
Ну почему дураки. Когда-то и на паровозах ездили по дорогам, и на телегах, не все же дураки поди были. Просто так тогда было модно или не могли иначе. Вот и сейчас так делают по привычке, т.к. отказаться нельзя, терабайты legacy кода куда девать?
Но то что в не legacy некоторые даже и сейчас паровой двигатель пытаются прикручивать к телегам, как в примере выше про паники как "прямой аналог исключений", то это вообще странно конечно, как и то, что принуждение к явной проверке возможных ошибок через перечислимые типы от их возможных кодов вызывает прям столько негатива.
Стоило про контрактное программирование так долго рассказывать, чтоб потом это все хрясь об колено неверифицируемыми исключениями (как по сути нелокальными goto переходами), контракты эти.
Да и вообще коды ошибок - это да, явно нечто плохое, нужно срочно в шредер их все, от 404 до ORA-00060 и далее.
Ну не хотите писать статически верифицируемый и чуть более надежный код без goto (зачем-то называя их exceptions) - продолжайте и дальше использовать исключения, кто запрещает? Тем более в случае Modern C++ и выбора иного реально нет.
Хотя конечно забавно - goto/setjmp/longjmp это значит бубу, ни за что нельзя использовать! А exceptions - это найс, это можно, нужно и даже полезно. Хотя они в принципе, по сути - мало чем между собой отличаются (хоть и реализованы чуть иначе, но ведут-то себя абсолютно аналогично, к примеру при выходе из циклов for/while).
А почему так? Почему goto это плохо, а exceptions - это хорошо? В чем между ними разница? Чуть иной и более приятный глазу синтаксис, что еще? Одобрение и неодобрение старших товарищей и прочих авторов явно умных книг?
А почему при goto безусловные нелокальные переходы не одобряются, а при exceptions - наоборот одобряются? Только потому что другим синтаксисом оформлены? Самим это не кажется странным?
Для второй в языке, как минимум, должны быть эти самые типы-суммы.
Типы-суммы? Какой-то хаскель головного мозга, простите. Достаточно просто возвращать обычный составной тип, struct/class в терминах С++
С введением в практику destructuring assignment и type introspection это все довольно просто и удобно в итоге, к примеру в С++ уже сейчас вполне возможно писать нечто вида:
Проверяется через clang ./test.cpp --std=c++23 && ./a.out
#include <stdlib.h>
#include <stdio.h>
#define var auto
#define func auto
#define HANDLE_ERROR(val) fprintf(stderr, "Error in %s, wrong value: %d\n", __FUNCTION__, val); abort();
struct SomeResult {
enum Errors {
OK = 0,
ERROR_BAD_X,
ERROR_BAD_Y,
ERROR_BAD_Z
} error;
int value;
SomeResult(Errors error, int value): error(error), value(value) {};
SomeResult(int value): error(Errors::OK), value(value) {};
static func doSomething(int x, int y) -> SomeResult {
if (x < 0)
return { Errors::ERROR_BAD_X, 0 };
if (y < 0)
return { Errors::ERROR_BAD_Y, 0 };
return x + y ;
}
};
func myFunc(int z) -> int {
using enum SomeResult::Errors;
var x = z / 2, y = z * 3;
var [error, result] = SomeResult::doSomething(x, y);
switch (error) {
case OK: return result * result;
case ERROR_BAD_X: HANDLE_ERROR(x);
case ERROR_BAD_Y: HANDLE_ERROR(y);
}
};
int main() {
var result = myFunc(33);
printf("Ook, result: %d\n", result);
return 0;
}
При этом конкретные типы составных кортежей, как и типы для уже error и result задает не пользователь/вызывающий doSomething(), а разработчик doSomething, самому выводить эти составные типы в местах пользования не нужно. Разве не удобно?
При этом компилятор сразу тебя носом тыкает, разве это не прелесть?
./test.cpp:44:11: warning: enumeration value 'ERROR_BAD_Z' not handled in switch [-Wswitch]
./test.cpp:40:1: warning: non-void function does not return a value in all control paths [-Wreturn-type] 40 | };
Сможете такое повторить на "стандартном" С++, чтоб введение нового типа Exception сразу автоматически компилятором подсказало все места, где теперь нужно озаботиться о его обработке?
Про зло в виде switch default говорить не нужно, просто не нужно его использовать
Python, C#, Java, JS и многие другие языки программирования с вами не согласятся. Да и в Rust паника - это исключение.
Паника есть паника, она не предусматривает обработки, только посмертный дамп.
А про Python, C#, Java, JS это вообще не аргумент, это все legacy из 90-х с заложенными еще тогда очень модными заблуждениями, а по сути - ошибками проектирования - мало кто понимал в те годы, как на самом деле нужно в надежность и прочие моменты.
С исключениями же достаточно покрыть тестами catch блоки, которых будет значительно меньше чем проверок кодов возврата.
Странный аргумент. Чего больше, чего меньше. Видимо пока еще не наступило понимание сути обработки ошибок в реальном коде.
Так что повторюсь: исключения и коды возврата - это два разных инструмента, для разных задач. Выбирайте то, что вам подходит больше для конкретной задачи
Не надо никуда повторяться. Если исключения продиктованы библиотеками - то от них не уйти, придется использовать, хочешь ты его или нет. Но как правило к обработке ошибок они имеют весьма... отдаленное отношение.
Разработчик библиотеки волен как чего угодно там внутри себе бросать в виде исключений, и никто ему не указ, да и никто их потом реально не проверит. Т.к. старые пользователи библиотеки и вовсе в неведении, что там в новой версии библиотеки им прилетит, сменили номер версии и ладушки, собралось - и в прод полетело.
В случае же с явными перечислениями тебя компилятор носом потыкает - что вот тут и тут и еще вот тут с новой версией библиотеки возможен новый код ошибки, а у тебя ее обработка не предусмотрена, вот и подумай теперь, что теперь тут может быть. В Java пытались с этим бороться, но потом в массе отчаялись - uncaughtException наше все.
Во что компилятор превращает ключевое слово throw?
В весьма своеобразную форму goto
Что лучше — исключение или коды возврата?
Конечно коды возврата. Авторы Go и Rust могут только подтвердить (если С ники не в авторитете).
Коды возврата более менее реально покрыть и статическим анализатором (в части вот тут добавляем еще один код возврата в enum, айда теперь смотреть где у нас там выпали константы из switch (errcode) обработчиков), ну и автотестами с покрытием, в отличие от.
Но если проект унаследован или хочет C++ библиотек - то ничего не попишешь, придется сидеть с exceptions, вымирать как мамонт и далее.
Интересно, а откуда такие интересные цифры вообще? Мне тут в Подмосковье разнорабочие вида подай -принеси выставляют зарплатные ожидания 5000р на руки в день (150к в месяц, читай $1500 на руки, если без выходных). А сантехники и электрики меньше чем за 16000р в день ($3200 в месяц по КЗОТ) не хотят даже просто рассматривать проектные задания. Доставщики тоже меньше чем за 200к рублей работать не собираются.
Но это не является основной проблемой портирования IDE под другие платформы. Основная проблема - VCL.
VCL это проблема? CLX (Kylix), LCL (FPC/Lazarus) - могут и не согласиться.
Да и при желании можно было сделать эмулятор нужных win32 API, вместо отдельного приколхоживания этого вашего FMX.
Реальная же проблема VCL там была скорее в таких штуках, как Comctrl32, где в 100500 версиях с не меньшим количеством багов в каждой сидели зашитые в Windows имплементации TTabControl, TTreeView, TRichEdit и так далее - вот их реально нельзя было никуда портировать, слишком сложно. А так сама по себе VCL она не сильно в своих внешних API на Win32 заточена, не то что MFC, можно было при желании сделать и кроссплатформенный ее вариант.
Впрочем, сейчас, в процессе доживания Windows - это уже малоактуально, HTML5/CSS3 всех победил.
Другими словами, в текущем состоянии Delphi не зависит от .Net или чего-то подобного.
Это, мягко говоря, не так. IDE примерно с 2007-й версии вобрала в себя очень много .NET барахла внутри, в виде всяких Borland.Studio.Vcl.Design.Refactoring.dll и т.д., что никак не могло положительно сказаться на ее стабильности.
И в последних версиях ситуация не улучшилась, что блокирует ее (IDE) портирование на Linux и macOS. Но сами Win32/Win64 Native приложения никогда не были зависимы от .NET, если только ты сам эту зависимость туда не вкрутишь.
Visual Studio всегда стоил весьма ощутимых денег, это потом уже сделали бесплатные редакции. И сейчас тоже стоит весьма прилично для предприятий, Community Edition это так, на "посмотреть".
Delphi изначально появился как прямой конкурент Visual Basic (а бейсик это первый проект мелкомягких, типа святое), вот с тех пор Delphi и хоронят усиленно. Но, что удивительно, похоронить полностью так и не получилось за три десятка лет.
Против Delphi в свое время была развернута мощная ИПСО компания со стороны маркетологов C#, т.к. они примерно в одной нише. И главный таран - тезис, что дескать за C# платят больше ЗП, и только неудачники пишут Паскале. Вполне сработало.
Сейчас аналогичное ИПСО заряжают в React и Rust, те-же внешние признаки пропаганды и манипуляций.
а есть ли случаи, когда использование mmap оправдано и даёт наилучшую производительность
zero-copy принцип. Когда у тебя вся база данных отображена в локальную память, то ORM строится очень просто - какой объект типа Клиент или Документ целиком, ну или строковые поля из него (это если каждое поле бизнес объекта это отдельный value со своим key) реализуются просто как указатель на нужный адрес в этой самой mmap, т.е. просто ссылаются на участок в файле базы данных. Ничего никуда копировать, пересылать по сети и преобразовывать не нужно, просто сразу ссылаешься на нужный адрес в файле с данными и все. И перебирая запросом сотни тысяч записей - тебе не нужно каждый раз конструировать (аллоцировать) и удалять эти самые бизнес-объекты.
Но когда сервер баз данных живет в отдельном процессе и обменивается с приложением данными через сетевой сокет, то действительно, никакого особого смысла в mmap() нет, ибо натужное копирование данных неизбежно.
Естественно - нужно понимать, что такая mmap() база данных может жить только в режиме read/only, а изменения в базу данных лучше реализовывать через отдельный буфер с изменениями, и уже потом write(), как защита от dangling pointer, reuse after free и подобного, плюс логирование изменений. Об этом (read/only mmap() + write() одновременно) авторы этой чудесной статьи с синтетическими тестами в выводах несколько умалчивают, предпочитая пугать ну очень страшным mmap(), обязательно потеряющими все ваши данные.
Да, mmap() в разумном применении может жить только как read/only, ну а т.к. 99.9% операций с БД и так идут только в режиме чтения, запросы-отчеты и т.д., то применение его вполне оправдано, если у тебя конечно не про конкурентный рандомный перекрестный доступ 100 потоков на 100 особо быстрых NVMe в RAID-0 массиве с инвалидацией TLB (шардирование? партицирование? нет, не слышали!)
А вот read/write mmap() - это скорее сценарии кеширования, когда персистентная консистентность (?) не нужна и данные можно относительно безопасно потерять, пересоздав после рестарта.
Итого за 10 часов ночи - полный образ снимется не более чем с 10 машин. А если их сотни на этаже?
а) Полный образ делается не каждый день, примерно раз в неделю? В остальные дни инкрементальный, нет? Расписание-распределение нагрузки по группам машин для отдельных дней (ночей) можно же сделать? Или каждый день полный бекап всем?
б) Речь выше была о том, что гигабитный аплинк нужен на последних метрах (там даже 100 мегабит вполне хватает, т.е. ничего лучше Cat5e реально и не нужно к рабочим столам тянуть), а вот межсвичи соединения - да, да там хоть 100 гигабит можно через SFP модули сделать, если сильно надо. Или у вас все эти сотни машин в один гигабитный порт по витой паре подключены?
в) Сотни уникальных машин со своими уникальными настройками - это конечно мощная организация сети предприятия, но реалии жизни звучат иначе - 99% пользователей обычно работают только с бразуером, Word, Excel и 1С клиент какой, и если их документы и профили хранятся на сервере - то никакого смысла бекапить их персональные Windows нет. А развернуть типовую word+excel+edge/chrome+1С машинку из образа через PXE ребут - элементарно быстрее, чем заниматься ерундой с backup/restore.
Да, отдельные категории пользователей требуют прям уникальных настроек и софта (к примеру CAD/CAM/CAE или разработчики), но таких обычно единицы.
Но что-то мне подсказывает - вы похоже просто не смогли заранее преднастроенные образы со всем нужным базовым софтом (в т.ч. Office) по сети автоматически разворачивать. Возможно даже каждую машину с нуля настраиваете - берем DVD/USB с Windows, потом ставим драйверы вручную, потом вручную ставим Office, WinRar, Касперского, прописываем вручную принтеры и так далее вручную по списку целый день, к каждой машине свой персональный и индивидуальный ручной подход.
Он жив еще? Раньше просто летал на 10 мегабитных хабах, даже не коммутаторах, что изменилось?
Roaming profiles.
Изначально оптимизированы чтоб только дельту гонять, они не целиком при каждом logon/logoff туда-сюда гоняются. А так хранятся локально. И на 100 мегабитах вполне работают.
1C в файловом виде.
Это 1С 6.0 или 1С 7.0? Насколько я помню в 8.х там уже массово ушли в понятие веб серверов и прочих тонких клиентов, и никто уже не гоняет на десктопы данные гигабайтами.
Да тысячи ихъ.
Пока ни одной не озвучено, которая обосновала бы прям 10 гигабит и более каждой офисной персоналке. Реально, кто-то мерял трафик отдельно взятого типового офисного десктопа в вакууме? Сколько килобит в среднем потребление? А если интернет отключить? Без интернета трафик до почти в 10килобит в среднем по рабочему дню падает? Нет? Больше?
Бакап рабочих станций. Оно в любом виде - время от времени требует снятия (плюс-минус лапоть в виде самой OS) образа жесткого диска. А это - долго и печально даже на гигабите.
Зачем делать бекап рабочей станции, если его всегда можно развернуть из типового шаблонного образа и рабочий софт автоматом доставить через какой Software Center? А профили же пользователей и так хранятся на сервере со всеми настройками.
Но даже если и делать бекап (типа каждая рабочая станция уникальна в своих настройках) - то инкрементальный бекап делается за несколько минут (передаются только измененные блоки), и даже полный бекап целого терабайта (при сжатии в 2.5 раза) займет ночью 4166 секунд, чуть больше часа. В реальности же типовые офисные десктопы редко когда выходят за 120 гигабайт на софт и папку Мои документы. Хоть каждую ночь их бекапь полностью по нескольку раз, о чем там по ночам грустить и кому?
Вот тут да, этой публике нужны и MacPro стоимостью по 20к евро каждый с терабайтом оперативки с 64 ядрами и прямое подключение на iSCSI стойки. А может и не нужны, и обычного ноутбука c WiFi или даже 3G вполне достаточно :) Но это скорее исключение из правил, так-то этим товарищам можно и отдельное помещение выделить и даже отдельное здание.
Но тянуть каждому бухгалтеру и кадровику по 10 гигабит? Зачем? Там и 100 мегабит всегда хватало, никаких новых задач, условий и требований за последние 20 лет не появилось, скорее наоборот, все улетело в облака и прочие тонкие-веб клиенты.
Единственное что изменилось - это ютуб к обычному вебсерфингу добавился, с FullHD и 4к. А они отлично работают на 100 мегабитах и даже меньше (31 мегабит вполне достаточно, чтоб прокачать за два часа типовой 4k фильм на 20 гигабайт весом).
Ну и видеоконференции в зуме или тимсе, но и они тоже не на 10 гигабит каждому рассчитаны, мягко говоря. Итого - зачем в офисе разворачивать более 1 гигабит - совершенно не понятно. Зачем между этажными или кампусными коммутаторами более 1 гигабита - там вполне понятно зачем (latency), но речь про конечный участок офисный письюк - свич на этаже. Кто-то мерял средний профиль нагрузки, сколько медиана и пик трафика по дню?
RDP на чисто офисных задачах изначально работает даже на модемных линиях в 19000 бод. Нагрузить его можно только если ютубик в 4к через него пропускать.
Документы по 500 мегабайт? Ок, возможно в Excel таблицу столько можно натолкать, но это будет и с SSD работать неприемлемо медленно, там дело не ограничивается задачами открыть-сохранить. Да и зачем эти файлы по сети гонять?
Пока потребность прокладывать каждому офисному компу 2.5 и более гигабит звучит сильно неубедительно.
Но для сети в офисе, мне кажется, найти сварщика дешевле (а для дома гигабита хватит для всех).
Простите, а почему в офисе не хватит гигабита (не в ДЦ, и не между зданиями)? Реально интересно стало, какие такие задачи диктуют большие потребности. 100 офисных человек с веб или веб подобным приложением в сумме какой дают трафик?
И кто данной мат.моделью пользуется? Программист? Или всё-таки сами логисты?
Вопрос был выше изначально в том, что дескать есть такие области, в которых матмодели не нужны и не применяются. Что довольно странно было услышать, т.к. понятие матмодель - это вовсе не обязательно про дифуры. Ибо даже простейшее y = x + С это уже матмодель (хоть и предельно примитивная).
А вот кнопку на формочке нарисовать с полем ввода - это да, скорее всего не матмоделирование, там нет никаких расчетных зависимостей - просто статически заданы мышкой свойства-координаты. И даже если координаты относительны, все равно никаких формул там нет.
Этож простое правило - берем типовую пояснительную записку к курсовой/диплому/диссертации - и там прям учат - вот Рисунок 1.1 , а вот формула (1.12), формула (2.4). Вот все что формулами обозначено - это и есть матмодели, о чем еще тут спорить?
А ещё всё время клиенты приходят, которые просят отгрузить больше всего ценных грузов заданного суммарного веса, ага.
Это была демонстрация второго захода на сдачу незачета?
Оптимизация логистики строится от портфеля заказов (в т.ч. прогнозных), с целью уменьшить (оптимизировать) объем отвлеченных оборотных средств на обеспечение технологических запасов (заделов) - т.е. не хранить на складах слишком долго даже ходовые позиции: они тоже и кредитные проценты потребляют, и место на стеллажах отнимают (за которые тоже аренда или амортизация платится). При том что для обеспечения ритмичности поставок определенные запасы иметь таки придется. Вопрос лишь в минимально достаточном объеме оных. Это даже в ВУЗе девочкам экономисткам на втором курсе рассказывают.
Подготовьтесь лучше, молодой человек, потом приходите искрометить. Пока получается совсем без огонька.
А вот бегать с плакатом с надписью "в логистике матмодели не нужны" - это конечно пять, но в несколько иной специализации училище :)
Ну ок, движок баз данных поймал панику, но мы продолжаем упорно делать вид, что если у нас микросхема памяти глюкнула или dangling pointer превратил всю память в кровавое месиво из мусора, то все нормас, т.к. нужно же дескать кому-то выдавать "сервер сломался, ждите пока починят". Кому же еще это делать, как не полуживому трупу с паникой. Про существование таких штук, как haproxy и прочие балансировщики и сервис мониторы - не, не слышали.
Но я так и так понял, что вы там точно не промышленным программированием занимаетесь. Забавны скорее плюсующие и минусующие, кто бы мог подумать, что это еще и массовое явление сейчас. Даже задумываться начинаешь, кого сейчас берут в IT по собеседованиям.
Ок, контекст держать уже не можем? До чего людей ChatGPT доводит в наше время, страшно подумать :) Ну да ладно, пусть это будут голоса в голове виноваты.
И дальше что? Бросили, заллогировали, далее работаем как ни чем не бывало? Тут вообще-то в abort() выпадать надо.
Кек лол, /** Environment maxdbs reached */ MDBX_DBS_FULL = -30791,
вы тут уже ничего не можете сделать, только рестарт процесса с исправлением конфига - т.е. читай выше про abort()
MDBX_NOTFOUND The specified database doesn't exist in the * environment and \ref MDBX_CREATE was not specified.
Тут тоже аборт и рестарт,
хотя вот тут да MDBX_NOTFOUND No matching key found.
Тут это просто даже не ошибка, а просто статус - нашли-не нашли, это не Exception ни разу, это банальное EXISTS() / NOT EXISTS(), просто Говарду Чу было проще это через код ошибки сделать, зачем-то.
Но забавно было конечно, вы там вообще чем занимаетесь? Точно программированием?
В иронии выше про EAGAIN и EACCESS было просто два реальных сценария.
Первый - это вовсе не ошибка, а просто такой себе очень странный API в виде "ой, что-то пошло не так, попробуй еще раз тож самое повторить, на этот раз точно получится". Если подобное делать на Exceptions - то это лишь делает код нечитабельным, ну и может просадить производительность, хоть и не так чтоб сильно.
А второй класс ошибок это - "а блин, что-то в процессе пошло не так, шеф, все пропало, гипс снимает, клиент уезжает" - никакой дальнейшей обработки реально уже и не нужно предусматривать, нужно просто в scope текущего вызова управляемо освободить все внешние ресурсы, которые в процессе вызова были заимствованы (управляемо освободить менеджером внешних ресурсов, а никак не своим говнокодом), хендлы, аллокации памяти, вот это вот все, как-то оформить вызывающему сообщение о возникшей неожиданной проблеме, и на этом прекратить обработку вызова. Именно так себя ведут к примеру серверы баз данных внутри, и не только они.
И... и все.
Попытка же писать некую прикладную логику на exceptions - это просто закамуфлированное goto программирование, и не более того. В говнокоде допустимо, там не критично, в системах 24/7 (серверы баз данных, ядра ОС и т.п.) за подобный "стиль" - тебя просто не поймут.
Но в индустрии в какой-то момент что-то пошло не так, и уже вроде и 30 лет прошло, но нет, продолжают эти goto exceptions двигать в массы, и никакого Go с Дейкстрой и прочей функциональщиной на них не хватает. Настолько legacy изначально криво спроектированных прикладных сред придавило создание этих масс, что не видят очевидный обман и подмену понятий.
Но зачем по стеку десяток раз передавать наверх код ошибки? Вот чтобы что?
Оно конечно понятно, что типовой Java и не только код stacktrace подразумевает от 70 уровней вложенности вызовов, если меньше - коллеги засмеют, но а вот если подумать? Взять реальный код, и посмотреть, на сколько уровней выше нужно к примеру передавать код ошибок EAGAIN или EACCES?
Но хоть кто-то решил немного подумать и сразу написать вопрос (про как десять раз передавать), вместо того чтобы молча минусы выставлять (как же так, бубубу, мне же говорили, что коды ошибок и goto это очень, очень плохо, а exceptions хорошо и я точно буду молодец, если буду их пытаться использовать, а сейчас, сейчас просто молча заминусую, выскажу тем самым свое мнение, в интернете кто-то не прав!).
Недолго музыка играла - мозг увидел макросы (аааа, макросы же это плохо, говорили мне умные книжки и старшие, более опытные товарищи), они дают НЕОЧЕВИДНЫЕ ошибки.
А то что ни один более менее большой и рабочий проект без макросов не обходится - ой, какая неудобная правда.
Ладно, весело тут с вами, но хоть бы что-то новое и свежее услышать, вместо молчаливо негодующей массы минусующей, впрочем, видимо и не в этот раз.
Ну почему дураки. Когда-то и на паровозах ездили по дорогам, и на телегах, не все же дураки поди были. Просто так тогда было модно или не могли иначе.
Вот и сейчас так делают по привычке, т.к. отказаться нельзя, терабайты legacy кода куда девать?
Но то что в не legacy некоторые даже и сейчас паровой двигатель пытаются прикручивать к телегам, как в примере выше про паники как "прямой аналог исключений", то это вообще странно конечно, как и то, что принуждение к явной проверке возможных ошибок через перечислимые типы от их возможных кодов вызывает прям столько негатива.
Стоило про контрактное программирование так долго рассказывать, чтоб потом это все хрясь об колено неверифицируемыми исключениями (как по сути нелокальными goto переходами), контракты эти.
Да и вообще коды ошибок - это да, явно нечто плохое, нужно срочно в шредер их все, от 404 до ORA-00060 и далее.
Ну не хотите писать статически верифицируемый и чуть более надежный код без goto (зачем-то называя их exceptions) - продолжайте и дальше использовать исключения, кто запрещает? Тем более в случае Modern C++ и выбора иного реально нет.
Хотя конечно забавно - goto/setjmp/longjmp это значит бубу, ни за что нельзя использовать! А exceptions - это найс, это можно, нужно и даже полезно. Хотя они в принципе, по сути - мало чем между собой отличаются (хоть и реализованы чуть иначе, но ведут-то себя абсолютно аналогично, к примеру при выходе из циклов for/while).
А почему так? Почему goto это плохо, а exceptions - это хорошо? В чем между ними разница? Чуть иной и более приятный глазу синтаксис, что еще? Одобрение и неодобрение старших товарищей и прочих авторов явно умных книг?
А почему при goto безусловные нелокальные переходы не одобряются, а при exceptions - наоборот одобряются? Только потому что другим синтаксисом оформлены? Самим это не кажется странным?
Типы-суммы? Какой-то хаскель головного мозга, простите. Достаточно просто возвращать обычный составной тип, struct/class в терминах С++
С введением в практику destructuring assignment и type introspection это все довольно просто и удобно в итоге, к примеру в С++ уже сейчас вполне возможно писать нечто вида:
Проверяется через clang ./test.cpp --std=c++23 && ./a.out
При этом конкретные типы составных кортежей, как и типы для уже error и result задает не пользователь/вызывающий doSomething(), а разработчик doSomething, самому выводить эти составные типы в местах пользования не нужно. Разве не удобно?
При этом компилятор сразу тебя носом тыкает, разве это не прелесть?
./test.cpp:44:11: warning: enumeration value 'ERROR_BAD_Z' not handled in switch [-Wswitch]
./test.cpp:40:1: warning: non-void function does not return a value in all control paths [-Wreturn-type] 40 | };
Сможете такое повторить на "стандартном" С++, чтоб введение нового типа Exception сразу автоматически компилятором подсказало все места, где теперь нужно озаботиться о его обработке?
Про зло в виде switch default говорить не нужно, просто не нужно его использовать
Паника есть паника, она не предусматривает обработки, только посмертный дамп.
А про Python, C#, Java, JS это вообще не аргумент, это все legacy из 90-х с заложенными еще тогда очень модными заблуждениями, а по сути - ошибками проектирования - мало кто понимал в те годы, как на самом деле нужно в надежность и прочие моменты.
Странный аргумент. Чего больше, чего меньше. Видимо пока еще не наступило понимание сути обработки ошибок в реальном коде.
Не надо никуда повторяться. Если исключения продиктованы библиотеками - то от них не уйти, придется использовать, хочешь ты его или нет. Но как правило к обработке ошибок они имеют весьма... отдаленное отношение.
Разработчик библиотеки волен как чего угодно там внутри себе бросать в виде исключений, и никто ему не указ, да и никто их потом реально не проверит. Т.к. старые пользователи библиотеки и вовсе в неведении, что там в новой версии библиотеки им прилетит, сменили номер версии и ладушки, собралось - и в прод полетело.
В случае же с явными перечислениями тебя компилятор носом потыкает - что вот тут и тут и еще вот тут с новой версией библиотеки возможен новый код ошибки, а у тебя ее обработка не предусмотрена, вот и подумай теперь, что теперь тут может быть. В Java пытались с этим бороться, но потом в массе отчаялись -
uncaughtException
наше все.В весьма своеобразную форму goto
Конечно коды возврата. Авторы Go и Rust могут только подтвердить (если С ники не в авторитете).
Коды возврата более менее реально покрыть и статическим анализатором (в части вот тут добавляем еще один код возврата в enum, айда теперь смотреть где у нас там выпали константы из switch (errcode) обработчиков), ну и автотестами с покрытием, в отличие от.
Но если проект унаследован или хочет C++ библиотек - то ничего не попишешь, придется сидеть с exceptions, вымирать как мамонт и далее.
Интересно, а откуда такие интересные цифры вообще? Мне тут в Подмосковье разнорабочие вида подай -принеси выставляют зарплатные ожидания 5000р на руки в день (150к в месяц, читай $1500 на руки, если без выходных). А сантехники и электрики меньше чем за 16000р в день ($3200 в месяц по КЗОТ) не хотят даже просто рассматривать проектные задания. Доставщики тоже меньше чем за 200к рублей работать не собираются.
VCL это проблема? CLX (Kylix), LCL (FPC/Lazarus) - могут и не согласиться.
Да и при желании можно было сделать эмулятор нужных win32 API, вместо отдельного приколхоживания этого вашего FMX.
Реальная же проблема VCL там была скорее в таких штуках, как Comctrl32, где в 100500 версиях с не меньшим количеством багов в каждой сидели зашитые в Windows имплементации TTabControl, TTreeView, TRichEdit и так далее - вот их реально нельзя было никуда портировать, слишком сложно. А так сама по себе VCL она не сильно в своих внешних API на Win32 заточена, не то что MFC, можно было при желании сделать и кроссплатформенный ее вариант.
Впрочем, сейчас, в процессе доживания Windows - это уже малоактуально, HTML5/CSS3 всех победил.
Это, мягко говоря, не так. IDE примерно с 2007-й версии вобрала в себя очень много .NET барахла внутри, в виде всяких Borland.Studio.Vcl.Design.Refactoring.dll и т.д., что никак не могло положительно сказаться на ее стабильности.
И в последних версиях ситуация не улучшилась, что блокирует ее (IDE) портирование на Linux и macOS.
Но сами Win32/Win64 Native приложения никогда не были зависимы от .NET, если только ты сам эту зависимость туда не вкрутишь.
Visual Studio всегда стоил весьма ощутимых денег, это потом уже сделали бесплатные редакции. И сейчас тоже стоит весьма прилично для предприятий, Community Edition это так, на "посмотреть".
Delphi изначально появился как прямой конкурент Visual Basic (а бейсик это первый проект мелкомягких, типа святое), вот с тех пор Delphi и хоронят усиленно. Но, что удивительно, похоронить полностью так и не получилось за три десятка лет.
Против Delphi в свое время была развернута мощная ИПСО компания со стороны маркетологов C#, т.к. они примерно в одной нише. И главный таран - тезис, что дескать за C# платят больше ЗП, и только неудачники пишут Паскале. Вполне сработало.
Сейчас аналогичное ИПСО заряжают в React и Rust, те-же внешние признаки пропаганды и манипуляций.
zero-copy принцип. Когда у тебя вся база данных отображена в локальную память, то ORM строится очень просто - какой объект типа Клиент или Документ целиком, ну или строковые поля из него (это если каждое поле бизнес объекта это отдельный value со своим key) реализуются просто как указатель на нужный адрес в этой самой mmap, т.е. просто ссылаются на участок в файле базы данных. Ничего никуда копировать, пересылать по сети и преобразовывать не нужно, просто сразу ссылаешься на нужный адрес в файле с данными и все. И перебирая запросом сотни тысяч записей - тебе не нужно каждый раз конструировать (аллоцировать) и удалять эти самые бизнес-объекты.
Но когда сервер баз данных живет в отдельном процессе и обменивается с приложением данными через сетевой сокет, то действительно, никакого особого смысла в mmap() нет, ибо натужное копирование данных неизбежно.
Естественно - нужно понимать, что такая mmap() база данных может жить только в режиме read/only, а изменения в базу данных лучше реализовывать через отдельный буфер с изменениями, и уже потом write(), как защита от dangling pointer, reuse after free и подобного, плюс логирование изменений. Об этом (read/only mmap() + write() одновременно) авторы этой чудесной статьи с синтетическими тестами в выводах несколько умалчивают, предпочитая пугать ну очень страшным mmap(), обязательно потеряющими все ваши данные.
Да, mmap() в разумном применении может жить только как read/only, ну а т.к. 99.9% операций с БД и так идут только в режиме чтения, запросы-отчеты и т.д., то применение его вполне оправдано, если у тебя конечно не про конкурентный рандомный перекрестный доступ 100 потоков на 100 особо быстрых NVMe в RAID-0 массиве с инвалидацией TLB (шардирование? партицирование? нет, не слышали!)
А вот read/write mmap() - это скорее сценарии кеширования, когда персистентная консистентность (?) не нужна и данные можно относительно безопасно потерять, пересоздав после рестарта.
а) Полный образ делается не каждый день, примерно раз в неделю? В остальные дни инкрементальный, нет? Расписание-распределение нагрузки по группам машин для отдельных дней (ночей) можно же сделать? Или каждый день полный бекап всем?
б) Речь выше была о том, что гигабитный аплинк нужен на последних метрах (там даже 100 мегабит вполне хватает, т.е. ничего лучше Cat5e реально и не нужно к рабочим столам тянуть), а вот межсвичи соединения - да, да там хоть 100 гигабит можно через SFP модули сделать, если сильно надо. Или у вас все эти сотни машин в один гигабитный порт по витой паре подключены?
в) Сотни уникальных машин со своими уникальными настройками - это конечно мощная организация сети предприятия, но реалии жизни звучат иначе - 99% пользователей обычно работают только с бразуером, Word, Excel и 1С клиент какой, и если их документы и профили хранятся на сервере - то никакого смысла бекапить их персональные Windows нет. А развернуть типовую word+excel+edge/chrome+1С машинку из образа через PXE ребут - элементарно быстрее, чем заниматься ерундой с backup/restore.
Да, отдельные категории пользователей требуют прям уникальных настроек и софта (к примеру CAD/CAM/CAE или разработчики), но таких обычно единицы.
Но что-то мне подсказывает - вы похоже просто не смогли заранее преднастроенные образы со всем нужным базовым софтом (в т.ч. Office) по сети автоматически разворачивать. Возможно даже каждую машину с нуля настраиваете - берем DVD/USB с Windows, потом ставим драйверы вручную, потом вручную ставим Office, WinRar, Касперского, прописываем вручную принтеры и так далее вручную по списку целый день, к каждой машине свой персональный и индивидуальный ручной подход.
Угадал?
Он жив еще? Раньше просто летал на 10 мегабитных хабах, даже не коммутаторах, что изменилось?
Изначально оптимизированы чтоб только дельту гонять, они не целиком при каждом logon/logoff туда-сюда гоняются. А так хранятся локально. И на 100 мегабитах вполне работают.
Это 1С 6.0 или 1С 7.0? Насколько я помню в 8.х там уже массово ушли в понятие веб серверов и прочих тонких клиентов, и никто уже не гоняет на десктопы данные гигабайтами.
Пока ни одной не озвучено, которая обосновала бы прям 10 гигабит и более каждой офисной персоналке. Реально, кто-то мерял трафик отдельно взятого типового офисного десктопа в вакууме? Сколько килобит в среднем потребление? А если интернет отключить? Без интернета трафик до почти в 10килобит в среднем по рабочему дню падает? Нет? Больше?
Зачем делать бекап рабочей станции, если его всегда можно развернуть из типового шаблонного образа и рабочий софт автоматом доставить через какой Software Center? А профили же пользователей и так хранятся на сервере со всеми настройками.
Но даже если и делать бекап (типа каждая рабочая станция уникальна в своих настройках) - то инкрементальный бекап делается за несколько минут (передаются только измененные блоки), и даже полный бекап целого терабайта (при сжатии в 2.5 раза) займет ночью 4166 секунд, чуть больше часа. В реальности же типовые офисные десктопы редко когда выходят за 120 гигабайт на софт и папку Мои документы. Хоть каждую ночь их бекапь полностью по нескольку раз, о чем там по ночам грустить и кому?
Вот тут да, этой публике нужны и MacPro стоимостью по 20к евро каждый с терабайтом оперативки с 64 ядрами и прямое подключение на iSCSI стойки. А может и не нужны, и обычного ноутбука c WiFi или даже 3G вполне достаточно :) Но это скорее исключение из правил, так-то этим товарищам можно и отдельное помещение выделить и даже отдельное здание.
Но тянуть каждому бухгалтеру и кадровику по 10 гигабит? Зачем? Там и 100 мегабит всегда хватало, никаких новых задач, условий и требований за последние 20 лет не появилось, скорее наоборот, все улетело в облака и прочие тонкие-веб клиенты.
Единственное что изменилось - это ютуб к обычному вебсерфингу добавился, с FullHD и 4к. А они отлично работают на 100 мегабитах и даже меньше (31 мегабит вполне достаточно, чтоб прокачать за два часа типовой 4k фильм на 20 гигабайт весом).
Ну и видеоконференции в зуме или тимсе, но и они тоже не на 10 гигабит каждому рассчитаны, мягко говоря. Итого - зачем в офисе разворачивать более 1 гигабит - совершенно не понятно. Зачем между этажными или кампусными коммутаторами более 1 гигабита - там вполне понятно зачем (latency), но речь про конечный участок офисный письюк - свич на этаже. Кто-то мерял средний профиль нагрузки, сколько медиана и пик трафика по дню?
RDP на чисто офисных задачах изначально работает даже на модемных линиях в 19000 бод. Нагрузить его можно только если ютубик в 4к через него пропускать.
Документы по 500 мегабайт? Ок, возможно в Excel таблицу столько можно натолкать, но это будет и с SSD работать неприемлемо медленно, там дело не ограничивается задачами открыть-сохранить. Да и зачем эти файлы по сети гонять?
Пока потребность прокладывать каждому офисному компу 2.5 и более гигабит звучит сильно неубедительно.
Простите, а почему в офисе не хватит гигабита (не в ДЦ, и не между зданиями)? Реально интересно стало, какие такие задачи диктуют большие потребности. 100 офисных человек с веб или веб подобным приложением в сумме какой дают трафик?
Вопрос был выше изначально в том, что дескать есть такие области, в которых матмодели не нужны и не применяются. Что довольно странно было услышать, т.к. понятие матмодель - это вовсе не обязательно про дифуры. Ибо даже простейшее y = x + С это уже матмодель (хоть и предельно примитивная).
А вот кнопку на формочке нарисовать с полем ввода - это да, скорее всего не матмоделирование, там нет никаких расчетных зависимостей - просто статически заданы мышкой свойства-координаты. И даже если координаты относительны, все равно никаких формул там нет.
Этож простое правило - берем типовую пояснительную записку к курсовой/диплому/диссертации - и там прям учат - вот Рисунок 1.1 , а вот формула (1.12), формула (2.4). Вот все что формулами обозначено - это и есть матмодели, о чем еще тут спорить?
Это была демонстрация второго захода на сдачу незачета?
Оптимизация логистики строится от портфеля заказов (в т.ч. прогнозных), с целью уменьшить (оптимизировать) объем отвлеченных оборотных средств на обеспечение технологических запасов (заделов) - т.е. не хранить на складах слишком долго даже ходовые позиции: они тоже и кредитные проценты потребляют, и место на стеллажах отнимают (за которые тоже аренда или амортизация платится). При том что для обеспечения ритмичности поставок определенные запасы иметь таки придется. Вопрос лишь в минимально достаточном объеме оных.
Это даже в ВУЗе девочкам экономисткам на втором курсе рассказывают.
Подготовьтесь лучше, молодой человек, потом приходите искрометить. Пока получается совсем без огонька.
А вот бегать с плакатом с надписью "в логистике матмодели не нужны" - это конечно пять, но в несколько иной специализации училище :)