29/10/2014

Co wyróżnia bardzo dobrego programistę (2)?

Home

Pewnie słyszeliście o strumieniach (ang. stream) w .NET. O tym, że się je otwiera, a po użyciu zamyka. Zresztą w innych technologiach jest podobnie. Sprawa stara jak świat i wydawałoby się, że każdy o tym wie. Ja w każdym razie z definicji tak robię.

Dziwi mnie więc, że po tylu latach istnienia .NET ciągle pojawiają się pytanie z tym związane, jak na przykład to na stackoverflow.com. Dziwi mnie również, że przy okazji tego rodzaju pytań często pojawiają się najróżniejsze koncepcje / pomysły / odpowiedzi i to od użytkowników, którzy wcale nie są początkujący. Tymczasem wystarczy wrócić do podstaw, aby rozwiązać problem.

A może jest tak, że kiedy na co dzień pracujemy z skomplikowanymi algorytmami / trudnymi problemami biznesowymi / strukturami danych (niepotrzebne skreślić) to w pewnym momencie tracimy perspektywę i każdy napotkany problem od razu wydaje się nam skomplikowany.

Kolejny czynnik powodujący tą utratę perspektywy to chyba również mnogość różnych technologii i bibliotek, jakie są u obecnie używane. Ta biblioteka do tego, tamta ułatwia to, ta automatyzuje tamto itd. W ten sposób przyzwyczajamy się do tego, że wiele rzeczy coś robi za nas i my nie wnikamy w szczegóły i równocześnie zapominamy również o podstawach.

Nie mówię, że nie należy używać bibliotek, framework'ów czyli ułatwiać sobie pracy, ale bardzo dobry programista powinien również wiedzieć co, się za tym wszystkim kryje i nie zapominać o podstawach.

20/10/2014

Z rozmów o pracę

Home

Nie wiem dlaczego, ale ostatnio wzięło mnie na refleksje. Siedzę, popijam sobie herbatę i tak ni z gruszki ni z pietruszki przypomniała mi się dawna rozmowa o pracę. Rozmawiałem z dwoma menadżerami, ale takimi z wiedzą techniczną, co to nie zmieniają szybko tematu, jak przechodzisz na tematy techniczne.

Rozmawialiśmy dość długo i w głowie utknęła mi jedna rzecz, jaką powiedzieli. Parafrazując, zgodnie stwierdzili, że ciężko znaleźć programistę, który nie byłby code monkey. Przy czym przez code monkey rozumieli trochę coś innego niż ja w tamtym momencie. Ja pod tym terminem rozumiałem osobę słabo radząca sobie z programowaniem, umiejąca napisać coś pod dyktando, ale nie dużo więcej. Dla nich jednak code monkey mógł być nawet bardzo dobry technicznie programista, doskonale radzący sobie z zadaniami, samodzielny... lecz z jednym bardzo istotnym z ich menadżerskiego punktu widzenia "ale". To jest nie umiejący lub słabo radzący sobie z komunikacją, w szczególności z biznesem, ludźmi nietechnicznymi, taki nieumiejący postawić się w roli użytkownika końcowego.

Z pewnością my programiści nie jesteśmy mistrzami komunikacji i Ci, którzy posiadają obok wiedzy technicznej umiejętności miękkie mogą się łatwo wyróżnić. Zastanawiam się jednak czy rzeczywiście większość z nas to geeki, którzy nie widzą nic poza kodem. Co myślicie?

19/10/2014

Problemy z MSDTC

Home

DTC - Distributed Transacion Coordinator to takie ustrojstwo w postaci usługi systemowej, które jest potrzebne, jeśli korzystamy z transakcji rozproszonych. Dostajemy to w komplecie razem z Windows'em, a zarządzamy tym z poziomu przystawki do konsoli zarządzania systemem Control Panel -> Administrative Tools -> Component Services. Jak działa to działa i nic nie trzeba robić, a jak nie to zaczynają się schody. Ja ostatnio spędziłem nad uruchomieniem DTC z pół dnia rozwiązując kolejne problemy. Oto moja historia ku pamięci (dotyczy Windows 7):

Problem 1

Usługa nie chce się uruchomić na domyślnym koncie Network Service, a jak zmienimy konto na Local System to w logu systemowym zaczną się pojawiać komunikaty:

The account that the MS DTC service is running under is invalid. This can happen if the service account information has been changed using the Services snap-in in Microsoft Management Console (MMC). MS DTC service will continue to start. Please make sure that the MS DTC service account information is updated using the Component Services Explorer.

Mi pomógł ten artykuł, a konkretniej nadanie uprawnień Read & Execute kontu Network Service do pliku C:\Windows\system32\Msdtc\MSDTC.LOG

Problem 2

Kolejny problem to słynna czerwona strzałka. Po otworzeniu Component Services i kliknięciu ikony My Computer dostajemy komunikat:

The Transaction Manager is not available. (Exception from HRESULT: 0x8004D01B).

Wypróbowałem wiele wskazówek, ale ostatecznie pomogło mi nadanie pełnych uprawnień kontu System i grupie Administrators do katalogu C:\Windows\registration. Zalecenie to wziąłem z tego artykułu. Dużo wskazówek dotyczących tego konkretnego problemu można też znaleźć tutaj.

Problem 3

Kiedy udało się już uruchomić usługę to przy próbie skorzystania z transakcji rozproszonej w kodzie był rzucany wyjątek z komunikatem:

Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool

Okazało się, że we właściwościach lokalnego DTC (dostępnych z wspomnianej przystawki konsoli zarządzania systemem Component Services) w zakładce Security nie włączyłem opcji Network DTC Access.

Problem 4

Kolejny wyjątek jakim dostałem po twarzy to:

The MSDTC transaction manager was unable to pull the transaction from the source transaction manager due to communication problems. Possible causes are: a firewall is present and it doesn't have an exception for the MSDTC process, the two machines cannot find each other by their NetBIOS names, or the support for network transactions is not enabled for one of the two transaction managers. (Exception from HRESULT: 0x8004D02B)"

W tym przypadku okazało się, że jedna z maszyn biorąca udział w transakcji rozproszonej nie potrafi znaleźć adresu IP mojej maszyny na podstawie jej nazwy. Pomogło dodanie wpisu do pliku hosts.

15/10/2014

Co wyróżnia bardzo dobrego programistę?

Home

Sądzę, że dla każdego bycie bardzo dobrym programistą oznacz trochę coś innego, na przykład do wyboru: znajomość nowych technologii, minimalizowanie używania myszki na rzecz posługiwania się głównie klawiaturą, samodzielne doszkalanie się, blogowanie, udział w konferencjach, komunikatywność, umiejętność pracy pod presją czasu... Ja jednak chciałbym zwrócić uwagę na inną rzecz.

Czasami jest tak, że dostajemy do naprawienie jakiś "wredny" błąd. Niekoniecznie wymaga on wielu zmian w kodzie, ale jest trudny do odtworzenia. Być może brakuje nam też danych, aby go powtórzyć lub opis jest niedokładny. A może jest tak, że błąd dotyczy nieznanego nam obszaru, kod jest brzydki albo to kolejny błąd dotyczący podobnej rzeczy i zaczyna nas to irytować.

W każdym razie mamy dosyć i, jak tylko znajdziemy przyczynę i wyk-minimy rozwiązanie (być może nietrywialne i wymagające dużo technicznej wiedzy), to szybko robimy commit i zapominamy o sprawie. To jest moim zdaniem ten moment, kiedy można zobaczyć na czym polega bycie bardzo dobrym programistą. Moim zdaniem w takiej sytuacji bardzo dobry programista, nawet mimo zniechęcenia, zada sobie dodatkowe pytania:
  • Czy ten błąd nie występuje jeszcze gdzieś indziej, nawet jeśli zgłoszenie tego nie dotyczy?
  • Jak jego poprawka wpłynie na resztę systemu? Powiązania pomiędzy różnymi modułami systemu mogą być nieoczywiste i często uzyskanie odpowiedzi na takie pytanie wymaga dużo wysiłku.
  • Jaka jest pra-przyczyna błędu? Na przykład NullReferenceException można "naprawić" bardzo łatwo przy pomocy jednego if'ka. Często będzie to dobre rozwiązanie, ale może być też tak, że null nigdy nie powinien się pojawić w danym miejscu i jest on wynikiem zmiany gdzieś indziej.
To mogą być bardzo niewygodne pytania, szczególnie, jeśli się nam nie chce, ręce bolą i jest coś ciekawszego do zrobienia, ale równocześnie bardzo potrzebne, szczególnie, jeśli pracujemy z starszymi systemami czy nawet tymi młodszymi, ale bez testów automatycznych.

Nie wiem jak Wy, ale ja na początku swojej kariery uważałem, że w zawodzie programisty właściwie liczy się tylko strona techniczna, znajomość nowych technologii, bibliotek itd. W obecnej chwili rzeczy te uważam za niezwykle ważne, ale nie najważniejsze i coraz większą wagę przywiązuje do umiejętności i predyspozycji, nazwijmy je około-technicznych i miękkich. A co wy o tym myślicie? Też tak macie, a może to tylko moje "zboczenie"?

06/10/2014

OxyPlot i nieciągłe przedziały

Home

Od dłuższego czasu używam biblioteki OxyPlot i bardzo ją sobie chwalę. Ostatnio zamarzyło mi się stworzenie wykresu przedziałowego. Na początek stwierdziłem, że wystarczy zastosować zwykły wykres liniowy czyli klasę LineSeries. Załóżmy, że chcemy zaprezentować na wykresy przedziały tj.; (2,3), (4,6) oraz (8,10). Spróbujmy, więc czegoś takiego:
var s = new LineSeries();
s.Title = "Nieciągłe przedziały";
s.Points.Add(new DataPoint(2, 1));
s.Points.Add(new DataPoint(3, 1));
           
s.Points.Add(new DataPoint(4, 1));
s.Points.Add(new DataPoint(6, 1));
        
s.Points.Add(new DataPoint(8, 1));
s.Points.Add(new DataPoint(10, 1));
To jednak nie zadziała gdyż w rezultacie otrzymamy linię ciągłą, czego zresztą należało się spodziewać ponieważ LineSeries po prostu łączy kolejne punkty. Wypróbowałem więc inne rodzaje wykresów, bawiłem się ustawieniami, ale bez rezultatów. Rozwiązanie okazało się jednak bardzo proste. Jeśli nie chcemy, aby dwa punkty zostały połączone linią to pomiędzy nimi należy umieścić punkt o współrzędnych (Double.Nan, Double.NaN).
var s = new LineSeries();
s.Title = "Nieciągłe przedziały";
s.Points.Add(new DataPoint(2, 1));
s.Points.Add(new DataPoint(3, 1));
s.Points.Add(new DataPoint(Double.NaN, Double.NaN));            
s.Points.Add(new DataPoint(4, 1));
s.Points.Add(new DataPoint(6, 1));
s.Points.Add(new DataPoint(Double.NaN, Double.NaN));       
s.Points.Add(new DataPoint(8, 1));
s.Points.Add(new DataPoint(10, 1));
Na koniec jeszcze przykład tak skonstruowanego wykresu: