macroevolution: (anomalocaris)
macroevolution ([personal profile] macroevolution) wrote2015-01-11 02:41 pm

Посоветуйте язык программирования

Я всю жизнь программировал только на бейсике, на разных его версиях.  Так получилось. Когда писал кандидатскую, набралось очень много таблиц с данными (это были морфологические признаки морских ежей), и я задолбался обсчитывать их на калькуляторе. Поэтому быстренько освоил бейсик (тогда персональные компьютеры IBM только начали появляться, и к ним прилагался язык GW-Basic). Освоил - и сразу почувствовал себя человеком. С тех пор не переучивался, сейчас пишу все свои программки на VBA в MS Access. То есть в программировании я дилетант, но опытный. Программированием пользуюсь сейчас для имитационного моделирования эволюционных процессов в популяциях. Подумываю об одной новой модели, но понимаю, что на VBA она будет работать невыносимо медленно. Насколько я понимаю, программа, написанная почти на любом другом языке, компилируемом, будет работать в разы быстрее. Вопрос такой: какой из этих языков мне будет быстрее и проще всего освоить? Времени, сил и желания преодолевать трудности и вникать в программистские проблемы - не имеется. Мне бы этот язык просто скачать (можно купить, если не слишком дорого), освоить за пару-тройку дней - и вперед. Т.е. главное, чтобы он был максимально простым в освоении для того, кто знает бейсик, без всяких интеллектуальных "понтов", но работал хотя бы раз в 10 быстрее.

[identity profile] agalakhov.livejournal.com 2015-01-11 04:53 pm (UTC)(link)
На C++ типичная ошибка - это написать пару malloc+free или new+delete. Это нормальная техника в Си, но недопустимо в языках, поддерживающих исключения. Потому что исключение перепрыгивает delete. Следует использовать unique_ptr или shared_ptr. И здесь есть еще отдельная пакость в использовании переменной после delete, потому что с большой вероятностью лежит она все еще в нашем адресном пространстве и даже может все еще иметь прошлое значение. Получается программа, которая ОБЫЧНО работает (ведь с вероятностью 99% переменная все еще имеет верное значение!), но время от времени жестоко глючит. И если программист не имеет представления об инструментах вроде Electric Fence, то из-за такого кода он рискует оказаться в глубокой заднице.

Другая типичная ошибка - забывать слово const и использовать string вместо const string&, а еще злоупотреблять присваиванием строк. Хотя это работает, это работает кошмарно медленно и жрет очень много памяти. В глубоком цикле такая ошибка может привести к высвоповыванию или даже к срабатыванию OOM killer, не говоря уж о том, что из-за этого жалкие несколько килобайт текста могут обрабатываться несколько минут.

На Java и других GC-языках тоже есть типичная ошибка - делать у объектов слишком большое время жизни. Из-за того, что объект не надо удалять, программист слабо следит за тем, в какой именно области видимости объект создан. В результате ссылка на объект может жить в сотни раз дольше, чем реально надо, и память забивается такими вот "вроде бы нужными" объектами, которые GC не удаляет, потому что формально они еще используются. Обычно это бывает, если программист ленится передавать переменную через параметры функции и потому делает переменную членом класса. Такая практика - вообще очень большое зло, но на языках без GC программист очень быстро получает по лбу граблями от деструктора этой переменной и перестает так делать, а на языках с GC можно писать так годами и не понимать, почему это плохо.

[identity profile] guga50.livejournal.com 2015-01-11 06:06 pm (UTC)(link)
>> Обычно это бывает, если программист ленится передавать переменную через параметры функции и потому делает переменную членом класса. Такая практика - вообще очень большое зло, но на языках без GC программист очень быстро получает по лбу граблями от деструктора этой переменной

не понял, если честно. это как?

[identity profile] agalakhov.livejournal.com 2015-01-11 06:45 pm (UTC)(link)
Это когда человек, вместо того, чтобы написать примерно так:

int x = 5;
f1(x);
f2(x);

делает переменную x членом класса и пишет примерно так:

this.x = 5;
f1();
f2();

В результате переменная x уничтожается гораздо позже, чем это реально требуется по логике кода. И обычно, увы, это вовсе не int, а некий довольно тяжелый объект класса.

[identity profile] guga50.livejournal.com 2015-01-11 07:55 pm (UTC)(link)
это я понял. как по жопе граблями получить в смысле по лбу я не понял.

[identity profile] agalakhov.livejournal.com 2015-01-11 09:49 pm (UTC)(link)
А очень просто. Если эта штука - объект, то она наверняка где-то конструируется и где-то уничтожается. Конструируют ее скорее всего не вместе с классом, а позднее - там, где в первый раз присвоили. На C++ это приводит к примерно такому коду:

class Foo {
public:
Foo() : x(nullptr) { }
~Foo() { if (x) delete x; }
void do() {
x = new int(42);
...
}
private:
int* x;
};

Понятно, что это кончается либо утечкой памяти, либо обращением по NULL, смотря как написано. Следующим этапом код переписывают на умные указатели - и получают примерно те же грабли с обращениями по NULL, проще не становится. Тогда до жирафа довольно быстро доходит, что локальные переменные должны быть локальными, и не фиг им делать в классе.

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

[identity profile] alex-197.livejournal.com 2015-01-12 12:32 am (UTC)(link)
за второе - нужно вообще лишать компа на год:)
особенно сладко будет тому, кто потом будет это г... отлаживать:)

[identity profile] agalakhov.livejournal.com 2015-01-12 08:49 am (UTC)(link)
Увы, реальность такова, что такой код присутствует в 99.9% закрытого софта. Как раз когда код пишется по идеологии ООП, чтобы "в разработке могли участвовать все, а не только узкие специалисты", такие штуки обязательно появляются. Особенно когда разработчики обучены исключительно ООП на Java/C# и никогда не проходили хардкорных курсов вроде построения и доказательства алгоритмов. Я встречал довольно много вполне успешных и развивающихся фирм, в которых подобная разработка считается нормой - ведь продукт выпускается, работает и хорошо продается.

[identity profile] psilogic.livejournal.com 2015-01-11 07:12 pm (UTC)(link)
отвечу за вашего собеседника

1. пусть есть временная переменная tmp, ей что-то присвоено

2. ссылку на эту переменную отдают какому-то долгоживущему объекту obj, прикапывают в каком-нибудь его поле obj.member

3. мы выходим из области видимости для tmp
на этом шаге в языке без GC tmp уничтожается
на этом шаге в языке с GC tmp остается т.к. на него есть ссылка из obj

4. мы пытаемся использовать obj.member
на этом шаге в языке без GC возможен краш
на этом шаге в языке с GC краша не будет, но будет обращение к вроде как валидному объекту, который давно не нужен и, скорее всего, никак не соответствует происходящему
Edited 2015-01-11 19:13 (UTC)

[identity profile] guga50.livejournal.com 2015-01-11 08:01 pm (UTC)(link)
как же можно такой дикий огород намутить?
если тэмп часть объекта такого не будет пока он живёт.

[identity profile] psilogic.livejournal.com 2015-01-11 08:20 pm (UTC)(link)
часть объекта не tmp, а member


struct HEX
{
   KakoiToTip *member;
};

void do_something(HEX *hex)
{
   KakoiToTip tmp;
   hex->member= &tmp;
   ...
   //forget clear hex->member
}

void do_something2(HEX *hex)
{
   if (hex->member)
      printf("%s", hex->member->name());
}

void main()
{
   HEX hex;
   do_something(&hex);
   do_something2(&hex); //ups!
}

[identity profile] guga50.livejournal.com 2015-01-11 08:28 pm (UTC)(link)
ну пральна. тмп то уничтожилось. хэкс продолжает показывать в никуда.

не, ну знаете... с дури можно х сломать...

[identity profile] psilogic.livejournal.com 2015-01-11 08:39 pm (UTC)(link)
ну во а если есть GC, то tmp не уничтожилось и программер может долго не осознавать, что то, что он делает - дурь :)

[identity profile] alex-197.livejournal.com 2015-01-12 12:37 am (UTC)(link)
а с какой стати оно уничтожилось? лучший способь получить по башке - предположить, что оно будет работать

[identity profile] guga50.livejournal.com 2015-01-12 04:38 am (UTC)(link)
с такой что функция завершилась. всё что осталось от неё - это уже невсчёт.

[identity profile] alex-197.livejournal.com 2015-01-12 04:40 am (UTC)(link)
лучший способ получить по башке - предположить, что оно будет работать - удачи в ебле с отладкой. Это вы еще не встречали прикол, когда работособность программы зависит от CPU - Intel - работает, AMD - в зависимости от ветра.

[identity profile] alex-197.livejournal.com 2015-01-12 04:45 am (UTC)(link)
лучший способ получить по башке - предположить, что оно будет работать - удачи в ебле с отладкой. Это вы еще не встречали прикол, когда работособность программы зависит от CPU - Intel - работает, AMD - в зависимости от ветра.

В качестве прикола - почему автору никто Clipper не посоветовал?:)

[identity profile] guga50.livejournal.com 2015-01-12 07:49 am (UTC)(link)
тоже самое когда после компиляции с жёсткой оптимизацией по скорости программа падает, а с О2 идёт без проблем.
ничего удивительного. это проблемы с компилятором.