35
2012 © Itransition Group. Proprietary and Confidential 1 2011 Типовые ошибки при разработке ПО, и методы их предотвращения Юрий Зеленский

лекция типовые ошибки

Embed Size (px)

DESCRIPTION

Слайды к лекции о типовых ошибках при разработке ПО (на русском языке).

Citation preview

Page 1: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 1

2011

Типовые ошибки при разработке ПО, и методы их предотвращенияЮрий Зеленский

Page 2: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 2

Page 3: лекция типовые ошибки

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 (найденная, функциональная) ошибка каждый день

Page 4: лекция типовые ошибки

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 и более ошибок

Page 5: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 55

Определение

Синонимы: ошибка, дефект, проблема, отказ, сбой, неисправность, повреждение, несоответствие, особенность, bug, issue

Система возвращает некорректный или неожидаемый результат или ведет себя непредусмотренным образомРасхождение между фактическим и

ожидаемым результатами

Page 6: лекция типовые ошибки

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);

}

}

Page 7: лекция типовые ошибки

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);

Page 8: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 88

Основные причины ошибок

Невежество

Безразличие

Лень

Page 9: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 99

Основные средства предотвращения

Кропотливость

Дотошность

Аккуратность

Внимание к деталям

Ответственность

Page 10: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 1010

Классификация по источнику

Ошибки процессанет времени, нет разработчиков, нет менеджера, нет спецификации, нет

issue tracking, нет version control, нет понимания задачи

Ошибки проектированияСложность, «велосипед» и другие design antipatterns.

Ошибки программированияCopy paste, неряшливость, и другие подводные камни (aka pitfalls)

Page 11: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 1111

Классификация по типу

Функциональные Проектирования и программирования: misconception Функциональные ошибки программирования

Не функциональные Тестопригодность (модульная, интеграционная) Надежность Простота внесения изменений(читаемость, понятность) Безопасность Эффективность (производительность) Портируемость Пригодность к повторному использованию Сопровождаемость(читаемость, понятность,

документированность)

Page 12: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 1212

Функциональные ошибки программирования

Логические: бесконечные циклы, off-by-one и т.п. Арифметические: деление на нуль, overflow,

underflow Синтаксические: = вместо == и т.п. Ресурсные: неинициализированные значения, утечки

памяти и ресурсов, переполнения буфера и стека Многопоточности: блокировки, гонки Интерфейсов: некорректное использование API,

протоколов, аппаратных возможностей Производительности: алгоритмическая сложность,

беспорядочные операции ввода вывода

Page 13: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 1313

Антипаттерн: определение

Часто встречающийся подход к решению проблем, приводящий к однозначно отрицательным последствиям.

http://c2.com/cgi/wiki?AntiPatternsCatalog

http://en.wikipedia.org/wiki/Antipatterns#Software_design_anti-patterns

Page 14: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 1414

Вот такая вот у нас ООПа

Глобальные переменные

Поведение без состояний

Необоснованное наследование

LCOM4>3

Божественный объект

Page 15: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 1515

Несколько (вопиющих) примеров

Не аккуратненько как-то: не выравнено, не единообразно, при изменении размера все расползается, не единообразно.

Что в имени тебе моем: невнятные, или даже стандартные имена переменных, классов объектов. Button1 на Form1?! Вы что издеваетесь?

Английский (можно подсматривать в словарь). Без акронимов! Не экономим символы!

Page 16: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 1616

Ещё примеры

Волшебная кнопка, она же волшебная ASP, волшебная JSP, волшебный сервлет, монолитный сервлет.

Неиспользование regexp (мне же, буквально, проверить email это или нет, что ради этого regexp учить?)

Отсутствие контроля данных (это же мы сами сформировали параметр, тут не может быть других значений)

Не использование кэша или бездумное использование кэша Ручной разбор текстовых форматов (xml, http, и т.п.) Ручная конкатенация данных для формирования текстовых

представлений (sql, xml, html, и т.п.) Не использование пула ресурсов(подключений) Манипуляции с immutable объектами Магические константы

Page 17: лекция типовые ошибки

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);}}

Page 18: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 18

А что делать?

Page 19: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 1919

Народная мудрость

Если что-то может сломаться - оно обязательно сломается (закон Мёрфи)

Сложность – главный враг надежности Самые дешевые, быстрые и надежные компоненты –

те, которых нет Два подхода: «так просто, что очевидно нет

недостатков» и «так сложно, что нет очевидных недостатков»

Сложность программы растет до тех пор, пока не превысит способности программиста

Один волос на голове - слишком мало, в супе - слишком много

Page 20: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 2020

Практические советы

Кропотливость

Дотошность

Аккуратность

Внимание к деталям

Ответственность

Page 21: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 2121

Ещё более практические советы

Используйте уже отлаженный код. Не пишите свой. Изучайте (стандартные) библиотеки. Повесьте cheetsheet, убедитесь что вы знаете про свою библиотеку все.

Боритесь за простоту. Refactor! Пишите хорошие комментарии и не пишите плохих, потому что это отнимает время от написания хороших (плеоназмы, тавтологии ничем не лучше отсутствия комментария)

Комментарий должен пояснять не что написано, а почему, и почему именно так. Лучше большой комментарий на большой кусок, чем много микро-комментариев.

Именуйте все (extract method, extract variable).

Пользуйтесь шаблонами IDE (как минимум всеми стандартными).

Page 22: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 2222

И ещё советы

Не используйте copy & paste – вы копируете ошибки!

Do not repeat yourself!

Регулярно проверяйте себя и окружающих на предмет использования copy & paste (при помощи специальных средств)

Если совсем невмоготу: можно cut & paste

Запускайте автоформат, пусть ваш код будет (хотя бы) гладким и шелковистым

Читайте чужой код (например код библиотек вашего языка)

Читайте свой код

Переведите написанное в коде на натуральный язык (обратная семантическая трассировка)

Требуйте проведения code review (Fagan process как апофеоз peer review – это работает!)

Page 23: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 2323

И ещё советы

Облегчите и ускорьте себе отладку. Под рукой должна быть возможность запустить отладчик, даже если код на далеком сервере.

Экстернализируйте параметры конфигурации. Обеспечьте возможность их менять в runtime.

Имейте хоть какой-то интеграционный тест.

Используйте модульные тесты.

Пользуйтесь edit & continue, hot replace и (или Ruby )

Дефекты в последних изменениях. Самый часто меняемый файл – проблемный.

Попробуйте time machine debug (intellitrace и подобные)

Page 24: лекция типовые ошибки

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.

Page 25: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 2525

Статический анализ?

Page 26: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 2626

Статический анализ? Да, но не так!

Page 27: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 2727

Статический анализ! Да! Вот так!

Page 28: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 28

Page 29: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 2929

Физики шутят

Борбаг (Bohrbug)Просто баг. Простой как планетарная модель ядра.

Page 30: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 3030

Физики шутят

Гейзенбаг (Heisenbug)Баг который меняет свое поведение при попытке его пронаблюдать.

Page 31: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 3131

Физики шутят

Мандельбаг (Mandelbug)Ошибки, чьи причины настолько сложны и неясны, что кажутся хаотичными (и завораживающими как одноименное множество).

Page 32: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 3232

Физики шутят

Шрединбаг (Schroedinbug)После того как в тексте обнаруживается критическая ошибка, программа (ранее вполне работающая) перестает функционировать.

Page 33: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 33

2011www.itransition.com [email protected]

Discuss!

Page 34: лекция типовые ошибки

2012 © Itransition Group. Proprietary and Confidential 3434

Внеклассное чтение

http://tinypaste.com/0659d1a1

Page 35: лекция типовые ошибки

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