O co chodzi z rynkiem pracy IT?

3
1a2b3c4d5e napisał(a):

@meehow.cpp:

Poza tym strasznie mnie wkurza, to jaranie się wzorcami projektowymi. Gdy rzeczywiście mocno do nich przysiadłem, zdałem sobie sprawę ile fabryk postawiłem, ile fasad, ile adapterów nawet nie wiedząc, że są to wzorce i że stosuję jakieś wzorce... :D

nice, no to jaki problem jest aby douczyć się jak coś się nazywa aby efektywniej komunikować się z innymi ludźmi?

Komunikować? Do czego Ci ta nazwa potrzebna? Ponad 7 lat w tym siedzę.
Czy to taki problem? Hmmmm... Zapewniam, że można ten czas poświęcić na o wiele pożyteczniejszą naukę.

4

@meehow.cpp:

Komunikować? Do czego Ci ta nazwa potrzebna? Ponad 7 lat w tym siedzę.

no aby móc powiedzieć / napisać komuś ee strzel sobie tu buildera / state machine / czy odwiedzacza zamiast pisać pół strony tekstu?

Zapewniam, że można ten czas poświęcić na o wiele pożyteczniejszą naukę.

Ile tego czasu "zaoszczędzisz"?

7
meehow.cpp napisał(a):

Poza tym strasznie mnie wkurza, to jaranie się wzorcami projektowymi. Gdy rzeczywiście mocno do nich przysiadłem, zdałem sobie sprawę ile fabryk postawiłem, ile fasad, ile adapterów nawet nie wiedząc, że są to wzorce i że stosuję jakieś wzorce... :D

Bo to nie jest żadna czarna magia, tylko sposoby organizacji obiektów w kodzie, odpowiednik budowy zdań w języku naturalnym. Całkiem sporo można odkryć samemu, intuicyjnie, w drodze samorozwoju.
Wzorcami jarają się nimi co najwyżej kandydaci i słabsi programiści, którzy ich nie ogarniają, ale zakuwają teorię przed rozmowami kwalifikacyjnymi. To oni narzekają na forach, że "o borze, po co te pytania z wzorców, jak ich się nie używa". Dla całej reszty to po prostu element pracy, jak skróty klawiaturowe w IDE.

Nie pytacie na tych swoich śmiesznych rozmowach o rzeczywiste umiejętności - ile razy gdy wlazłem w mięcho, słyszałem po krótkiej chwili "ale nie wchodźmy aż tak w szczegóły".

Czym Twoim zdaniem są rzeczywiste umiejętności? Czemu wzorce projektowe albo pisanie kodu zgodnie z DRY to nie są rzeczywiste umiejętności?

meehow.cpp napisał(a):

Komunikować? Do czego Ci ta nazwa potrzebna? Ponad 7 lat w tym siedzę.

Czyli nie po to szedłeś w IT, żeby z ludźmi rozmawiać? ;)

3
1a2b3c4d5e napisał(a):

@meehow.cpp:

Komunikować? Do czego Ci ta nazwa potrzebna? Ponad 7 lat w tym siedzę.

no aby móc powiedzieć / napisać komuś ee strzel sobie tu buildera / state machine / czy odwiedzacza zamiast pisać pół strony tekstu?

Kurde. 10 lat pracuję jako programista i nigdy w pracy odwiedzającego nie napisałem :D
Raz maszynę stanów poprawiałem, tylko że nigdy nie słyszałem o takim wzorcu jak maszyna stanów :D
Kilka razy dodawałem funkcjonaljośc do builderów, ale to były takie uproszczone buildery, a nie takie prawilne z GoF. Takiego prawilnego to też nigdy nie widziałem w kodzie produkcyjnym
A pyłek? Implementował ktoś pyłek?

BTW ja to się bardzo cieszę że na rozmowach rekrutacyjnych ze Scali nie pytają o wzorce i dobre praktyki (za wyjątkiem TDD).
Za to pytają z nowych featurów Scali 3, Monad, Transformarów Monad, Catsów, i Catsów Effect. Czyli z rzeczy których faktycznie używa się w pracy

Update

somekind napisał(a):

Czemu wzorce projektowe albo pisanie kodu zgodnie z DRY to nie są rzeczywiste umiejętności?

No ale to że zapytasz kandydata czy pisze kod zgodnie z DRY to nie jest żaden dowód że rzeczywiście pisze z DRY. Musiałby napisać jakiś kod który mógłby tobie pokazać. Oraz musiałby mieć na tyle dużo czasu żeby móc zastosować DRY i wzorce. O ile komuś chciało by się rzeźbić np Buildera dla kodu który i tak zaraz pójdzie do zaorania

Update 2

Jak przeszedłem do Scali to wiele wzorców jest dla mnie martwych. Np:

  • Singleton - jest częścią języka
  • Iterator - część biblioteki standardowej
  • Builder zamiast konstruktora - niepotrzebny bo są parametry nazwane i domyślne wartości parametrów
  • Odwiedzający - Odersky go odradza i poleca używac Pattern Matchingu
  • Strategia - u nas to lamdy i funkcja wyższego rzędu są
  • Pamiątka - a po co to komu jak promowane są case classy i programowanie funkcyjne :P
3

Kurde, to w takim razie jak będę kiedyś rekrutował programistów to będę się pytał z jakich monad korzystają. Bo jak powiedzą że nie wiedzą co to monady to znaczy że nie umieją korzystać ze Streamów ani Optionali.

ee strzel sobie tu buildera / state machine / czy odwiedzacza

Odwiedzacza? You mean Sealed Class + switch pattern matching?
A, i jak sobie do filter wstawiam lambdę to mam powiedzieć że to strategia? xD

4
chomikowski napisał(a):

@piotrpo: no to mozesz uzyc przeciez Lazy Loading do Singletona i nie bedziesz musial powolywac obiektu jesli nie zajdzie taka potrzeba a w dodatku dodasz sobie static metody i masz dostep do metod bez tworzenia instancji tej klasy nawet. Wyuczyles sie jakis regulek i powtarzasz to co inni :) Singleton nie jest zadnym antywzorcem pod warunkiem ze wiesz jak i gdzie go stosowac.

Jest, i to strasznym.

Idea istnienia jednej instancji obiektu w aplikacji jest okej, np jedna instancja połączenia z bazą - pod warunkiem że traktujesz ją z głową, przekazujesz ją fabrykami, kompozytami, dekoratorami lub innymi wzorcami. Ale jak dodajesz dostęp do tej instancji, nie w normalny sposób (typu argumenty funkcji lub pola klas), tylko poprzez globalny stan albo statyczne funkcje jak getInstance(), to to jest dokładnie to co mówi @piotrpo - turbo anty wzorzec.

scibi_92 napisał(a):

Kurde, to w takim razie jak będę kiedyś rekrutował programistów to będę się pytał z jakich monad korzystają. Bo jak powiedzą że nie wiedzą co to monady to znaczy że nie umieją korzystać ze Streamów ani Optionali.

Może nie za raz że nie umieją korzystać; ale ja bym powiedział że nie rozumieją do końca ich idei, istoty, i tego czemu faktycznie są pomocne. Nie trzeba wiedzieć jak działa silnik, żeby prowadzić, ale jak jesteś zawodowym rajdowcą, to lepiej żebyś wiedział co to jest moment obrotowy i dokładnie jak działa skrzynia.

scibi_92 napisał(a):

A, i jak sobie do filter wstawiam lambdę to mam powiedzieć że to strategia? xD

Ja chyba też bym powiedział ze przekazanie callbacka/lamdy to coś bardzo podobnego do strategii (a możliwe że nawet tożsamym). Niektóre języki zacierają granicę między implementacjami interfejsów a funkcjami.

KamilAdam napisał(a):

Kurde. 10 lat pracuję jako programista i nigdy w pracy odwiedzającego nie napisałem :D

Ja w pracy niby też nie, bo i po co.

Ale w prywatnych projektach kilka razy tak, zwłaszcza tam gdzie jest dużo relacji, np w parserach, jak chcesz iść w Dependency Inversion.

0

@somekind:

Czym Twoim zdaniem są rzeczywiste umiejętności? Czemu wzorce projektowe albo pisanie kodu zgodnie z DRY to nie są rzeczywiste umiejętności?

A mógłbyś zacytować, gdzie napisałem, że wzorce są złe? Albo gdzie napisałem, że stosowanie zasady DRY jest złe?
DRY - to jest tak oczywista oczywistość... Tylko jak Ci ktoś walnie jakimś skrótowcem QWERTY...

Czyli nie po to szedłeś w IT, żeby z ludźmi rozmawiać? ;)

Nie, nie po to. Poszedłem do IT po to by programować, a obecnie tak się fajnie złożyło, że i popracować ze sprzętem.

A co myślisz o zasadzie PPK? Nie mam na myśli planów kapitałowych. Chodzi mi o zasadę w programowaniu.

0
scibi_92 napisał(a):

Kurde, to w takim razie jak będę kiedyś rekrutował programistów to będę się pytał z jakich monad korzystają. Bo jak powiedzą że nie wiedzą co to monady to znaczy że nie umieją korzystać ze Streamów ani Optionali.

ee strzel sobie tu buildera / state machine / czy odwiedzacza

Odwiedzacza? You mean Sealed Class + switch pattern matching?
A, i jak sobie do filter wstawiam lambdę to mam powiedzieć że to strategia? xD

I to jest z d**y, bo też to kiedyś rozkminiałem. Wzorce takie jak strategy, command czy state to to samo: ktoś uznał, że warto nazwać interfejs znany z Javy różnymi nazwami, żeby było śmiesznie. Nie widziałbym problemu, gdyby przypadki użycia całkowicie się wykluczały ale tak oczywiście nie jest.

Riddle napisał(a):

Idea istnienia jednej instancji obiektu w aplikacji jest okej, np jedna instancja połączenia z bazą - pod warunkiem że traktujesz ją z głową, przekazujesz ją fabrykami, kompozytami, dekoratorami lub innymi wzorcami. Ale jak dodajesz dostęp do tej instancji, nie w normalny sposób (typu argumenty funkcji lub pola klas), tylko poprzez globalny stan albo statyczne funkcje jak getInstance(), to to jest dokładnie to co mówi @piotrpo - turbo anty wzorzec.

Sama idea, że klasa może istnieć w tylko jednej instancji to oczywiście błąd, ale czasami widzę zastosowanie na używanie globalnych zmiennych, jeśli podnoszą performance albo ułatwiają trywialny kod. Np. cachowanie regexów w pythonie jest spoko, bo python to i tak wolny język i często deweloperzy używają pakiet re ad-hoc bez re.compile, bo im się nie chcę w głupim skrypcie. Albo większość języków/bibliotek pozwala na wołanie serwisów HTTP używając globalnego klienta, który cachuje połączenia TCP/HTTP. Niech pierwszy rzuci kamień kto zawołał serwis HTTPS bez utworzenia fabryki certyfikatów xd, programista nawet nie musi wiedzieć, że istnieje takie coś jak SSL, żeby zrobić poprawnego calla

0
KamilAdam napisał(a):

Kurde. 10 lat pracuję jako programista i nigdy w pracy odwiedzającego nie napisałem :D

Ja pracuję nieco dłużej, też odwiedzającego nie pisałem. Podobnie jak nie pisałem obserwatora czy iteratora, bo te akurat są wbudowane w język.
Tylko co z tego? Ktoś pyta na rozmowach o wzorce, których się nie używało? :)

BTW ja to się bardzo cieszę że na rozmowach rekrutacyjnych ze Scali nie pytają o wzorce i dobre praktyki (za wyjątkiem TDD).
Za to pytają z nowych featurów Scali 3, Monad, Transformarów Monad, Catsów, i Catsów Effect. Czyli z rzeczy których faktycznie używa się w pracy

Ale jakie monady? Toć to zbędna teoria, jak wzorce projektowe w OOP.

No ale to że zapytasz kandydata czy pisze kod zgodnie z DRY to nie jest żaden dowód że rzeczywiście pisze z DRY. Musiałby napisać jakiś kod który mógłby tobie pokazać. Oraz musiałby mieć na tyle dużo czasu żeby móc zastosować DRY i wzorce.

Oczywiście, że nie, dlatego ja uważam, że najlepsza rekrutacja jest przez kod, a nie tylko pogaduszki.

  • Builder zamiast konstruktora - niepotrzebny bo są parametry nazwane i domyślne wartości parametrów

To taki słaby zamiennik. Konstruktora nie nazwiesz, a metody buildera tak.

meehow.cpp napisał(a):

A mógłbyś zacytować, gdzie napisałem, że wzorce są złe? Albo gdzie napisałem, że stosowanie zasady DRY jest złe?

A mógłbyś zacytować, gdzie ja napisałem, że Ty napisałeś, że te rzeczy są złe? Ja pytam czemu uważasz, ze to nie są rzeczywiste umiejętności w pracy programisty, bo tak brzmiały dla mnie Twoje słowa z poprzedniego postu - narzekasz na takie pytania, zamiast pytania o "rzeczywiste umiejętności".

Nie, nie po to. Poszedłem do IT po to by programować, a obecnie tak się fajnie złożyło, że i popracować ze sprzętem.

No ok, Ty pracujesz ze sprzętem. Większość ludzi pracuje z innymi ludźmi nad tworzeniem czegoś wspólnie, dlatego muszą się komunikować, w przeciwnym razie wychodzi z tego syf.

A co myślisz o zasadzie PPK? Nie mam na myśli planów kapitałowych. Chodzi mi o zasadę w programowaniu.

Nie wiem, nie znam, nie sądzę, żebym powinien znać.

slsy napisał(a):

I to jest z d**y, bo też to kiedyś rozkminiałem. Wzorce takie jak strategy, command czy state to to samo: ktoś uznał, że warto nazwać interfejs znany z Javy różnymi nazwami, żeby było śmiesznie. Nie widziałbym problemu, gdyby przypadki użycia całkowicie się wykluczały ale tak oczywiście nie jest.

Not even wrong.
Po pierwsze interfejs to konstrukt językowy, którego można użyć. Sam w sobie jest tylko mechanizmem, niczym więcej, w przeciwieństwie do wzorca nie posiada kontekstu użycia.
Po drugie wymienione przez Ciebie wzorce, to nie jest to samo, bo rozwiązują różne problemy.
Po trzecie to koncepcje starsze od interfejsów w Javie. Od Javy też.

0
somekind napisał(a):
KamilAdam napisał(a):zywiście, że nie, dlatego ja uważam, że najlepsza rekrutacja jest przez kod, a nie tylko pogaduszki.
  • Builder zamiast konstruktora - niepotrzebny bo są parametry nazwane i domyślne wartości parametrów

To taki słaby zamiennik. Konstruktora nie nazwiesz, a metody buildera tak.

Nie lubię takich debat, bo mam wrażenie że różnica w kontekście "pure constructor" vs "builder" miałoby znaczenie, wtedy kiedy mamy obiekty z dużą ilością argumentów.

Jeśli projektujesz małe klasy (a moim zdaniem takie powinny być), to właściwie nie ma różnicy.

0
Riddle napisał(a):
somekind napisał(a):
KamilAdam napisał(a):zywiście, że nie, dlatego ja uważam, że najlepsza rekrutacja jest przez kod, a nie tylko pogaduszki.
  • Builder zamiast konstruktora - niepotrzebny bo są parametry nazwane i domyślne wartości parametrów

To taki słaby zamiennik. Konstruktora nie nazwiesz, a metody buildera tak.

Nie lubię takich debat, bo mam wrażenie że różnica w kontekście "pure constructor" vs "builder" miałoby znaczenie, wtedy kiedy mamy obiekty z dużą ilością argumentów.

Jeśli projektujesz małe klasy (a moim zdaniem takie powinny być), to właściwie nie ma różnicy.

różnica jest taka, że jak dodasz nowy atrybut to przy dobrym builderze nie wymusi to poprawiania w kazdym miejscu, gdzie jest tworzony obiekt. Masz forward compatibility.

0
LitwinWileński napisał(a):

różnica jest taka, że jak dodasz nowy atrybut to przy dobrym builderze nie wymusi to poprawiania w kazdym miejscu, gdzie jest tworzony obiekt. Masz forward compatibility.

To co mówisz jest tylko półprawdą. To o czym mówisz to jest "foward compatibility" w compile-time'ie. Przy użyciu buildera również możesz mieć "forward compatibility", tylko że w runtime'ie.

Więc różnica nie polega na tym czy "masz czy nie masz" tylko czy "podczas kompilacji czy podczas uruchomienia".

1
somekind napisał(a):

Ja pracuję nieco dłużej, też odwiedzającego nie pisałem. Podobnie jak nie pisałem obserwatora czy iteratora, bo te akurat są wbudowane w język.

W jaki sposób observer jest wbudowany w język?

Oczywiście, że nie, dlatego ja uważam, że najlepsza rekrutacja jest przez kod, a nie tylko pogaduszki.

Z rekrutacją przez kod jest ten problem, że stres bardzo wpływa na wyniki.

  • Builder zamiast konstruktora - niepotrzebny bo są parametry nazwane i domyślne wartości parametrów

To taki słaby zamiennik. Konstruktora nie nazwiesz, a metody buildera tak.

Dlatego parametry są nazwane, w znaczeniu - widać je na zewnątrz. Moim zdaniem ten ficzer kompletnie eliminuje potrzebę używania buildera.

Po drugie wymienione przez Ciebie wzorce, to nie jest to samo, bo rozwiązują różne problemy.

Dokładnie. W OOP można określić "inną nazwą na interface albo klasę".

Riddle napisał(a):

Nie lubię takich debat, bo mam wrażenie że różnica w kontekście "pure constructor" vs "builder" miałoby znaczenie, wtedy kiedy mamy obiekty z dużą ilością argumentów.

Jeśli projektujesz małe klasy (a moim zdaniem takie powinny być), to właściwie nie ma różnicy.

Tu się (delikatnie) nie zgodzę. Celem stosowania Buildera nie jest przemycanie setki parametrów konstruktora. Praktyka jest inna. Podstawowym zadaniem konstruktora i buildera jest (powinno być?) uniemożliwienie stworzenia niedziałającego obiektu. Czyli moim skromnym zdaniem jeżeli mamy np. klasę Employee, która zawsze ma zawierać imię i nazwisko, a opcjonalnie ileś tam z 50 innych wartości (tak, wiem dużo), to jej wywołanie powinno wyglądać ~tak:

Person.builder("Jan", "Kowalski")
.withPesel("123123123")
.withNip("....")
...
build()

Gdzie wszystkie obowiązkowe parametry są podawane na etapie tworzenia samego buildera, a opcjonalne już na etapie konfiguracji.

1
piotrpo napisał(a):

W jaki sposób observer jest wbudowany w język?

Spokojnie, nie pisałem o Javie, tylko o językach wyposażonych w eventy.

Z rekrutacją przez kod jest ten problem, że stres bardzo wpływa na wyniki.

Jeśli ktoś się stresuje pisząc kod w swoim domu, to prawdopodobnie powinien wziąć rozwód.

Dlatego parametry są nazwane, w znaczeniu - widać je na zewnątrz. Moim zdaniem ten ficzer kompletnie eliminuje potrzebę używania buildera.

Jest fajny, owszem, ale na pewno nie kompletnie, pewnie nawet nie w większości przypadków. Nazwane parametry nadal nie przekazują kontekstu, nie wynika z nich też czemu akurat taki obiekt, z takimi danymi jest tworzony.

3

Chciałem sobie poczytać o co chodzi z tym rynkiem IT, a tu 8 stron o wzorcach projektowych xD Czy leci z nami pilot? Znaczy ten... moderator?? 😁

1
Riddle napisał(a):

Nie lubię takich debat, bo mam wrażenie że różnica w kontekście "pure constructor" vs "builder" miałoby znaczenie, wtedy kiedy mamy obiekty z dużą ilością argumentów.

Jeśli projektujesz małe klasy (a moim zdaniem takie powinny być), to właściwie nie ma różnicy.

Tu się (delikatnie) nie zgodzę. Celem stosowania Buildera nie jest przemycanie setki parametrów konstruktora. Praktyka jest inna. Podstawowym zadaniem konstruktora i buildera jest (powinno być?) uniemożliwienie stworzenia niedziałającego obiektu. Czyli moim skromnym zdaniem jeżeli mamy np. klasę Employee, która zawsze ma zawierać imię i nazwisko, a opcjonalnie ileś tam z 50 innych wartości (tak, wiem dużo), to jej wywołanie powinno wyglądać ~tak:

Person.builder("Jan", "Kowalski")
.withPesel("123123123")
.withNip("....")
...
build()

Gdzie wszystkie obowiązkowe parametry są podawane na etapie tworzenia samego buildera, a opcjonalne już na etapie konfiguracji.

Oryginalny Builder służył do tego, aby niedokończony obiekt można było sobie przykisić, przekazać do innej funkcji, itd.

W praktyce programiści Java, gdy mówią „builder”, to myślą o takim fluent-konstruktorze jak wyżej. A builder w ogóle nie musi być fluent. Może mieć normalne settery.
fluent builder jest po prostu odpowiedzią na brak nazwanych parametrów oraz brak domyślnych wartości dla parametrów w języku Java. Jest to jakiś pattern, ale to nie jest Builder. Jak było powiedziane wyżej, w niektórych innych językach jest to niepotrzebne.

0
meehow.cpp napisał(a):

A mógłbyś zacytować, gdzie napisałem, że wzorce są złe? Albo gdzie napisałem, że stosowanie zasady DRY jest złe?

A mógłbyś zacytować, gdzie ja napisałem, że Ty napisałeś, że te rzeczy są złe? Ja pytam czemu uważasz, ze to nie są rzeczywiste umiejętności w pracy programisty, bo tak brzmiały dla mnie Twoje słowa z poprzedniego postu - narzekasz na takie pytania, zamiast pytania o "rzeczywiste umiejętności".

Nie, nie po to. Poszedłem do IT po to by programować, a obecnie tak się fajnie złożyło, że i popracować ze sprzętem.

No ok, Ty pracujesz ze sprzętem. Większość ludzi pracuje z innymi ludźmi nad tworzeniem czegoś wspólnie, dlatego muszą się komunikować, w przeciwnym razie wychodzi z tego syf.

A co myślisz o zasadzie PPK? Nie mam na myśli planów kapitałowych. Chodzi mi o zasadę w programowaniu.

Nie wiem, nie znam, nie sądzę, żebym powinien znać.

Ale ja nigdzie nie pisałem o tym co napisałeś. Wzorce nie są złe. Wręcz powinno się zaglądać nie tylko do wzorców, ale i kodu różnych projektów. Analizować kod i czerpać pomysły, jeśli uzna się je za dobre.
Natomiast nauka nadmiernego nazewnictwa w programowaniu nie ma sensu.

Osiągnęliśmy skraj absurdu. Ja przed studiami wiedziałem co to np. iterator, długo później nie wiedziałem, że zalicza się do wzorców projektowych - po cholerę mi to wiedzieć? Plus ta masa durnych skrótowców.

Nie wiesz co to PPK? Ale jak to? To oburzające! A tak serio... Wymyśliłem to na prędce, aby zobrazować guano tego absurdu w którym się borykamy. PPK - poprawne pisanie kodu.
Miałem też sytuację podczas kilku rekrutacji, że usłyszałem: "pan wie o co chodzi, ale nie znał pan nazwy". Na jednej opisałem pewną konstrukcję którą zastosowałem w projekcie hobbystycznym i dowiedziałem się podczas rozmowy, że to fasada.

Zacytuję kolegę z pierwszej firmy IT w której pracowałem, tak mniej więcej (on też widział mój kod i z nim pracował):

Stosujesz wzorce projektowe i nawet o tym nie wiesz. Każdy je stosuje i często nie zdaje sobie z tego sprawy

Co do komunikacji, to dobry temat na nowy toppic i nie kryję, ciekawi mnie Wasza opinia na ten temat. W każdej pracy musisz się komunikować. Jednak "komunikacja" w IT potrafi dominować pracę. Kiedyś ludzie mniej się komunikowali i powstawały nieporównywalnie bardziej dopracowane i wydajniejsze projekty.

0
meehow.cpp napisał(a):

Natomiast nauka nadmiernego nazewnictwa w programowaniu nie ma sensu.

Ogólnie zgoda. Pytanie co to jest nadmierne nazewnictwo i tutaj każdy rabin ma swoje zdanie.

Osiągnęliśmy skraj absurdu. Ja przed studiami wiedziałem co to np. iterator, długo później nie wiedziałem, że zalicza się do wzorców projektowych - po cholerę mi to wiedzieć? Plus ta masa durnych skrótowców.

Ogólnie całe to DRY, SOLID, KISS to taki raczek. W sensie sprowadzania czasami złożonych problemów do umiejętności rozwinięcia skrótu. Bo to co się kryje za tymi skrótami ma sens. Akurat te skróty, to już rekrutacyjna sztampa i pewnie 90% kandydatów je rozwinie, tylko co z tego? Pytanie o to co oznacza DRY jest tak samo bez sensu, jak pytanie "Czy używasz clean code?". Ale jeżeli zostanie sformułowane "Czy powtarzanie tego samego kawałka kodu jest złe?", "Jak tego unikać?" ma sens, bo w trakcie rozmowy o tym, można przegadać zarówno DRY, jak i pewnie większość SOLID, zahaczyć o parę innych tematów.

Miałem też sytuację podczas kilku rekrutacji, że usłyszałem: "pan wie o co chodzi, ale nie znał pan nazwy". Na jednej opisałem pewną konstrukcję którą zastosowałem w projekcie hobbystycznym i dowiedziałem się podczas rozmowy, że to fasada.

Znowu - sposób zadania pytania i oczekiwania. Jeżeli pytający przedkłada zdolność do nazwania jakiejś konstrukcji ponad jej sens. Co jest złego w pytaniu "Projektujesz logikę kalkulatora jednostek, wewnątrz masz mnóstwo sporo klas, które odpowiadają za poszczególne działania. Jak sprawisz, żeby osoby próbujące użyć tego kawałka kodu nie musiały wnikać w to jakie to klasy i jak używać każdej z nich?". Albo "Masz swój guzik na UI, który wie, że został przyciśnięty, wywołuje się w nim wtedy jakaś metoda, którą napisałeś. W jaki sposób umożliwisz innym elementom programu dowiadywanie się o tym zdarzeniu?"

Zacytuję kolegę z pierwszej firmy IT w której pracowałem, tak mniej więcej (on też widział mój kod i z nim pracował):

Stosujesz wzorce projektowe i nawet o tym nie wiesz. Każdy je stosuje i często nie zdaje sobie z tego sprawy

Tak, chociaż to zdawanie sobie sprawy też ma jakąś wartość. Umiejętność nazwania wzorca ma najmniejsze znaczenie w tym wszystkim.

Co do komunikacji, to dobry temat na nowy toppic i nie kryję, ciekawi mnie Wasza opinia na ten temat. W każdej pracy musisz się komunikować. Jednak "komunikacja" w IT potrafi dominować pracę. Kiedyś ludzie mniej się komunikowali i powstawały nieporównywalnie bardziej dopracowane i wydajniejsze projekty.

To dobry temat, żeby pogadać. Jak wiadomo 5 godzin projektowania w 10 osobowym zespole, może zaoszczędzić 5 minut pisania kodu przez jedną osobę. Może osobny wątek?

1

Mamy klasę Salary, która służy do wyliczania kapuchy jaką mamy zapłacić programiście. W tej chwili wyliczenie polega tylko na wyliczeniu kwoty netto z podanego brutto mnożąc brutto przez 80%.

class Salary {

  private final BigDecimal grossValue;

  Salary(BigDecimal grossValue) {
    this.grossValue = grossValue;
  }

  BigDecimal calculateNetValueToPay() {
    return grossValue.multiply(BigDecimal.valueOf(.8));
  }
}

Product Owner rzecze: programista nie był zbyt inteligentny i zgodził się na kary umowne hehe xD beka z niego. Uwzględnijmy w wyliczeniach pensyjki możliwość nakładania kar umownych.

class Salary {

  private final BigDecimal grossValue;
  private final Penalty penalty;

  Salary(BigDecimal grossValue, Penalty penalty) {
    this.grossValue = grossValue;
    this.grossPenalty = penalty;
  }

  BigDecimal calculateNetValueToPay() {
    return grossValue
        .substract(penalty.getGrossValue())
        .multiply(BigDecimal.valueOf(.8));
  }
}

Zapytali mnie na rekrutacji jaki wzorzec projektowy zastosowany został przy dodaniu wyliczenia tej kary umownej w taki sposób.

0
somekind napisał(a):
KamilAdam napisał(a):

Kurde. 10 lat pracuję jako programista i nigdy w pracy odwiedzającego nie napisałem :D

Ja pracuję nieco dłużej, też odwiedzającego nie pisałem. Podobnie jak nie pisałem obserwatora czy iteratora, bo te akurat są wbudowane w język.
Tylko co z tego? Ktoś pyta na rozmowach o wzorce, których się nie używało? :)

To po co pytać o rzeczy których się nie uzywa? Można też pytać o budowę procesora czy tranzystora. Na to samo wyjdzie

BTW ja to się bardzo cieszę że na rozmowach rekrutacyjnych ze Scali nie pytają o wzorce i dobre praktyki (za wyjątkiem TDD).
Za to pytają z nowych featurów Scali 3, Monad, Transformarów Monad, Catsów, i Catsów Effect. Czyli z rzeczy których faktycznie używa się w pracy

Ale jakie monady? Toć to zbędna teoria, jak wzorce projektowe w OOP.

Monada to jest konkretny interfejs (TypeClassa). Tak wygląda Monada w catsach:

trait FlatMap[F[_]] extends Apply[F] {
  def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
}

trait Monad[F[_]] extends FlatMap[F] with Applicative[F]

Transformatory monad to konkretna biblioteka

  • Builder zamiast konstruktora - niepotrzebny bo są parametry nazwane i domyślne wartości parametrów

To taki słaby zamiennik. Konstruktora nie nazwiesz, a metody buildera tak.

Statyczną metodą tworzącą obiekt też nazwę

case class MyRecord(name: String, surname: String)

object MyRecord {
  def onlyName(name: String) = MyRecord(name, "")
  def onlySurname(surname: String) = MyRecord("", surname)
}
4

Panowie, jak tak tylko przypominam, że programowanie to nie tylko backend i frontend.

0
LitwinWileński napisał(a):
Riddle napisał(a):
somekind napisał(a):
KamilAdam napisał(a):zywiście, że nie, dlatego ja uważam, że najlepsza rekrutacja jest przez kod, a nie tylko pogaduszki.
  • Builder zamiast konstruktora - niepotrzebny bo są parametry nazwane i domyślne wartości parametrów

To taki słaby zamiennik. Konstruktora nie nazwiesz, a metody buildera tak.

Nie lubię takich debat, bo mam wrażenie że różnica w kontekście "pure constructor" vs "builder" miałoby znaczenie, wtedy kiedy mamy obiekty z dużą ilością argumentów.

Jeśli projektujesz małe klasy (a moim zdaniem takie powinny być), to właściwie nie ma różnicy.

różnica jest taka, że jak dodasz nowy atrybut to przy dobrym builderze nie wymusi to poprawiania w kazdym miejscu, gdzie jest tworzony obiekt. Masz forward compatibility.

Miałem kod

class Person(name: String, surname: String)

val bush = new MyRecord("Dżordz", "Bush")

o sh't zapomniałem o middlename. Co ja teraz zrobię? Nie mam pojęcia. Może zdefiniuje nowy konstruktor?

class Person(name: String, middlename: String, surname: String) {
  def this(name: String, surname: String) = Person(name, "", surname)
}

val bush = new Person("Dżordz", "Bush")
val bush2 = new Person("Dżordz", "dablju", "Bush")

Jesteśmy uratowani. Kompatybilność zachowana

UPDATE owczywiście w Scali jest też możliwe rozwiązanie z domyślnymi wartościami parametrów, ale prawie nigdy nie jest ono tak ładne jak drugi konstruktor

class Person(name: String, surname: String, middlename: String = "")

val bush = new Person("Dżordz", "Bush")
val bush2 = new Person("Dżordz", "Bush", "dablju")
val bush3 = new Person(name = "Dżordz", middlename = "dablju", surname = "Bush")
1

@KamilAdam: W Javie też da się wybrnąć z tego:

public class Person{
....
  Person(String firstName, String middleName){...}
  Person(String firstName, String middleName, String lastName){
    this(firstName, middleName);
    this.lastName = lastName;
  }

}

Tak, m.in w Scali jest prościej, elastyczniej i ładniej.

3

Natomiast nauka nadmiernego nazewnictwa w programowaniu nie ma sensu.

Osiągnęliśmy skraj absurdu. Ja przed studiami wiedziałem co to np. iterator, długo później nie wiedziałem, że zalicza się do wzorców projektowych - po cholerę mi to wiedzieć? Plus ta masa durnych skrótowców.

Tu się nie zgodzę. Zaletą wzorców jest właśnie słownictwo i możliwość otworzenia wikipedii z opisem wzorca.

Właśnie pracuję z kodem, gdzie autor nie wiedział, że warto użyć iteratora. Wyciągamy przez api długą listę obiektów. Api restowe udostępnia pageowanie. Tzn ustawia się maxResults, nextPageToken i w pętli się iteruje po chunkach, aż osiągniemy pustą ostatnią stronę. Niestety autor kodu, który przerabiam, kopiuje tę strukturę pętli(nextPageToken, chunki, maxResults) przez wszystkie warstwy aplikacji.

Gdyby było robione code review(a nie było), to napisałbym „weź opakuj najniższą warstwę w Iterator” i jeśli programista twierdzi, że jest seniorem, to NIC nie trzebaby było tłumaczyć.

3
somekind napisał(a):
piotrpo napisał(a):

Z rekrutacją przez kod jest ten problem, że stres bardzo wpływa na wyniki.

Jeśli ktoś się stresuje pisząc kod w swoim domu, to prawdopodobnie powinien wziąć rozwód.

Dlaczego aż tak zerojedynkowo do tego podchodzimy?
W pracy(czyli w domu) nikt nie stoi mi za plecami i nie patrzy w czasie rzeczywistym jak pisze kod, tylko później widzi efekt końcowy.

W domu też możemy prowadzić konferencje dla 200 osób, a jednak można się stresować. Dlaczego? Przecież i tak siedzimy w swoim domu.

4
meehow.cpp napisał(a):

Natomiast nauka nadmiernego nazewnictwa w programowaniu nie ma sensu.

Poznanie branżowego żargonu (w dowolnej branży) nie wymaga żadnej specjalnej nauki, to się chłonie podczas pracy. Jeśli zatem ktoś nie zna słownictwa, to sugeruje, że nie ma doświadczenia w branży.

A już tak ogólnie, to stosowanie poprawnego nazewnictwa po prostu upraszcza przekazywanie swoich myśli innym ludziom. W codziennym życiu mówisz, że idziesz na tureckie mięso skrawane z pionowego rożna, wraz z surówką i sosami podawane zawinięte w tortillę?

Nie wiesz co to PPK? Ale jak to? To oburzające! A tak serio... Wymyśliłem to na prędce, aby zobrazować guano tego absurdu w którym się borykamy. PPK - poprawne pisanie kodu.

Niczego w ten sposób nie zobrazowałeś, bo na rekrutacjach nikt nie pyta o rzeczy, które sobie sam naprędce wymyślił, lecz o te powszechnie znane.

Co do komunikacji, to dobry temat na nowy toppic i nie kryję, ciekawi mnie Wasza opinia na ten temat. W każdej pracy musisz się komunikować. Jednak "komunikacja" w IT potrafi dominować pracę. Kiedyś ludzie mniej się komunikowali i powstawały nieporównywalnie bardziej dopracowane i wydajniejsze projekty.

Nie wiem jaką "komunikację" masz na myśli.
Ogólnie bez komunikacji zazwyczaj powstaje oprogramowanie, które ani nie spełnia wymagań biznesowych ani technicznych. Za to kod zdaniem niekomunikujących się profesjonalistów może być przepiękny. Tylko co z tego?
Ta niechęć do komunikacji przypomina mi programistów z Bangalore. Oni zazwyczaj do końca mówią, że wszystko jest w porządku, że wszystko rozumieją, że nie potrzebują dodatkowych wyjaśnień, i że nie ma żadnych problemów.

Rozmowa kwalifikacyjna ma na celu także odsianie tych antykomunikatywnych indywidualistów. Nie chcę pracować z kimś, kto nie umie ani pomóc, ani poprosić o pomoc, bo to będzie nieefektywna męczarnia.

KamilAdam napisał(a):

To po co pytać o rzeczy których się nie uzywa? Można też pytać o budowę procesora czy tranzystora. Na to samo wyjdzie

Nie wiem, ja pytam o rzeczy, których sam używam, i których kandydat powinien być w stanie używać ze zrozumieniem.
Dlatego jak ktoś na pytanie o wzorce projektowe odpowiada wyuczonymi regułkami albo wymienia na pierwszym miejscu singleton, to jest skreślony. Bo nie umie programować w języku, z którego go pytam. Bez wzorców wyprodukuje co najwyżej jakieś proceduralne spaghetti.

Monada to jest konkretny interfejs (TypeClassa). Tak wygląda Monada w catsach:

Skoro wzorce projektowe to zbędna teoria w programowaniu OOP, to monada to zbędna teoria w FP.

mariusz00 napisał(a):

W domu też możemy prowadzić konferencje dla 200 osób, a jednak można się stresować. Dlaczego? Przecież i tak siedzimy w swoim domu.

Ale to słabe porównanie. Konferencja to interakcja z ludźmi, więc faktycznie może stresować. Ale w jaki sposób stresuje interakcja wyłącznie z komputerem? Jeśli nawet, to w takim razie programowanie nie jest branżą dla takiej osoby.

0
KamilAdam napisał(a):

Monada to jest konkretny interfejs (TypeClassa). Tak wygląda Monada w catsach:

Skoro wzorce projektowe to zbędna teoria w programowaniu OOP, to monada to zbędna teoria w FP.

Jeszcze raz powtórzę. Monada to nie jest teoria. To jest rzeczywisty interfejs (TypeClassa konkretniej) i ma rzeczywiste metody zwane zwykle flatMap/bind/(>>=) i pure/point/return. To tak jakby powiedzieć że List czy Collection to teoria

Tak wygląda ten interfejs w Haskellu w bibliotece standardowej:

class Applicative m => Monad m where
    (>>=)       :: forall a b. m a -> (a -> m b) -> m b
    (>>)        :: forall a b. m a -> m b -> m b
    return      :: a -> m a
    return      = pure

A tak wygląda monada w Idris

interface Applicative m => Monad (m : Type -> Type) where
    ||| Also called `bind`.
    (>>=)  : m a -> ((result : a) -> m b) -> m b

    ||| Also called `flatten` or mu
    join : m (m a) -> m a

    -- default implementations
    (>>=) x f = join (f <$> x)
    join x = x >>= id

Nawet jest napisane że to interface. Co za miły w czytaniu język

6

No to o co w końcu chodzi z tym rynkiem pracy IT??

10
Pinek napisał(a):

No to o co w końcu chodzi z tym rynkiem pracy IT??

W ogólności to chyba o to, że:

  1. ludzie chcą mieć dobrą pracę;
  2. ludzie nie chcą brać udziału w rekrutacjach, bo źle że o cokolwiek pytają, a zwłaszcza o rzeczy związane z programowaniem;
  3. jak już ktoś przychodzi na rekrutację, to niewiele umie, ale chce dużo kasy.
1

Dwa lata temu jak szukałem roboty to nie przygotowywałem się do rozmów bo myślałem ,że jestem geniuszem programowania. Ostatnio przed wysyłaniem CV spędziłem sporo czasu na przygotowania do rozmów. Z 6 rekuratcji dostałem 4 oferty pracy. Wydaje mi się że to nie rekrutacje są słabe tylko niektórzy ludzie rozpuszczeni.

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