Przepraszam za moje zmieszane pytanie. Szukam wskazówek.
Do tej pory pracowałem głównie z Javą i Pythonem w warstwie aplikacji i mam tylko niejasne rozumienie systemów operacyjnych i sprzętu. Chcę zrozumieć znacznie więcej na niższych poziomach komputerów, ale robi się naprawdę przytłaczający. Na uniwersytecie wziąłem udział w zajęciach z mikroprogramowania, tj. W jaki sposób procesory są podłączone do implementacji kodów ASM. Do tej pory zawsze myślałem, że nie zrobię więcej, jeśli dowiem się więcej o „niskim poziomie”.
Jedno z moich pytań brzmi: jak to możliwe, że sprzęt jest prawie całkowicie ukryty przed deweloperem? Czy słusznie jest powiedzieć, że system operacyjny jest warstwą oprogramowania dla sprzętu? Jeden mały przykład: w programowaniu nigdy nie spotkałem się z potrzebą zrozumienia, czym jest L2 lub L3 Cache. W typowym środowisku aplikacji biznesowych prawie nigdy nie trzeba rozumieć asemblera i niższych poziomów obliczeń, ponieważ obecnie istnieje stos technologii dla prawie wszystkiego. Wydaje mi się, że celem tych niższych poziomów jest zapewnienie interfejsu do wyższych poziomów. Z drugiej strony zastanawiam się, jak duży wpływ mogą mieć niższe poziomy, na przykład cała ta gra komputerowa.
Z drugiej strony istnieje teoretyczna gałąź informatyki, która działa na abstrakcyjnych modelach komputerowych. Rzadko jednak zdarzały mi się sytuacje, w których pomocne okazało się myślenie w kategoriach modeli złożoności, weryfikacji dowodów itp. Wiem, że istnieje klasa złożoności o nazwie NP i że są one w pewnym stopniu niemożliwe do rozwiązania duża liczba N. Brakuje mi odniesienia do ram do myślenia o tych rzeczach. Wydaje mi się, że istnieją różnego rodzaju obozy, które rzadko wchodzą w interakcje.
W ostatnich tygodniach czytałem o kwestiach bezpieczeństwa. Tutaj w jakiś sposób łączy się wiele różnych warstw. Ataki i exploity prawie zawsze występują na niższym poziomie, dlatego w tym przypadku konieczne jest poznanie szczegółów warstw OSI, wewnętrznych zasad funkcjonowania systemu operacyjnego itp.
źródło
Odpowiedzi:
Słowem kluczowym do myślenia o tych rzeczach jest abstrakcja .
Abstrakcja oznacza po prostu celowe ignorowanie szczegółów systemu, aby można było myśleć o nim jako o pojedynczym, niepodzielnym składniku podczas składania większego systemu z wielu podsystemów. Jest niewyobrażalnie potężny - pisanie nowoczesnego programu aplikacyjnego z uwzględnieniem szczegółów alokacji pamięci i rozlewania rejestrów oraz czasu pracy tranzystora byłoby możliwe w jakiś wyidealizowany sposób, ale nie jest to nieporównanie łatwiejsze niż niepomyśleć o nich i po prostu użyć operacji wysokiego poziomu. Nowoczesny paradygmat obliczeniowy opiera się w dużej mierze na wielu poziomach abstrakcji: elektronika półprzewodnikowa, mikroprogramowanie, instrukcje maszynowe, języki programowania wysokiego poziomu, interfejsy API do programowania systemu operacyjnego i sieci Web, frameworki i aplikacje programowane przez użytkownika. Praktycznie nikt obecnie nie jest w stanie zrozumieć całego systemu i nie ma nawet możliwej do pomyślenia ścieżki, którą moglibyśmy kiedykolwiek wrócić do tego stanu rzeczy.
Drugą stroną abstrakcji jest utrata mocy. Pozostawiając decyzje o szczegółach niższym poziomom, często akceptujemy, że mogą być podejmowane z nieoptymalną wydajnością, ponieważ niższe poziomy nie mają „dużego obrazu” i mogą zoptymalizować swoje działania tylko na podstawie lokalnej wiedzy i nie są tak (potencjalnie) inteligentny jak człowiek. (Zwykle. Na początku kompilowanie HLL do kodu maszynowego jest obecnie często lepiej wykonywane przez maszyny niż nawet najbardziej doświadczony człowiek, ponieważ architektura procesorów stała się tak skomplikowana.)
Kwestia bezpieczeństwa jest interesująca, ponieważ wady i „wycieki” w abstrakcji mogą być często wykorzystywane do naruszania integralności systemu. Gdy interfejs API postuluje, że możesz wywoływać metody A, B i C, ale tylko wtedy, gdy warunek X się utrzymuje, łatwo jest zapomnieć o tym warunku i nie być przygotowanym na opadanie, które nastąpi, gdy warunek zostanie naruszony. Na przykład klasyczny przepełnienie bufora wykorzystuje fakt, że zapis do komórek pamięci daje niezdefiniowane zachowanie, chyba że sam przydzielisz ten konkretny blok pamięci. API gwarantuje jedynie, że cośnastąpi w wyniku, ale w praktyce wynik jest określony przez szczegóły systemu na następnym niższym poziomie - o którym celowo zapomnieliśmy! Dopóki spełnimy ten warunek, nie ma to znaczenia, ale jeśli nie, atakujący, który dokładnie rozumie oba poziomy, może zwykle kierować zachowaniem całego systemu zgodnie z potrzebami i powodować złe rzeczy.
Przypadki błędów przydziału pamięci są szczególnie złe, ponieważ okazało się, że naprawdę bardzo trudno ręcznie zarządzać pamięcią bez jednego błędu w dużym systemie. Może to być postrzegane jako nieudany przypadek abstrakcji: chociaż można zrobić wszystko, czego potrzebujesz za pomocą C.
malloc
Interfejs API jest po prostu łatwy do nadużyć. Część społeczności programistów uważa teraz, że to niewłaściwe miejsce do wprowadzenia granicy poziomu do systemu i zamiast tego promuje języki z automatycznym zarządzaniem pamięcią i wyrzucaniem elementów bezużytecznych, które tracą trochę mocy, ale zapewniają ochronę przed uszkodzeniem pamięci i nieokreślonym zachowaniem . W rzeczywistości głównym powodem wciąż używania C ++ jest właśnie fakt, że pozwala on dokładnie kontrolować, jakie zasoby są pozyskiwane i zwalniane, kiedy. W ten sposób główną schizmy między zarządzanymi i niezarządzanymi językami można dziś postrzegać jako spór o to, gdzie dokładnie zdefiniować warstwę abstrakcji.To samo można powiedzieć o wielu innych głównych alternatywnych paradygmatach obliczeniowych - problem pojawia się cały czas, gdy trzeba budować duże systemy, ponieważ po prostu nie jesteśmy w stanie zaprojektować od zera rozwiązań dla złożonych, wspólnych wymagań. (W dzisiejszych czasach sztucznym poglądem w AI jest to, że ludzki mózg faktycznie tak działa - zachowanie wynikające z pętli sprzężenia zwrotnego, masowo połączonych sieci itp. Zamiast oddzielnych modułów i warstw z prostymi, abstrakcyjnymi interfejsami między nimi, i dlatego właśnie odniosły tak mały sukces w symulowaniu naszej inteligencji).
źródło