Weźmy przypadek dwóch programistów siedzących nad jednym kawałkiem kodu i zastanawiających się nad bardzo skrajnym przypadkiem, który może wystąpić w naprawdę ograniczonym wypadku. Pracują nad algorytmem odpowiedzialnym za zachowania i działania autonomicznego samochodu. Przed swoimi oczami mają jedynie blok kodu, po którym próżno odczytać scenę, która za moment wydarzy się naprawdę.
Nie zdają sobie sprawy, że pracują nad kawałkiem oprogramowania, które podejmie określoną akcję, na którą w realnym życiu mielibyśmy zaledwie sekundę. Sytuacja na którą patrzą jest hipotetyczna, niedająca się opisać słowami ani obrazem – po prostu jest. Siedzą i programują, piją czwartą już kawę i kompletnie nie zdają sobie w żaden sposób powagi tej sytuacji. Nagle zapada z nikim nieskonsultowana, nieodwracalna decyzja. Nawet gdyby to zrobili, to czy przełożony wiedziałby, czym grozi ta decyzja? W branży motoryzacyjnej nie ma jednostki czuwającej nad jakością oprogramowania, tak jak jest chociażby w przypadku samolotów. Nie ma nikogo, kto wiedziałby, jak się zająć tym tematem i kto zadawałby sobie pytanie, jak drobne decyzje – podjęte wspólnie przez dwóch programistów – bez konsultacji lub punktu odniesienia mogą wpłynąć na otaczający nas świat? Przecież to tylko jedna linijka kodu, parę znaków, niby nic. Jednak parę miesięcy później ktoś przez tę drobną pomyłkę ginie na pasach.
Opisana sytuacja jest czysto hipotetyczna i koloryzowana. Jednak wiele lat temu to właśnie przez taki błąd w oprogramowaniu Toyota Camry nie pozwoliła kierowcy się zatrzymać. W wyniku uderzenia zginęła pasażerka. Zaś nie tak dawno, bo w 2018 roku, samojezdne auto Ubera zabiło kobietę. Wówczas Rada Bezpieczeństwa Transportu ujawniła, że autonomiczne pojazdy testowe firmy były zaangażowane w aż 37 wypadków w ciągu 18 miesięcy poprzedzających czas tego wydarzenia.
Spróbuj wezwać pomoc
10 kwietnia 2014 roku pewna kobieta mieszkająca w Seattle dzwoniła na numer 911 ponad 35 razy. Jedyne, co słyszała w słuchawce, to sygnał zajętości, a tymczasem nieznany sprawca próbował włamać się do jej domu. Ten sam sygnał zajętości pojawił się w całym stanie Waszyngton. 11 milionów Amerykanów przestało mieć możliwość wezwania pomocy.
Kilka lat wcześniej zrezygnowano z lokalnych systemów wsparcia na rzecz bardziej złożonego oprogramowania działającego w oparciu o Internet. Serwer znajdujący się w Kolorado obsługiwał dyspozycje z całego kraju i to tam trafiały wszystkie połączenia na numer alarmowy.
Okazało się, że tę wielką awarię spowodował niewielki kawałek kodu. Błąd prozaicznie prosty. Programiści wyznaczyli próg określający, jak wiele (łącznie) oprogramowanie może przyjąć połączeń.
A kiedy osiągnęło ten próg, wszystko zwyczajnie przestało działać. Nie było żadnych systemów ostrzegawczych, a ponieważ oprogramowania nie da się zbadać gołym okiem, nic nie wskazywało na to, że jest z nim coś nie tak.
Co się dzieje nad naszymi głowami
W zależności od pory roku, czy też dnia, nad naszymi głowami znajduje się od 8 000 do 20 000 samolotów. Statystycznie, loty nimi to najbezpieczniejsza forma transportu, pomimo że każdy z tych samolotów jest wielką metalową puszką, w której znajdują się setki kilometrów kabli i wielka maszyneria obliczeniowa na pokładzie (a druga pracuje na ziemi). Od lat 80. ubiegłego wieku samoloty stają się coraz bardziej zależne od oprogramowania. Całe szczęście, że Federal Aviation Administration podchodzi bardzo restrykcyjnie nie tylko do jego testowania, ale także dbania o jego dokumentowanie. Dzięki temu liczba produkowanych błędów jest stosunkowo niska.
Należy jednak pamiętać, że niezależnie od tego jak skrupulatnie będziemy testować wytwarzane oprogramowanie, nie jest możliwym znalezienie wszystkich błędów i rozpatrzenie wszystkich możliwych przypadków ich wystąpienia. Tylko w ostatnich latach mieliśmy dziesiątki przypadków uziemień samolotów z powodu błędnie napisanego kodu. W 2019 roku British Airlines odwołało ponad 100 lotów, a ponad 200 zostało opóźnionych. W maju 2017 roku ta sama linia lotnicza miała problemy z ponad 1000 lotów, infolinią, stroną internetową i aplikacją mobilną.
To jednak nic w porównaniu z tym, gdy Boeing 737 Max spowodował dwie katastrofy lotnicze właśnie z powodu błędnie napisanego programu. Ich przyczyną było najprawdopodobniej wadliwe oprogramowanie systemu MCAS, które automatycznie zapobiega przeciągnięciu (utracie siły nośnej). Mówi się, że powodem tej wady były naciski na wprowadzenie tańszego outsourcingu do mniej kosztownych kontrahentów. Oprogramowanie zostało wytworzone przez firmę, która zatrudniała tymczasowych pracowników z Indii za stawkę 9$/h.
W tym samym czasie Boeing zwalniał swoich doświadczonych inżynierów, co spowodowało utratę kontroli nad tworzonym oprogramowaniem. Boeing przygotowywał specyfikację, zaś wcześniej wspomniana firma miała tworzyć wedle niej działający program. Pracowało nad nim kilka rzędów pracowników, posadzonych przy biurkach. Oprogramowanie, które trafiało do Boeinga, nie przechodziło nawet najprostszych testów, a jej kod był bardzo kiepskiej jakości. Mimo ogromnych ilości zgłaszanych nieprawidłowości, nie udało się wyłapać ich wszystkich. Podjęta w ten sposób decyzja o cięciu kosztów stała się dramatyczna w skutkach. Możemy sobie jedynie wyobrazić skalę tego problemu i zastanawiać się, na ile oprogramowanie, które jest dość często aktualizowane w samolotach, jest bezpieczne. Boeing zgłosił 636 mln. dolarów straty za 2019 r.
Skoro jesteśmy już tak wysoko
Gdzie się nie udamy, możemy usłyszeć opinię, że wszystko powinno teraz działać w chmurze. To w niej jest przyszłość, tylko ona zapewni nam wysokie bezpieczeństwo, skalowalność i jakość dla naszego biznesu. Otaczający nas świat, urządzenia podłączone do Internetu, większość oprogramowania, stron, serwisów internetowych, aplikacji mobilnych opiera swoje rozwiązania właśnie na takich usługach. Oczywiście nie podważam słuszności tego rozwiązania, ale warto zastanowić się mocno, czy nie jest ono zbytnio gloryfikowane.
Jednym z dostawców rozwiązań chmurowych jest firma Amazon, która uchodzi za najbardziej niezawodnego gracza na rynku oferującego usługi hostingowe. Wiele firm różnej wielkości i z różnych branż przechowuje swoje dane w centrach danych AWS. Obejmuje to znane marki, takie jak: Netflix, Slack, Business Insider, IFTTT, Nest Trello, Quora czy Splitwise. Wiele startupów czy firm także opiera swoje działania w oparciu o obliczenia lub mikro-usługi tego dostawcy. Można więc łatwo wyobrazić sobie, co się stało, gdy w 2017 roku drobna awaria serwerów AWS na zachodnim wybrzeżu Stanów Zjednoczonych przyczyniła się do setek problemów w Internecie na całym świecie. Awarii uległy także urządzenia, które wykorzystywały do swojego działania Internet i były do niego podłączone.
Najzimniejszy dzień w roku i karta wychodzisz wolny z więzienia
Firma Nest, której właścicielem jest Google, w grudniu 2015 r. wydała aktualizację oprogramowania do swoich termostatów. Niestety – aktualizacja nie udała się i 99,5% użytkowników tych inteligentnych urządzeń pozostało bez dostępu do ciepłej wody i ogrzewania w jeden z najzimniejszych weekendów tamtego roku.
Także w grudniu 2015 r. usterka w oprogramowaniu spowodowała, że z więzienia zostało zwolnionych przed czasem ponad 3200 więźniów. Oprogramowanie to działało od 2002 roku i obliczało wyrok więźnia w zależności od dobrego i złego zachowania.
Przypadków z niedziałającym oprogramowaniem jest wiele. Czasem to problemy z wykonaniem transakcji, złożeniem wniosku przez Internet, podpisaniem dokumentów, zamówieniem w sklepie internetowym, płatnością kartą, zamówieniem taksówki. Te małe i drobne usterki towarzyszą nam na każdym kroku i póki nie stanowią o naszym życiu, nie są dla nas wielkim problemem.
To nie jest problem ostatnich lat
Już pomiędzy rokiem 1985 a 1987 co najmniej 5 pacjentów zmarło, a wielu innych doznało krytycznych obrażeń przez błąd w oprogramowaniu urządzeń do radioterapii. Podobny incydent miał miejsce później w roku 2000. W 1991 roku błąd oprogramowania uniemożliwił przechwycenie pocisku balistycznego, który uderzył w koszary USA w Arabii Saudyjskiej, zabijając 28 osób i raniąc kolejne 96.
Skąd takie zmiany
Za każdym razem, kiedy jako społeczeństwo wchodziliśmy na wyższy poziom cywilizacyjny, w naszym otoczeniu pojawiały się coraz nowsze rozwiązania ułatwiające nam życie. Od mniej do bardziej skomplikowanych urządzeń. Do czasu miały one swoje pewne fizyczne ograniczenia.
To, czy coś się wydarzy czy nie i czy jest możliwe, definiowaliśmy za pomocą części, przekładni i elementów mechanicznych. Później za pomocą nieskomplikowanej elektroniki. Prosto więc było przewidzieć wszystkie możliwe stany, w których dana maszyna mogła się znaleźć. Z oprogramowaniem jest inaczej. Jego elastyczność zmian jest tak duża, że niesie za sobą ogromne możliwości, ale także ogromne niebezpieczeństwo.
Wydaje się jednak, że umiemy programować, wiemy jak to robić – przynajmniej w teorii. Technologii oprogramowania czy sposobów jego wytwarzania są dziesiątki. Mamy do tego dedykowane środowiska, nie musimy już programować za pomocą zer i jedynek (warto wspomnieć, że jeden z największych programów do pisania oprogramowania – Visual Studio – ma 55 milionów linii kodu). Oprogramowanie dokładnie wie, co ma robić – pod warunkiem, że zostanie mu to dobrze zdefiniowane. Właśnie te definicje stanowią błędy w oprogramowaniu, a te rodzą się w umysłach ludzi, którzy tworzą kod. Przecież w oprogramowaniu nie ma nic fizycznego, nie można zobaczyć jego odzwierciedlenia. Program jest tysiąckroć bardziej skomplikowany, niż elementy mechaniczne, przez co tworzymy często coś, co przekracza nasze możliwości poznawcze i intelektualne.
Kod jest swego rodzaju rękodziełem. W przypadku ręcznego wytwarzania 10 000 linii kodu, nie ma większego problemu, by nad nim zapanować. Jednak kiedy mówimy już o 30 milionach lub 100 milionach – jak w przypadku oprogramowania Tesli, czy innych samochodów wyższej klasy – to nie tylko tworzenie, ale także testowanie i utrzymanie go staje się ogromnie kosztowne i skomplikowane.
Tworzy się ostatnio trend, by programistów zastępować kolejnym oprogramowaniem, żeby to maszyny tworzyły kod. Jestem bardzo sceptycznie do tego nastawiony. W końcu maszyny tworzące oprogramowanie nadal zostaną stworzone przez tych, którzy ten kod aktualnie wytwarzają. Jeden błąd stworzony przez programistów, może w konsekwencji przyczynić się do nieskończonej, ciągle powtarzanej ilości błędów tworzonych już przez maszynę. Innym pomysłem na rozwój oprogramowania jest tworzenie go poprzez schematy blokowe opisujące reguły, które program powinien przestrzegać, a przecież komputer sam generuje dla niego kod właśnie na podstawie tych reguł.
Myślę, że otaczających nas zmian i tego, że oprogramowanie zjada świat, nie da się już cofnąć. Warto jednak pamiętać o ograniczeniach programów oraz o tym, że ludzie go tworzący nie są nieomylni. Trzeba uważać, by nie zapełniać luk w świecie programistycznym ludźmi, którzy mogą się do tego zwyczajnie nie nadawać (w końcu nie każdy ma predyspozycje do bycia lekarzem, nauczycielem, przedszkolanką czy fizykiem jądrowym) lub takimi, którzy mogą negatywnie wpływać na tworzone oprogramowanie i jego bezpieczeństwo. To jedno z wielu aktualnych niebezpieczeństw, z którymi musimy się zmierzyć.
–
Adam Trojańczyk, członek zarządu i COO w software house’ie Inwedo.
Posiada czternaście lat doświadczenia w branży IT. Pracował z firmami z różnych zakątków świata. Od strefy ekonomicznej w Meksyku, firm w USA, poprzez dziesiątki firm z Europy, największe agencje interaktywne w Polsce, aż po firmy z Japonii i Australii. Przez ten czas zarządzał swoim software housem oraz współtworzył i angażował się w rozwój wielu startupów. Był mentorem i ekspertem w programach akceleracyjnych. Po godzinach pisze artykuły na swoim blogu https://trojanczyk.pl.