W podcastie 73 Joel Spolsky i Jeff Atwood rozmawiają między innymi o „pięciu rzeczach, których każdy powinien nienawidzić w swoim ulubionym języku programowania”:
Jeśli jesteś zadowolony ze swojego obecnego łańcucha narzędzi, nie ma powodu, aby zmieniać. Jeśli jednak nie możesz wymienić pięciu rzeczy, których nienawidzisz w swoim ulubionym języku programowania, to twierdzę, że nie znasz go wystarczająco dobrze, aby go ocenić. Dobrze jest być świadomym alternatyw i mieć zdrowe oko krytyczne na to, czego używasz.
Z ciekawości zadałem to pytanie każdemu kandydatowi, z którym przeprowadziłem wywiad. Żaden z nich nie był w stanie zacytować przynajmniej jednej rzeczy, której nienawidzi w C # ¹.
Czemu? Co jest takiego trudnego w tym pytaniu? Czy ze względu na stresujący kontekst rozmowy respondenci nie mogą odpowiedzieć na to pytanie?
Czy jest coś w tym pytaniu, co czyni go złym do rozmowy kwalifikacyjnej?
Oczywiście nie oznacza to, że C # jest idealny. Mam listę pięciu rzeczy, których nienawidzę w C #:
Brak zmiennej liczby typów w nazwach ogólnych (podobnie jak w
params
przypadku argumentów).
Action<T>
,
Action<T1, T2>
,
Action<T1, T2, T3>
,
⁞ Poważnie ?!
Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>
Brak wsparcia dla jednostek miary, jak w F #.
Brak właściwości tylko do odczytu. Pisanie
private readonly
pola zaplecza za każdym razem, gdy chcę właściwość tylko do odczytu, jest nudne.Brak właściwości o wartościach domyślnych. I tak, wiem, że mogę zainicjować je w konstruktorze bez parametrów i wywołać je ze wszystkich innych konstruktorów. Ale nie chcę.
Wielokrotne dziedziczenie. Tak, powoduje zamieszanie i nie potrzebujesz go w większości przypadków. Nadal jest użyteczny w niektórych (bardzo rzadkich) przypadkach, a zamieszanie dotyczy również (i zostało rozwiązane w języku C #) klasy, która dziedziczy kilka interfejsów zawierających metody o tej samej nazwie.
Jestem prawie pewien, że ta lista jest daleka od ukończenia, i jest o wiele więcej punktów do podkreślenia, a zwłaszcza o wiele lepsze niż moje.
¹ Kilka osób skrytykowało niektóre zestawy w .NET Framework lub brak niektórych bibliotek w frameworku lub skrytykowało CLR. To się nie liczy, ponieważ pytanie dotyczyło samego języka i chociaż potencjalnie mógłbym zaakceptować odpowiedź na coś negatywnego w rdzeniu .NET Framework (na przykład coś takiego jak fakt, że nie ma wspólnego interfejsu TryParse
, więc jeśli chcesz parsować ciąg do kilku typów, musisz powtórzyć się dla każdego typu), odpowiedź na temat JSON lub WCF jest całkowicie nie na temat.
Why the question “give five things you hate about C#” is so difficult to answer
Ponieważ jest to pytanie z listy, a zły modOdpowiedzi:
Gdybym musiał zgadywać:
Niektórym programistom brakuje różnorodnej znajomości języka. Trudno jest dostrzec, że coś jest nie tak z językiem, jeśli nie wiesz, że istnieją lepsze rzeczy.
Niektórzy programiści są zwykłymi małpami kodowymi. Ledwo analizują stojące przed nimi problemy, nie mówiąc już o tym, jak ich język programowania mógłby być lepszy.
Niewiele osób jest szczególnie krytycznych. Widzą zalety i funkcje, a nie niedociągnięcia. Trudno im przejść do takiego sposobu myślenia, jeśli wywiad nie idzie w tym kierunku.
Przynajmniej w tym miejscu nadmierna krytyczność postrzegana jest jako śmiertelna wada osobowości. Zamiast być „wnikliwym deweloperem, który zawsze szuka lepszych sposobów robienia rzeczy” (jak niektóre obszary, w których mieszkałem), są „dupkiem, który nienawidzi wszystkiego”. Nawet ludzie, którzy potrafią myśleć o rzeczach, których nienawidzą w tym języku, mogą odłożyć się na rozmowę kwalifikacyjną, by wydawać się mniej ostra.
źródło
Wyobrażam sobie, że na pytanie trudno jest odpowiedzieć podczas wywiadu, ponieważ:
Naprawdę nieoczekiwane
Wymaga dużo myślenia i myślenia w zupełnie inny sposób niż podczas wywiadu,
Na ogół trudno jest odpowiedzieć w krótkim czasie (chyba że zostanie przygotowany przed rozmową kwalifikacyjną).
1. To nieoczekiwane
Nieoczekiwane pytania są naprawdę trudne, szczególnie w stresującym kontekście. Wyobraź sobie następujące okno dialogowe podczas wywiadu:
2. Wymaga to różnego myślenia
Kiedy zadawane są ogólne pytania typu wywiad, używasz pamięci, aby przypomnieć sobie, czego nauczyłeś się z książek lub z praktyki na temat języka i frameworka. Możesz trochę pomyśleć, aby znaleźć odpowiedź, ale nie za dużo.
Z drugiej strony pytanie o pięć rzeczy, których nienawidzisz, wymaga głębszego przemyślenia. Nie możesz po prostu przypomnieć sobie czegoś, czego nauczyłeś się z książek, i nie możesz niczego znaleźć przez analogię. Zamiast być biernym, musisz być krytykiem i znaleźć to, co może być nieprzyjemne w języku, którego używasz.
3. Wymaga czasu
Szczerze mówiąc, mam swoją listę pięciu (właściwie więcej) rzeczy, których nienawidzę w C #, ale myślałem o tym przez długi okres czasu. Kilka rzeczy pochodzi z ery .NET Framework 2; większość problemów wymienionych dla .NET Framework 2 nie jest już ważna, ponieważ zostały usunięte, niektóre z LINQ i wszystkimi innymi funkcjami programowania, inne z programowaniem dynamicznym. Nie jestem pewien, czy bez przygotowania tego pytania byłbym w stanie znaleźć wszystkie pięć elementów podczas wywiadu.
źródło
Myślę, że to trudne ze względu na słowo piąte . I w mniejszym stopniu z powodu słowa nienawiść .
Pięć ? Co jeśli wymyślisz tylko cztery? Nie odpowiedziałeś na pytanie? Co jeśli masz więcej niż pięć? Teraz na miejscu musisz dowiedzieć się, który z nich jest najlepszy do użycia.
Nienawiść to bardzo negatywne słowo. Jest to rodzaj negatywności, której ludzie powinni unikać podczas wywiadów. Co więcej, myślę, że to brzmi dziwnie, wielu ludzi ma, że wiele rzeczy, które „hate” o języku będą spędzać całe programowanie dniową u niektórych osób może nawet pomyśleć, że to podchwytliwe pytanie. Jeśli oni rzeczywiście mają pochodzić z pięcioma rzeczami, zostaną zdyskwalifikowani za zbytnie nienawidzenie C #, aby dobrze się programować. Niestety, tego rodzaju przewrotne pytanie o sztuczkę nie jest niespotykane w wywiadach.
Zamiast tego możesz zapytać Co poprawiłbyś o C #, gdyby to zależało od ciebie? To pozwala rozmówcy odpowiedzieć na dowolną liczbę rzeczy. To wyrażenie zamienia również negatywność słowa „nienawiść” w stosunku do względnie pozytywnego „ulepszenia”.
źródło
Disposed
, ale przy braku wymogu wymuszania tego przez wszystkie języki, można argumentować, że języki, które to robią, wzbudzają fałszywe oczekiwania. Może być zatem niejasne, czy trudność uniknięcia wycieku zasobów w przypadku awarii konstruktora C # należy winić za C # lub CLS.Większość kandydatów nie jest tak głęboko zaangażowana w więcej niż jeden język lub paradygmat, aby się przeciwstawić . Nie pracuję z innym językiem obiektowym od ponad 5 lat, a w tym, w którym pracowałem (PowerBuilder), miałem dużorękawów z. Większość facetów świeżo po studiach jest (lub myśli, że są) gorącymi rzeczami w jednym, może w dwóch językach, i otrzymali „kontakt” z trzema lub czterema innymi (co oznacza, że wykonali co najmniej jedno zadanie domowe wymagające tego, ale mniej niż pełny semestr oczywiście studiowanie). To za mało wiedzy lub doświadczenia, aby naprawdę wiedzieć, co jest nie tak z językiem. Znajdź pracę w prawdziwym świecie, a ta koncentracja znacznie się zawęzi; dowiadujesz się znacznie więcej o języku, który daje ci wypłatę niż jakikolwiek inny, a następnie przychodzisz do zaakceptowania tego, czego ten język nie zrobi lub robi w dziwny sposób, do tego stopnia, że nie pamiętasz robić to inaczej.
Większość zadowolonych z języka C # kandydatów, którzy porównują go do Java / C / C ++, jest z tego bardzo zadowolona . C # został zaprojektowany od podstaw, aby robić wiele rzeczy lepiej niż Java (zdarzenia, wywołania zwrotne, biblioteka grafiki, praca z bazą danych). Z kolei Java została zaprojektowana tak, aby była łatwiejsza w użyciu, a więc bardziej skupiona na poprawnym kodzie niż C ++. Jeszcze nie spotkałem programisty C #, który chce wrócić do C ++ w każdym środowisku, w którym zawrotna wydajność i kontrola na poziomie zbliżonym do obwodu nie są krytycznymi potrzebami.
Innymi słowy, See-Sharpers mają to całkiem niezłe, biorąc pod uwagę wszystko.
Oto moja lista:
Nie można oglądać / oceniać instrukcji lambda . Wywołania nazwanych metod można podłączyć do QuickWatch VS. Podobnie wyrażenia. Ale lambdas? Nie (przynajmniej nie w VS2010). Sprawia, że debugowanie łańcuchów Linq staje się prawdziwym obowiązkiem.
Opcjonalne wartości parametrów dla typów referencyjnych innych niż łańcuch mogą mieć wartość null . gdybym tworzył stos przeciążenia, może chciałbym użyć innych ustawień domyślnych. Mogę być w stanie ustawić jedną wartość na podstawie właściwości lub prostego wyrażenia na podstawie innego parametru. Ale nie mogę. Tak więc wartość braku konieczności tworzenia stosu przeciążenia (co jest niewielkie w przypadku asystenta refaktoryzacji, takiego jak ReSharper do obsługi płyty kotłowej) jest zmniejszona, gdy opcje parametrów opcjonalnych są tak drastycznie ograniczone.
C # staje się wystarczająco stary, aby mieć poważne problemy ze starszym kodem . Kod pierwotnie napisany dla 1.1 sprawiłby, że każdy, kto przyzwyczaił się do wersji 4.0, zaczął się przerażać. Nawet kod 2.0 bardzo często mija. W tym samym czasie pojawiły się biblioteki innych firm, które sprawiają, że takie rzeczy jak ADO.NET wydają się żałośnie prymitywne (a duża część „podłączonego modelu” ADO.NET jest teraz dużym anty-wzorcem). Jednak ze względu na zgodność z poprzednimi wersjami .NET obsługuje cały ten stary, zły kod, nigdy nie ośmielając się powiedzieć czegoś takiego: „ArrayList był kiepskim sposobem na zrobienie tego, przykro nam, że to zrobiliśmy i bierzemy obecnie, użyj Listy zamiast, a jeśli absolutnie potrzebujesz listy różnych typów, zadeklaruj ją jako
List<Object>
.Poważnie ograniczone reguły instrukcji switch . Prawdopodobnie jedną z najlepszych rzeczy, które mogę powiedzieć o PowerBuilder, jest to, że instrukcja Select Case (odpowiednik przełącznika) zezwala na wyrażenia logiczne na podstawie zmiennej. Pozwoliło to również na przewrócenie instrukcji switch, nawet jeśli miały kod. Rozumiem powody, dla których ten drugi jest niedozwolony (jest bardziej prawdopodobne, że zostanie to zrobione nieumyślnie niż celowo), ale od czasu do czasu miło byłoby napisać takie zdanie:
źródło
Bag<Fruit> bag = Bag<Huckleberry>
oznaczałoby, że możesz zrobić,bag.add(new Watermelon())
co nie mogło go utrzymać.Thing<out T>
ma pole statyczne, do którego dostęp ma zarówno metoda instancji, jak i metoda statyczna. Jeśli aThing<Cat>
jest przekazywane do metody, która oczekuje aThing<Animal>
, i ta metoda wywołuje wspomniane powyżej wystąpienie i metody statyczne wThing<Animal>
odniesieniu, do jakich pól statycznych powinny mieć dostęp te metody?Sugerowałbym, że częścią problemu jest strach przed udzieleniem złej odpowiedzi - mówisz, że nienawidzisz X, ankieter uwielbia X lub myślisz, że twój powód nienawidzenia X jest idiotyczny, mówiąc, że uważasz, że to w porządku może wydawać się mniej kontrowersyjną opcją.
Jest to prawdopodobnie coś, o czym większość ludzi tak naprawdę nie zastanawiała się; mają bieżące problemy i problemy z przeszłości, problemy z przeszłości, które były spowodowane przez język, zostały zakończone, więc ludzie głównie myślą o rozwiązaniu, a nie o problemie, ponieważ był on bardziej znaczący, a niewielu będzie miało obecny problem spowodowany przez język.
źródło
Na rozmowę poprosiłbym tylko o 1 lub 2, ale zgadzam się, jeśli nie potrafisz wymienić żadnych ograniczeń używanego narzędzia, to prawdopodobnie nie znasz go zbyt dobrze. Zadajemy dokładnie to pytanie dotyczące SSIS i naprawdę pomaga oddzielić pszenicę od plew; wszyscy, których zatrudniliśmy, którzy dobrze odpowiedzieli na to pytanie, stali się świetnym pracownikiem. Potrzebujemy ludzi, którzy posiadają zaawansowaną wiedzę, a nie kogoś, kto spojrzał na nią kilka razy. Założę się, że tego też chcesz.
Myślę, że to ważne pytanie, a fakt, że tak wielu nie mogło na nie odpowiedzieć, jest tylko przykładem tego, jak bardzo biedni jest wielu kandydatów do pracy. Jeśli ktoś nie jest wystarczająco analityczny, aby zrozumieć pewne ograniczenia tego narzędzia, to w jaki sposób będzie wystarczająco analityczny, aby rozwiązać trudne problemy programistyczne?
źródło
Sprowadza się to do tego, jak powiedziałeś, brak dogłębnego doświadczenia z C # i / lub brak kontaktu z innymi językami. Przeprowadziłem wywiad z wieloma programistami, którzy uważali się za starszych, którzy nie byli w stanie odpowiedzieć na pytania, które nawet lekkie rysy na powierzchni C # powinny były im ujawnić.
Bez wystarczającego kopania nie osiągniesz granic języka i nie żałujesz, że ich nie ma. Moja pierwsza piątka na wypadek, gdyby ktoś się zastanawiał
źródło
Myślę w jego kręgu o tym, co mówi; jeśli uważasz, że jest zepsuty, prawdopodobnie nie rozumiesz, dlaczego tak jest. W twojej wiedzy może być dziura.
Jak na ironię, ankieterzy, którzy myślą, że cytują „wielkiego Joela”, używając go jako pytania do wywiadu, prawdopodobnie raczej nie rozumieją tego.
źródło
Mogą niechętnie odpowiadać, ponieważ mogą mieć wrażenie, że jeśli potrafią wymienić 5 rzeczy, których nienawidzą w języku, ankieter może się odwrócić i powiedzieć „Och, szukamy ninja C #”, a ty nie wydajesz się polubić język ”lub„ Dlaczego złożyłeś podanie o pracę, jeśli nie podoba ci się ten język? ”.
Respondenci są pod dużą presją, aby pozostać pozytywnymi podczas wywiadów.
źródło
Ponieważ języki kształtują nasz sposób myślenia . Używając C # na co dzień, przyzwyczaiłeś się do myślenia i projektowania kodu w sposób, który naturalnie rozwiązuje problemy języka.
Robisz to teraz bez zastanowienia, nawet nie wiedząc, że to robisz. Dlatego tak trudno jest wskazać, jakie są złe rzeczy. Bez wątpienia w dniu, w którym zacząłeś uczyć się języka C #, natrafiłeś na wiele problemów, ale teraz już ich nie widzisz. Nawyki to potężne rzeczy. Zwyczaje myślowe, a nawet więcej .
Pozytywną stroną tego jest to, że jeśli trudno ci wymienić błędy w C #, to musi być tak, że jesteś dobrym programistą w C #, lubisz język i używasz go bardziej niż innych języków.
Ale jeśli chcesz lepiej widzieć wady w C #, musisz zmienić sposób myślenia. Dowiedz się więcej języków programowania i przyzwyczaj się do nich. Celuj w możliwie różne języki. Jesteś przyzwyczajony do pisania statycznego? Wypróbuj Python lub Ruby. Jesteś przyzwyczajony do obiektowego i imperatywnego? Haskell to zupełnie inny świat.
A kiedy wrócisz do C #, pomyślisz: „Dlaczego potrzebuję stu linii C #, aby zrobić tę prostą rzecz, która jest tylko jedną linią w Haskell?”. Nienawidzisz wielu rzeczy o C #.
(Oczywiście żaden język nie może mieć wszystkiego. Projektowanie języka jest niezwykle trudne, a dodanie każdej funkcji do tego samego języka nie działa. Różne narzędzia do różnych celów.)
Tak, na pytanie trudno odpowiedzieć dobrze, szczególnie podczas wywiadu. Ale ludzie, którzy potrafią na to odpowiedzieć, dowodzą, że pomyśleli o tym, że mają jakąś perspektywę.
źródło
(a, b) = this.something();
czegoś podobnego w Pythonie) jest pierwszą rzeczą, jaka przychodzi mi do głowy.