Czasami widzę pytania na temat przypadków skrajnych i innych dziwności w przepełnieniu stosu, na które z łatwością odpowiadają Jona Skeeta i Erica Lipperta, wykazując głęboką znajomość języka i jego wielu zawiłości, takich jak ten:
Możesz pomyśleć, że aby użyć
foreach
pętli, kolekcja, nad którą się iterujesz, musi zaimplementowaćIEnumerable
lubIEnumerable<T>
. Ale jak się okazuje, tak naprawdę nie jest to wymóg. Wymagane jest, aby typ kolekcji miał wywoływaną metodę publicznąGetEnumerator
, i która musi zwracać jakiś typ, który ma wywoływany moduł pobierania właściwości publicznejCurrent
i metodę publiczną,MoveNext
która zwraca abool
. Jeśli kompilator może stwierdzić, że wszystkie te wymagania są spełnione, generowany jest kod, aby użyć tych metod. Tylko jeśli te wymagania nie są spełnione, sprawdzamy, czy obiekt implementujeIEnumerable
lubIEnumerable<T>
.
To fajne rzeczy, które warto wiedzieć. Rozumiem, dlaczego Eric to wie; jest w zespole kompilatorów, więc musi wiedzieć. Ale co z tymi, którzy wykazują tak głęboką wiedzę, ale nie są poufnymi?
Jak zwykli śmiertelnicy (którzy nie należą do zespołu kompilatora C #) dowiadują się o takich rzeczach?
W szczególności, czy istnieją metody, których używają ci ludzie, aby systematycznie wykorzeniać taką wiedzę, eksplorować ją i internalizować (uczynić ją własną)?
źródło
Odpowiedzi:
Po pierwsze, dzięki za miłe słowa.
Jeśli chcesz uzyskać dogłębną znajomość C #, niewątpliwie zaletą jest posiadanie specyfikacji języka, dziesięciu lat notatek projektowych, kodu źródłowego, bazy danych błędów oraz Andersa, Madsa, Scotta i Petera. Z pewnością mam szczęście, nie ma co do tego wątpliwości.
Jednak nawet bez tych zalet nadal można uzyskać głęboką wiedzę na ten temat.
Kiedy zaczynałem w firmie Microsoft, pracowałem nad interpretatorem JScript dostarczanym z programem Internet Explorer 3. Mój menedżer w tym czasie powiedział mi coś, co było jedną z najlepszych rad, jakie kiedykolwiek otrzymałem. Powiedział, że chce, abym został uznanym ekspertem w Microsoft w zakresie składni i semantyki języka JScript, i że powinienem zająć się tym, szukając pytań na temat tych aspektów JScript i odpowiadając na nie. W szczególności odpowiadanie na pytania, na które nie znałem odpowiedzi, ponieważ to są te, z których chciałbym się uczyć.
Oczywiście StackOverflow i inne publiczne fora pytań i odpowiedzi są jak picie z węża strażackiego dla tego rodzaju rzeczy. Wówczas czytałem religijnie comp.lang.javascript i nasze wewnętrzne fora Microsoft „JS User” i postępowałem zgodnie z radą mojego menedżera: kiedy zobaczyłem pytanie dotyczące semantyki języka, na które nie znałem odpowiedzi, zrobiłem to mój interes, aby się dowiedzieć.
Jeśli chcesz wykonać „głębokie nurkowanie”, musisz ostrożnie wybrać. Do dziś jestem niesamowicie nieświadomy działania modelu obiektowego przeglądarki. Ponieważ w ostatnich latach koncentrowałem się na zostaniu ekspertem w języku C #, jestem niesamowicie nieświadomy, jak działają różne klasy w bibliotekach klas podstawowych. Mam szczęście, że mam pracę, która nagradza konkretną głęboką wiedzę; jeśli twoja praca lub twoje talenty są bardziej zgodne z byciem generalistą, pójście głęboko może nie działać dla ciebie.
Bardzo pomocne jest również pisanie bloga; wymagając ode mnie wyjaśniania innym skomplikowanych tematów, jestem zmuszony przez cały czas stawić czoła własnemu niedostatecznemu zrozumieniu różnych tematów.
źródło
Będąc po stronie „guru” raz lub dwa, mogę ci powiedzieć, że często to, co postrzegasz jako „głęboką znajomość” języka lub systemu programowania, jest często wynikiem „guru”, który ostatnio walczył o miesiąc, aby rozwiązać dokładnie ten sam problem. Jest to szczególnie prawdziwe na forum, na którym ludzie mogą wybrać pytania, na które odpowiedzą. Nawet tacy jak Jon Skeet i Eric Lippert musieli w pewnym momencie nauczyć się cześć. Zdobywają wiedzę jedną koncepcję na raz, tak samo jak wszyscy inni.
źródło
Parafrazując jogina bhadżana:
Programowanie jest jak największe wyzwanie dydaktyczne. Nauczenie komputera zrobienia czegoś wymaga, abyś naprawdę dobrze znał swoje umiejętności - lub nauczysz się je opanowywać.
Na przykład, jeśli chcesz nauczyć się fizyki, napisz silnik fizyki. Jeśli chcesz nauczyć się szachów, zaprogramuj grę w szachy. Jeśli chcesz nauczyć się głębokiej wiedzy w języku C #, napisz kompilator C # (lub inne narzędzie).
źródło
O ile mi wiadomo, sposobami na nauczenie się tego są:
Drugi sposób może potrwać znacznie dłużej, ale prawdopodobnie doprowadzi do głębszego zrozumienia (ale nie zawsze).
źródło
Powiedziałbym:
Po nauczeniu się stosunkowo przydatnego zestawu języków (tych, których potrzebujesz do prawdziwej pracy) na poziomie, na którym możesz wykonywać najczęstsze zadania, przestań uczyć się więcej języków, dopóki nie przestudiujesz przynajmniej jednego dogłębnie. Moim zdaniem część problemu w naszej branży polega na tym, że ludzie uczą się pierwszych 5-10% języka, zanim przejdą do innego języka. Gdy będziesz już w stanie wykonywać najczęstsze zadania w pracy, zacznij od głębszej analizy jednego. (Możesz wrócić do poszerzania się po osiągnięciu pewnej głębokości, a następnie poruszać się między nimi.)
Zgłaszaj się na bardziej złożone, trudniejsze zadania, które zmuszają cię do dokładnego rozwiązania problemów. Jeśli nie ma tam, gdzie pracujesz, poszukaj zadań do wykonania na licencji open source lub rozpocznij pracę nad osobistym projektem, który sprawi, że będziesz musiał przejść dogłębnie. Jeśli Twoja praca nie ma interesujących problemów, zastanów się, czy nie znaleźć bardziej wymagającej pracy.
Przeczytaj zaawansowane książki w jednym języku (na przykład w przypadku SQl Server, będzie to obejmowało czytanie o dostrajaniu wydajności i wewnętrznych elementach bazy danych) zamiast uczenia się X za 30 dni.
Przeczytaj interesujące pytania tutaj i inne miejsca, w których są zadawane, i spróbuj rozwiązać je samodzielnie. Jeśli chcesz się uczyć, spróbuj rozwiązać niektóre bez wcześniejszego przeczytania innych odpowiedzi. Nawet jeśli pytanie już zostało udzielone, dowiesz się więcej, jeśli sam znajdziesz odpowiedź. Możesz nawet znaleźć lepszą odpowiedź niż ta, na którą było pytanie.
Zadaj kilka trudniejszych pytań. Oceń odpowiedzi, które otrzymałeś, a nie tylko ich używaj. Upewnij się, że rozumiesz, dlaczego odpowiedź zadziała lub nie. Wykorzystaj te odpowiedzi jako miejsce rozpoczęcia badań.
Znajdź dobre blogi techniczne od znanych ekspertów w tej dziedzinie i przeczytaj je.
Przestańcie wyrzucać swoją wiedzę po jej zakończeniu. Naucz się zachować. Większość ekspertów nie musi szukać wspólnej składni. Nie muszą wymyślać koła za każdym razem, gdy napotykają problem, ponieważ pamiętają, jak wcześniej podeszli do podobnego problemu. Mogą połączyć kropki i zobaczyć, jak problem X, który zrobili dwa lata temu, jest podobny do problemu Y, który mają teraz (zadziwia mnie, jak niewiele osób wydaje się w stanie tworzyć takie połączenia). Dzięki temu mają więcej czasu na badania bardziej interesujących tematów.
źródło
Można zacząć od głęboko przestudiowaniu specyfikacji językowych tych, które starają się być ekspertem off. Na przykład:
źródło
foreach
zachowania opisanego w cytowanym poście na blogu autorstwa Erica Lipperta. Jeśli ktoś kiedykolwiek znajdzie się myśli coś w stylu „Zastanawiam się, jak foreach naprawdę działa ..” to byłoby dobrym miejscem do rozpoczęcia poszukiwań.Zdobądź Reflector lub inny dekompilator (ponieważ teraz płaci) i zacznij otwierać niektóre z najczęściej używanych bibliotek .NET, aby dowiedzieć się, jak działają elementy wewnętrzne. W połączeniu z książką taką jak CLR przez C # dostaniesz się dość głęboko (głębiej niż większość z nas pójdzie do swojej zwykłej pracy).
źródło
BitConverter
klasami i odkryłemIsLittleEndian
flagę specyficzną dla systemu.Tę wiedzę rozwinąłem w C ++, spędzając
comp.lang.c++.moderated
tam kilka lat, chociaż tak naprawdę nie pracowałem tak ciężko, aby w niej napisać kod. Nie jestem jednak pewien, jak guru mogę powiedzieć, że jestem.Myślę, że istnieją dwa rodzaje wiedzy na temat języka programowania:
Numer 2 można osiągnąć tylko przez programowanie w języku i przyglądanie się kodowi innych osób, ale numer 1 można osiągnąć, poświęcając dużo czasu na czytanie o języku na forach dyskusyjnych, sprawdzając, jakie pytania zadają ludzie i jakie odpowiedzi są. StackOverflow to również dobre miejsce do tego.
źródło
Głęboka wiedza i wiedza programistyczna oznaczają wygodę na wszystkich poziomach abstrakcji. To znaczy
Wszystko, co widziałem w ciągu ostatnich 15 lat, pokazało, że tylko jeśli naprawdę możesz dostać się do kompilatora i środowiska uruchomieniowego, masz szansę na głęboką biegłość. Być może będziesz musiał zmusić się do zrobienia kroku i rozpoczęcia rozumowania (i budowania) oprogramowania na kolejnym poziomie abstrakcji niżej na stosie , ale jest to jedyny sposób na ekspertyzę.
Wszystko, co mamy, to język abstrakcji. Musisz zrozumieć, w jaki sposób języki programowania są projektowane i budowane, aby naprawdę wiedzieć, co robi maszyna.
źródło
Przeczytaj dokładny podręcznik Nie jest to szczególnie głęboka wiedza. Jest opublikowany w sekcji 8.6.4 specyfikacji języka C # . Powinieneś mieć zwyczaj przynajmniej przeszukiwania specyfikacji dla używanych języków, a także przeszukiwania dokumentacji dla wszystkich wbudowanych bibliotek.
W każdym razie, to nie jest mój pomysł na głęboką wiedzę; to tylko nieciekawy szczegół implementacyjny. Może być bardziej interesujące, jeśli projektant wyjaśni, dlaczego zostało to zrobione w bardziej dynamiczny sposób, zamiast po prostu sprawdzić, czy obiekt implementuje Iterable.
źródło