24/12/2014

Życzenia świąteczne

Home

Kolejne Święta Bożego Narodzenia już tuż tuż. W tym roku czekam na nie jeszcze bardziej niż zwykle, bo to pierwsze wydarzenie tego rodzaju dla naszej córeczki. Wszystkim czytającym mojego bloga i nie tylko życzę dużo radości w gronie bliskich Im osób, a w Nowym Roku ciekawych wyzwań zawodowych oraz zapału do nauki i doskonalenia się.

Serdecznie Pozdrawiam,
Michał Komorowski

21/12/2014

Czego prawdopodobnie nie wiedzieliście o Excel'u

Home

Sądzę, że wielu z Was otarło się na studiach o programowanie liniowe oraz algorytm sympleks. Ja uczyłem się o tym na przedmiocie zwanym w skrócie POBO, co rozwija się dumnie brzmiące Podstawy badań operacyjnych. Od czasów studiów nie zajmowałem się tym zagadnieniem, aż do dzisiaj. Pomagając siostrze w rozwiązywaniu zadań na studia dowiedziałem się o możliwościach Excel'a, których w ogóle nie byłem świadomy, a są naprawdę super i każdy ma do nich dostęp. Mam tutaj na myśli dodatek Solver, który, między innymi, implementuje algorytm sympleks w bardzo przystępnej formie. Tyle tytułem wstępu. Spójrzmy na prosty przykład.

Zaczynamy od uruchomienia Excel'a. Następnie klikamy tą fikuśną okrągłą ikonę w lewym górnym roku okna i wybieramy Opcje programu Excel. Dalej przechodzimy do zakładki Dodatki i klikamy przycisk Przejdź.



W oknie, jakie się pojawi, wybieramy Dodatek Solver i zatwierdzamy.



Po zatwierdzeniu w zakładce Dane na wstążce pojawi się nowa opcja.



Teraz spróbujmy rozwiązać przykładowe proste zadanie. Załóżmy, że mamy 5 fabryk i chcemy znaleźć lokalizację centrum dystrybucyjnego tak aby suma odległości od wszystkich fabryk była minimalna. Dodatkowe ograniczenie jest takie, że odległość od każdej z fabryk nie może być większa niż 60. Położenia fabryk podane są we współrzędnych kartezjańskich. Odległość pomiędzy fabrykami, a centrum obliczamy przy pomocy standardowego wzoru. Sytuacja początkowa wygląda tak. Dla ułatwienia naniosłem położenia fabryk i początkowe położenie centrum na wykres.



Teraz uruchamiamy Solver. Jako komórkę celu wybieram pole z sumą odległości i zaznaczam, że tą wartość chcę minimalizować. Jako komórki zmieniane wybieram współrzędne centrum. Dodajemy też ograniczenie na odległość każdej z fabryk od centrum. Na koniec uruchamiam obliczenia i klikam Rozwiąż.



Wynik końcowy wygląda w następujący sposób:



To tylko wierzchołek góry lodowej. Dodatek Solver ma dużo większe możliwość i wiele opcji. Można go wykorzystać do harmonogramowania, zdefiniować wiele ograniczeń, ustalić maksymalny czas obliczeń, dokładność uzyskanego wyniku i wiele więcej. Sądzę, że warto sobie zapamiętać, że Excel ma takie możliwości i w razie potrzeby doczytać i douczyć się jak z tego korzystać.

08/12/2014

Wykrywanie nieużywanych elementów bibliografii

Home

Moim zdaniem LaTeX ma wspaniałą obsługę cytowań i bibliografii. Jest to jeden z powodów, dla którego tak lubię go używać np.: bardzo łatwo znaleźć cytowania w formacie rozumianym przez LaTeX'a, nie musimy martwić się o formatowanie, odpowiednie posortowanie czy numerowanie.

Domyślnie jest dodamy jakąś pozycję do bazy danych odnośników literaturowych, a jej nie zacytujemy to w finalnym dokumencie wygenerowanym przez LaTeX'a (np.: PDF) zostanie ona pominięta. Może to być zachowanie pożądane lub nie. Jeśli nie jest z pomocą przychodzi komenda \nocite, w szczególności jej forma \nocite{*}, która powoduje, że cokolwiek dodamy do spisu odnośników to znajdzie się to w finalnym dokumencie w sekcji z bibliografią. W pewnym momencie możemy jednak chcieć uporządkować bazę odnośników i sprawdzić co używamy, a czego nie. Przy dużym dokumencie, z dziesiątkami lub setkami cytowań nie jest to sprawa oczywista.

W takiej sytuacji z pomocą przychodzi, odkryty przeze mnie ostatnio, pakiet refcheck. Po jego włączeniu dla każdego nieużywanego elementu bibliografii, ale także dla każdej nieużywanej etykiety zostanie wygenerowane ostrzeżenie. Dodatkowo nieużywane elementy zostaną oznaczone w wygenerowanym dokumencie przy pomocy etykiet na marginesie dokumentu.

Kolejny raz okazuje się, że czegokolwiek bym sobie nie zamarzył to istnieje już pakiet, który to zapewnia :)

05/12/2014

Latex i drzewa

Home

Wczoraj już późno w nocy zamarzyło mi się umieścić w dokumencie tworzonym w LaTeX'u rysunki drzew binarnych. Początkowo myślałem o narysowaniu ich w jakimś programie graficznym, a następnie wyeksportowaniu do jpg z czym LaTeX już sobie poradzi. Potem pomyślałem jednak, że to nie ma sensu bo z pewnością już ktoś miał taki problem i stworzył odpowiedni pakiet gotowy do użycia. Nie pomyliłem się. Bardzo szybko znalazłem pakiet qtree i już 5 minut później miałem w swoim artykule piękne drzewka. Przykład użycia:.
\Tree[.{L0 - Root} 
 [.{L1 - Left child} 
  [.{L2 - Left child} ] 
  [.{L2 - Right child} ]]
 [.{L1 - Right child} ]]
Efekt końcowy wygląda natomiast następująco:



LaTeX z pewnością jest trudniejszy w użyciu niż taki Word, ale jak już się go poznasz to zrobisz wszystko. Społeczność około LaTeX'owa stworzyła tyle różnych pakietów, że nie pozostaje nic innego jak brać i korzystać.

02/12/2014

Zabawy z domenami aplikacyjnymi

Home

Proponuję zabawę z serii co zostanie wypisana na ekran. Mamy dwie klasy jak poniżej. Pierwsza z nich przekazywana jest pomiędzy domenami przez referencję, a druga przez wartość. Interfejs ITest ma charakter pomocniczy i nie ma znaczenia.
public interface ITest
{
   int Value { get; set; }
   void Start();
}

public class MarshalByRefObjectClass : MarshalByRefObject, ITest
{
   public int Value { get; set; }

   public void Start()
   {
      Console.WriteLine(AppDomain.CurrentDomain.FriendlyName);
      Value++;
   }
}

[Serializable]
public class MarshalByValueClass : ITest
{
   public int Value { get; set; }

   public void Start()
   {
      Console.WriteLine(AppDomain.CurrentDomain.FriendlyName);
      Value++;
   }
}
Mamy również następujący kod, w którym testuję jak zachowuja się:
  • Obiekty przekazywane przez wartość i przez referencję.
  • Utworzone w bieżącej (przy pomocy konstruktora) oraz w innej domenie (przy pomocy AppDomain.CreateInstanceFromAndUnwrap).
  • Przy wywołaniu na nich metody bezpośrednio oraz przy pomocy AppDomain.Callback.
Co daje łączenie 2 x 2 x 2 = 8 możliwości. Do testowania używam takiej metody pomocniczej:
private static void Test(AppDomain app, ITest test, bool doCallBack)
{
   if (doCallBack)
      app.DoCallBack(test.Start);
   else
      test.Start();

   Console.WriteLine(test.Value);
}
A to właściwy test, w którym najpierw tworzę obiekty przekazywane przez wartość/referencję lokalnie i w nowej domenie. Następnie wywołuję dla nich metodę Start i odczytuję właściwość Value.
var app = AppDomain.CreateDomain("TestDomain");

var asm = Assembly.GetExecutingAssembly();
var byRef = new MarshalByRefObjectClass();
var byRef1 = new MarshalByRefObjectClass();
var byRef2 = (MarshalByRefObjectClass)app.CreateInstanceFromAndUnwrap(asm.CodeBase, typeof(MarshalByRefObjectClass).FullName);
var byRef3 = (MarshalByRefObjectClass)app.CreateInstanceFromAndUnwrap(asm.CodeBase, typeof(MarshalByRefObjectClass).FullName);

var byValue = new MarshalByValueClass();
var byValue1 = new MarshalByValueClass();
var byValue2 = (MarshalByValueClass)app.CreateInstanceFromAndUnwrap(asm.CodeBase, typeof(MarshalByValueClass).FullName);
var byValue3 = (MarshalByValueClass)app.CreateInstanceFromAndUnwrap(asm.CodeBase, typeof(MarshalByValueClass).FullName);

Test(app, byRef, true);
Test(app, byRef1, false);
Test(app, byRef2, true);
Test(app, byRef3, false);

Test(app, byValue, true);
Test(app, byValue1, false);
Test(app, byValue2, true);
Test(app, byValue3, false);
Pytanie brzmi co zostanie wypisane na ekranie? Pokaż/Ukryj odpowiedź

Obiekty przekazywane przez referencję wypiszą na ekran nazwę domeny w jakiej zostały utworzone. Nawet jeśli wywołanie jest inicjowane w innej domenie to zostanie przekazne do domeny orginalej ponieważ pracujemy z proxy do obiektu. W przypadku obiektów przekazywanych przez wartość na ekran zostanie wypisana nazwa domeny w jakiej następuje wywołanie.

Jeśli chodzi o wartość wypisaną na ekran to obiekty przekazywane przez referencję zawsze wypiszą ten sam wynik = 1 ponieważ zarówno wywołanie metody Start jak i odczyt Value dotyczy tego samego obiektu. W przypadku obiektów przekazywanych przez wartość w niektórych przypadkach możemy otrzymać zero. Stanie się tak kiedy wywołanie Start nastąpi w innej domenie niż ta, w której odczytujemy właściwość Value. A dzieje sie tak ponieważ obie czynność dotyczą de facto innych obiektów.
Sandbox.vshost.exe
1
Sandbox.vshost.exe
1
TestDomain
1
TestDomain
1
TestDomain
0
Sandbox.vshost.exe
1
TestDomain
0
Sandbox.vshost.exe
1

25/11/2014

Trochę o wynagradzaniu w IT 2

Home

W tym poście będę kontynuował tematykę wynagradzaniu programistów i napiszę o tzw. bonusach na wejście oraz pakietach akcji (znanych też pod nazwą RSU - Restricted Stock Unit). W Polsce są to rzeczy, powiedziałbym, egzotyczne. O pakietach akcji to pewnie jeszcze sporo osób słyszało, ale o bonusie na wejście to pewnie mało kto.

Tak jak napisałem w poprzednim poście, obie te rzeczy są dodatkiem do systemu poziomów. Sprawiają, że jest bardziej elastyczny i dają pole do negocjacji, czego w systemie poziomów nie ma. Bonus na wejście, po pierwsze, pozwala przyciągnąć pracownika, jeśli goła pensja wynikająca z poziomu jest za niska, a jednak chcemy go zatrudnić. Bonus na wejście wypłacany jest w całości z pierwszą pensją albo proporcjonalne co miesiąc przez 1 lub 2 lata. Czasami jest tak, że w pierwszy roku bonus wynosi X, a w drugim mniej. Bonus potrafi stanowić bardzo ważną część pensji, nawet 30%!

Ktoś zapyta, a po co taki bonus skoro od razu można dać więcej? No właśnie nie można, bo system poziomów jest po to, aby się go trzymać. Jeśli robimy wyjątki to nie ma on sensu. Sensu nie ma też sztuczne zawyżanie poziomu, to byłoby jeszcze gorsze. W tym momencie dochodzimy do drugiej funkcji bonusu. Tak jak napisałem jest on czasowy i stanowi ważną część pensji. Po upływie 2 lat potencjalnie możemy więc ''stracić'' kawał grosza, o ile się nie wykażemy i nie awansujemy na kolejny poziom. Czyli ten bonus w założeniu działa dodatkowo jako motywator.

Teraz trochę o akcje. Ten element wynagrodzenia ma za zadanie związać pracownika z firmą. Chodzi o to, że na wejściu dostajesz na przykład pakiet 50 akcji, ale nie możesz ich od razu sprzedać. Dopiero po upływie 1 roku uzyskujesz dostęp na przykład do 10% z nich, po upływie 2 roku kolejne 15%, a w każdym kolejnym roku kolejne 25%. Systemy różnią się w zależności od firmy. Co więcej, co roku możemy dostać kolejny pakiet akcji. Załóżmy, że na wejściu dostaliśmy 50 akcji, a potem co roku po 50. Pracujemy już 5 i do tej pory nie sprzedawaliśmy niczego, a więc na koniec 5 roku mamy przypisanych 250 akcji i według moich obliczeń możemy sprzedać 170 z nich. A, jeśli pracujemy dla takiego Google, będzie to stanowić na dzisiaj około 90 tysięcy $, a akcje warte kolejne 42 tysiące $ będą na nas czekać i wciąż możemy dostawać kolejne porcje.

Z tego co wiem, zdarza się tak, że niektórzy pracownicy dostają co roku w akcjach nawet więcej niż ich pensja. Zauważcie, że celowo w pierwszych latach dostaje się mało akcji, aby ich nie marnować na pracowników, którzy się nie sprawdzą lub szybko odejdą. Równocześnie odchodząc z pracy po kilku latach mamy świadomość, że tyle, a tyle akcji na nas jeszcze czeka i jak tu zmienić pracę w takiej sytuacji ;)

Co o tym myślicie? Ja mam mieszane uczucia, szczególnie jeśli chodzi o bonus na wejście. Z drugiej strony to pewnie dlatego, że jestem przyzwyczajony do konkretnej kwoty w umowie, którą staram się maksymalizować. Przy systemie z bonusem na wejście i dodatkowymi akcjami bazowa pensja może być niższa, niż gdyby tych bonusów nie było i dochodzi też element niepewności. Jak zawsze jest coś za coś.

20/11/2014

Trochę o wynagradzaniu w IT

Home

W Polsce system wynagrodzeń w IT przeważnie wygląda tak. Przychodzi się do firmy i na wejściu dostaje się tyle, ile wynegocjowało się na początku. W niektórych firmach co roku można też liczyć na wyrównanie inflacyjne (z reguły kilka procent), a jeśli się posiedzi w firmie dłużej lub awansuje to jest szansa na większą podwyżkę. Czasami jest też tak, że pensje są zamrożone nawet prze kilka lat. Według mojego i ludzi z jakim rozmawiałem doświadczenia o dużą podwyżkę najłatwiej zmieniając pracę. Dodatkowe benefity to przeważnie opieka medyczna i karta Multisport lub podobna. Bywają też inne, ale, moim zdaniem, jeśli już są, to pełnią rolę wisienki na torcie niż czegoś co mogłoby rzeczywiście kogoś skusić. Oczywiście szczegóły zależą od firmy, ale moim zdaniem ten system jest mocno nieokreślony i bardzo dużo zależy od umiejętności negocjowania i momentu, kiedy przyszło się do firmy.

Mi do gustu przypadł system stosowany w niektórych, bo w cale nie wszystkich, firmach na zachodzie. Zacznę od tego, że opiera się na systemie poziomów, a od zdobytego poziomu bezpośrednio zależy nasza pensja. Nie jest to regułą, ale ja akurat spotkałem się ze skalą zaczynającą się w okolicach 8 oraz kończącą się w okolicach 20 i zawsze się zastanawiam z czego to wynika. Nawet o to pytałem, ale odpowiedzi były, jak dla mnie, mgliste. Na przykład spotkałem się z stwierdzeniem, że z powodów psychologicznych po poziom 1 to brzmi źle.

Ostatnio, całkiem przez przypadek, natknąłem się na kilka artykułów na ten temat napisanych, między innymi, przez Joel'a Spolsky'ego jednego z założycieli portalu stackoverflow.com. W firmie Joel'a algorytm liczenia poziomu jest funkcją 3 zmiennych tj. doświadczenia (liczonego w latach), umiejętności (ocenianych w zakresie 0-6) oraz zakresu obowiązków (również ocenianego w zakresie 0-6). A możliwe kombinacje zostały ujęte w taką tabelkę:



Ważne jest to, że pracowniczy na danym poziomie zarabiają tyle samo względem kwoty bazowej, która aktualizowana jest co jakiś czas. Czyli na przykład na poziomie dziewiątym zarabiasz X, na dziesiątym X+10%, a na jedenastym X+20% itd. Kwota X nie podlega dyskusji. Jeśli chce się zarabiać więcej to najłatwiej osiągnąć to przez zwiększenie swoich umiejętności. Zauważcie, że według powyższej tabelki wraz z kolejnymi latami doświadczenia poziom rośnie powoli w porównaniu do wzrostu umiejętności i zakresu obowiązków.

Istotne jest to, że osiągniecie maksymalnego poziomu nie oznacza, że programista przestaje być programistą i staje się menadżerem. Wprost odwrotnie, to oznacza, że jest wyjebistym programistą i będzie nadal robił to w czym jest najlepszy. Natomiast jak zaczynasz bez żadnego doświadczenia to dostajesz co prawda najniższy poziom, ale po pierwszym roku możesz skoczyć o 5 oczek do przodu, czyli tyle co ma ktoś z 15 latami doświadczenia, ale nie jest tak dobry jak ty.

Jak dla mnie takie postawienie sprawy to super rzecz. Każdy wie, na co może liczyć i mniej więcej przewidzieć, jak będzie wyglądała jego pensja w przyszłości. Można się pewnie czepiać, że ocena umiejętności jest subiektywna, że ktoś może nas nam zaniżyć ocenę... Ja na taki zarzut odpowiem tak: nie ma systemu idealnego i uważam, że ten jest dużo lepszy od tego co opisałem na początki postu. Natomiast jeśli uważasz, że ktoś może Ci celowo zaniżyć ocenę to lepiej bierz nogi za pas i zmień pracę.

Co o tym myślicie? Czy taki system mógłby przyjąć się w Polsce?

Na koniec trochę linków:
W kolejnym poście napiszę o systemie bonusów na wejście oraz opcji na akcje, które stanowią ważne uzupełnienie czystego systemu poziomów, a są bardzo mało znane w Polsce.

11/11/2014

Domeny aplikacyjne i wątki

Home

Jakiś czas temu odpowiedziałem na pytanie na stackoverflow.com dotyczące kończenia pracy wątków z zewnętrznej biblioteki w sytuacji kiedy powinny już zakończyć pracę, a jednak tego nie zrobiły. Moja odpowiedź została co prawda skrytykowana, zresztą słusznie, ale dzięki temu dowiedziałem się rzeczy, która mi wcześniej umknęła.

W mojej odpowiedzi zasugerowałem, że skoro z jakiegoś powodu musimy użyć zewnętrznej biblioteki i ona nie działa to ja bym ją załadował do oddzielnej domeny aplikacyjnej i w tej nowej domenie uruchomił też obliczenia (wątki). Taką domeną można natomiast w dowolnym momencie "odładować" przy pomocy AppDomain.Unload. Napisałem nawet przykład pokazujący, że to działa. W czym więc problem?

Otóż wywołanie AppDomain.Unload może się nie powieść i zostanie wtedy rzucony wyjątku CannotUnloadAppDomainException. Powodów mogą być trzy, ale nas interesuje jeden. Kiedy wołamy AppDomain.Unload i wewnątrz domeny są aktywne jakieś wątki to AppDomain.Unload spróbuje je ubić przy pomocy metody Thread.Abort. Jeśli się uda to ok, ale Thread.Abort może nie być w stanie ubić wątku i wtedy zostanie wygenerowany wzmiankowany powyżej wyjątek.

Kiedy Thread.Abort nie zadziała? Dokumentacja wspomina o dwóch przypadkach.
  • Kiedy wątek wykonuje kod niezarządzany.
  • Kiedy wątek wykonuje właśnie kod wewnątrz bloku finally. To można bardzo łatwo symulować przez umieszczenie wywołania Thread.Sleep(100000) wewnątrz bloku finally.

08/11/2014

Jako programista przyzwyczaiłem się do...

Home

Jakiś czas temu rozmawiałem z kolegą z branży i w pewnym momencie powiedział on zdanie, które utkwiło mi w pamięci. Parafrazując stwierdził, że:

"Jako programista przyzwyczaiłem się do tego, że się ze mną rozmawia."

Powiedział to w kontekście pracy w firmie, dla kogoś. Chodziło o to, że nawet jeśli coś mu się nie podobało, ale musiał to zrobić bo ktoś podjął taką decyzję, to nie bolało tak bardzo jeśli ktoś z nim wcześniej o tym porozmawiał. Mam tutaj na myśli zarówno sprawy techniczne co nasuwa się samo, ale również te "miękkie" na przykład związane z organizacją pracy.

Jak się nad tym chwilę zastanowiłem to stwierdziłem, że z pewnymi wyjątkami mam podobne doświadczenie i w sumie takie podejście wydało mi się oczywiste. Pytanie czy tak jest wszędzie? Może po prostu mieliśmy szczęście. Czy macie podobne wrażenia, a może wprost przeciwnie?

01/11/2014

Własne komendy w menu kontekstowym Windows'a

Home

Kiedy napiszę jakieś narzędzie to często chcę mieć do niego łatwy dostęp z poziomu menu kontekstowego Windows'a. Już od dłuższego czasu robię to przez dodanie odpowiednich wpisów do rejestru systemowego. W ogólności grzebanie w rejestrze nie jest bardzo przyjemne i istnieje ryzyko, że się coś popsuje. Dlatego też korzystam z następujących wypróbowanych wzorców.

Jeśli polecenie ma być dostępne dla wszystkich plików
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\*\Shell\COMMAND_NAME]
[HKEY_CLASSES_ROOT\*\Shell\COMMAND_NAME\command]
@="COMMAND"
Jeśli polecenie ma być dostępne dla określonych plików
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\.EXTENSION\Shell\COMMAND_NAME]
[HKEY_CLASSES_ROOT\.EXTENSION\Shell\COMMAND_NAME\command]
@="COMMAND"
Jeśli polecenie ma być dostępne dla katalogów
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Directory\Shell\COMMAND_NAME]
[HKEY_CLASSES_ROOT\Directory\Shell\COMMAND_NAME\command]
@="COMMAND"

[HKEY_CLASSES_ROOT\Directory\Background\Shell\COMMAND_NAME]
[HKEY_CLASSES_ROOT\Directory\Background\Shell\COMMAND_NAME\command]
@="COMMAND"
W powyższych wzorcach COMMAND_NAME oznacza nazwę opcji jaka pojawi się w menu kontekstowym np.: Shred, EXTENSION to rozszerzenie pliku np.: txt i w końcu COMMAND to skrypt/polecenie jakie ma zostać wykonane po wybraniu przez użytkownika określonej opcji z menu kontekstowego np.: T:\\bin\\shred -n 10 -v -z \"%1\". Zwróćcie uwagę, że przy podawaniu ścieżki stosuję podwójny ukośnik tj. \\ oraz, że cudzysłów wewnątrz polecenia jest poprzedzony ukośnikiem tj. \". Na koniec uzupełnione wzorce należy zapisać w pliku z rozszerzeniem *.reg i przez podwójne kliknięcie na takim pliku dodać go do rejestru. Zmiany będą widoczne natychmiast.

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.