Niski poziom jest prosty

0

Niedawno przeczytałem ciekawy artykuł:
http://www.yosefk.com/blog/low-level-is-easy.html
Dosyć długi ale warto przeczytać. Generalnie zgadzam się z gościem, że niski poziom jest prostszy (tj. prostszy koncepcyjnie i mniej upierdliwy). Zastanawia mnie tylko skąd wzięła się powszechna opinia, że jest odwrotnie: że to niski poziom jest trudniejszy?
Zapraszam do dyskusji.

0

Trudne może być przejście z wysokiego poziomu na niski, bo trzeba jednak zmienić sposób myślenia. Nie jest prawdą, że niski poziom to łatwizna i każdy programista javy czy .net bez problemu nagle może przejść na programowanie niskopoziomowe, bo to łatwizna. Ogólnie to całkiem 2 różne rzeczy, ciężko powiedzieć co jest trudniejsze.

A czemu jest uwazany za trudniejszy? Pewnie dlatego że mało jest programistów "niskiego poziomu", a dla reszty to jakaś czarna magia. Tak samo jak reverse-engineering.

0

Ja się z tym nie zgadzam. Znacznie łatwiej jest napisać coś obiektowo. Napisałem wiele programów obiektowo, których albo nie potrafił bym przetłumaczyć na niski poziom, albo zajęło by mi to 5 razy więcej czasu..
Chyba samo założenie zakłada, że wyższy pozio
m jest przyjemniejszy dla człowieka..

0

Ogólnie nauczenie się składni języków niskiego poziomu nie jest trudne, trudne jest dopiero zastosowanie wiedzy w praktyce, bo np. wywołanie funkcji w asemblerze jest trochę bardziej skomplikowane, tak samo jak, np. tworzenie zmiennych lokalnych.
Osobiście uważam, że dużo łatwiej jest przenieść się z C na Asma niż na odwrót bo potem niestety ale programista Asm piszący w C tworzy straszne spaghetti ze względu na przyzwyczajenia, a nie na brak wiedzy.

0

Trudne może być przejście z wysokiego poziomu na niski, bo trzeba jednak zmienić sposób myślenia.

I vice versa. Szczególnie trudne dla niskopodłogowców gdy ma się podejście, że obiektowość to niepotrzebny bajer.

Nie jest prawdą, że niski poziom to łatwizna i każdy programista javy czy .net bez problemu nagle może przejść na programowanie niskopoziomowe, bo to łatwizna.

Akurat ja zrobiłem takie przejście (dokładnie z Javy). Na początku trzeba obczaić zbiór trochę innych zasad potem jest z górki. Na niskim poziomie wszystko jest bardziej przewidywalne i tak na prawdę łatwiej to ogarnąć niż np. takie bazy danych.

0

Z programowaniem niskopoziomowym problem jest taki, że masz do dyspozycji znacznie mniejszy arsenał, a musisz zrobić za jego pomocą dużo. Z kolei, jeśli chodzi o wysoki poziom (java, .net), arsenał jest tak ogromny, że mało kto w całości go ogarnia. Tym bardziej, że nie ma tu zastoju - ciągle pojawiają się usprawnienia, dodatkowe rzeczy i dodatkowe nowe frameworki.

Czyli problemem nie jest zrobienie czegoś, tylko ogarnięcie wszystkiego co się ma do dyspozycji aby osiągnąć cel i poskładanie tego razem w sensowny, logiczny nie tylko dla autora sposób.

0

autor:
Mieszasz dwie różne sprawy:

  1. Łatwość języka: Asembler jest zdecydowanie jednym z najprostszych języków. W zasadzie format instrukcji jest banalny, obsługa wskaźników jest oczywista, składnia (oprócz mnemoników) jest też zwykle dość prosta.
  2. Łatwość tworzenia programów: Programy w asemblerze są wielokrotnie większe, zawierają zwykle zbyt dużo ręcznych optymalizacji, aby analiza składniowa czy refaktoryzacja była efektywna. Wobec tego utrzymywanie kodu asemblerowego złożonego z milionów linijek jest bardzo kosztowne, generalnie koszty rosną dużo szybciej niż przy wykorzystaniu innych języków.

Ja zacząłem programować od czystego asemblera (pomijając HTML/ CSS/ JavaScript), potem K&R C oraz Turbo Pascal. Opanowanie C i Pascala było raczej łatwe, przede wszystkim dlatego, że te języki wiele się od asemblera nie różnią, w zasadzie można powiedzieć, że C to jest przenośny asembler. Problem miałem właśnie przy przejściu na Javę, zrozumienie obiektowości oraz rozróżnienia między zmiennymi statycznymi i zmiennymi instancji trochę mi zajęło (mimo iż używałem zmiennych lokalnych w asemblerze).

W sumie asembler to idealny język, jeżeli chce się dobrze zrozumieć ideę wskaźników.

0

Z programowaniem niskopoziomowym problem jest taki, że masz do dyspozycji znacznie mniejszy arsenał, a musisz zrobić za jego pomocą dużo

Wcale nie musisz zrobić dużo. Dużo to by było jakbyś musiał np. zaimplementować serwer http w assemblerze. Oczywiście zaimplementowanie serwera HTTP w Javie jest znacznie prostsze. Sęk w tym, że nikt nie implementuje serwerów HTTP w assemblerze.
Na niskim poziomie masz zupełnie inne zadania ładnie dostosowane do pracy w niskopoziomowych językach i środowiskach.

0

Ja miałem styczność i z niskim i wysokim poziomem. Dla mnie wysoki poziom jest łatwiejszy. Trochę ciężko mi wyjaśnić dlaczego ale w ogólności chodzi o to, że na wyższym poziomie łatwiej mi zbudować pewną abstrakcję która pomaga przy projektowaniu programu i organizacji kodu. Dzięki obiektowemu podejściu jakoś łatwiej mi rozrysować sobie schemat na kartce, widzę wtedy więcej zależności i jakoś tak samo wychodzi jakich mechanizmów muszę użyć.

0

Jak się wie co się robi to nic nie jest trudne. "Czarna magia" zaczyna się wtedy kiedy człowiek chce zrobić coś czego do końca nie czai.

0

Gdyby niski poziom był łatwiejszy, to po cholerę wysoki był wymyślany?
Dla mnie sprawa jest oczywista. Pisałem na prawdę sporo w rammachine, assemblerze,c,c++ i c# i poziom trudności napisania takiego samego programu maleje wraz z kolejnym jezykiem.

@ zjarek linux jest pisany w czystym c i asm. I nie
ma to nic wspolnego z obiektowoscia.

0

poza tym termin jądro oznacza "nisko poziomowe oprogramowanie systemowe". I jądro możesz sobie nazwać wysoko poziomowym jeżeli uważasz c za wysoko poziomowy..
P.s prosilbym modelatora o złożenie moich postów;)

0

Są jądra pisane w C# i Javie. To znaczy, że te języki są niskopoziomowe?

0

Jakiś przykład takiego jadra?
@Zjarek&&@Endrju zwracam honor, po przeczytaniu linku endrju.
Chociaz zastanawia mnie czy to jest jakies ulatwienie dla niskopoziomowcow, czy tez tylko mozliwosc pokazania, ze sie da;)

0
Kopernik napisał(a)

Gdyby niski poziom był łatwiejszy, to po cholerę wysoki był wymyślany?
Dla mnie sprawa jest oczywista. Pisałem na prawdę sporo w rammachine, assemblerze,c,c++ i c# i poziom trudności napisania takiego samego programu maleje wraz z kolejnym jezykiem.

Już mówłem o tym - Programiści niskopoziomowi nie piszą takich samych programów co programiści wysokopoziomowi. Zadaniem programisty niskopoziomowego jest najczęściej pisanie różnego rodzaju sterowników do sprzętu. Sterowniki są relatywnie małymi programami, które bez problemu można pisać w językach które nie posiadają mechanizmów kontroli złożoności (np. takich jak obiektowość i inne rodzaje abstrakcji), czyli w językach takich jak assembler i C. Dodatkowo raz napisany sterownik najczęściej nie jest modyfikowany, nikt nie żąda co rusz dodawania nowych cool ficzerów do sterowników. Kolejna kwestia, że sterownik wchodzi w interakcje ze sprzętem, który rzadko jest wadliwy. Sprzęt albo działa dobrze albo wypada z rynku (tak jak to się niemal stało z x86 gdy wypuścili procesor z bugiem w FPU).
Programowanie wysokopoziomowe jest prawie dokładnym przeciwieństwem. Programiści wysokopoziomowi muszą pisać i modyfikować mocno złożone systemy - tutaj wprowadzenie abstrakcji jest konieczne. Gdy używasz abstrakcji, przestajesz być świadomym co się dokładnie dzieje w programie, np. wchodzisz w interakcję z bibliotekami lub innymi systemami które często są wadliwe i mają bugi. Gdy natrafisz na buga w bibliotece, to masz 3 opcję:

  • czekasz na fix buga, co się może wydarzyć za kilka miesięcy lub w ogóle może się nie wydarzyć jeżeli biblioteka już nie jest utrzymywana
  • sam naprawić buga - co wymaga zmiany poziomu abstrakcji na którym operujesz. W przypadku prostych bibliotek to może nie być takie trudne, gorzej jak bug jest w czymś mocno złożonym jak np. baza danych
  • szukać obejścia, tzw hacka co nie jest ani proste ani ładne, a czasami niemożliwe
    Więc tak na prawdę nie ma dobrego wyjścia w tym przypadku. Programiści niskopoziomowi rzadko muszą stawać przed takimi dylematami.
0
Kopernik napisał(a)

Gdyby niski poziom był łatwiejszy, to po cholerę wysoki był wymyślany?

Czyli łatwiej zbudować wieżowiec przy użyciu koparek i dźwigów niż drewnianą chatę przy użyciu młotka i piły?

Dla mnie sprawa jest oczywista. Pisałem na prawdę sporo w rammachine, assemblerze,c,c++ i c# i poziom trudności napisania takiego samego programu maleje wraz z kolejnym jezykiem.

Sprawa jest oczywista, dlatego w takich językach nie pisze się takich samych programów.

0

@Koper: C# - Singularity
Java - np. JNode

0

Swego czasu opłacało się pisać komercyjne systemy operacyjne w asemblerze:

http://en.wikipedia.org/wiki/GEOS_(16-bit_operating_system) napisał(a)

Being written directly in object-oriented assembly language (ESP), it also provided much better performance than the relatively sluggish Microsoft Windows 3.0 on 386 and 486 PCs.[1]

0

Idac tym tropem co somekind jezyki wysoko i nisko poziomowe nie mogą być porównywane, bo to tak jakbyśmy porównywali szkołę z dyskoteka. I chyba po namyske, pod tym się podpisuję..

0

nie stawiałbym takiej grubej betonowej ściany pomiędzy „niskim” i „wysokim” poziomem. oświecenie przychodzi w momencie zrozumienia, że wywołanie metody obiektu to wywołanie funkcji z parametrem „this”; że wywołanie funkcji to odłożenie parametrów gdzieś (na stos, do rejestrów) i CALL do funkcji; że instrukcje warunkowe i pętle przekładają się na skoki warunkowe; że ściana nie jest z betonu, tylko najwyżej z papieru i można ją przebić poślinionym palcem.

1

Ja proponuje niskopoziomowcom zrobić mały eksperyment:
Ściągnijcie sobie kod źródłowy jakiejś bazy danych napisanej w wysokopoziomowym języku (np. Cassandra jest napisana w Javie, Mnesia w Erlangu, etc.) i spróbujcie zrozumieć jak to działa. Bez znajomości algorytmów, systemów rozproszonych a w prypadku Mnesi - paradygmatu funkcyjnego jesteście bez szans. A takie rzeczy przecież nie przydają się zbyt często na niskim poziomie więc zdziwiłbym się gdyby jakiś niskopoziomowiec zaprzątał by sobie tym głowę.

Ze swojej strony zrobiłem podobny eksperyment - wczoraj np. analizowałem jak działa sterownik Wiresharka do sniffowania pakietów (WinPcap). Do obczajenia w kilka godzinek bez wielkiej znajomości WDK (w życiu jeden prosty sterownik napisałem).

W sumie to fajnie być programistą niskopoziomowym. W pracy się nie przemęczasz, i jeszcze możesz wmówić innym że twoja robota jest trudniejsza. W końcu 90% programistów myśli, że pod spodem to jakieś czarna magia się dzieje...

0

No to ja proponuję wysokopoziomowcom dowiedzenie się jak odbywa się wywołanie metody wirtualnej oraz optymalizacja takich wywołań w np Javie. Myślę, że mało kto wie co to są v-tables. Poza tym można łączyć np Haskella z asemblerem. No i jeszcze jedna sprawa: zamiast pisać w asemblerze bezpośrednio można skorzystać z intrisincs i pisać w ten dziwaczny sposób kod który korzysta z SIMD czy dziwnych instrukcji.

Wiadomo, iż im więcej się wie, tym lepiej. Np aby napisać dobrą maszynę wirtualną z JIT dla Erlanga czy kompilator dla Haskella trzeba znać zarówno wysoki jak i niski poziom. Język, tak samo jak programowanie niskopoziomowe czy wysokopoziomowe to narzędzie, a nie sposób myślenia, tzn niski poziom stosuje się do pewnych działań, do których się najlepiej nadaje.

ATSD:
Kogoś kto pisze kompilator lub maszynę wirtualną nazwałbyś niskopoziomowcem czy wysokopoziomowcem?

0

Ja proponuje niskopoziomowcom zrobić mały eksperyment:
Ściągnijcie sobie kod źródłowy jakiejś bazy danych napisanej w wysokopoziomowym języku (np. Cassandra jest napisana w Javie, Mnesia w Erlangu, etc.) i spróbujcie zrozumieć jak to działa.

Tutaj to przeholowałeś. Weź np. głównego programistę .net w twojej firmie i poproś aby wytłumaczył ci jak to działa. Jestem w 90% pewien że nie będzie potrafił pomimo że to napisane w języku wysokiego poziomu.

Z tego co zauważyłem, aby być dobrym programistą wysokiego poziomu np. w .net wystarczy:

  • świetnie znać entity framework i inne orm jak nhibernate
  • świetnie znać wpf i wielowątkowość w .net
  • o znajomości składni i sposobu wykonywania typowych zadań (czego użyć, jakiej klasy, w jaki sposób) już nawet nie wspominam bo oczywiste
  • przyjąć sobie pewne wzorce przy pisaniu kodów i tylko ich się trzymać (najczęściej w firmie obowiązuje jedna konwencja i wszyscy do niej się stosują) - mowa o hierarchii klas, nazewnictwie metod, zmiennch itd itp

Żaden z typowych wysokopoziomowców, nie ma pojęcia np o:

  • jak działa baza danych (to co pisanne wcześniej) - nie jak używać, tylko jak działa wszystko od środka
  • nic na temat winapi
  • nie implementuje samodzielnie żadnych algorytmów, np szyfrowania itd (jak nie ma w frameworku to nie używamy tego)

Tylko też zadajmy sobie pytanie, czy to co podałem rzeczywiście często jest potrzebne dla programisty wysokiego poziomu, ja twierdzę że rzadko a właściwie prawie nigdy

0

Żaden z typowych wysokopoziomowców, nie ma pojęcia np o:

  • jak działa baza danych (to co pisanne wcześniej) - nie jak używać, tylko jak działa wszystko od środka

Zauważ, że ci co pisali Cassandrę musieli wiedzieć jak działa bazę danych ;).

Tylko też zadajmy sobie pytanie, czy to co podałem rzeczywiście często jest potrzebne dla programisty wysokiego poziomu, ja twierdzę że rzadko a właściwie prawie nigdy

Wychodzę z założenia, że każdy powinien chociaż mniej więcej wiedzieć jak działają warstwy, która znajduje się poniżej z tego z czego aktualnie korzysta. Czyli im wyższy poziom tym więcej wiedzy do przyswojenia. Jak ktoś nie wie jak działa baza danych to znaczy, że będzie miał spory problem gdy będzie ją musiał kiedyś zoptymalizować.
Wiedza z niższych poziomów głównie jest potrzeba do:

  • optymalizacji
  • obchodzenia/fixowania błędów w niższych poziomach - a generalnie im wyższy poziom tym większa szansa, że na któymś poziomie jest błąd w oprogramowaniu (dlaczego, jest to ładnie wyjaśnione w artykule z pierwszego postu).
0

W Comarchu wielcy analitycy nie wiedzieli dlaczego, gdy podzielą sobie tabelę na dwie tabele, to zapytanie do połówki trwa praktycznie tyle samo co zapytanie do pełnej tabeli. Oczywiście zapytanie było na zaindeksowanych kolumnach. Bynajmniej nie jest to wiedza niskopoziomowa - nie trzeba znać szczegółów implementacyjnych struktur danych (czy też samodzielnie je implementować), aby wiedzieć jakie mają własności. To jest w zasadzie podstawowa sprawa, którą należy znać, aby w ogóle myśleć o projektowaniu wydajnych systemów baz danych.

0

A wyjasnij prosze ten watek z tabelami? Jak byly dzielone? Partycjonowane dane (czyli obie tabele mialy te same kolumny i polowe danych) czy obie tabele mialy czesci kolumn z jednej tabeli?

0

No to dlaczego trwalo tyle samo?

0

Bo jest polowa mniej danych? Chyba ze byly dziesiatki rekordow, wtedy caly czas i tak trwalo parsowanie zapytania, i dane byly ladnie w kubeczkach ktorych bylo tyle samo. Ale naprawede nie wiem.

0

No, niech ktoś spróbuje zgadnąć :D

A dlaczego miałoby trwać szybciej?

Zapytanie do połówki trwało niewiele szybciej niż zapytanie do pełnej tabeli. Aby uzyskać wszystkie dane należałoby albo wysłać zapytania do dwóch połówek albo do pełnej tabeli. Skoro zapytanie do połówki trwało niewiele mniej niż zapytanie do pełnej to dwa zapytania do połówek trwały w sumie sporo więcej niż jedno zapytanie do pełnej tabeli.

Update:
0x20 podał dobrą odpowiedź. Jak widać mało kto wie jak baza działa.

1 użytkowników online, w tym zalogowanych: 0, gości: 1