KS>Это да... вот у нас в конторе есть один специфический тип отчета по неким данным... Спустя пару лет после его >написания, выяснилось, что неправильно был реализован математический алгоритм, считающий ряд стандартных статистик. >Но все заказчики давно привыкли к тем цифрам, и правильный вариант их категорически не устроил... Так и продаем до
в любой большой системе есть некоторое количество багов, иногда получается так что некоторые из них "взаимоуничтожают" друг друга и все работает правильно.
Здравствуйте, Awaken, Вы писали:
KS>Это да... вот у нас в конторе есть один специфический тип отчета по неким данным... Спустя пару лет после его >написания, выяснилось, что неправильно был реализован математический алгоритм, считающий ряд стандартных статистик. >Но все заказчики давно привыкли к тем цифрам, и правильный вариант их категорически не устроил... Так и продаем до
A>в любой большой системе есть некоторое количество багов, иногда получается так что некоторые из них "взаимоуничтожают" друг друга и все работает правильно.
Довольно распростронённое убеждение. Но не стоит забывать, что содержание системы не равно сумме содержаний компонентов. И учитывая это замечание, можно найти несколько типичных баговых ситуаций (и пути их решения):
где n — чётное число.
Эта самая благоприятная ситуация для программиста. Особый случай ситуации — когда сумма положительных багов равна сумме отрицательных. В этом случае баги никиа не влияют на работу программы. Задача программиста в этом случае — стараться делать одинаковые по проявлению баги и следить, чтобы сумма багов была чётным числом.
где n — любое целое число.
Это тоже очень распространённая ситуация. В этом случае — задача программиста — свести хотя-бы один баг к нулю или бесконечно малому значению.
2. Проявление_багов = баг1^баг2;
Это уже более серьёзная ситуация. Есть два решения такой проблемы.
1. Попытаться свести баг1 к нулю. Задача, как правило, невыполнимая, т.к. почти всегда баг1 не поддаётся локализации.
2. Прологарифмировать Проявление_багов. В этом случае пропадает экспоненциальная зависимость от 2-го бага.
Как правило, в реальности встречаются все три ситуации в перемешку. Задача программиста — свести Проявление_багов к минимуму, использую вышеприведённые примеры.
S>Господа программисты.
S>А почему бы нам не сделать конкурс на самый глючный баг? Ведь чем сложнее и трудноуловимее баг, тем профессиональнее считается программист. Вот примеры:
А еще очень долго можно искать вот такую простую ошибку:
S>Но, с другой стороны, написать кусок кода длиной в ~20 строк, содержащий заведомый баг, и при этом неочевидный — это тоже своего рода искусство.
Есть вообще высший пилотаж: кусок кода длинной ~20 строк, при взляде на который понимаешь, что он явно содержит ошибки... на самом деле ошибок не содержащий. Во как!
Здравствуйте, scaramush, Вы писали:
S>Есть вообще высший пилотаж: кусок кода длинной ~20 строк, при взляде на который понимаешь, что он явно содержит ошибки... на самом деле ошибок не содержащий. Во как!
Да ну! Мне студенты постоянно такой код сдают.
... << RSDN@Home 1.0 beta 7a >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Вообще конечно да. В жизни хороший баг распределен как минимум по трем исходникам, достаточно далеко разнесенным по структуре проекта, и каждый в отдельности никаких подозрений не вызывает.
Однажды на ежемесячном собрании я получил премию от компании за нахождение фатальной ошибки перезаписи памяти, которая была ошибкой "седьмого уровня", а именно, указатель, превращенный в мусор перезаписью поверх него другого валидного (но неверного) указателя, приводил к разрушению другого указателя, что приводило к неверному вычислению индекса, что приводило ... — и так разрушения до седьмого уровня, что в конце-концов вызывало фатальную ошибку доступа. Т.к. для данной системы не было возможности сгенерировать финальную версию с отладочной информацией, я провел чистых 17 часов, пошагово исполняя инструкции, отслеживая обратные связи, и последовательно сужая зону поиска. У меня было 2 терминала — на одном исполнялась отладочная, а на другом финальная версии программы. После того, как я нашел ошибку, по отладочной версии было очевидно, что происходило не так, но в неоптимизированном коде описанное выше явление скрывало истинную ошибку.
Здравствуйте, Lonely Dog, Вы писали:
LD>Здравствуйте, ArtDenis, Вы писали:
LD>---покусано----
LD>Предлагаю придумать новую науку: Баговедение. Во время изучения этой науки студенты будут обучаться исскуству планирования багов, и пр.
LD>PS: народ, предлагайте новые направления этой науки...
Только не Баговедение, а БагоЛогия.
Выписка из статьи газеты "Практическая БагоЛогия":
Российская Академия Багологии дистанционно присвоила звание Профессора багологических наук Биллу Калиткину...
S>Господа программисты.
S>А почему бы нам не сделать конкурс на самый глючный баг? Ведь чем сложнее и трудноуловимее баг, тем профессиональнее считается программист. Вот примеры:
Вот вы говорите, баги... А у нас в институте народ, натурально, сдает вот такое:
TSPRab = class(TFRSP)
public
function MXTheor: TReal; virtual; abstract;
function DXTheor: TReal; virtual; abstract; // теор. DX
// к-т асимметрииfunction Assym: TReal; virtual; abstract;
// к-т эксцессаfunction Excess: TReal; virtual; abstract;
procedure Model(ALength: Integer; A, B: TReal); reintroduce;
end;
{-----------}implementation
var
Y,X: TArrayX;
a, b, mu, mu3, mu4, gamma, alpha, betta, sigma: Real;
i:word; //счетчикfunction SPRab.MXTheor;
begin
MXTheor:=(a+b)/2;
end;
function SPRab.Assym;
begin
KATheor:=0;
end;
{-----------}Function SPSimp.Model;
begin
For i:=1 to N do
if Random=0 then FArrayX[i]:=a else
if (Random>0) and (Random<0.5) then FArrayX[i]:=(b-a)*sqrt(X[i]/2)+a else
if (Random>=0,5) and (Random<1) then
FArrayX[i]:=b*sqrt((1-X[i])/2)*(b-a) else
if Random=1 then FArrayX[i]:=b;
end;
{-----------}function SPVeyb.Assym;
begin
mu3=(Г(1+3/alpha)- 3*Г(1+1/alpha)* (Г(1+2/alpha)+2*Г{в кубе}(1+1/alpha))
*betta{в степени -2/alpha??}) *betta{в степени -3/alpha??};
KATheor:=mu3/DXTheor{в степени 3/2};
end;
Самый смешной баг была "ленивая" программистка. Был как то баг, в качестве параметра передавалась единичка в место нуля. Так вот эта программистка с этим не стала разбираться, а решила, что проблема эта из за отсутствия нужной функции. Она ее написала, а неправильный вызов с еденичкой выкинула. Ну и началась потом свистопляска, она этот баг пофиксила, а на его месте появился другой. Она его тоже зафиксила и так это длилось полтора месяца и пока она не написала копию той функции вызов которой она закоментировала в самом начале. Потом она ушла, а посадили меня и я неделю удалял, то что она там накОдила, что бы потом в итоге поменять 1 на 0 в уже существующей функции.
S>Господа программисты.
S>А почему бы нам не сделать конкурс на самый глючный баг? Ведь чем сложнее и трудноуловимее баг, тем профессиональнее считается программист. Вот примеры:
class Test
{
int x, y, char * s;
public:
Test(int a_x, int a_y, const char * a_s) { x = a_a; y = a_y; s = a_s; }
Test(const Test & t) { *this = t };
Test & operator=(const Test t) { x = t.x; y = t.y; s = strdup(t.s); return *this; }
};
int main()
{
Test t1(0, 0, "test1");
Test t2 = t1;
return 0;
}
Stack overflow
Это, кстати, еще и пример извращенности мышления...
C> Test & operator=(const Test t) { x = t.x; y = t.y; s = strdup(t.s); return *this; }
C>Stack overflow
Долго хлопал глазами, потом как дошло, аж больно стало!!!
C>Это, кстати, еще и пример извращенности мышления...
Необязательно: copy-ctor и operator= могут, к примеру, вызывать функцию assign(), которая объявлена именно с такой плюшкой.
S>Господа программисты.
S>А почему бы нам не сделать конкурс на самый глючный баг? Ведь чем сложнее и трудноуловимее баг, тем профессиональнее считается программист.
У меня на C++ самый популярный баг
Здравствуйте, ch00k, Вы писали:
C>Здравствуйте, sercher, Вы писали:
S>>Господа программисты.
S>>А почему бы нам не сделать конкурс на самый глючный баг? Ведь чем сложнее и трудноуловимее баг, тем профессиональнее считается программист. Вот примеры:
C>
C>class Test
C>{
C> int x, y, char * s;
C>public:
C> Test(int a_x, int a_y, const char * a_s) { x = a_a; y = a_y; s = a_s; }
C> Test(const Test & t) { *this = t };
C> Test & operator=(const Test t) { x = t.x; y = t.y; s = strdup(t.s); return *this; }
C>};
C>int main()
C>{
C> Test t1(0, 0, "test1");
C> Test t2 = t1;
C> return 0;
C>}
C>
C>Stack overflow C>Это, кстати, еще и пример извращенности мышления...
Почему извращенного? Почти классический пример из книжки... Правда я только со второго раза понял что к чему , но с передачей объектов по значению в свое время намучился так что рефлекс остался... Но на собеседовании я бы наверное не сообразил .