Upload
yury-zelensky
View
666
Download
2
Embed Size (px)
DESCRIPTION
Слайды к лекции о типовых ошибках при разработке ПО (на русском языке).
Citation preview
2012 © Itransition Group. Proprietary and Confidential 1
2011
Типовые ошибки при разработке ПО, и методы их предотвращенияЮрий Зеленский
2012 © Itransition Group. Proprietary and Confidential 2
2012 © Itransition Group. Proprietary and Confidential 33
Статистика
0 4 8 12 16 20 24 28 32 36 40 44 48 52 540
1
2
3
4
5
6
7
8
9
10
количество проектов с issue/fte
1 (найденная, функциональная) ошибка каждый день
2012 © Itransition Group. Proprietary and Confidential 44
Статистика
20-30 ошибок на kSloc “свежего” кода (1 на 40 строк) 1-5 ошибок на kSloc в тестированном release
10 строк в час – наша производительность
Лучшие показатели (embedded в aerospace) 0.1/kSloc
35% изменений в support не вносят ошибок (international conference software maintainers 1998)
16% изменений вносят 15 и более ошибок
2012 © Itransition Group. Proprietary and Confidential 55
Определение
Синонимы: ошибка, дефект, проблема, отказ, сбой, неисправность, повреждение, несоответствие, особенность, bug, issue
Система возвращает некорректный или неожидаемый результат или ведет себя непредусмотренным образомРасхождение между фактическим и
ожидаемым результатами
2012 © Itransition Group. Proprietary and Confidential 66
Ошибка?
send(to, from, count)
register short *to, *from;
register count;
{
register n = (count + 7) / 8;
switch(count % 8) {
case 0: do { *to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
} while(--n > 0);
}
}
2012 © Itransition Group. Proprietary and Confidential 77
Так лучше?
do { /* count > 0 assumed, “to” pointer have to have “volatile” qualifier */
*to = *from++; /* Note that the 'to' pointer is NOT incremented */
} while(--count > 0);
2012 © Itransition Group. Proprietary and Confidential 88
Основные причины ошибок
Невежество
Безразличие
Лень
2012 © Itransition Group. Proprietary and Confidential 99
Основные средства предотвращения
Кропотливость
Дотошность
Аккуратность
Внимание к деталям
Ответственность
2012 © Itransition Group. Proprietary and Confidential 1010
Классификация по источнику
Ошибки процессанет времени, нет разработчиков, нет менеджера, нет спецификации, нет
issue tracking, нет version control, нет понимания задачи
Ошибки проектированияСложность, «велосипед» и другие design antipatterns.
Ошибки программированияCopy paste, неряшливость, и другие подводные камни (aka pitfalls)
2012 © Itransition Group. Proprietary and Confidential 1111
Классификация по типу
Функциональные Проектирования и программирования: misconception Функциональные ошибки программирования
Не функциональные Тестопригодность (модульная, интеграционная) Надежность Простота внесения изменений(читаемость, понятность) Безопасность Эффективность (производительность) Портируемость Пригодность к повторному использованию Сопровождаемость(читаемость, понятность,
документированность)
2012 © Itransition Group. Proprietary and Confidential 1212
Функциональные ошибки программирования
Логические: бесконечные циклы, off-by-one и т.п. Арифметические: деление на нуль, overflow,
underflow Синтаксические: = вместо == и т.п. Ресурсные: неинициализированные значения, утечки
памяти и ресурсов, переполнения буфера и стека Многопоточности: блокировки, гонки Интерфейсов: некорректное использование API,
протоколов, аппаратных возможностей Производительности: алгоритмическая сложность,
беспорядочные операции ввода вывода
2012 © Itransition Group. Proprietary and Confidential 1313
Антипаттерн: определение
Часто встречающийся подход к решению проблем, приводящий к однозначно отрицательным последствиям.
http://c2.com/cgi/wiki?AntiPatternsCatalog
http://en.wikipedia.org/wiki/Antipatterns#Software_design_anti-patterns
2012 © Itransition Group. Proprietary and Confidential 1414
Вот такая вот у нас ООПа
Глобальные переменные
Поведение без состояний
Необоснованное наследование
LCOM4>3
Божественный объект
2012 © Itransition Group. Proprietary and Confidential 1515
Несколько (вопиющих) примеров
Не аккуратненько как-то: не выравнено, не единообразно, при изменении размера все расползается, не единообразно.
Что в имени тебе моем: невнятные, или даже стандартные имена переменных, классов объектов. Button1 на Form1?! Вы что издеваетесь?
Английский (можно подсматривать в словарь). Без акронимов! Не экономим символы!
2012 © Itransition Group. Proprietary and Confidential 1616
Ещё примеры
Волшебная кнопка, она же волшебная ASP, волшебная JSP, волшебный сервлет, монолитный сервлет.
Неиспользование regexp (мне же, буквально, проверить email это или нет, что ради этого regexp учить?)
Отсутствие контроля данных (это же мы сами сформировали параметр, тут не может быть других значений)
Не использование кэша или бездумное использование кэша Ручной разбор текстовых форматов (xml, http, и т.п.) Ручная конкатенация данных для формирования текстовых
представлений (sql, xml, html, и т.п.) Не использование пула ресурсов(подключений) Манипуляции с immutable объектами Магические константы
2012 © Itransition Group. Proprietary and Confidential 1717
Ещё пример
Компактно, эффектно, возможно даже эффективно, но не читаемо.
IOCCC открыт для всех. Эта программа играет в шахматы, всё ещё гордитесь мастерством владения тернарным оператором?
char*l="ustvrtsuqqqqqqqqyyyyyyyy}{|~z|{}" " 76Lsabcddcba .pknbrq PKNBRQ ?A6J57IKJT576,+-48HLSU"; #define F getchar()&z #define v X(0,0,0,21, #define Z while( #define _ ;if( #define P return--G,y^=8, B,i,y,u,b,I[411],*G=I,x=10,z=15,M=1e4;X(w,c,h,e,S,s){int t,o,L,E,d,O=e,N=-M*M,K =78-h<<x,p,*g,n,*m,A,q,r,C,J,a=y?-x:x;y^=8;G++;d=w||s&&s>=h&&v 0,0)>M;do{_ o=I[ p=O]){q=o&z^y _ q<7){A=q--&2?8:4;C=o-9&z?q["& .$ "]:42;do{r=I[p+=C[l]-64]_!w|p ==w){g=q|p+a-S?0:I+S _!r&(q|A<3||g)||(r+1&z^y)>9&&q|A>2){_ m=!(r-2&7))P G[1]=O, K;J=n=o&z;E=I[p-a]&z;t=q|E-7?n:(n+=2,6^y);Z n<=t){L=r?l[r&7]*9-189-h-q:0 _ s)L +=(1-q?l[p/x+5]-l[O/x+5]+l[p%x+6]*-~!q-l[O%x+6]+o/16*8:!!m*9)+(q?0:!(I[p-1]^n)+ !(I[p+1]^n)+l[n&7]*9-386+!!g*99+(A<2))+!(E^y^9)_ s>h||1<s&s==h&&L>z|d){p[I]=n,O [I]=m?*g=*m,*m=0:g?*g=0:0;L-=X(s>h|d?0:p,L-N,h+1,G[1],J=q|A>1?0:p,s)_!(h||s-1|B -O|i-n|p-b|L<-M))P y^=8,u=J;J=q-1|A<7||m||!s|d|r|o<z||v 0,0)>M;O[I]=o;p[I]=r;m? *m=*g,*g=0:g?*g=9^y:0;}_ L>N){*G=O _ s>1){_ h&&c-L<0)P L _!h)i=n,B=O,b=p;}N=L;} n+=J||(g=I+p,m=p<O?g-3:g+2,*m<z|m[O-p]||I[p+=p-O]);}}}}Z!r&q>2||(p=O,q|A>2|o>z& !r&&++C*--A));}}}Z++O>98?O=20:e-O);P N+M*M&&N>-K+1924|d?N:0;}main(){Z++B<121)*G ++=B/x%x<2|B%x<2?7:B/x&4?0:*l++&31;Z B=19){Z B++<99)putchar(B%x?l[B[I]|16]:x)_ x-(B=F)){i=I[B+=(x-F)*x]&z;b=F;b+=(x-F)*x;Z x-(*G=F))i=*G^8^y;}else v u,5);v u, 1);}}
2012 © Itransition Group. Proprietary and Confidential 18
А что делать?
2012 © Itransition Group. Proprietary and Confidential 1919
Народная мудрость
Если что-то может сломаться - оно обязательно сломается (закон Мёрфи)
Сложность – главный враг надежности Самые дешевые, быстрые и надежные компоненты –
те, которых нет Два подхода: «так просто, что очевидно нет
недостатков» и «так сложно, что нет очевидных недостатков»
Сложность программы растет до тех пор, пока не превысит способности программиста
Один волос на голове - слишком мало, в супе - слишком много
2012 © Itransition Group. Proprietary and Confidential 2020
Практические советы
Кропотливость
Дотошность
Аккуратность
Внимание к деталям
Ответственность
2012 © Itransition Group. Proprietary and Confidential 2121
Ещё более практические советы
Используйте уже отлаженный код. Не пишите свой. Изучайте (стандартные) библиотеки. Повесьте cheetsheet, убедитесь что вы знаете про свою библиотеку все.
Боритесь за простоту. Refactor! Пишите хорошие комментарии и не пишите плохих, потому что это отнимает время от написания хороших (плеоназмы, тавтологии ничем не лучше отсутствия комментария)
Комментарий должен пояснять не что написано, а почему, и почему именно так. Лучше большой комментарий на большой кусок, чем много микро-комментариев.
Именуйте все (extract method, extract variable).
Пользуйтесь шаблонами IDE (как минимум всеми стандартными).
2012 © Itransition Group. Proprietary and Confidential 2222
И ещё советы
Не используйте copy & paste – вы копируете ошибки!
Do not repeat yourself!
Регулярно проверяйте себя и окружающих на предмет использования copy & paste (при помощи специальных средств)
Если совсем невмоготу: можно cut & paste
Запускайте автоформат, пусть ваш код будет (хотя бы) гладким и шелковистым
Читайте чужой код (например код библиотек вашего языка)
Читайте свой код
Переведите написанное в коде на натуральный язык (обратная семантическая трассировка)
Требуйте проведения code review (Fagan process как апофеоз peer review – это работает!)
2012 © Itransition Group. Proprietary and Confidential 2323
И ещё советы
Облегчите и ускорьте себе отладку. Под рукой должна быть возможность запустить отладчик, даже если код на далеком сервере.
Экстернализируйте параметры конфигурации. Обеспечьте возможность их менять в runtime.
Имейте хоть какой-то интеграционный тест.
Используйте модульные тесты.
Пользуйтесь edit & continue, hot replace и (или Ruby )
Дефекты в последних изменениях. Самый часто меняемый файл – проблемный.
Попробуйте time machine debug (intellitrace и подобные)
2012 © Itransition Group. Proprietary and Confidential 2424
Последнее но не по значению
Статический анализ кода
Sonar (требуйте размещения своего проекта на корпоративном sonar сервере)
FindBugs, FxCop, lint, PMD, тысячи их:http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis
Источник информации об antipatterns.
2012 © Itransition Group. Proprietary and Confidential 2525
Статический анализ?
2012 © Itransition Group. Proprietary and Confidential 2626
Статический анализ? Да, но не так!
2012 © Itransition Group. Proprietary and Confidential 2727
Статический анализ! Да! Вот так!
2012 © Itransition Group. Proprietary and Confidential 28
2012 © Itransition Group. Proprietary and Confidential 2929
Физики шутят
Борбаг (Bohrbug)Просто баг. Простой как планетарная модель ядра.
2012 © Itransition Group. Proprietary and Confidential 3030
Физики шутят
Гейзенбаг (Heisenbug)Баг который меняет свое поведение при попытке его пронаблюдать.
2012 © Itransition Group. Proprietary and Confidential 3131
Физики шутят
Мандельбаг (Mandelbug)Ошибки, чьи причины настолько сложны и неясны, что кажутся хаотичными (и завораживающими как одноименное множество).
2012 © Itransition Group. Proprietary and Confidential 3232
Физики шутят
Шрединбаг (Schroedinbug)После того как в тексте обнаруживается критическая ошибка, программа (ранее вполне работающая) перестает функционировать.
2012 © Itransition Group. Proprietary and Confidential 33
2011www.itransition.com [email protected]
Discuss!
2012 © Itransition Group. Proprietary and Confidential 3434
Внеклассное чтение
http://tinypaste.com/0659d1a1
2012 © Itransition Group. Proprietary and Confidential 3535
Внеклассное чтение
http://en.wikipedia.org/wiki/Duff's_device
http://en.wikipedia.org/wiki/Software_bug
http://en.wikipedia.org/wiki/Software_bug#Common_types_of_computer_bugs
http://c2.com/cgi/wiki?AntiPatternsBook
http://dou.ua/lenta/articles/resign-patterns/
http://en.wikipedia.org/wiki/Anti-pattern
http://en.wikipedia.org/wiki/Antipatterns#Object-oriented_design_anti-patterns
http://en.wikipedia.org/wiki/Fagan_inspection
http://en.wikipedia.org/wiki/Category:Software_engineering_disasters
http://ru.wikipedia.org/wiki/Обратная_семантическая_трассировка
http://msdn.microsoft.com/en-us/library/dd264915.aspx //intelliTrace
http://www.lambdacs.com/debugger/ //historical debugger for Java
http://www.chrononsystems.com/ //another historical debugger for Java
http://en.wikipedia.org/wiki/SQALE#The_indices
http://quotes.cat-v.org/programming/
http://lib.ru/ANEKDOTY/marphy.txt
http://www.opennet.ru/opennews/art.shtml?num=19763 //most widespread that lead to SW vulnerabilities
http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601/
http://en.wikipedia.org/wiki/Toledo_Nanochess
http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis
http://en.wikipedia.org/wiki/Static_program_analysis
http://www.aivosto.com/project/help/pm-oo-cohesion.html
http://www.ozon.ru/context/detail/id/1425895/ //горький вкус Java