• ↓
  • ↑
  • ⇑
 
Записи с темой: компьютеры (список заголовков)
00:05 

Don't write what you don't need

Опять программирование. Когда пишешь одну функцию, часто подмывает заодно написать с десяток - и обратное преобразование, и с параметром, и Анси-версию, чтоб уж сразу была библиотечка всего такого на потом. Программисты обожают библиотечки. У каждого программиста своя работа со строками и своё буферизованное чтение в запасах.

Но понемногу я пришёл к выводу, что это вредно.

Даже не тем, что тратится лишнее время. Функции могут однажды пригодиться, и потом, это мелочи, тут нечто гораздо более страшное.

Написав ненужный код, вы его не тестируете. Его не на чем тестировать: в текущем проекте он нигде не используется, ведь если бы он использовался, то это был бы нужный код! И если вы серьёзно хотите, чтобы я поверил, что вы оторвётесь от работы над проектом и напишете юнит-тест для каждой функции, которые вам сейчас толком и не нужны, то тренируйтесь врать. Я - точно не напишу. Мне лень.

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

Возможно, вы узнаете об этом через год, отлаживая загадочные баги в новой программе, использующей старую, давно проверенную библиотеку. Наткнётесь на ошибку в коде функции, удивитесь: "Да как оно вообще работало?" А оно и не работало.
Даже если вы не тестируете новые функции специально, нужные функции сами собой проверяются в ходе работы программы. Пусть это не полноценное тестирование, но большинство путей кода всё-таки оказываются покрыты. Дополнительные же функции не вызывались ни разу, поэтому баг может быть где угодно, даже на самом виду.

Но мало того, когда вы захотите исправить ошибку, вам вдруг станет страшно. Вы подумаете: "А что, если?.."

Что, если эта функция кем-то используется? Ведь неспроста она оказалась в библиотеке. Никто не будет писать функции просто так. Значит, какой-то из проектов вызывает эту функцию и притом работает.
Если вы её сейчас исправите - не сломается ли он?
Да, у вас тут индексация с нуля, а не с единицы, как сказано в комментарии. Вызывая функцию правильно, получить хороший результат невозможно. Значит, кто-то вызывает её неправильно, по ошибке передаёт как раз нужный ошибочный индекс. Если вы функцию почините, тот проект сломается.
Неизвестно, какой. Неизвестно, когда и где. Но что сломается - это почти наверняка.

Нет такого программиста, которому нравилось бы наугад портить свои проекты. И вы откатываете правки и оставляете функцию сломанной, а рядом пишете новую, functionName2(). На этот раз правильную.
И заодно ещё что-нибудь.

@темы: Компьютеры

02:09 

Wakan

Wakan 1.80.8 переводит 1 мегабайт текста за 4 секунды!
Стабильная версия, 1.67, на него же тратила 26.5 минут.

Ещё он понимает Аозора-Руби. Можно вставлять текст в таком: 大人《おとな》びた雰囲気 - формате, и вот эти скобочки превратятся в подпись над 大人. А ещё Вакан может сохранять свой собственный автоматический перевод в виде руби! Это значит, что можно загрузить книжку, нажать "Auto-Translate", и Вакан расставит чтение всем тем словам, которые вы ещё не выучили. И эту книжку потом можно читать в любой из тысяч поддерживающих руби читалок, и слова будут подписаны!

@темы: Компьютеры

22:45 

Консты нереально круты

Да, я понимаю, что тут никто не пишет на дельфи, но раз уж я иногда что-то пишу о ней, то позвольте мне.

В дельфи есть элемент языка, которым все пренебрегают. Очень крутой. Это атрибут входного параметра const.
Вместо:
function IsStringAbrakadabra(s:string): boolean
Получится:
function IsStringAbrakadabra(const s:string): boolean

Зачем?
Строки в Дельфи ведут учёт ссылок. Каждое присваивание увеличивает счётчик на 1. Каждое зануление - уменьшает его. Поэтому любая функция, которая получает строки, преобразуется компилятором в следующую:
UStrLAsg(s); //увеличить счётчик ссылок
try
//сама функция
finally
UStrLClr(s); //уменьшить счётчик ссылок
end;
Два лишних вызова! И фрейм try..finally (это очень дорогая конструкция). Эта обёртка легко может тратить больше времени, чем сама ваша функция! Скомпилите и посмотрите в ассемблер - инлайнить такую дуру тоже пропадает всякая выгода.

На помощь спешит модификатор const! Он говорит компилятору, что вы клянётесь героиней любимого мультика не трогать полученной строки. Тогда можно учёт ссылок не вести, и фрейм try..finally тоже не нужен. Вместо 60 ассемблерных инструкций ваша функция внезапно компилируется в шесть!

Но это ещё не всё.
Мало добавлять const к строковым параметрам. Строки могут передаваться неявно. Функция, которая получает структуру со строкой внутри, тоже требует учёта ссылок и фрейма try..finally. Даже хуже: вместо прямолинейного UStrLAsg будет вызван AddRefRecord, который с помощью некоего подобия рефлекшна изучает вашу структуру и решает, каким полям нужен какой учёт ссылок. И так в каждой функции!
Дельфи не глупая, и если структуре совсем не нужен учёт ссылок, она поймёт это при компиляции, и фрейм не вставит. Но когда хоть одно поле требует учёта, вы получите пенальти в размере полного разбора всей структуры дважды.

Поэтому ставьте const везде, где можно. Ставьте const всему, что передаёте на копирование во всевозможные "SetSomething" или "InitSomething". В крайнем случае он будет просто подсказкой читающему код.

Ещё очень важная информация: отключайте "String format checking" в настройках компиляции. Всегда. Сразу же. Эту опцию следовало бы назвать "замедлить в три раза все операции со строками, для того, чтобы спрятать от вас чудовищные баги в вашем коде".

@темы: Компьютеры

01:54 

HDTV

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

Теперь-то мне стало понятно, зачем мыII-Subs выпускали Бакемоногатри в BD-формате. Это затем, чтоб я его через пару лет на телевизоре посмотрел. От качества перехватывает дыхание. (Ну или в комнате наконец надо проветрить)

Но лучше я расскажу о телевизоре - возможно, кого-то заинтересует.

Оказывается, современные телевизоры умеют подключаться к рутеру по Wi-Fi и проигрывать видео с компьютеров напрямую. Не нужно тянуть никакие провода, кроме обычного электричества. И понимают они почти все популярные форматы и кодеки, включая матрёшку. Только новомодное десятибитное видео на телевизоре пока проигрывается с подтёками.
Можно поставить телевизор, воткнуть в розетку и смотреть по воздуху всё, что лежит у вас на компьютере!
Да если б я знал раньше, я бы из больницы в магазин побежал.

Конечно, на деле всё немного неудобней. Просто расшарить файлы нельзя: нужно ставить программу, сервер медиа-вещания, и объяснять ей, где у вас что лежит. Программа пожует-пожуёт ваши файлы, и они станут доступны на телевизоре.

Хорошие новости: таких программ много. Не обязательно использовать глючную от Samsungвашего корейского производителя телевизора, можно скачать бесплатную открытую и более надёжную Serviio, например (к ней ещё есть плагины). Ну или любую другую.
Хорошие новости: Serviio и некоторые другие программы умеют перекодировать на лету. Если телевизор всё-таки не поддерживает формат файла, так его можно посмотреть.

Плохие новости: безупречных медиа-вещателей нет. Все они глючны, какие больше, какие меньше! Один раз настроить и забыть не выйдет; привыкайте, что с каждым новым сериалом или фильмом придётся минут 15 возиться, перезагружая сервер, скармливая ему файлы, гладя по головке, упрашивая проиндексировать... Ну почему ты не индексируешь? Ну что тебе не нравится? Ах не под тем аккаунтом ты запущен? Ах под администратором тебе не нравится? Запустить твою службу под обычным пользователем? Конечно, запущу, ты только не плачь.
Привыкайте, что телевизор будет файл за файлом отказываться проигрывать, упрямо глядя на вас, как баран, и талдыча: "Ничего не знаю, формат пока не поддерживается". Что перекодированный файл он не сможет скроллить. Вот так! Смотрите от начала и до конца. Что наткнувшись на восьмую серию Нисемоногатари, медиа-сервер сойдёт с ума, и все дальнейшие папки на телевизоре будут одинаково называться "Ore no imouto".

Но зато вы можете посмотреть Бакемоногатари в офигенном разрешении 1080p. Это правда очень красиво.

P.S. Плохие новости: медиа-серверы не очень любят внешние сабы, только встроенные. И у встроенных теряется разметка.
Хорошие новости: скоро Новый год.

P.P.S. Забыл сказать, что на телевизор можно устанавливать приложения для работы с интернетом. Например, можно смотреть ютюб. Только это неудобно.

@темы: Околоанимешное, Компьютеры, Будни

04:41 

Это просто праздник какой-то

if AnsiCompareStr(uppercase(value),uppercase(s))<0 then r:=c else
if AnsiCompareStr(uppercase(value),uppercase(s))>0 then l:=c+1 else
if AnsiCompareStr(uppercase(value),uppercase(s))=0 then r:=c;


Мало того, что "<=" разбито на "<" и "=" с одинаковым исходом, так тут вообще достаточно одной проверки:

if AnsiCompareStr(uppercase(value),uppercase(s))<=0 then r:=c else l:=c+1;

UPD. Я в этот пост буду складывать все такие примеры!
if (doall) then
begin
if not doall then
begin

@темы: Компьютеры

00:49 

Трудно быть богом

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

Всем строкам кода не поможешь, их слишком много, а наши силы ограничены! Закрой глаза на это чудовищное условие для while из 15 строк. Отвернись, когда видишь, как одна и та же проверка снова и снова вызывается в цикле. Занимайся своим делом: переписывай самые медленные места, а остальное оставь как есть. Тут просто эпоха такая.

@темы: Компьютеры

14:54 

Оптимизация

Ну вот, после моих переделок текст, который раньше переводился в Вакане минуту 10 секунд, переводится за 5 секунд.
Хо-хо!

Полюбуйтесь, что для этого пришлось нагородить:
{$IFDEF INTEGER_HELL}
{
Note on integer comparison optimization:
We're not checking if roma_t[i].hiragana has one or two 4-chars.
It's okay. If it has one, then roma_t[i].hiragana[5]==#00, and it wouldn't match
to any 4-char hex combination.
It also won't AV because the memory's dword aligned and hiragana[5] is accessible already.
}
if ((pinteger(ps)^=pinteger(roma_t[i].hiragana_ptr)^)
and (pinteger(integer(ps)+4)^=pinteger(integer(roma_t[i].hiragana_ptr)+4)^))
or ((pinteger(ps)^=pinteger(roma_t[i].katakana_ptr)^)
and (pinteger(integer(ps)+4)^=pinteger(integer(roma_t[i].katakana_ptr)+4)^)) then begin
{$ELSE}
if FcharCmp(ps, roma_t[i].hiragana_ptr, 2)
or FcharCmp(ps, roma_t[i].katakana_ptr, 2) then begin
{$ENDIF}


Это я здесь сравниваю строки из 4-символов (4 байта на хекс-код).

@темы: Компьютеры

16:15 

Капусту в студию

Хотите посмотреть на код, от которого хочется плакать кровавыми слезами? Исходный код Вакана... Я когда-то его выпросил у автора в рассчёте исправить баги.
Только посмотрите на TfUser.DicSearch... TfUser.RenderText... Да на что угодно! Эти простыни непрокомментированного кода! Эти сотни переменных с именами s, i, w, f, buf, ws, wss, wcs, l, ls, dp, tp, jtt, dot, s2, s3! Эти затычки для экспшнов повсюду, где (автор удивлённо пожимает плечами) почему-то случаются эксепшны... Эти названия компонентов Label1-Label123! Это ДНК. Никому не ясно, как в нём работает, что в нём работает, и зачем оно в нём работает.

Функция перебирает строку по символу (на самом деле, по 4 символа):
if i<=9 then se.Add(inttostr(9-j)+'0'+inttostr(i)+'F'+copy(s,1,i*4)) else se.Add(inttostr(9-j)+inttostr(i)+'F'+copy(s,1,i*4));
Если номер символа меньше девяти, то мы добавляем куда-то... какую-то хрень с нулём в середине. Если больше девяти, то без нуля. Что? Почему?! Почему девять? Что это за нули? Что это за F? Куда мы их добавляем? В чём смысл жизни?! Есть ли бог?! Почему мы сравниваем с девятью i, а вычитаем из девяти j?! Все эти вопросы оставлены без ответа.

На всякий случай скажу, что к автору Вакана претензий нет - он не обязан был публиковать код, и когда я просил его открыть, то сказал, чтоб он не стеснялся кривого кода, я разберусь; этим сейчас и занимаюсь. Но того, что код кошмарный, это не меняет.

@темы: Компьютеры

00:01 

Simcracy

Последние пару недель я играю в симулятор капитализма "Simcracy". Давайте все регистрируйтесь и становитесь моими рефералами, вам от этого хуже не будет, а мне дополнительно золото придёт.
Ну ладно, если вы против рефералов - вот чистая регистрация.

Чтобы вам далеко не ходить, тут же расскажу вкратце, как устроена игра, и как в неё играть.

@темы: Будни, Компьютеры

19:37 

Ну вот, теперь у меня очень, очень быстрый интернет. Как я давно о нём мечтал! Но зачем он мне был нужен?..

@темы: Будни, Компьютеры

23:05 

One hyperlink multiple hrefs

The simple thing that HTML really lacks is the ability to set multiple HREF targets for a single link:
<a href="iichan.ru" href="iichan.hk">
Why would you need this?
1. To specify multiple hosts serving the same thing, ensuring that even if one host goes down, it's still accessible (for instance, multiple sources for a pic you're linking to)
2. To aid with domain name changes (linking to both old and new domains)
3. To keep information well-organized (for instance, there's a well-known domain hosting this which is down now, but may be revived later, and you're linking to a google cache copy or a mirror, and still want the main domain to be the logical "target")

How to implement this:
Browsers shall try HREF links one after another, in the order of declaration. They MAY probe them all at once and choose the fastest server, or probe in batches. They MUST though choose one "default" HREF and display it in the interface, and navigate to other HREFs only after asking for permission from the user. They MAY let the user choose the HREF manually when clicking on link.

Correct: The browser randomly chooses second HREF as the default HREF. When the user clicks on link, the server is not accessible, so the browser asks for permission to use next randomly chosen (fifth) HREF. This one is not accessible too. The browser asks for permission to use next randomly chosen (first) HREF, which turns out to be available.
Correct: When the user clicks on link, the browser probes all the available HREFs. Since the default one is not accessible, the browser asks for permission to use the fastest available alternative.
Correct: When rendering the page, the browser probes all the available HREFs and uses the fastest available server as the default HREF.
Correct: When rendering the page, the browser uses it's knowledge of which servers were available and which were down before, to guess the best default HREF without actually probing HREFs.

@темы: Компьютеры

12:26 

Контакты

Реально не хватает какого-нибудь сервиса, чтобы отметить друзей, и они автоматически синхронизировались между всеми соц. сетями. Я уж молчу о дайри, которые деревня, но вконтакте, фейсбук, гугл плюс, контакты телефона, твиттер, скайп! И везде всех ищи заново.

Ещё в каждой соц. сети должны быть "Заметки о друге, видимые только вам", чтоб написать там, допустим:
Девушка такого-то знакомого
Задавал вопросы по Харухи 3 года назад
Познакомились на ДР такого-то друга
А то смотришь на список друзей - кто эти люди?! (Ещё и фамилию некоторые меняют)

@темы: Компьютеры

18:22 

Дыра на дыре!

Компьютерщики, сыграем в игру: вас связали, все ваши компьютеры - в руках злоумышленников. Отвёртка в попе не помогает, вы молчите как партизан и паролей не говорите. Смогут ли вас в целом взломать?

Один-два сайта - это мелочи. Будем считать, злоумышленнику нужно ваше хранилище паролей или его аналог, т.е. способ получения паролей для всех сайтов, где вы зарегистрированы, а также личные секретные данные с каждого из устройств. Допускается заявить, что на каком-то устройстве их нет, но только на одном-двух.
У вас есть домашний ПК, рабочий ПК, ноутбук, планшет, мобильник. Как вы организуете защиту?

Обратите внимание:
- Если получен доступ к почте - вы взломаны! Через неё можно восстановить почти любой пароль.
- Используете куки на компьютере, и к браузеру получен доступ - вы крупно попали! Если не используете, опишите, как вы это устроили. Настройки браузера? Временный диск в памяти для кеша?
- Используете куки и залогинены в почту - вы взломаны полностью!
- Пользуетесь почтовым клиентом? Дважды попали! Пароль к почте можно вытащить из его настроек, а пароли к другим сервисам - из кешированных локально писем.
- Пользуетесь браузером? В вашем кеше много всего интересного! Незащищённый кеш приравнивается к незащищённым личным данным (с той разницей, что кеш разрешается уничтожать, а не шифровать/прятать).
- Ваша почта находится на собственном сервере? Пароль от хостинга равносилен взлому!
- Почта находится на собственном домене? Пароль от регистратора равносилен взлому! Перенаправляем почту на другой ящик и восстанавливаем пароли.
- Мобильник или планшетка в дурных руках? Там были ваши логины почты, и кешированные локально письма - вы взломаны!
- Сим-карту с вашим номером отняли? С помощью СМС на телефон восстанавливают пароль многие сервисы.
- Храните на дропбоксе бэкапы ключей шифрования, паролей, настройки подключения к компьютерам? Враг попал в дропбокс - и всё это взломано! Для простоты считаем, что сам дропбокс без пароля не откроется, хотя были случаи... Дополнительные очки тем, кто воспользуется только локально-шифрующимися сервисами типа SpiderOak/LastPass.

И ещё дополнительные очки тем, кто позаботится о бэкапе, так, чтобы когда злоумышленники сдадутся и отступят, и на прощание из вредности отформатируют вам диски, вы легко могли восстановить свою секретную и важную информацию!

@темы: Компьютеры

12:07 

Барри Келли ушёл из Дельфи, надо же. Язык ему надоел. Интересно почитать его объяснения в комментариях:

Delphi is very procedural. It grew out of Pascal, a language designed in an era when memory was very expensive. So most of its core runtime is based around mutation and destructive updates.

But the longer I've been coding, the greater and greater benefit I see to more functional approaches - which pretty much require garbage collection - and persistent data structures like you see in Clojure.

Этого я не понимаю, слишком плохо разбираюсь в функциональных языках. Они кажутся мне математическими упражнениями без настоящих применений. А с другим согласен:

I see the bureaucracy and busywork involved in creating class hierarchies, how it can fool you into thinking you're doing productive work when you're filling out various idioms and "patterns".

Но идиомы и паттерны - это опыт: "такой подход работает". Там, где их нет, обо всём надо подумать заново. Так что и тут не всё однозначно.

@темы: Компьютеры

18:09 

Metro 2033

Прошёл игру.

Сцены разрушенного города и метро интересны. Могло быть лучше, но всё-таки неплохо. Заброшенные туннели, подземные реки, разрушенная Останкинская башня (на неё можно залезть) - на всё это стоит посмотреть.
Графика ничем не удивляет.
Геймплей тоже, хотя кое-что неплохо (патроны как валюта). Но в целом тупые рельсы с тупыми заданиями.
Сюжет и его воплощение в игре бездарные абсолютно. Смеюсь с американцев, которые в эту чушь играют и говорят "необычный сюжет". Куда пальцем не ткни - какая-нибудь нестыковка, нелепость, условность. Как в Doom3, короче.

Играть не особо интересно, но пройти один раз можно.

@темы: Компьютеры

17:37 

День, когда Wordpress подавился метадатой

Сегодняшняя история програмистская. Кому компьютеры скучны, можете смело пропускать.

Как все знают, у меня есть отдельный блог на boku.ru. Записи туда по большей части копируются отсюда - в виде исключения я пару раз выложил там скучные рассказы, чтобы включить их в архив, но не афишировать.

Блог сделан на Wordpress. Копирование записей устроено так: специальный скрипт генерирует RSS из дневника на Diary, а плагин FeedWordPress забирает RSS и импортирует в Wordpress.

Категории при этом сохраняются, внутренние ссылки мой собственный плагин заменяет на местные, а если пост на дайри изменился - изменяется и пост на boku.ru, так что всё устроено достаточно удобно.

Но есть проблема. (далее)

@темы: Компьютеры

17:42 

Бессмысленное мышление

В комментариях к посту Реймонда Чена зашла речь о занулении памяти. Перед тем, как новой памятью воспользоваться, полезно заполнить её нулями, чтобы твёрдо знать, какие значения будут у переменных. Однако это не всегда нужно. Некоторые функции выделяют уже нулевую память, и повторно занулять её - только тратить время зря.

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

В принципе он прав - с бездумностью надо бороться. Но зачем думать над всем подряд?

Ресурсы мозга ограничены. Нельзя уследить за всем и мыслить по-хардкору круглые сутки напролёт. Попробуйте восемь-то часов проработать как следует - вы к вечеру два и два сложить не сможете! Поэтому надо выбирать, чему уделить внимание, а на что махнуть рукой - полностью сознавая последствия.

Так получается, что лишнее зануление - операция быстрая и безвредная. Поэтому хороший программист не станет специально размышлять, где нужно, а где не нужно занулять память. Он просто занулит её везде, и этим освободит себе время подумать над действительно важными вещами - над теми, где ошибочное решение приведёт к тяжёлым последствиям. А программист, воспитанный таким начальством, обдумает каждое зануление, и от усталости забудет про слона.
Бессмысленное мышление вредно :)

Кроме того, не придётся ломать голову и проверяющему: "Тут память не занулили. Это потому, что было не нужно? Или программист забыл?" Ещё одна экономия внимания.

@темы: Компьютеры

01:39 

Ищу бета-тестеров

Я пишу расширение для Оперы, которое показывает на экспресс-панели дневник, число комментариев, дискуссий и ю-мылов. Выглядит примерно так:



Когда появляются сообщения, выглядит так:



Нужны бета-тестеры, т.е. люди, которые будут проверять сырую версию, натыкаться на ошибки и приставать ко мне до тех пор, пока я их не исправлю. Знание HTML/Javasсript/CSS приветствуется. Ошибок будет много.

@темы: Компьютеры

23:05 

Про CSS

CSS - язык, который был создан для удобства разметки страницы, и за 15 лет разработки превратил простейшие задачи в Ад.

Попробуйте оформить с помощью CSS такие понятные вещи, как:
- элемент произвольного размера по центру страницы, который начинает уменьшаться, когда не влезает целиком
- заверщающий элемент (footer) произвольного размера, который находится после содержимого, а если содержимое меньше экрана - в нижней части экрана

Нет, это можно сделать! Существуют целые сайты, посвящённые "center vertically" или "sticky footer", где приведены магические заклинания, которые для этого нужно произнести. (Правда, footer случайного размера так никто и не умеет делать иначе, чем через css-3).

...Когда-то у Каганова на сайте был конкурс на лучшее слово из трёх букв. Первая, вторая и третья буквы выбирались из списков. Казалось бы, почти все буквы в списках присутствовали, но - то в одной колонке "Х" нет, то в другой "Б" или в третьей "Я". И за какое интересное слово не схватишься - ничего не составляется. Вот и CSS так же.

@темы: Компьютеры

14:28 

Кеширование рисунков в Опере

По умолчанию в Опере очень плохо кешируются рисунки. Изменив пару настроек, можно сильно ускорить работу с ними.

(читать дальше)

Бонус: какими расширениями Оперы я пользуюсь.

@темы: Компьютеры

void

главная