Author Archives: Paweł Trojanowski

Gdzie przenieść środowisko programistyczne (chmura, dedyk, vps)?

W dzisiejszych czasach wszystko związane z IT zaczyna przenosić się do sieci, chodzi mi o streamingi muzyki, filmów, pliki archiwizujemy na dropboxach czy innych drive’ach. Dlatego zadałem sobie pytanie, czy nie byłoby dobrym pomysłem przenieść swoje środowisko programistyczne do sieci?

W jednym z poprzednich wpisów opisywałem że kupiłem sobie komputer z dość dobrymi podzespołami do moich rozwiązań programistycznych i z uwagi na wydajne i stabilne łącze pracuje na nim zamiast lokalnie na komputerze. Jednak ostatnio zacząłem coraz bardziej odczuwać minusy tego rozwiązania, ponieważ dostawca internetu zaczął szwankować a ja kilka razy w miesiącu przez kilka godzin nie miałem dostępu do serwera. A to nie może się zdarzać, bo jednak w przypadku spotkania z klientem tłumaczenie że pewnie internet w domu się zawiesił może postawić mnie w złym świetle, a dodatkowo każda godzina przestoju w pracy kosztuje coraz więcej.

Zacząłem więc szukać alternatywnych rozwiązań. Pierwszym rozwiązaniem o którym pomyślałem była chmura. Miała wiele zalet, np. to że mogłem szybko i tanio utworzyć instancję a następnie płacić tylko za godziny pracy serwera. To rozwiązanie się bardzo dobrze sprawdza pod względem technicznym, ale finansowo jednak nie do końca. Okazało się że w ciągu miesiąca pracy w takim środowisku kilka razy zdarzyło mi się nie wyłączyć serwera po pracy a co za tym idzie przez następne kilkanaście godzin naliczane były mi opłaty za działający serwer. W wyniku takich niedopatrzeń niestety w ciągu miesiąca straciłem tyle pieniędzy za ile miałbym serwer dedykowany dostępny 24h na dobę. Dodatkowym minusem jest niewielka ilość powierzchni dyskowej na dysku systemowym, przez co byłem zmuszony dopłacić za dodatkowy dysk SSD co już znacząco przekracza próg opłacalności tego rozwiązania. Najwidoczniej do tego chmura się nie najlepiej nadaje.

Zwróciłem również uwagę na VPSy, jednak z tego rozwiązania zrezygnowałem na starcie z uwagi na ograniczenia ilości rdzeni na maszynę, wolne dyski, bo jednak współdzielone i stosunkowo wysoki koszt, ponieważ serwer w takiej konfiguracji jaką wymagam nie różnił się praktycznie ceną z dedykiem w podobnej konfiguracji w jednej z polskiej serwerowni.

W końcu zwróciłem się w kierunku serwera dedykowanego i tutaj oferty są na prawdę korzystne, ponieważ za dobry serwer z 4 rdzeniami ponad 3Ghz, 32GB Ram i dwoma dyskami 120 GB i Windows Server 2012 z RDS za 300 zł netto. Pewnie można taniej, ale akurat taka konfiguracja mi odpowiada w 100%. Plusy są takie same jak powyżej, ale nie mamy minusa w postaci zmiennej kwoty w zależności od nieuwagi, a dodatkowo zawsze można postawić na takim serwerze coś więcej niż tylko środowisko programistyczne.

Na ten moment ciężko mi określić czy takie rozwiązanie jest idealne, ale na pewno będę je dalej sprawdzał i napiszę za jakiś czas tak jak teraz kontynuuję wpis o pracy na serwerze zdalnym.

Jak zabezpieczyć środowisko programistyczne przed awarią

Prawdopodobnie każdemu z Was kiedyś przytrafiła się awaria dysku twardego, czy też kupno nowego komputera i odtworzenie środowiska programistycznego na innym komputerze kosztowało Was dużo pracy i czasu, a niektóre dobrze skonfigurowane programy już nigdy nie były tak wygodne jak wcześniej.

Był to dla mnie poważny problem, którego nie potrafiłem przez dłuższy czas rozwiązać i choć systemy backupowania potrafią już robić kopię całych partycji, było to dla mnie zbyt uciążliwe i wymagało mojej uwagi. Jednak po zakupie porządnego komputera do programowania zacząłem się znów interesować wirtualizacją i to podsunęło mi świetny pomysł, że po co mam pracować bezpośrednio na maszynie jak mogę pracować na maszynie wirtualnej.

I teraz pewnie odezwą się głosy, że tracę część mocy obliczeniowej na środowisko hypervisora, że łącząc się przez pulpit zdalny ze swoją maszyną wirtualną mam niewielkie lagi i utraty płynności wyświetlanego obrazu i nawet z tymi głosami mogę się zgodzić, ale takie rozwiązanie ma także wiele zalet.

A zaletą jest to, że gdy chcę zrobić backup maszyny wirtualnej, to mogę skorzystać z metody snapshotów (do której nie jestem przekonany) lub po prostu zatrzymać maszynę wirtualną na kilka minut i przekopiować pliki na dysk sieciowy. Czyli zapewniam sobie w ten sposób kopię całego środowiska ze wszystkimi programami, plikami i przeglądarkami, które potrzebuję i w razie potrzeby mogę szybko odtworzyć na innym komputerze maszynę wirtualną i dalej pracować. Dzięki czemu nie tracę czasu w przypadku poważnych problemów.

Kolejną zaletą jest oddzielenie środowiska developerskiego od środowiska prywatnego, bo jednak co by nie powiedzieć jestem trochę bałaganiarzem w trakcie pracy i mój pulpit szybko zapełnia się różnego rodzaju śmieciami, których nie chciałbym mieć na prywatnym komputerze. A w ten sposób mam jeden komputer, który jest jednocześnie prywatnym i firmowym.

Niektórzy korzystają z mechanizmu snapshotów czego ja akurat nie potrzebuję, ale widzę pewne plusy tego rozwiązania, takie jak możliwość cofnięcia się do punktu z przed zaśmiecenia systemu zbędnymi danymi. Jednak ja wyszedłem z założenia, że i tak jak będę chciał się cofnąć to po prostu załaduję odpowiedni backup, który jest kopią całościową a snapshoty są przyrostowe, czyli w przypadku kopiowania tylko kolejnych plików przyrostowych jest to mniej bezpieczna metoda.

Ewentualnie polecam również stworzenie sobie środowiska developerskiego w chmurze, ponieważ tam też mamy możliwość ustalenia backupów całościowych, kopiowania środowiska i mamy dostęp praktycznie wszędzie, ale jest to rozwiązanie niestety dosyć drogie. Nawet jeżeli zdecydujemy się włączać instancję tylko na czas pracy, to wychodzi około 200 zł miesięcznie, a to pozwala w ciągu roku kupić już jakiś w miarę dobry komputer do programowania.

Podsumowując: By dobrze zabezpieczyć się przed utratą danych, programów i konfiguracji warto pracować na wirtualnej maszynie. Skonfigurowanie i zainstalowanie systemu na środowisku wirtualnym chwilę trwa, jak każda instalacja systemu na nowym komputerze, ale po jakimś czasie bardzo możliwe że się zwróci w postaci łatwego przeniesienia środowiska na inny komputer.

5 błędów które popełniają młodzi programiści

Nikt nie jest idealny i zdaję sobie sprawę że nie można od nikogo tego wymagać, jednak mój wpis nie ma za zadanie wyśmiewać się z błędów młodych programistów tylko zwrócić uwagę na błędy, które popełniają. Jest to lista całkowicie subiektywna i prawdopodobnie nie zawiera 99% błędów popełnianych przez programistów, ale akurat z takimi sytuacjami się spotkałem i wiem że po poprawie tych błędów było już dużo lepiej.

  1. Nie używanie breakpointów i nie sprawdzanie wartości zmiennych – nie wiem czy to z lenistwa, czy niewiedzy zauważyłem że nowo zatrudnieni programiści nie używają breakpointów w trakcie pracy nad problematycznym kodem. Rozumiem że niektórych błędów się można domyślić, ale przejście wykonania kodu krok po kroku ułatwia zrozumienie co się dzieje, co oczywiście polecam.
  2. Nie szukanie rozwiązań problemów w internecie – tutaj prawdopodobnie jest to lenistwo, ponieważ łatwiej zapytać kolegę z pracy jak rozwiązać problem niż zacząć szukać na własną rękę, ale polecam jednak spróbować najpierw szukać w google i jeżeli w krótkim czasie nie znajdziesz problemu, spytać współpracownika. Każde pytanie zadane współpracownikowi wybija go z pracy, więc warto ograniczać to tylko do najważniejszych tematów.
  3. Nie proszenie o pomoc lub proszenie o pomoc zbyt częste – tutaj przewija się temat zbyt częstego zadania pytań z poprzedniego punktu, ale również dodałem element nie pytania w ogóle. Rozumiem, że czasami programista nie chce ujawnić swojej niewiedzy, ale wierzcie mi lub nie, niewiedza i tak wyjdzie prędzej czy później. Więc nie bój się pytać jeżeli nie masz już żadnego sensownego pomysłu na rozwiązanie problemu.
  4. Nie przewidywanie nietypowych warunków działania algorytmu – to jest notoryczny problem nowych programistów, ponieważ nie rozwiązali odpowiedniej ilości błędów i nie potrafią ich przewidzieć. Tutaj mogę doradzić tylko jedno, próbuj zepsuć działanie programu na wszelkie sposoby po napisaniu kodu, a jeżeli ktoś wytknął Ci błąd, to podpatrz jak on doszedł do tego że go popełniłeś.
  5. Nie szukanie rozwiązań problemu w projekcie – ten punkt trochę wynika również z nieznajomości projektu w którym się piszę kod. Ale nie można się tak tłumaczyć, ponieważ nawet jeżeli nie znamy projektu w 100% to możemy przynajmniej spróbować poszukać, czy w kodzie któregoś modułu nie ma jakiegoś kawałka kodu który przyda się podczas tworzenia kodu. Ważne jest żeby inni pracownicy również uważali na swój kod i pisali go możliwie uniwersalnie. Zasada jest taka: jeżeli masz napisać jakąś funkcję, która się przyda w wielu miejscach projektu to przemyśl lub zapytaj współpracownika gdzie taki kod powinien się znaleźć. W różnych firmach są różne podejścia i czasami w zależności od zastosowania kodu powinien on znaleźć się w określonym miejscu i w takim momencie musisz pytać bo sam możesz nie dojść do tego jak zrobić to dobrze.

A dla ludzi współpracujących z młodymi programistami polecam code review. Wiem że to brzmi jak strata czasu, ale tylko w ten sposób jesteście w stanie wcześnie wykryć złe nawyki programisty i nauczyć go tego co w waszej firmie jest pożądane.

Wyszukiwanie binarne [C#]

Wyszukiwanie binarne jest algorytmem opierającym się na metodzie dziel i zwyciężaj, który w czasie logarytmicznym stwierdza, czy szukany element znajduje się w uporządkowanej tablicy i jeśli się znajduje, podaje jego indeks. Algorytm, który napisałem korzysta z bibliotek dodatkowych (linq czy Collections.Generic), które są dostępne w C# a niekoniecznie będą dostępne w innych językach programowania, ale jeżeli chodzi o założenia algorytmu to jest on przepisywalny w łatwy sposób na C++ czy JAVA bo semantyka tych języków jest bardzo podobna.

Ważne: Działa on dla listy o wielkości większej niż 1. Nie wdrażałem tego zabezpieczenia z uwagi że generuję losowo listę o ilości elementów większej niż 1.


using System;
using System.Collections.Generic;
using System.Linq;

namespace Wyszukiwanie_binarne
{
    class Program
    {
        static void Main(string[] args)
        {
            Random rand = new Random();

            // tworzę listę i wypełniam losowymi danymi
            List<int> listaLiczb = new List<int>();
            for (int i = 0; i < 100; i++) listaLiczb.Add(rand.Next(0, 1000));

            // czyszczę listę z powtórzonych wartości i sortuję
            listaLiczb = listaLiczb.Distinct().ToList();
            listaLiczb.Sort();

            Console.WriteLine("Liczby na liście:");
            Console.WriteLine(String.Join(",", listaLiczb));

            Console.WriteLine("Podaj liczbę której pozycję szukasz:");
            var szukanaLiczba = int.Parse(Console.ReadLine());

            Console.WriteLine("Poszukiwana liczba znajduje się na liście pod indexem: ");
            try
            {
                Console.Write(Szukaj(listaLiczb, szukanaLiczba));
            }
            catch (Exception)
            {
                Console.Write("Podana liczba nie znajduje się na liście!");
            }

            Console.ReadKey();
        }

        public static int Szukaj(List<int> przeszukiwanaLista, int szukanaLiczba)
        {
            // ilość elementów w liście
            var iloscElementow = przeszukiwanaLista.Count();

            // jeżeli ilość elementów wynosi jeden to znaczy że liczba nie została znaleziona
            if (iloscElementow == 1) throw new Exception("Podana liczba nie znajduje się na liście!");
            
            // wyliczenie połowy z ilości elementów
            var polowa = iloscElementow / 2;

            // wyciągnięcie z listy wartości środkowego elementu
            var srodkowyElement = przeszukiwanaLista[polowa];

            // jeżeli wartość środkowego elementu jest większa niż szukana liczba, to weź pierwszą połowę listy i przekaż do funkcji Szukaj()
            if (srodkowyElement > szukanaLiczba) return Szukaj(przeszukiwanaLista.Take(polowa).ToList(), szukanaLiczba);

            // jeżeli wartość środkowego elementu jest mniejsza niż szukana liczba, to weź drugą połowę listy i przekaż do funkcji Szukaj()
            else if (srodkowyElement < szukanaLiczba) return Szukaj(przeszukiwanaLista.Skip(polowa).ToList(), szukanaLiczba) + polowa; // tutaj dodajemy index połowy, poniważ znaleziona liczba będzie z drugiej połowy listy

            // Jeżeli jest równa co szukana liczba to zwróć index aktualnej połowy
            return polowa;
        }
    }
}


 

Zapobieganie pożarom – czyli jak lepiej tworzyć oprogramowanie z użyciem metodyki programowania zwinnego

Gdy zaczyna się pożar…

Najgorszym momentem podczas tworzenia oprogramowania jest chwila w której dowiadujemy się że końcowy produkt nie jest zgodny z oczekiwaniami klienta i prawdopodobnie czas doprowadzenia produktu do stanu oczekiwanego będzie dużo dłuższy niż zakładaliśmy.

Jak daleko trzeba się cofnąć jeżeli dopiero podczas testowania znajdziemy błąd analizy oczekiwań klienta źródło: Wikipedia.org

Zwykle nie jest to wina tylko jednej strony, ale wynika ze złożenia braku zrozumienia klienta, a z drugiej strony klient też nie do końca potrafi określić czego potrzebuje. Jednak zwykle wina pozostanie jednak po naszej stronie, ponieważ to my zgodziliśmy się na warunki klienta. Następnie trwa gaszenie pożaru, czyli łatanie oprogramowania lub kary umowne i utrata klienta, co nie jest zbyt optymistyczną perspektywą.

Jednak okazuje się że jest sposób na to żeby się uchronić przed niektórymi błędami. A sposobem na to jest metodyka programowania zwinnego (nie jest to panaceum na problemy ale na pewno pomoże). Oczywiście dla każdego to określenie może znaczyć co innego, ważne żeby jej fundamenty były oparte na wzajemnym sprawdzaniu się klienta i wykonawcy.

Samych metodyk zwinnych jest wiele i trzeba się zastanowić jaką chcemy wdrożyć i jak dużo chcemy z niej czerpać. Może nawet ktoś skusi się wykorzystać kilka pomysłów z jednej a kilka z innej i też może się to okazać poprawne, ważne żeby to robić z głową.

Jak się to u mnie robi?

  1. Projekt jest dzielony na sprinty, czyli okres czasu (1 do max 2 tygodnie) w którym zakładamy wykonanie zaplanowanych zadań,
  2. Każdego dnia odbywa się daily, na którym zespół zbiera się żeby wymienić się wykonaną pracą z poprzedniego dnia i przekazuje informację na temat aktualnych prac (punkt dla większego zespołu powyżej 3-4 osób i ważne jest żeby nie przekroczyć 15 – 20 min na takie spotkanie, ponieważ gdy jest dłużej to spada efektywność pracy w danym dniu),
  3. Ostatniego dnia każdego sprintu odbywa się demo, czyli prezentacja wykonanych zadań przed klientem (bardzo ważny punkt),
  4. Oraz ostatni punkt – planowanie zadań na następny sprint.

Oprócz sprintów określane są jeszcze kamienie milowe, czyli momenty w których ma zostać wdrożona jakaś większa funkcjonalność, przy czym ważne jest żeby każdy znał cel i datę w której powinien zostać osiągnięty.

Dlaczego demo w sprincie jest takie ważne? ponieważ jest to ten moment w którym klient dowiaduje się co w ciągu tego sprintu udało się nam zrobić i w jaki sposób to działa. Jeżeli się okaże że minęliśmy się z założeniami klienta lub zostały one źle sformułowane, to ostatecznie tracimy jedynie jeden sprint i możemy gasić malutki płomień zamiast wielomiesięcznego pożaru. Swoją drogą porównanie do pożaru jest bardzo dobre, ponieważ mały płomień zwykle da się ugasić i nie powinien poczynić wielkich strat, ale jeżeli stracimy nad nim panowanie lub nie będziemy wiedzieć że się rozprzestrzenia to może pochłonąć cały nasz dobytek, czyli projekt nad którym długo pracowaliśmy.

Ale pamiętaj że nie tylko demo jest ważne i w zasadzie te 4 (ewentualnie przy mniejszym zespole 3) punkty które napisałem to jest taki plan minimum, które warto wdrożyć, a ponieważ przeszedłem przez różne firmy i różne sposoby zarządzania projektem, mogę powiedzieć że ten sposób jest dla mnie najbardziej odpowiedni i daje pojęcie na temat tego ile pozostało jeszcze pracy.

Planowanie, jak to robić?

Nie jest to proste i przez pierwsze sprinty w których miałem sam szacować czas pracy na wykonanie określonych zadań wszystko mi się rozjechało i nie domknąłem sprintu. Dlatego dam Wam kilka pomysłów na to jak to robić trochę łatwiej.

  1. Wszystkie zadania jakie są do zrobienia w ramach projektu powinny zostać rozdzielone na moduły, grupy i kolejne mniejsze jednostki w zależności od złożoności projektu (lepiej zadanie na tydzień rozłożyć na dwa zadania po 2,5 dnia bo to już tak nie przeraża, a dodatkowo łatwiej jest oszacować czas) i umieszczone w pliku dostępnym dla całego zespołu,
  2. Jeżeli zadanie wydaje się zbyt ogólne, to rozpisz w kilku punktach co powinno zostać zrobione w takim zadaniu (łatwiej oszacować czas pisania małej funkcji niż dużego modułu),
  3. Wybierz i oszacuj czas wykonania zadań w sprincie a następnie w zespole skonsultuj czy oszacowany przez ciebie czas jest odpowiedni (być może ktoś podsunie ci pomysł jak to zadanie wykonać szybciej lub wyprowadzi cię z błędu i wyjaśni dlaczego w takim czasie się nie da tego zrobić),
  4. Staraj się nie przekraczać 2 godzin na planowanie, ponieważ wiem że w większości wypadków da się zaplanować pracę w zespole ok 5 osób w takim czasie, a ludzie i tak już będą coraz gorzej myśleć.

Nie rozumiem dlaczego mam to wdrażać, przecież to trwa tyle czasu

Na początku ja też tak myślałem i strasznie demotywowało mnie to że muszę znów oszacować swój czas (co szło mi słabo) i pewnie się nie wyrobię, a tracę czas na głupoty, które i tak mi nic nie dają. I tak było przez kilka sprintów, po czym nagle zacząłem mimowolnie wsiąkać w to. Okazało się po dłuższym czasie że nawet to zrozumiałem 🙂 a teraz nie mogę inaczej pracować. Okazuje się że teraz nie dość że potrafię zaplanować sobie sprint i z dużą dozą prawdopodobieństwa dobrze oszacować czas zadań (o ile nie będzie dużo wrzutek, czyli dodatkowych zadań, które trzeba zrobić w czasie sprintu) i coraz rzadziej zdarza mi się że przed deadline muszę się spinać i siedzieć po nocach. Właśnie idea programowania zwinnego również chroni przed tym, ponieważ na każdym małym etapie widzisz ile jeszcze zostało ci do końca projektu.

Taki pro-tip dla firm, które jeszcze nie wdrożyły metodyki zwinnej a chciałyby: jest wiele warsztatów i szkoleniowców, którzy przekonają i pokażą jak to robić dobrze. Ważne jest żeby zespół lub jego manager tego chciał bo po chwili męki będą z tego same korzyści.

Czy ta metodyka sprawdza się tylko w programowaniu?

Sądzę że nie, zwłaszcza że w coraz większej ilości firm jest ona wdrażane, tylko nikt jej tak nie nazywa. Wg. mnie każda praca twórcza powinna być dzielona na mniejsze kawałeczki dzięki czemu łatwiej to w jakiś sposób ogarnąć rozumem, a przecież nikt nie będzie mówił że tego się używa w programowaniu więc nie możesz używać gdzie indziej. W każdej firmie można znaleźć jakieś fajne pomysły, tylko warto sprawdzić czy są one dobre dla naszej firmy i jeżeli tak to się nie zniechęcać, bo gdybym się zniechęcił to nie poznałbym tak dobrego sposobu zarządzania projektem.

Konwersja z vmdk do Hyper-V (vhdx) – Problem „The entry is not a supported disk database entry” …

Podczas konwersji z formatu vmdk (VMware) do vhdx (Hyper-V)  za pomocą programu … dość często pojawia się problem „ConvertTo-MvmcVirtualHardDisk : The entry 00000000-0000-0000-0000-000000000000 is not a supported disk database entry for the descriptor…

Każdy plik vmdk posiada nagłówek, w którym zapisane są podstawowe informacje na temat obrazu dysku. Z jakiegoś powodu w dużej części obrazów owe dane są błędne. Nie badałem szczegółów wystąpienia tego błędu, ale udało mi się znaleźć rozwiązanie.

 

  1. Należy pobrać i rozpakować program dsfok. Służy on do rozpakowania deskryptora z obrazu do pliku tekstowego.
  2. W wierszu poleceń należy wpisać polecenie:
    dsfo.exe „D:\Ścieżka do pliku obrazu\disk1.vmdk” 512 1024 „D:\Ścieżka do pliku obrazu\descriptor.txt”
  3. Następnie można otworzyć descriptor.txt za pomocą dowolnego programu do edycji tekstu.
  4. Należy odnaleźć 5 linijek zaczynających się od poniższych tesktów i usunąć je:
    1. ddb.comment
    2. ddb.uuid.image
    3. ddb.uuid.modification
    4. ddb.uuid.parent
    5. ddb.uuid.parentmodification
  5. Następnie można zapisać deskryptor do pliku obrazu:
    dsfi.exe „D:\Ścieżka do pliku obrazu\disk1.vmdk” 512 1024 „D:\Ścieżka do pliku obrazu\descriptor.txt”
  6. Następnie można spróbować wykonać polecenie ConvertTo-MvmcVirtualHardDisk ponownie.

Problem powinien zniknąć i maszyna wirtualna powinna zostać pomyślnie przekonwertowana.

 

Co nowego u mnie?

Dawno nie pisałem niczego na bloga (ponad pół roku), a mam wrażenie że każdego miesiąca wchodzi tu coraz więcej osób, to chciałbym coś napisać do tych nowych osób, żeby mnie trochę zaczęli poznawać. Staram się nie poruszać prywatnych spraw, więc nie bójcie się nie będzie zbyt depresyjnie 😉

Trochę opowiadania …

Jakieś dwa lata temu (może nawet trochę więcej) miałem swoje pierwsze podejście do freelancingu, tzn. rzuciłem pracę w której dotychczas pracowałem i zacząłem szukać zleceń które mógłbym wykonywać na własną rękę. Pierwszy miesiąc był bardzo słaby, ponieważ głównie zajmowałem się poszukiwaniem zleceń a nie ich realizacją, a dzięki temu że wcześniej odłożyłem trochę pieniędzy to nie było źle. Później znalazłem kilka dobrych zleceń i projekt aplikacji webowej do obsługi firm księgowych który rozwijam do dzisiaj. Jednak pół roku później zrozumiałem, że nie jestem w stanie utrzymać się na dobrym poziomie z uwagi na to że realizowałem głównie małe projekty, które szybko się kończyły a znalezienie następnych trwało.

Tak więc postanowiłem zatrudnić się w firmie programistycznej poleconej przez znajomego, gdzie rzeczywiście mnie przyjęli i zacząłem pracę na 3/5 etatu, a w pozostałym czasie realizowałem projekty dla swoich klientów. Tak było przez około półtorej roku w którym miałem zarówno wzloty i upadki. Tzn. spotkałem 3 nieuczciwych kontrahentów, nie doprowadziłem do końca jednego projektu z uwagi na brak czasu, ale miałem też wiele świetnych realizacji, które dały mi sporo doświadczenia. Jednak tak jak wspomniałem, brakowało mi czasu.

Po dłuższym czasie intensywnej pracy zacząłem odczuwać że spada dokładność mojej pracy, ponieważ praktycznie cały czas jestem w pracy i niektóre rzeczy zacząłem robić z mniejszą chęcią. Być może się trochę zacząłem wypalać jako programista. Więc postanowiłem coś z tym zrobić. A coś oznaczało konkretnie ograniczenie ilości pobocznych projektów i skupienie się jedynie na najważniejszych i pozostawienie większej ilości wolnego czasu. Przecież muszę mieć też czas dla swojej dziewczyny czy na wypoczynek po pracy.

Nie chcę pisać że w tym momencie mam pewność że to działa, ale wydaje mi się że w ciągu ostatnich 3 miesięcy zacząłem mieć więcej czasu i rzadko zdarza mi się pracować po nocach a to duży skok w dobrą stronę 🙂

Odpoczynek jest bardzo ważny

Mam zasadę, którą niestety z przyczyn niezależnych w tym roku złamałem (czynnik losowy). A mianowicie każdego roku staram się gdzieś wyjechać na dłużej z moją drugą połówką. A na dłużej znaczy zwykle 2 tygodnie, co polecam każdemu, ponieważ w czasie tak długiego oderwania się od komputerów/programowania na prawdę można się zregenerować. Pewnie to sprawa indywidualna, ale dla mnie 2 tygodnie są na prawdę idealne. W tamtym roku byliśmy z Asią w Maroko, gdzie przez tydzień mieliśmy wycieczki po różnych pięknych miejscach, a kolejny tydzień byczyliśmy się na plaży i na własną rękę organizowaliśmy wyjazdy. Było na prawdę świetnie, a muszę się przyznać że już pod koniec wyjazdu miałem ogromną chęć programować. Taki reset jest ważny.

Nie mówić ciągle o pracy

Ktoś kto przejrzał tego bloga może myśleć że raczej w moim wypadku jest odwrotnie. Ale staram się to zmieniać. Kiedyś jarało mnie strasznie opowiadanie znajomym jakie ciekawe projekty robiłem, kiedy się nie widzieliśmy, ale widzę że już zaczynam zmieniać podejście. Pewnie są dwie przyczyny. Jedna taka, że już zacząłem się przyzwyczajać do tego co robię i staje się to niczym niezwykłym. A druga, to taka że zrozumiałem że nie każdego to interesuje 🙂 Jest tyle innych ciekawych tematów do rozmowy, że aż szkoda je tracić na gadanie o komputerach. To nie jest żadna rada, bo każdy ma różnych znajomych, różne podejście do życia, więc się nie wtrącam, ale w sumie cały ten wpis jest takim moim luźnym wyznaniem, więc o tym też piszę.

Założenie działalności i trochę rad

Jakiś czas temu założyłem działalność gospodarczą z uwagi na to że już nie miałem ubezpieczenia zdrowotnego z uwagi na skończone 26 lat, a druga sprawa że nie chciałem już robić wszystkiego na umowę o dzieło. To wyglądało czasami trochę niepoważnie, więc trzeba było się za to zabrać.

Generalnie sprawa jest mega prosta, ponieważ wszystko da się załatwić w jeden dzień i nie wymaga ogromnej wiedzy, choć warto wcześniej mieć już księgowego, ponieważ jest kilka błędów, które można popełnić. Ja zacząłem od wypełnienia formularza na CEIDG https://prod.ceidg.gov.pl/ceidg.cms.engine/ , w zasadzie wszystko co potrzeba można znaleźć na tej stronie. Dodatkowo podczas wypełniania formularza warto sugerować się jakąś firmą, która świadczy podobne usługi, ponieważ można od nich wziąć kody pkd. A warto najpierw wypełnić formularz online, ponieważ później przychodzi się do urzędu i tylko składa podpisy, bez żadnych większych problemów (u mnie wizyta w urzędzie trwała jakieś 20 min.)

Następnie trzeba się udać do ZUS, żeby złożyć wniosek o przyjęcie do ubezpieczenia. Jest tak że przy zakładaniu działalności informacje o założeniu trafiają do ZUS, ale jednak i tak trzeba osobiście zgłosić się do ubezpieczenia. To też trwało 20 min, ale trzeba było wypełnić dwustronnicowy formularz. Podpowiadam, weź 2 sztuki, bo łatwo się pomylić 🙂

(Dla chętnych*) Po tym udałem się do urzędu skarbowego, w celu złożenia deklaracji VAT, ponieważ chciałem zostać płatnikiem VAT. Tutaj temat jest dla chętnych, ponieważ jeżeli zaznaczyłeś we wniosku o założenie działalności że nie chcesz być płatnikiem to nie musisz. Generalnie opłaca się to bardzo, ale jest trochę więcej papierkowej roboty dla księgowego. Ja akurat chciałem więc się zgłosiłem. Polecam jednak zabrać ze sobą umowę wynajmu/własności nieruchomości/biura w którym działalność jest prowadzona, bo bez tego dokumentu nie da się złożyć tego wniosku. W moim wypadku wystarczyła umowa użyczenia nieruchomości, ponieważ rodzic(akurat ojciec jest właścicielem nieruchomości) nie musi w takiej sytuacji płacić podatku od tej umowy. Dodatkowo żeby nie płacić 180 zł w urzędzie skarbowym tylko zrobić to za darmo trzeba zaznaczyć na wniosku że nie potrzebujemy potwierdzenia złożenia deklaracji VAT (jeżeli dobrze pamiętam), z uwagi że teraz nie jest to potwierdzenie wymagane, a po co wydawać kasę bez sensu.

Podsumowując nie kosztowało mnie to ani złotówkę, a mam już wszystko załatwione i zarabiam więcej niż gdybym był na umowę o pracę. Jeżeli będzie taka potrzeba to mogę to dodatkowo wyjaśnić. Jakby coś to proście w komentarzu 🙂

Jakie plany na przyszłość?

Przede wszystkim pracować trochę mniej a skupić się na rzeczach ważniejszych. Mam też kilka fajnych pomysłów do zrealizowania tak „just for fun” bo ostatnio zacząłem znów mieć wenę, więc pewnie coś nowego się pojawi na Poradniku 🙂 Ogólnie chciałbym trochę przerobić poradnik, ponieważ taka forma strony mi trochę nie odpowiada. Na pewno muszę na nowo określić cele strony, przejrzeć artykuły i usunąć te które są już nieaktualne lub nie licują z moją wizją oraz stworzyć nowy design, który tym razem prawdopodobnie zlecę, ponieważ darmowe szablony mają wiele ograniczeń. (Tutaj jeszcze taka mała rada: jeżeli się nie znasz na czymś a nie zależy ci się tego nauczyć to zleć tego wykonanie, bo suma summarum stracisz więcej pieniędzy robiąc to samemu a efekt też nie będzie zadowalający)

Na pewno chciałbym żeby poradnik się rozwijał, dlatego też szukam ludzi do współpracy. Przez jakiś czas próbowałem namówić jedną firmę produkującą roboty do nauki programowania do wypożyczenia do testów i opisania na łamach poradnika, ale niestety bezskutecznie. Więc jeżeli macie jakieś pomysły na artykuły czy produkty do promowania to zapraszam, nie mogę wiele zaoferować poza sporą liczbą czytelników, którzy (wiem to z wcześniejszych współpracy) są chętni kupić produkt jeżeli jest warty kupienia. Jeżeli będzie to produkt warty zakupu to z pewnością będę chętny o nim napisać.

Także, do następnego 🙂

Najlepszy komputer dla programisty za niewiele ponad 1200 zł

Pewnie w tym wpisie nie odkryję Ameryki, ale podążając za modnymi ostatnio zestawami z Youtuba do kilkudziesięciu złotych dla graczy polecę Wam realny zestaw, który z pewnością uciągnie wszystkie bardziej skomplikowane projekty programistyczne, a nie spędzicie roku na kompletowaniu części. Pokażę jak kupić gotowy zestaw, co w nim wymienić i zmieścić się w budżecie.

Jakieś dwa miesiące temu stwierdziłem, że laptop, którego dotychczas używałem do programowania już powoli zaczyna nie ogarniać rosnących w zastraszającym tempie projektów. Kompilowanie i pierwsze uruchomienie projektów trwało wieki. Trwało to na tyle długo, że zacząłem w wolnym czasie przeglądać strony ze śmiesznymi obrazkami, co mi również marnowało masę czasu. Więc w końcu stwierdziłem, że muszę kupić komputer (ale tym razem stacjonarny), który ogarnie to co dotychczas robię i wiele więcej. Laptop będzie po prostu cienkim klientem, dzięki któremu będę łączył się do pulpitu zdalnego komputera znajdującego się w domu.

Podstawą zestawu jest procesor. Jak najsilniejszy. Nie zależało mi na największej ilości rdzeni w procesorze ani ogromnej ilości wątków, ale dużej mocy obliczeniowej. Okazało się, że mogę mieć to i to 🙂 Wiedziałem również że wchodzi w grę jedynie Intel, ponieważ od wielu lat korzystam jedynie z procesorów Intela i wiem że im mogę zaufać (oczywiście nie twierdzę, że AMD nie można zaufać, po prostu w ogóle nie znam ich procesorów).

Drugą sprawą również bardzo ważną jest dysk twardy. Tutaj w ogóle odrzucam na wstępie wszystkie dyski talerzowe, ponieważ wiem, że SSD sprawuje się dziesiątki razy lepiej niż dotychczas używane przeze mnie RAIDy z dysków talerzowych. Po prostu nawet nie brałem pod uwagę użycia dysku talerzowego pod system operacyjny i środowisko programistyczne. Ponieważ postanowiłem, że koszt komputera nie może wynieść więcej niż 1300 zł, nie mogłem szaleć. Dysk 240GB nie wchodził w grę, ale 120GB owszem.

Trzecią bardzo ważną sprawą jest pamięć RAM. Całkowitym minimum w dzisiejszych czasach jest mieć 8GB i ja właśnie tyle kupiłem. Choć uważam, że to mało. Postanowiłem, że w późniejszym czasie dokupię jeszcze raz tyle. Jeżeli zamierza się rozbudowywać zestaw, to warto przewidzieć w ile pamięci maksymalnie chce się go wyposażyć. Ja chcę mieć 16GB, więc mając zakupione 2x4GB, mam jeszcze 2 sloty na pamięć wolne na dalszą rozbudowę.

Niektórzy z Was z pewnością będą potrzebowali karty graficznej innej niż zapewnionej przez procesor do programowania swoich gier czy programów multimedialnych. Dla mnie wystarczające w zupełności jest to co dostarczył mi procesor i7, ale za chwilę opiszę szczegóły konfiguracji.

Moim dodatkowym wymaganiem są wymiary. Ja akurat mam niewielkie, dobrze wentylowane miejsce, w którym chciałem ukryć komputer, ponieważ z założenia mam korzystać z niego wyłącznie zdalnie i nie chciałem słyszeć szumu wiatraczków.

Patrząc na te wymagania, to w zasadzie większość osób zastanawia się czy ten zestaw zmieści się w cenie 3000 zł. Zmieści się w 1300 zł, a to dlatego, bo komputer, który kupiłem nie jest nowy. Jest to sprzęt po leasingowy, który po ok 2 latach zostaje wyłączony z eksploatacji w firmie i zostaje sprzedany dalej za część wartości nominalnej. Oczywiście wielu ludzi to odstraszy, ale warto spróbować, bo cena jest na tyle zachęcająca, że nawet jeżeli mielibyśmy kolejny komputer kupić za rok, to nadal będziemy do przodu. Zresztą w większości te sprzęty są eksploatowane w biurach i raczej nikt na nich nie kopie kryptowalut (przynajmniej mam taką nadzieję), więc powinny posłużyć jeszcze parę lat.

Zestaw, który udało mi się kupić:

  • i7-2600 3,40Ghz (8 wątków)
  • 8GB DDR 3
  • 250GB Dysk talerzowy (nawet ciężko mi powiedzieć jaki, bo akurat dysk się zepsuł, ale nie był mi do niczego potrzebny)
  • Windows 7 PRO (miał być starter, ale w wyniku błędu była wersja PRO. Zamieniłem na Windows 10, ale uważam że 7 też w zupełności by wystarczał)
  • karta graficzna NVIDIA QUADRO 300 (została wyjęta z zestawu, ponieważ była zbędna)

Koszt zestawu: 979 zł z przesyłką (dobry kurier w 48 godzin od zamówienia był u mnie)

http://allegro.pl/okazja-hp-8200-i7-3-8ghz-8gb-250gb-win7-nvidia-fv-i6752070698.html

Dodatkowo dokupiłem:

120GB GOODRAM C40 – 239 zł (https://www.x-kom.pl/p/189568-dysk-ssd-goodram-120gb-25-sata-ssd-c40.html)

Wrażenia

Wydajność wzrosła tak bardzo, że w tej chwili projekt ładuje się zamiast 1 min, jakieś max. 10 sekund. Wynik świetny, ale muszę być szczery, że mogło być lepiej na systemie dołączonym do komputera. Windows 10 choć szybki nie jest w stanie dorównać 7, która nie ma niepotrzebnych gadżetów i usług. Zainstalowałem Windows 10 głównie z uwagi na dysk SSD, ponieważ nie wiem jak jest w Windows 7 z obsługą wszystkich protokołów, które są obecnie używane w dyskach. Pewnie Windows 7 dostał wszystkie niezbłedne aktualizację, ale jednak wybór padł na Windows 10 (może po prostu jest ładniejszy 😉 )

Komputer chodzi bez przerwy od 2 miesięcy i jakieś 20% czasu jest dość mocno obciążony przez różne workery, które działają w ramach projektu który tworzę i przez ten czas był prawie niezawodny. Niestety prawie, ponieważ padł dysk, który został dostarczony w zestawie. To nie był wielki problem, ponieważ się tego spodziewałem. Dyski nie są zbyt trwałym elementem komputera. Po usunięciu dysku z zestawu, komputer już nie robił żadnych problemów.

Za nieco ponad 1200 zł (relatywnie niską kwotę), zwiększyłem wydajność pracy 10-cio krotnie, co jest bardzo dobrym wynikiem i polecam osobom zastanawiającym się nad zestawem komputerowym do pracy. Ten jest na prawdę warty swojej ceny. Oczywiście komputer można również rozszerzyć o dobrą kartę graficzną i używać do gier, ale do zakupu używanej karty graficznej nie będę namawiał. Zbyt duże ryzyko kupienia bubla, który kopał kryptowaluty. Dodatkowo polecam inne zestawy z tego sklepu, bo mają bardzo dobrą relację jakość-cena.

Matematyka w życiu, czyli jaka średnica pizzy jest najkorzystniejsza?

Matematyka przydaje się dosłownie wszędzie, a ludzie, którzy z niej nie korzystają dużo tracą. Najprostszym przykładem jest zakup pizzy w przypadku gdy mamy kilka dobrych pizzerii i nie wiemy z której zamówić. W każdej z pizzerii jest inna wielkość pizzy i inna cena.

W takim wypadku nie wiemy, która oferta jest najkorzystniejsza, ponieważ pole powierzchni nie rośnie liniowo wraz ze wzrostem średnicy, więc musimy liczyć bo inaczej może się okazać że przepłacimy (takie studenckie podejście :D). Parę lat temu wpadłem na napisanie programu wyliczającego współczynnik ceny za cm2 pizzy, a teraz ten program odnalazłem, poprawiłem i trochę ulepszyłem 🙂

W niektórych miejscach dodałem LINQ, ponieważ działa szybciej i wygląda lepiej niż samodzielnie napisany kod, no i dodałem TryParse których kilka lat temu nie znałem. Kod jest napisany możliwie uniwersalnie, dlatego można dodać jeszcze inne parametry do obliczeń. A choć wiem, że można wydzielić jego fragmenty do funkcji, nie zrobiłem tego z uwagi na to, że ten kod jest napisany w celach rozrywkowych, a jeżeli ktoś ma ochotę to zachęcam do przeróbek.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PolePizzy
{
    class Program
    {
        static void Main(string[] args)
        {
            var iloscPizz = 0;
            var typOdcinka = new TypOdcinka();
            var dlugoscOdcinka = new List<double>();
            var cenyPizz = new List<double>();

            // Wczytywanie ilości pizz
            var success = false;
            while (!success)
            {
                Console.WriteLine("Wpisz ile placków zamierzasz porównywać: ");
                // sprawdzanie czy da się parsować poprawnie dane z konsoli, jeżeli tak to przypisuje do zmiennej iloscPizz
                success = int.TryParse(Console.ReadLine(), out iloscPizz);
                // Sprawdzanie czy iloscPizz jest większe od 0
                success = iloscPizz > 0;
                Console.Clear();
            }

            // Wczytywanie typu odcinka
            // Zamiana enumu na tablicę elementów
            var tablicaTypow = Enum.GetNames(typeof(TypOdcinka));
            // Dodanie elementów do stringa i przedzielenie ich przecinkiem
            var typyJakoString = String.Join(", ", tablicaTypow);
            success = false;
            while (!success)
            {
                Console.WriteLine("Podaj typ odcinka (" + typyJakoString + "): ");
                // Sprawdzanie czy da się parsować poprawnie dane z konsoli, jeżeli tak to przypisuje do zmiennej typOdcinka
                success = Enum.TryParse(Console.ReadLine(), true, out typOdcinka);
                Console.Clear();
            }

            // Wczytywanie wielkości pizz i cen
            for (int i = 0; i < iloscPizz; i++)             {                 success = false;                 while (!success)                 {                     double tmp = 0;                     Console.WriteLine(typOdcinka.ToString() + " " + (i + 1) + " pizzy (w cm): ");                     // Sprawdzenie czy da się parsować poprawnie dane z konsoli, jeżeli tak to przypisuje do zmiennej tmp                     success = double.TryParse(Console.ReadLine(), out tmp);                     // Sprawdzanie czy zmienna tmp jest większa od 0                     success = tmp > 0;
                    // Jeżeli wartość jest poprawna to dodawana jest na listę długości odcinków
                    if (success)
                    {
                        dlugoscOdcinka.Add(tmp);

                        success = false;
                        while (!success)
                        {
                            tmp = 0;
                            Console.WriteLine("Podaj cenę " + (i + 1) + " pizzy (w zł): ");
                            // Sprawdzenie czy da się parsować poprawnie dane z konsoli, jeżeli tak to przypisuje do zmiennej tmp
                            success = double.TryParse(Console.ReadLine(), out tmp);
                            // Sprawdzanie czy zmienna tmp jest większa od 0
                            success = tmp > 0;
                            // Jeżeli wartość jest poprawna to dodawana jest na listę długości odcinków
                            if (success)
                            {
                                cenyPizz.Add(tmp);
                            }
                        }

                    }
                    Console.Clear();
                }
            }

            // Obliczanie pól powierzchni
            double wynik = 0;
            var listaPolPowierzchni = new List<double>();
            for (int i = 0; i < iloscPizz; i++)
            {
                double promien = 0;
                if (typOdcinka == TypOdcinka.Promień)
                {
                    promien = dlugoscOdcinka.ElementAt(i);
                } 
                else if (typOdcinka == TypOdcinka.Średnica)
                {
                    promien = dlugoscOdcinka.ElementAt(i) / 2;
                }

                // Liczenie pola powierzchni
                double polePowierzchni = Math.PI*Math.Pow(promien, 2);
                // Pole powierzchni zostaje dodane do listy pól powierzchnii
                listaPolPowierzchni.Add(polePowierzchni);
            }

            // Obliczam cenę za cm² pizzy
            List<double> wspolczynniki = new List<double>();
            for (int i = 0; i < iloscPizz; i++)
            {
                wspolczynniki.Add(cenyPizz.ElementAt(i) / listaPolPowierzchni.ElementAt(i));
            }

            for (int i = 0; i < iloscPizz; i++)             {                 Console.WriteLine("Pizza " + (i + 1) + " posiada pole powierzchni: " + listaPolPowierzchni.ElementAt(i) + " cm²");                 Console.WriteLine("Kosztuje: " + cenyPizz.ElementAt(i) + " zł");                 Console.WriteLine("czyli " + wspolczynniki.ElementAt(i) + " zł za cm²");                 Console.WriteLine();             }             // Sprawdzanie która pizza jest korzystniejsza             // Najpierw sprawdzam, czy czasem ktoś nie dodał kilku takich samych pizz z taką samą ceną             if (listaPolPowierzchni.Any(o => o != listaPolPowierzchni[0]) && cenyPizz.Any(o => o != cenyPizz[0]))
            {
                // Ustalam jaki jest index minimalnej ceny za cm²
                var indexAtMax = wspolczynniki.ToList().IndexOf(wspolczynniki.Min());
                // ponieważ index jest zawsze od 0 to muszę dodać 1 do tej wartości żeby uzyskać numer najkorzystniejszej pizzy
                Console.WriteLine((indexAtMax + 1) + " pizza jest najkorzystniejsza!");
            }
            else
            {
                Console.WriteLine("Obie pizze mają identyczne pole powierzchni");
            }

            // Dodane żeby program nie zakończył się automatycznie, tylko oczekiwał naciśnięcia jakiegokolwiek przycisku
            Console.ReadKey();
        }

        // Enum typów odcinka
        public enum TypOdcinka
        {
            Średnica,
            Promień
        }
    }
}

Screen z działania programu: