Потому что осьдва стоила раз в пять дороже, банальная терминалка сверху и tcp/ip — хотела еще денег больше, чем вся уиндоусь (это я про Connect), а SDK стоил… вообще что-то неадекватное стоил.
Плюс требования по железу были сильно выше.
Причина такого очевидна — межделмаш хотел рубить бабок с корпоратов, поэтому вкладывался не в подложку, а в свой Works и прикупленный по случаю Lotus. А чтобы окучить клиентов, уже севших за окошки — микрософт по контракту им пилила Win-OS/2.
Жизнь была прекрасна, ожидания чрезмерны…
А рыночек порешал в пользу более дешевых и более удобных предложений.
Кстати, милый штришок. Именно в те времена производительность погромистов в ибеме пытались оценивать по числу наколоченных ими строк кода :-)
Ну запускаться она на этом запускалась, да. Но не работала.
Хехе. Я на такой конфигурации не то что программировать умудрялся, а даже эксель в ворд вставлял через OLE. Тюнить надо было! Главным элементом — убрать воллпапир и заменить его solid color :-)
С процом конечно хотелось бы 486DX25 — он был пошустрее… Ну и с 8М ОЗУ наступало просветление.
А вот NT или OS/2 такой же комфорт давали уже только на Pentium-75, 16М ОЗУ, при тогдашних ценах это было «ой».
про дискету, потому что у него есть архитектурные основания
причем — вовсе не микрософтовские :-)
В те бородатые времена — форматировали дискеты встроенной 16битной подпрограммой BIOS, которая задержки между командами головкам привода вычисляла через пустые циклы. Вот и прерви такую :-)
Конечно, были и альтернативные «прошивки» типа 800.com, pu1700.com, которые «расширяли» эту «подпрограмму». Отсюда и «однозадачное» форматирование дискет.
А еще был целый класс досовских программ форматирования дискет, типа легендарной fdformat, которая умела возвращать к жизни сбойные дискеты.
Поэтому микрософт поступила именно так — да пусть 16битный старый код этим занимается, мы его аккуратненько виртуализуем… а вот в OS/2 или NT — форматирование дискет осуществлялось собственным кодом, работавшим по прерываниям, а не по задержкам. Поэтому никаких вам нестандартных форматов, да и требования к состоянию дискет были куда выше…
Мне для своего кода надо было, а штатный эмулятор бесит неимоверно. Можно было конечно использовать реальный телефон — но я как раз с графикой развлекался, на мелком экранчике как-то не очень.
Так что opengapps существует — и хорошо, если понадобится — попробую :-)
Все так же запутанно и требует большого бубна. Первый запуск все так же крышесносящ — о том как называются два демона на вики не пишут, но прилагают картинку о том что они существуют :-)
Правда появились отдельные «выжившие», которые скриптуют установку тех же opengapps… но не только лишь всякий может долйти до этого шага.
Я лично знаю героя, который не только в одно лицо выдал «продукт года» в транс-наци-анальной конторе, но и при этом уволил парочку директоров (включая собственного начальника), пытавшихся успех перехватить. Несмотря на попытку в последний момент слить героя его собственной крышей в виде Senior VP, хехе.
И да, герой добровольно покинул транс-наци-анальную лавку после триумфа, мотивировав под пиво так: «Ну, если они сами хотят в интриги вместо результата, как я могу им помочь?»
:-)
Уже год героя зовут обратно в эту лавку. Нужны новые прорывы, а «по скраму» хорошо только с тикетами и KPI поверх них… Герой смеется, и говорит что как пропозал дотикает до x3 от его прошлой salary с бонусами, он подумает :-) До x2 уже дотикало, шансы есть…
Я бы даже добавил, что в местах где «непонятно, в чем заключается работа» получение однозначно положительного результата действительно можно сравнить с геройством.
Я таких живьем видел.
«Пока мы все нарезали круги вокруг кофеварки и славили гендира, этот отморозок в свитере с оленями что-то там реально сделал. Подвергнем же его остракизму!»
из этих крутых лавок не выходила бы всякая говнотека ± среднего индусского уровня
Это вещи слабосвязанные.
Можно любого «крутяка» укатать, устрой ему кранчей на пару месяцев нон-стоп, «патамушта-бызнесь-хочет-вчера». И как инженер ни крут, а сидит и херачит по тикетам, с дейли митингами и ретроспективами. И каждый день оправдывается — почему не успевает.
И выбора у него нет — говнокод или говнокод :-)
А бывает еще круче. Бывает что саентисты по скраму должны выдавать прорывные инвеншены по тикетам (сам такое видел, офигел в край и быстро убег). Результат? Зачем?
Визуально хоть пытается выглядеть не ужас-ужасом, не?
Зато сколько тут копирований и вызовов небесплатного и недешевого аллокатора… вроде бы (вроде бы!) мы не должны за это все радостно платить, а по факту — ух!!!
Вот так уже несколько лучше. std::to_string() все еще делает много лишнего, но это уже лучше. Теперь — задумаемся, а в правильном ли порядке идут вычисления, и не добавить ли скобок? А то присваивания идут справа налево…
Не, в Java/C# это решали умные люди, у них компилятор автоматом преобразует строчные плюсики в
str = (new StringBuilder(N)).append(...).append(...).toString();
и это все еще хуже, чем ветхозаветный sprintf(), но значительно лучше чем постоянные аллокации / копирования. Почти полный эквивалент той травы что чуть выше в скобках. Ну и плюс свои накладные расходы несет, на аллокацию объекта и массива у него внутри.
Пайтонисты и дотнетчики пошли еще дальше — и у них в строчках прямо переменные указывать можно, типа такого
str += $" {i} {j}:";
и некоторые даже этим злоупотреблять научились, указывая вместо переменных многоэтажные конструкции :-)
Вы спросите, так а чем не нравится путь комитета? Тем более stringstream завезли, стало чуть проще…
Давайте вспомним, как часто и зачем нам надо в коде много форматирования? Вот именно, логи! И что, нам теперь по три строчки каждый раз вставлять, и плодить локальных переменных? Не, конечно можно… но лениво.
Неужели все так плохо?
По счастью, нет. В новейшем стандарте завезли std::format! Господь услышал наши молитвы!
Что делать олдфагам тем, у кого легаси? Нууу, в принципе, можно вот как-то так вывернуться —
#include <memory>
#include <string>
#include <stdexcept>
template<typename ... Args>
std::string string_format( const std::string& format, Args ... args )
{
size_t size = snprintf( nullptr, 0, format.c_str(), args ... ) + 1; // Extra space for '\0'
if( size <= 0 ){ throw std::runtime_error( "Error during formatting." ); }
std::unique_ptr<char[]> buf( new char[ size ] );
snprintf( buf.get(), size, format.c_str(), args ... );
return std::string( buf.get(), buf.get() + size - 1 ); // We don't want the '\0' inside
}
но тут наш sprintf все еще с нами и у него все те же проблемы несоответствия фактического списка параметров и декларированных спецификаций форматирования. Да и кроме примитивных типов есть еще и структуры-классы, они снова идут мимо.
Меня бы устроило, если бы этот «эмулятор» работал по типу Wine — имитируя не телефон, а именно андроид как окружение. Примерно как anbox сейчас делает, но чтобы не выполнять инструкцию из 18 пунктов для установки opengapps :-)
А уж ели в каком-то разумном виде заработает хотя бы часть гуглосервисов — то это будет вполне себе победа, запустил полдесятка андроидо-приложений, каждое в своем окошке одновременно — лепота…
И подозреваю, куда-то в эту сторону мы в итоге и придем.
Вот насчет «не нужно» — споры как раз и идут. Оно наверное все еще полезно, уметь в структуры данных, обычно это хэштаблицы-списки-кольца-деревья, графы уже сильно реже. Но это неточно :-)
Шутка в том, что я еще помню, как задача транспонирования матрицы занимала несколько суток, занимая при этом весь объем — нет, не тогдашней оперативы, а тогдашнего жесткого диска! и я тогда самолично изобретал — как это в почти 3 мегабайта кэша воткнуть работу с матрицей, которая сводится к треугольному виду методом Гаусса. Lookahead и вот это вот все, чтобы диск не трещал так жалобно своими головами.
Причем даже не «повысить перформанс», а потому что «в лоб» предыдущий диск за выходные сгорел. :-)
Уже в двухтысячных — такие матрицы просто помещались в оперативе, их сводили стандартным матпакетом или на пайтоне, и перформанс вообще никого не волновал.
Теперь сотни мегабайт воспринимаются как «лабораторная работа», тут вообще нечего делать. Что тут оптимизировать?..
Соответственно в мейнстриме и «тюнинг» структур данных и алгоритмов вокруг них — нет, не исчез! но сильно изменился :-)
(присаживается поудобнее в кресло-качалку, накрывается клетчатым пледом, наливает в кружку что-то горячее с молоком, отхлебывает)
А ведь я застал-с те времена, когда знание алгоритмов всяческих там сортировок, деревьев и прочих списков было обязательным, да-с…
Лет двадцать пять назад, когда программы были маленькие, а 640 килобайт еще многим хватало, я непосредственно и всегда использовал эти самые алгоритмы и структуры данных. В этом было целое искусство — как бы так написать, чтобы втиснуться в требования задачи…
Вся работа начиналась вот примерно с таких креативов
На этом полет креатива не останавливался — появлялись mutex для параллельной работы, списки менялись на деревья и прочая, а для работы со структурами данных изобретался паттерн visitor в стиле «лямбд пока не завезли»:
Это сейчас за такое я джунов луплю по рукам линейкой не одобряю, а тогда… тогда даже строки были квадратно-колесными, и в приличном проекте их было полдюжины разных. Роднило их только одно — все они умели в char*, а наиболее грамотные — еще и в const char*.
Это сейчас за попытку изобрести свой аналог std::string ваш лид спросит — в своем ли вы уме, а 25 лет назад он бы поинтересовался, как это удалось сделать copy-on-write и при этом работающую форму
str[n] = 'a';
и как при этом избежать O(n^2) в случае классики
result = a + "\\" + b +"\\" + c + "." + d;
Следом обычно шел кастомный аллокатор, современный tcmalloc() тогда тоже еще не завозили, и героическая борьба с memory leaks…
И вот когда я в очередной раз читаю про штурм вершин изучение алгоритмов для собеса, я вспоминаю эти уже далекие времена.
Вот честно сказать, если бы я в то время ушел «на руко-водящую работу», больше бы не программировал (ну кроме макросов в экселе), и мне бы вдруг! надо было бы отсобесседовать молодежь — я бы вспомнил именно про алгоритмы :-)
Ну, просто потому, что на «а вот тут у нас в шаблоне дуал байндинг», или «а тут я сделал автомаппинг дэтэошек на доменную модельку через аннотации», «а тут у нас стандартный рипазиторий», «а спрингбутовый тест я сделал через рест темплейт», я бы смог только выдавить «че?...»
А вот когда я грозно бы спросил про о-большое в случае реализации ArrayList на вставку в середине — я бы и произвел нужное впечатление на молодняк, и хотя бы смог бы понять их ответ :-)
Яблочные вот анонсировали. Андроидные вполне в anbox можно, тем кому opengapps хватает.
Глядишь, и мелкомягкие тоже через пару лет очухаются, и мы еще не раз потом услышим, что именно в микрософт придумали запускать на десктопе мобильные приложения, еще в 2012 году :-)
Плюс требования по железу были сильно выше.
Причина такого очевидна — межделмаш хотел рубить бабок с корпоратов, поэтому вкладывался не в подложку, а в свой Works и прикупленный по случаю Lotus. А чтобы окучить клиентов, уже севших за окошки — микрософт по контракту им пилила Win-OS/2.
Жизнь была прекрасна, ожидания чрезмерны…
А рыночек порешал в пользу более дешевых и более удобных предложений.
Кстати, милый штришок. Именно в те времена производительность погромистов в ибеме пытались оценивать по числу наколоченных ими строк кода :-)
С процом конечно хотелось бы 486DX25 — он был пошустрее… Ну и с 8М ОЗУ наступало просветление.
А вот NT или OS/2 такой же комфорт давали уже только на Pentium-75, 16М ОЗУ, при тогдашних ценах это было «ой».
Ну и маленький штришок — hpfs прекрасно поддерживалась WinNT.
Расплевались с межделмашем мелкомягкие несколько позже… и сугубо по дури самих межделмашевцев.
В те бородатые времена — форматировали дискеты встроенной 16битной подпрограммой BIOS, которая задержки между командами головкам привода вычисляла через пустые циклы. Вот и прерви такую :-)
Конечно, были и альтернативные «прошивки» типа 800.com, pu1700.com, которые «расширяли» эту «подпрограмму». Отсюда и «однозадачное» форматирование дискет.
А еще был целый класс досовских программ форматирования дискет, типа легендарной fdformat, которая умела возвращать к жизни сбойные дискеты.
Поэтому микрософт поступила именно так — да пусть 16битный старый код этим занимается, мы его аккуратненько виртуализуем… а вот в OS/2 или NT — форматирование дискет осуществлялось собственным кодом, работавшим по прерываниям, а не по задержкам. Поэтому никаких вам нестандартных форматов, да и требования к состоянию дискет были куда выше…
Мне для своего кода надо было, а штатный эмулятор бесит неимоверно. Можно было конечно использовать реальный телефон — но я как раз с графикой развлекался, на мелком экранчике как-то не очень.
Так что opengapps существует — и хорошо, если понадобится — попробую :-)
Правда появились отдельные «выжившие», которые скриптуют установку тех же opengapps… но не только лишь всякий может долйти до этого шага.
Если гм гм «Грязный Гарри» вместе бухают с «Лаки Люком», а с Люком терки, то странно рассчитывать что Гарри придет на помощь :-)
Я лично знаю героя, который не только в одно лицо выдал «продукт года» в транс-наци-анальной конторе, но и при этом уволил парочку директоров (включая собственного начальника), пытавшихся успех перехватить. Несмотря на попытку в последний момент слить героя его собственной крышей в виде Senior VP, хехе.
И да, герой добровольно покинул транс-наци-анальную лавку после триумфа, мотивировав под пиво так: «Ну, если они сами хотят в интриги вместо результата, как я могу им помочь?»
:-)
Уже год героя зовут обратно в эту лавку. Нужны новые прорывы, а «по скраму» хорошо только с тикетами и KPI поверх них… Герой смеется, и говорит что как пропозал дотикает до x3 от его прошлой salary с бонусами, он подумает :-) До x2 уже дотикало, шансы есть…
Я таких живьем видел.
«Пока мы все нарезали круги вокруг кофеварки и славили гендира, этот отморозок в свитере с оленями что-то там реально сделал. Подвергнем же его остракизму!»
:-)
Можно любого «крутяка» укатать, устрой ему кранчей на пару месяцев нон-стоп, «патамушта-бызнесь-хочет-вчера». И как инженер ни крут, а сидит и херачит по тикетам, с дейли митингами и ретроспективами. И каждый день оправдывается — почему не успевает.
И выбора у него нет — говнокод или говнокод :-)
А бывает еще круче. Бывает что саентисты по скраму должны выдавать прорывные инвеншены по тикетам (сам такое видел
, офигел в край и быстро убег). Результат? Зачем?Зато сколько тут копирований и вызовов небесплатного и недешевого аллокатора… вроде бы (вроде бы!) мы не должны за это все радостно платить, а по факту — ух!!!
Давайте попробуем удешевить.
Вот так уже несколько лучше. std::to_string() все еще делает много лишнего, но это уже лучше. Теперь — задумаемся, а в правильном ли порядке идут вычисления, и не добавить ли скобок? А то присваивания идут справа налево…
Ну и кто в здравом уме будет так писать?
Не, в Java/C#
это решали умные люди, у нихкомпилятор автоматом преобразует строчные плюсики в и это все еще хуже, чем ветхозаветный sprintf(), но значительно лучше чем постоянные аллокации / копирования. Почти полный эквивалент той травы что чуть выше в скобках. Ну и плюс свои накладные расходы несет, на аллокацию объекта и массива у него внутри.Пайтонисты и дотнетчики пошли еще дальше — и у них в строчках прямо переменные указывать можно, типа такого
и некоторые даже этим злоупотреблять научились, указывая вместо переменных многоэтажные конструкции :-)
Вы спросите, так а чем не нравится путь комитета? Тем более stringstream завезли, стало чуть проще…
Вполне же?
Давайте вспомним, как часто и зачем нам надо в коде много форматирования? Вот именно, логи! И что, нам теперь по три строчки каждый раз вставлять, и плодить локальных переменных? Не, конечно можно… но лениво.
Неужели все так плохо?
По счастью, нет. В новейшем стандарте завезли std::format!
Господь услышал наши молитвы!Что делать
олдфагамтем, у кого легаси? Нууу, в принципе, можно вот как-то так вывернуться — но тут наш sprintf все еще с нами и у него все те же проблемы несоответствия фактического списка параметров и декларированных спецификаций форматирования. Да и кроме примитивных типов есть еще и структуры-классы, они снова идут мимо.И зачем я это все вспомнил -\_(o^o)_/-
А уж ели в каком-то разумном виде заработает хотя бы часть гуглосервисов — то это будет вполне себе победа, запустил полдесятка андроидо-приложений, каждое в своем окошке одновременно — лепота…
И подозреваю, куда-то в эту сторону мы в итоге и придем.
Шутка в том, что я еще помню, как задача транспонирования матрицы занимала несколько суток, занимая при этом весь объем — нет, не тогдашней оперативы, а тогдашнего жесткого диска! и я тогда самолично изобретал — как это в почти 3 мегабайта кэша воткнуть работу с матрицей, которая сводится к треугольному виду методом Гаусса. Lookahead и вот это вот все, чтобы диск не трещал так жалобно своими головами.
Причем даже не «повысить перформанс», а потому что «в лоб» предыдущий диск за выходные сгорел. :-)
Уже в двухтысячных — такие матрицы просто помещались в оперативе, их сводили стандартным матпакетом или на пайтоне, и перформанс вообще никого не волновал.
Теперь сотни мегабайт воспринимаются как «лабораторная работа», тут вообще нечего делать. Что тут оптимизировать?..
Соответственно в мейнстриме и «тюнинг» структур данных и алгоритмов вокруг них — нет, не исчез! но сильно изменился :-)
за что хочется немедленно убить на месте, съесть и закопать. Но с другой стороны, что предлагает нам комитет?
это как бы не сильно лучше :-)
Да, второй вариант категорически неправильный. Но что с правильным?
И так — во всех местах, где надо форматный вывод? Да ну нафиг, что там с неверным вариантом, может уже не так плох? :-)
(присаживается поудобнее в кресло-качалку, накрывается клетчатым пледом, наливает в кружку что-то горячее с молоком, отхлебывает)
А ведь я застал-с те времена, когда знание алгоритмов всяческих там сортировок, деревьев и прочих списков было обязательным, да-с…
Лет двадцать пять назад, когда программы были маленькие, а 640 килобайт еще многим хватало, я непосредственно и всегда использовал эти самые алгоритмы и структуры данных. В этом было целое искусство — как бы так написать, чтобы втиснуться в требования задачи…
Вся работа начиналась вот примерно с таких креативов
в тяжелых случаях вытаскивался препроцессор
На этом полет креатива не останавливался — появлялись mutex для параллельной работы, списки менялись на деревья и прочая, а для работы со структурами данных изобретался паттерн visitor в стиле «лямбд пока не завезли»:
Это сейчас за такое я джунов
луплю по рукам линейкойне одобряю, а тогда… тогда даже строки были квадратно-колесными, и в приличном проекте их было полдюжины разных. Роднило их только одно — все они умели в char*, а наиболее грамотные — еще и в const char*.Это сейчас за попытку изобрести свой аналог std::string ваш лид спросит — в своем ли вы уме, а 25 лет назад он бы поинтересовался, как это удалось сделать copy-on-write и при этом работающую форму и как при этом избежать O(n^2) в случае классики
Следом обычно шел кастомный аллокатор, современный tcmalloc() тогда тоже еще не завозили, и героическая борьба с memory leaks…
И вот когда я в очередной раз читаю про
штурм вершинизучение алгоритмов для собеса, я вспоминаю эти уже далекие времена.Вот честно сказать, если бы я в то время ушел «на руко-водящую работу», больше бы не программировал (ну кроме макросов в экселе), и мне бы вдруг! надо было бы отсобесседовать молодежь — я бы вспомнил именно про алгоритмы :-)
Ну, просто потому, что на «а вот тут у нас в шаблоне дуал байндинг», или «а тут я сделал автомаппинг дэтэошек на доменную модельку через аннотации», «а тут у нас стандартный рипазиторий», «а спрингбутовый тест я сделал через рест темплейт», я бы смог только выдавить «че?...»
А вот когда я грозно бы спросил про о-большое в случае реализации ArrayList на вставку в середине — я бы и произвел нужное впечатление на молодняк, и хотя бы смог бы понять их ответ :-)
Глядишь, и мелкомягкие тоже через пару лет очухаются, и мы еще не раз потом услышим, что именно в микрософт придумали запускать на десктопе мобильные приложения, еще в 2012 году :-)