niedziela, marca 12, 2023

Mam milion rzeczy na głowie... co robić?

Zacząć od pierwszej ;-)

Mam ostatnio dużo na głowie, głównie w pracy, ale później dochodzą maile z ofertami pracy, albo konieczne zakupy, albo formalności i jest tego "za dużo", a wtedy jak się ma takie przejmujące wrażenie przytłoczenia sprawami i nie wiadomo gdzie ręce włożyć.

Są ludzie którzy taki stan mają dopiero jak się na nich zwali tona rzeczy, są tacy którzy przy 3 się gubią.

Ja znam kilka sposób na to, chociaż fakt trzeba dojść do stanu w którym człowiek o nich pamięta i próbuje ich używać.

Kroki do zapanowania są proste i cała sztuka polega na ich prostocie.

Krok pierwszy to sobie to co mamy na głowie zapisać. Tworzymy tak sobie backlog rzeczy do zrobienia.
To pomaga bo podobno sam akt zapisania daje mózgowi sygnał "to nie zostanie zapomniane" i mózg dzięki temu przestaje ciążyć nad człowiekiem to przekonanie o milionie rzeczy na głowie.
Dodatkowo czasem dociera do nas, że wcale tego tyle nie ma, to nie jest milion spraw, ale np. 6.
Czyli to już nie jest taka bezkształtna chmura z milionem rzeczy, a konkretna lista z konkretną liczbą spraw.
Łatwiej zapanować nad czymś nazwanym, czy zidentyfikowanym.
Tu taka rada, że dobrze pisać na początku sprawami, nie zawsze da się zrobić konkretne ToDo, ale zwykle da się hasłami. Może po prostu w kroku 3 pierwszym zadaniem będzie próba przekucia tego zapisanego hasła na jakieś ToDo.

Krok drugi to jakaś forma traige'u. Zwykle widzimy co jest ważniejsze. 
W razie czego można użyć hacka, który polega na nadaniu rzeczom ocen wg ważności i prostoty (od 1 do 7) i można je pomnożyć i użyć tego jako sposobu na prioryteryzację, najprostsze i najważniejsze na początku...
Ten drugi krok bywa zbędny i nie zawsze człowiek ma nań siłę.

Krok trzeci jest najważniejszy ;-)
Trzeba wziąć pierwszą rzeczy (czy to wg priorytetu, wg kolejności zapisania czy nawet losowo) i trzeba jej poświęcić jakiś czas. Najpierw można sobie powiedzieć "OK, 15 minut", a nawet "OK, 5 minut".
Te ramy czasowe powodują, że się nie przestraszymy. Nie będzie tego czegoś co nas stopuje, tego przekonania "rany boskie mam tyle do zrobienia", bo w danym momencie mamy dokładnie 1 rzecz do robienia i to jeszcze w ramach czasowych.
Jeśli po tych 5 czy 15 minutach mamy ochotę dalej coś robić, ale akurat w tej sprawie nic się nie udało, to trzeba to zwrócić na listę i wziąć następne. 
Kluczem jest by w końcu mieć coś co da się zrobić ;-)

No i jak zrobimy 1 rzecz, to z listy tam znika jedna rzecz :-)

To oczywiście brzmi prosto, a człowiek zwykle jest w takim stanie gdy "ma taki zapieprz, że nawet czasu nie ma by taczkę załadować" ;-)

Jest jeszcze jedna opcja, zamiast zrobić to co powyżej, można o tym napisać mając nadzieję, że jakoś magicznie to się zacznie samo robić ;-)



Podobne postybeta
Cybernetyka w działaniu ;-)
Czy vibecoding zmienia ważność ludzi? Czy PM/PO stają się bardziej niezbędni od inżynierów?
Be human for engineers: Instrukcja obsługi człowieka - marzy mi się coś takiego ;-)
Hackowanie teorii umysłu ;-)
Projekty Informatyczne - Mity ;-)

sobota, marca 11, 2023

Chciałem popsuć G1 i mi się na razie nie udało ;-)

GC w Java'ie w większości przypadków opiera się na hipotezie, która najlepiej wyraża się słowami: obiekty umierają młodo.

Niby to nie jest ważne, ale jak się dowiadujemy o GC to jest mowa o tym, że obiekty żyją sobie tam gdzieś na pastwisku sterty i wiodą sobie swój żywot tak długo jak nie przyjdzie GC i po stwierdzeniu, że obiekt nie jest już nikomu potrzebny to go morduje i zwalnia pamięć.
To ma oczywiście konsekwencje w tym, że jak już zamorduje to mamy trochę wolnej pamięci, ale przed i za może być obiekt który nadal żyje... co prowadzi do fragmentacji sterty i trzeba tu sprzątać, bo może się okazać, że mamy wystarczająco wolnego miejsca, ale w kawałkach i nie da się nigdzie wcisnąć naszego obiektu... Czyli trzeba jakoś zdefragmentować stertę, ale to jest trudne bo to taki puzzel.

Stąd używając tej hipotezy, że przytłaczająca większość obiektów umiera młodo można podzielić pamięć tak by mieć miejsce gdzie obiekty będą szybko tworzone i szybko będą mogły umierać, a ich zwłoki nie będą nikomu przeszkadzać i ich usunięcie nie będzie zbytnio zużywało CPU, te które przeżyją można już wypuścić na pastwisko i niech się tam pasą i w razie umrą to będzie to na tyle rzadkie, że ich ewakuacja nie będzie taka straszna i będzie rzadka.

Stąd większość kolektorów w Java'ie to Generational Garbage Collectors (chyba najlepszym polskim tłumaczeniem by było pokoleniowe GC ;-)).
I pamięć dzielą mniej więcej tak:
  • eden - obiekty są tu tworzone (prawie wszystkie, poza tymi które wydają się być za dużo, co znaczy chyba 1/4 rozmiaru edenu
  • survivor 1 i survivor 2
  • old gen
Oczywiście przyszedł G1 dawno temu i trochę sprawę popsuł. Np. złośliwa bestia nie dziedziczy po GenCollectedHeap ;-) a wprost po CollectedHeap co by mogło sugerować, że nie jest generacyjny (pokoleniowy), a jest, najwyraźniej po prostu metody z GenCollectedHeap nie pasowały bo w G1 nie ma ciągłych obszarów pamięci dla każdej z generacji...

Ale nadal wszystko opiera się o generacje, tylko, że w G1 są one takie jakby poszarpane... 

Ale nadal jest tak, że obiekt (jeśli jest mały) tworzony jest w edenie, tworzony jest zaraz po poprzednim (OK, może być z wyrównaniem bo CPU mają taki zwyczaj, że zwykle szybciej się potrafią dostać do pamięci która jest pod adresem będącym wielokrotnością jakiejś tam liczby będącej potęgą 2) i przez to jak w edenie się kończy miejsce to można zrobić bardzo prostą i tanią operację i przejść przez wszystkie obiekty, sprawdzić które są jeszcze używane i które już nie i coś z nimi zrobić.
To coś to skopiowanie tych, które nadal żyją do aktualnego survivor (są 2) i nie kopiowanie tych, których już nikt nie używa. Po czym możemy znów zacząć wrzucać do edenu nowe obiekty. Tak obiekty w Edenie chodzą i leżą na zwłokach swoich poprzedników ;-)
Z survivor jest tak, że jak się kończy w nim miejsce to robimy ten sam numer co z edenem tylko przepisujemy te nadal żywe obiekty do drugiego surviovora i je zamieniamy (czyli jak byliśmy w 1, skończył się to przepisujemy do 2, i piszemy nowe do 2, jak się skończy to kopiujemy to 1...).
Oczywiście jest problem bo nagle będzie za dużo rzeczy w survivor... więc stąd też odbywa się promocja do old ;-)
Ona się odbywa głównie "za zasługi", czyli obiekt przeżył ileś tam przepisań z s1 do s2 i z powrotem i wszystko wskazuje, że to jeden z obiektów matuzalemów więc trzeba go wysłać do old.
Jest jeszcze taki deal, że jak survivor jest przepisywany to najpierw sprawdzane jest czy w old jest jeszcze miejsce i jeśli nie to odbywa się ta paskudna operacja defragmentacji sterty i jakby się nie udało odzyskać pamięci tyle by skopiować całego survivor to poleci OutOufMemoryError (to jest Error, nie Exception).
To w końcu prowadzi do najbardziej pożądanego kształtu wykresu pokazującego zużycie pamięci czyli do piły... jak jest trend wzrostowy to jest sugestia wycieku pamięci (na razie tylko sugestia).

W G1 jest to bardziej powariowane, ale z grubsza to tak działa...

Więc ja dziś, czy bardziej wczoraj chciałem pobawić się w G1 wielkością tych obszarów bo zazdroszczę moim developerem którzy pracują nad naszym softem, że właśnie się bawią GC (OK, oni tak na to nie patrzą, tu chyba trzeba wysublimowanego smaku, który potrafi docenić smak GC (podejrzewam, że to podobne jest do takiego kiszonego śledzia czy czegoś podobnego)) i z opisów moja hipoteza jest, że ponieważ do pamięci trafia multum rzeczy, która jest w protobuf to po sparsowaniu tablice char[] które tam są się pałętają po pamięci i przez to GC ma czasem problemy.
Próbowałem zasymulować coś takiego.. nawet by CPU bardziej użyć dodałem sortowanie bąbelkowe (czyli żeby CPU więcej był obciążony) i chciałem drania (G1) popsuć, ale na razie bez sukcesów ;-)
Robiłem to w Java 8 (bo Scala...) i pierwsza lekcja z dziś, Java 8 nadal używała -server żeby odpalić serwerową Java'ę ;-)

W ogóle dziś mi coś dziwnie szło, np. apka obserwowana z JVisualVM nie używała więcej niż 30% CPU.... co przekładało się na jakieś 300% w ActivityMonitor co by znaczyło jakieś 3 rdzenie z 12 (OK, tak naprawdę jest 6 rdzeni, ale jest HyperThread)... a jak odpaliłem z -server to leciało na 12 rdzeniach... ale później zacząłem sprawdzać i jednak jest tak, że -server jest mniej nice niż było -client i od razu próbuje zagarnąć całe CPU, a client tak bardziej subtelnie to robi ;-) [nice jest w *nix i im aplikacja bardziej nice to tym chętniej oddaje CPU, im mniej nice tym mniej chętnie to robi ;-)]
Ustawiałem też np. -Xmx czyli max sterty i mi to ignorował jak przekazywałem do java'y w cmd line, ale jak wrzuciłem do _JAVA_OPTIONS to działało...

Wnioski na dziś takie:
  • zrobienie syntetycznego psuja do GC jest trudne,
  • wiedza nie używana wyparowuje... 8 miesięcy pisania głównie w Pythonie i robienia za Engineering Managera (przy okazji Product Ownera i coś pokroju Data Analyst) i robienie jakichś zadanek na LeetCode prowadzi do atrofii Java'y ;-) stąd trzeba zacząć sobie pisać jakiś projekt, w którym będę mógł trenować (btw. nawet teraz nie pamiętam jak zrobić by testy z lokalnym DynamoDb działały na każdym OSie... a kiedyś to zrobiłem w parę godzin ;-))
  • trzeba znów zacząć czytać kod JVM
  • _JAVA_OPTIONS zawsze działa ;-)



Podobne postybeta
Samochód jako zmniejszacz temperatury.... GC i jak to możliwe, że Young Generation może być zbyt duże, strzeż się finalize() i muzyczka :-) Czyli potok świadomości....
Nieznane skarby JDK - JConsole :-)
finalize() - do czego służy, a do czego nie i z czym to się je.
Referencje w Java'ie
Odrobina miłości i serwery działają ;-)

piątek, marca 10, 2023

Hmm... znów się bawię ChatGPT i rysujemy obrazek ;-) a później piszemy kod z obrazka ;-)

 Mam pustkę w głowie co dziś napisać ;-)

Więc próbowałem użyć ChatGPT, najpierw próbowałem z nim rysować domek. Da się rysować :-) wystarczy poprosić by użył SVG i generuje kod :-)

Coś takiego w końcu "narysował" ;-)

Później prosiłem by mi pomógł wymyślić temat do bloga, ale żaden z pomysłów mi się nie podobał...

Btw rysunków, kiedyś mi się nawet udało ChatGPT przekonać do zamiany jakiegoś programu w Pythonie w coś na kształt flow chartu, ale nie powiem żeby to było najlepsze.

Btw. ciekawe czy jakby zrobić maszynę stanów to by napisał program ;-)

(jakieś 15 minut temu....) coś zrobił ;-)

Dostał taki prompt:


I wygenerował taki kod:

def read_input():
return input()

def add_autocomplete():
# kod do dodawania autocomplete

def send_query():
# kod do wysyłania zapytania o autocomplete

def display_autocomplete():
# kod do wyświetlania autocomplete

state = "start"

while True:
if state == "start":
print("Enter input:")
state = "czytaj znak"
elif state == "czytaj znak":
znak = read_input()
if len(znak) > 0:
state = "czy więcej niż 3" if len(znak) > 3 else "czytaj znak"
else:
continue
elif state == "czy więcej niż 3":
if len(znak) < 3:
state = "czytaj znak"
else:
add_autocomplete()
state = "czytaj znaki i dodawaj autocomplete"
elif state == "czytaj znaki i dodawaj autocomplete":
znak = read_input()
if len(znak) > 0:
send_query()
state = "wyślij zapytanie o autocomplete"
else:
continue
elif state == "wyślij zapytanie o autocomplete":
znak = read_input()
display_autocomplete()
state = "czytaj znaki i wyświetlaj autocomplete"
elif state == "czytaj znaki i wyświetlaj autocomplete":
znak = read_input()
if len(znak) > 0:
if znak == "\x1b[A": # strzałka w górę
# kod do podkreślenia poprzedniego elementu w autocomplete
continue
elif znak == "\x1b[B": # strzałka w dół
# kod do podkreślenia kolejnego elementu w autocomplete
continue
elif znak == "\r": # Enter
# kod do wypełnienia pola tekstowego tekstem z autocomplete
state = "czytaj znaki i dodawaj autocomplete"
elif znak == "\x1b": # Esc
state = "czytaj znak"
else:
continue
else:
continue

Co jest lekko przerażające....
Nie będzie to działać bo trochę pomieszał znaki chyba z całym stringiem, ale jest dużo lepiej niż się spodziewałem.

ChatGPT jest jak sawant ;-) 
I nie wiadomo czego się po nim spodziewać ;-)

Ja go używam nawet do pytania o ficzery platformy z którą teoretycznie pracuję ;-)




Podobne postybeta
Maszyna stanów kontra labirynt ;-)
Kiedy skończyć pracę...
Czasem człowiek musi napisać dekodowanie Base64 w JavaScript ;-)
Dodawaj automagicznie tagi do swoich postów w Pocket :-)
Historia jednego #....

czwartek, marca 09, 2023

Exceptiony i programowanie są jednak trudne ;-)

Widziałem dziś takiego kwiatka:

public void save(Object entity) {
try {
dynamoDBTable.putItem(entity);
logger.debug("Saved {}", entity);
} catch (DynamoDbException e) {
logger.error("Cannot store {}", entity, e);
}
}

Który tak naprawdę jest odpowiednikiem:

public void save(Object entity) {
try {
dynamoDBTable.putItem(entity);
logger.debug("Saved {}", entity);
} catch (DynamoDbException e) {
// ignore
}
}

Do tego był też test ;-) który najpierw używając Mockito powodował, że putItem wyrzuci wyjątek, wołał to save, a później sprawdzał czy czasem coś w bazie się zapisało i test nazywał się saveThrowsException ;-)

Tak mam wrażenie, że parę lat temu poszła plota, że wyjątki są złe i ludzie zaczęli je po prostu ignorować.

Albo robią rethrow i w przypadku apek używających Spring MVC piszą handlery które raczą usera info o tym, że był błąd, albo dławią ;-)

Inny przypadek, który widziałem, pobieranie masy danych z paginacją z jakiegoś serwera w Internecie, i retry bez limitu wywołań wszystkich odwołań nawet jak ostatni call padnie.

Oczywiście pewnego dnia to się wydarzyło, że po pobraniu 200 stron na ostatniej padło, więc spróbowało jeszcze raz i jeszcze raz i jeszcze raz... w końcu coś zablokował IP.

Błąd został znaleziony (też przez przypadek ;-) - jakiś dziwny zwyczaj budowania alertów do wszystkiego, ale takich dziwnych, że się patrzy w logi czy jest jakiś message... i jak go nie ma to alert ;p) poszła poprawka i wszystko działa.

Dwa miesiące później nie można się połączyć do serwera, developer zagląda i stwierdza, że właściciel serwera blokuje.
W koło panika, co zrobić, potrzeba tego, a oni blokują...

Od razu hipotezy, może chcą więcej kasy, może mają deal z kimś by blokować...

Okazuje się, że z innego komputera pobieranie działa, user/hasło działają... nadal panika.

Developer nie sprawdził tego nawet, od razu powiedział, że blokują.

Chwila sprawdzania pokazuje, że blokada jest na IP, nie robi jej właściciel serwera, a ktoś kto broni ich przed DDoS... 2 miesiące temu błąd w kodzie zrobił DDoS... ale jak poszedł deploy z poprawką to adres się podmienił, a po 2 miesiącach kolejny deploy wrócił do oryginalnego błędu ;-)

Mail do właściciela serwera i po godzinie wszystko działa... 

Inny przykład. Był sobie system do urlopów, ale postanowiono go zmienić.

Ktoś napisał toola do przenoszenia danych, leciały mu/jej wyjątki więc dodano łapanie wyjątków.

Sprawdzam kiedyś swoje urlopy i mam urlop 12 marca... a wiem, że nie miałem, za to planowałem na 3 grudnia ;-) 

To wszystko robią ludzie, którzy kosztują po 20-30 tysięcy za miesiąc ;-) albo i więcej.

Nie mówimy o głupich błędach, które przeszły bo nikt ich nie zauważył, nie mówimy o czymś skomplikowanym. Mówimy o rzeczach, które widać na pierwszy rzut oka.

Jak widzisz coś co rzuca wyjątek i ten jest dławiony to zawsze jest pytanie czy to jest OK, wyjątek służy do obsługi sytuacji wyjątkowej, ale takiej które może się zdarzyć. Takiej którą można zwykle odkręcić.

Ale łatwiej zignorować ;-)

Taki venting po prostu ;-)



Podobne postybeta
Weekendy robią znów za krótkie.....
Thread.stop() i "nieśmiertelne" wątki ;-)
Alert RCB - minimalizacja false negative prowadzi do zwiększenia false positive ;-)
Nauka ;-)
Google App Engine i DatastoreTimeoutException

środa, marca 08, 2023

1096 dni...

Dotarło do mnie, że 3 lata i 2 dni temu, 6 marca 2020 pracowałem pierwszy dzień z domu... a dokładniej z hotelu.
To było jak twierdzi ChatGPT 1096 dni temu.

Wtedy zaczął się ten koszmar.

Bylem wtedy w USA w Foster City, robiłem zdjęcia kwiatków i wysyłałem koleżance ;-) w ramach dzielenia się pogodą.

Wszędzie było pełno informacji o COVID, ale USA jeszcze wyglądały na bezpieczne (bo mieli złe testy nadal), chociaż już pojawił się statek z chorymi na pokładzie.
W Niemczech już było widać mniej ludzi na lotnisku, w samolocie też. Obok mnie siedziała pani w masce, z którą zresztą przegadałem pół lotu ;-) (z Hawaii była)

W hotelu wszędzie były taśmy i podobne rzeczy na guzikach.

Wiem, że w czwartek albo piątek oglądałem na YouTube film Zaraza o epidemii ospy we Wrocławiu.

I w czwartek przyszedł e-mail, że w związku z tą niepewną sytuacją z COVID-19 firma chce przetestować jak to jest pracować z domu, żeby w razie czego mieć plan awaryjny, więc w piątek 6 marca mamy nie przychodzić do pracy i sprawdzimy.
Tam akurat zwykle nikogo nie było w biurze w piątki.

To nie był pierwszy sygnał, pierwszy był we wtorek gdy wylądowaliśmy i kolega dostał maila, że klient odwołał demo u niego w Phoenix...

W piątek pracowałem ze swojego pokoju i trochę z centrum biznesowego, bo we wtorek mieliśmy mieć pierwsze demo naszego produktu dla klientów, więc chciałem być przygotowany.
Centrum biznesowego używałem też po to by dać obsłudze czas na posprzątanie mojego pokoju ;-)
Poszedłem też sobie do sklepu bo nadal nie sprzątnęli mojego pokoju.

Jakoś w sobotę czy niedzielę przyszedł mail, że mamy w ogóle do biura nie wracać...

Poszliśmy z kolegą we wtorek, gdy robiliśmy demo uznając, że jednak lepiej być wtedy gdzieś gdzie jest pewny internet.

Ja jeszcze przyszedłem w piątek gdy wracałem, bo czekałem na buty ;-) i tak naprawdę nie wiedziałem czy będę miał czym wrócić do Polski bo akurat Trump wprowadzał zakaz lotów z Europy, więc się bałem, że United uzna, że po co wysyłać samolot do Europy...

Pierwszy raz w samolocie było tylu Polaków.

Wcześniej jeszcze istniała dodatkowa obawa czy z Frankfurtu się do Krakowa dostanę bo Polska też zamknęła granice... aż koleżanka (inna) proponowała mi, że w razie czego przyjadę po mnie z mężem.
Ale samolot jednak leciał ;-)

W Niemczech się zgadaliśmy z jakimś człowiekiem z Samsunga, że pewnie nas w Polsce czeka kwarantanna... a ja dostałem maila z Tesco, że mi odwołali zamówienie.

Gdy lądowaliśmy w Polsce zmierzyli nam temperaturę i byliśmy wolni... bo wylądowaliśmy 14 marca po 18:30, a zakaz wchodził o północy.

Od wtedy było zgadywanie jak długo będziemy pracować z domu. Z koleżanką (tą od zdjęć kwiatków i pogody) liczyliśmy, że może maj... 

Wprowadzili zakaz wychodzenia z domu.... 

To był dziwny czas. Ale taki, że nie wiadomo było co będzie, ale było tak inaczej, ale nie strasznie.
Dopiero później przyszło zwątpienie, jak przyszedł maj i nie wróciliśmy do biura... liczyłem na wrzesień... na początek 2021... na wrzesień 2021... 

Nakaz pracy z domu z całkiem rozsądnego sposobu dmuchania na zimne zmienił się w coś co zostało bo tak było wygodniej. Nie lepiej, nie milej, ale po prostu wygodniej.
Chociaż może spowolniło COVIDa..

Ja chyba zachorowałem (nie robiłem testów, po objawach wnoszę) w okolicach Wigilii 2021, a złapałem go chyba na firmowej imprezie tydzień wcześniej... 
Rok wcześniej Wigilię spędziłem sam w domu budując Saturna V z Lego.

Czasem mam marzenie by mieć wehikuł czasu ;-) wrócić do 2019 roku, dać WHO info o COVID-19, wraz z szczepionkami. Może by tego koszmaru siedzenia w domu nie było.
Może przez to nie byłoby wojny w Ukrainie, bo Putinowi by nie odwaliło od izolacji?




Podobne postybeta
Ukradli nam przyszłość....
Browser2Browser, czyli prześlij stronę z przeglądarki do przeglądarki ;-)
finalize() - do czego służy, a do czego nie i z czym to się je.
Niepewność wielostopniowa ;-)
Foldery

16 GB to zbrodnia...

Mój pracowy laptop ma 16 GB RAM... to za mało.
Niemal dzień w dzień mam tak, że coś przez parę sekund, albo i paręnaście wisi.

Zwykle jakieś głupie WebExy i nie wiedzieć czemu strona Miro z jednym z diagramów ;-)
Najlepsze jest jak teraz robię dość dużo interview i przejdę do Miro bo chcę coś sprawdzić to mi się kamerka zawiesza ;-) i zastygam na video ;-)

Pierwy raz komputer z 16 GB kupiłem w 2012 roku, w lipcy i kosztował całe 3999 PLN ;-)
Wtedy 16 GB RAM było rozsądne.

W 2018 przeszedłem z kupnem nowego Macbooka Pro na 32 GB RAM i teraz wydaje mi się to być rozsądnym minimum.

Kupiłem co prawda w 2020 roku komputer z 16 GB RAM, ale to jest Macbook Air i po pierwsze nie było takich z 32 GB RAM ;-) po drugie jednak na nim nie robię tylu rzeczy, które robię na swoim "głównym" komputerze.

Teraz gdybym kupował Macbooka poszedłbym w 64, a może 96 GB RAM :-)
Tam zapewne Chrome można używać bez problemów ;-)

Btw. na komputerze z małą ilością RAM Chrome robi unload stron, spoko, ale najlepsze jest to jak chcesz zamknąć "nadmiarowe" tabki i wtedy często wszystko zwisa bo Chrome przed zamknięciem często ładuje stronę od nowa, tylko po to by ją zamknąć ;p

Tak mało dziś twórczo, ale wkurza mnie ten laptop. A oczywiście jak to w korpo trzeba jakieś czary odwalić żeby wymienić laptopa.
Inna sprawa, że w poprzedniej firmie dostałem pod koniec M1 z 16 GB RAM ;-)
Aż się zastanawiam po co Apple takie produkuje.

Zaprawdę ktoś kupujący dziś komputer z 16 GB RAM, szczególnie Macbooka nie wie co czyni. Chcesz Macbooka bo taki seksowny? To kup tego z najmniej 32 GB RAM, wtedy można go raz na jakiś czas otworzyć i coś nawet na nim zrobić ;-)

A wkrótce zacznę znów pisać w Java'ie i pewnie w TypeScript'cie, nie tylko w Pythonie, więc będzie jeszcze zabawniej ;-)


Podobne postybeta
Metapost o pisaniu posta, albo moje próby z Obsidianem
Bestyjka - nowy mac podróżny ;-)
Jak się czuje włączając Windowsa...
Przyroda...
Mój Macbook ma 4 lata

wtorek, marca 07, 2023

Gdyby przez kolejne 5 lat wszystko mi się udawało to za 5 lat.....

Chyba w Search Inside Yourself jest podany ciekawy sposób na to by sobie uporządkować myśli, przemyślenia i ogólnie lepiej się czuć.
Nie na wszystkich działa, ale na niektórych tak.
Chodzi o to by wybrać jeden z tematów i powiedzmy przez 5 minut pisać co przyjdzie do głowy w danym temacie, nie zaważając zbytnio na interpunkcję czy ortografię.
Tematy są mniej więcej takie:
  • czuję teraz
  • jestem świadom(a)
  • tym co mnie motywuje jest
  • dziś, pragnę/dążę do
  • boli mnie
  • chciałbym/chciałabym
  • inni są
  • wbrew temu co chciałem/chciałam, szczęśliwie stało się że
  • moje wartości to
  • popieram
  • gdyby przez kolejne 5 lat wszystko mi się udawało to za 5 lat.....
I wiem, że jak próbuję to robię (i używam swojego "toola", który mi losuje o czym pisać ;-)) to najbardziej nienawidzę tego ostatniego "gdyby przez kolejne 5 lat wszystko mi się udawało to za 5 lat....." ;-)

I wydaje mi się, że w dzisiejszych czasach, w bogatszych krajach coraz więcej ludzi ma problem z tym pytaniem ;-)
Kiedyś nie było prościej, po prostu był mniejszy wybór, a teraz jest większy wybór, więc trudniej wybierać.

Taki mentalny paradox of choice ;-)

Marzenia i możliwości były mniejsze więc chyba i cele były "prostsze".
Teraz teoretycznie masz otwartą szansę zostać astronautą, prezydentem czy baletnicą ;-) ale niby droga jest otwarta dla większej ilości ludzi i jest tych dróg więcej to wcale nie znaczy, że po pierwsze wiemy którą drogą iść, po drugie nawet jak już wiemy to teoretyczna możliwość, a praktyka nieczęsto idą w parze ;-)

Teraz mamy ciągły przekaz "możesz wszystko", "zasługujesz na więcej". Marzeniem więc już nie jest rodzina, mieszkanie i samochód, ale najlepsza rodzina, najlepsze mieszkanie, najlepszy samochód, a tak właściwie to może nie? Może lepiej wyższe stanowisko, albo stworzenie powieści czy filmu?

I to co powinno dawać nam większe szczęście powoduje, że jesteśmy nieszczęśliwsi bo nie mamy celu, i nawet najlepsze rzeczy, które nam się zdarzają są zawsze porównywane z tym, co by mogło być lepszego.

Albo nie mam racji i mam po prostu jakiś depresyjny nastrój ;-)


Podobne postybeta
Journaling
My = Bogacze.
Serce czy rozum?
Studia wyższe
Lipcowe książki :-)

poniedziałek, marca 06, 2023

Nie wierze w polyglot developer, ale... ;-)

Nie trafia do mnie idea "polyglot developer", nie wydaje mi się by developerzy byli w stanie w danym momencie znać więcej niż 2 języki na takim poziomie by w nich swobodnie pisać.
Sam się łapałem gdy używałem Java'y, JavaScripta i Pythona na tym, że po dłuższej sesji w jednym języku w drugim chciałem pisać tak samo ;-)
Ułatwiło mi wprowadzenie var do Java'y bo nagle było ciut prościej ;-) ale nadal czasem się łapię na tym, że w Pythonie wstawiam ; na końcu ;-)

Ale właśnie, nie trafia do mine "polyglot developer" od strony praktycznej, nie wydaje mi się by większość developerów była w stanie tak działać. 
Jednak trafia do mnie od strony też praktycznej, ale patrzenia na efekty ;-)

Parę lat temu zacząłem prawie wszystkie automatyzacje pisać w Pythonie, bo jak Java jest świetna do pisania backendu czy nawet frontendu (IntelliJ to nadal gównie Java ;-), do tego Swing..) to jednak nie jest najlepszym narzędziem do pisania skryptów, czy małych tooli. 
Python sprawdza się tu dużo lepiej.

Do tego Python jako uznany język skryptowy świetnie integruje się z wieloma narzędziami takimi jak np. Alfred, albo Shortcuts czy Keyboard Maestro :-)

Od kilku lat mam to, że muszę co jakiś czas formatować gdzieś JSONa, albo po prostu posortować coś, zrobić uniqu czy zmienić listę w linię, albo linię w listę ;-) (większość tych rzeczy wyszła przy okazji różnych narzędzi które pisałem w poprzedniej i obecnej pracy, bo np. łatwiej do skryptu przekazać coś jako jedną linię oddzieloną spacjami czy przecinkami, ale znów jak ktoś do Ciebie pisze w mailu "chcę scope X, Y, Z" to oni to zwykle robią jako listę ;-), ręczne przerabianie jest wkurzające... więc lepiej mieć do tego narzędzie) i mam w Alfredzie swój workflow w którym piszę tx (od text operations) i mam zaraz na ekranie listę narzędzi, które używają schowka :-)

Stąd Polyglot Programmer/Developer do mnie nie dociera gdy chodzi o budowanie dużych systemów i ogólnie jestem przeciwny mieszaniu po jednej stronie systemu kilku języków, ale w oddzielnych obszarach mogę zrozumieć urok.
Nie każde narzędzie służy do wszystkiego, więc po co je zmuszać do działania w obszarach w których sobie nie radzą?


Podobne postybeta
Hacky tool ;-) - workflow do Alfreda, który pozwala wykonywać różne konwersje na zawartości schowka ;-)
Jak zobaczę good fit, to będzie good fit - najbardziej prawdziwy opis pozycji w IT ;-)
5 lat z macOS w domu ;-)
AI kradnie może (na razie?) nie pracę, ale „wieczorną zabawę w kodowanie” już tak ;-)
Znaczące wersji Java'y ;-)

niedziela, marca 05, 2023

Instalowanie SkyShowtime na Androidzie i Chromecast with Google TV to mordęga

Jakieś 2 tygodnie temu do Polski wszedł SkyShowtime. 

Od razu udało mi się zainstalować jego apkę na iOS i iPadOS, ale na Androidzie mi pisało, że nie jest dostępna, to samo w Chromecast z Google TV.

Próbowałem wiele razy, na kilku urządzeniach i nic.

Wychodziło, że nie ma go w Polsce i koniec. Nie mamy pańskiego płaszcza i co nam pan zrobi? ;-)

Wczoraj więc zacząłem zabawy z sidelodem ;-)

Dla Androida to był błysk ciupagi, wejść na APK Mirror, pobrać, zainstalować, wcześniej tylko zaznaczyć, że z tej apki wolno instalować aplikacje spoza Play Store.

Do logowania nawet nie musiałem podać usera i hasła bo sam sobie je wyciągnął z Chrome.

W instalacji z sideloadem na Chromecast with Google TV musiałem posiłkować się ChatGPT ;-)
Trzeba było pobrać apkę z APK Mirror na telefon albo komputer, później na Chromecast with Google TV zainstalować specjalną apkę, która robi serwer HTTP i pozwala wrzucić pliki... długo się nie chciał ten APK wrzucić, w końcu trzeba go było tam otworzyć co też nie chciało działać... z pół godziny wcześniej szukałem opcji na akceptację instalacji spoza sklepu i nie znalazłem...

Ale w końcu udało mi się jakoś zmusić system do próby instalacji APK i wtedy mogłem zaznaczyć, że zgadzam się by ta apka mogła instalować aplikacje spoza sklepu.

A wszystko po to bym mógł im te 13 PLN miesięcznie płacić ;-)




Podobne postybeta
Okrutniki ;-)
Nie, to brak HDCP 2.2, a nie backdrop nie służy Chromecastowi Ultra ;-)
Nexus 7 i Chromecast... nie wiem czy kupię, ale mi się podobają :-)
Chromecast
In vitro

sobota, marca 04, 2023

Lubię bity, czyli jak dodawać, odejmować, mnożyć i dzielić na bitach ;-)

Lubię bity.

Pamiętam, że te lata temu zastanawiało mnie jak komputer liczy.
Początkowo wydawało mi się, że robi to w jakiś głupi sposób, np. że dodawanie to jest inc na jednej liczbie i dec na drugiej i że mamy pętlę aż ta druga będzie 0 (mówimy o liczbach dodatnich tutaj).

Później do mnie dotarło, że tego się tak nie robi, że się da liczyć np. pod kreskę na bitach :-)

Tylko, że zamiast na każdym bicie robić tą operację oddzielnie robi się je na wszystkich jednocześnie ;-)

No bo jak popatrzeć na wyniki dodawania 2 bitów to mamy:

bit 1bit 2+carry
0000
0110
1010
1101

Co jest podejrzanie podobne do wyniku z xor ;-) dla tego co mamy w +:

 
bit 1bit 2^
000
011
101
110

oraz do and tego co mamy w carry ;-)

 
bit 1bit 2&
000
010
100
111

No i wiemy, że carry idzie o 1 bit  dalej, czyli trzeba na nim zrobić << :-)

Czyli jak chcemy dodać a do b to wiemy, że będziemy musieli zrobić:
c = a^b które da nam wartość bitów "po dodaniu", ale brakuje nam carry, które to carry mamy z (a&b)<<1 :-)

stąd may:
public int add(int a, int b) {
while (b!=0) {
var c = a&b;
a^=b;
b=c<<1;
}
return a;
}
Teraz jak mamy dodawanie to wystarczy wiedzieć, że odejmowanie to dodawanie liczby o przeciwnym znaku ;-) i tego, że liczba plus jej element odwrotny to 0 ;-)
Wtedy jasne się staje jak są reprezentowane liczby ujemne, czyli jako negacja wszystkich bitów... ale to by było za mało bo wtedy 0 miałoby odwrotność... i 1 + -1 by było wszystkimi zapalonymi bitami ;-) 
Więc jest negacja wszystkich bitów +1 ;-)
Czyli:
-1 = -(0001) = ~(0001)+1 = 1110+0001 = 1111
stąd -1 + 1 = 1111 + 0001 = (1)0000 (gdzie to (1) to carry które jest wyniesione poza liczbę :-)).
Stąd możemy powiedzieć, że odejmowanie b od a to dodanie do a -b ;-)
No i mamy:
public int minus(int b) {
return add(~b, 1);
}

public int sub(int a, int b) {
return add(a, minus(b));
}

Btw. a jak rozpoznać, że liczba jest ujemna? ;-)
Tak się fajnie składa, że ma zapalony najwyższy bit ;p

Czyli np. tak:
private int sig(int a) {
return new int[]{1,-1}[a>>>=31];
}

Ale OK, już umiemy dodawać i odejmować, nawet powiedzieć jaki jest znak liczby, ale może by tak pomnożyć? ;-)

Niby mnożenie to tylko dodawanie.. wystarczy dodać mnożną tyle razy jak mówi mnożnik i mamy wynik... (a, że w komputerze to będzie pętla, to to nawet działa dla ujemnych liczb, ale dziwnie ;-))

No więc: 7*3=7+7+7=21

Ale... 3 to 2 +1, czyli 7*3=7*2+7=21

a 2 i 1 to potęgi dwójki ;-)

A znamy operację shift :-) [użyliśmy jej już w dodawaniu i w wyznaczaniu znaku :-)]

Czyli co by było gdybyśmy zaczęli od liczby 0, i dodali do niej a jeśli bit dla 1 się świeci w b? później przesunęli a o 1 bit w kierunku wyższych liczb (czyli pomnożyli x2), a b o jeden bit w kierunku mniejszych (czyli podzielili przez 2), i znów sprawdzili? ;-)

No to użyjmy tej wiedzy ;-)
public int mul(int a, int b) {
var sum = 0;
while (b!=0) {
if ((b&1)==1) sum=add(sum,a);
a<<=1;
b>>>=1;
}
return sum;
}

I mamy mnożenie :-) jak widać nawet się nie musimy przejmować znakami... 

W końcu jest czas na dzielenie, to jest najtrudniejsze.

Ale coby było gdyby oszukać? I zamiast dzielić to mnożyć? ;-)
No bo przecież dzielenie to znalezienie liczby, która pomnożona przez dzielnik da dzielną... albo będzie największą liczbą nie większą od dzielnej, która jest wielokrotnością dzielnika.
Czyli musimy znaleźć tylko liczbę, która pomnożona razy dzielnika będzie równa dzielnej, lub będzie jej najbliższa.

Moglibyśmy więc przelecieć od 1 wzwyż, aż wynik mnożenia tej liczby z dzielnikiem będzie większy od dzielnej, wiemy wtedy, że liczba o 1 mniejsza jest wynikiem dzielenia :-)

Ale co będziemy wszystkie bity po drodze zapalać? Pamiętamy z mnożenia, że mnożenie to dodawanie mnożnej * potęga dwójki dla której pali się bit w mnożniku...

Co nam więc szkodzi poszukać największego bitu naszego wyniku dzielenia, który będzie zapalony? ;-)
Zaczniemy od 1 i będziemy je przesuwać w lewo (czyli mnożyć x2) aż będzie większa od dzielnej... wtedy wystarczy przesunąć raz w prawo i mamy najstarszy bit wyniku dzielenia :-)

A jak mamy najstarszy bit... to dodajemy tą liczbę do wyniku, i teraz przesuwamy ten bit znów w prawo (dzielimy przez 2) i sprawdzamy czy suma jest mniejsza lub równa dzielnej... jak jest mniejsza lub równa, znaczy, że ten bit też trzeba zapalić (+ nam to zrobi, ale i or)...

Znaki nam tu trochę przeszkadzają, ale użyjemy magii, że - i + robią -, a + i + oraz - i - robią + (takie odwrotne xor ;-)), i jeśli zrobimy działanie na liczbach dodatnich, ale zapamiętamy znaki z początku to możemy później po prostu zrobić odpowiedni znak.
I nasze dzielenie wygląda tak ;-)
public int div(int a, int b) {
// c = a/b => a=b*c
if (b==0) throw new ArithmeticException("Div by 0");
var sigA = sig(a);
var sigB = sig(b);
a=mul(sigA,a);
b=mul(sigB,b);
var d = 1;
while (a>=mul(b,d<<1) && mul(b,d<<1)>0 && (d<<1>0)) {
d<<=1;
}
var c = 0;
while (d>0) {
var mul = mul(b, c | d);
if (a>=mul && mul>0) c|=d;
d>>>=1;
}
c=mul(c,mul(sigA,sigB));
return c;
}
Jak widać musimy jakoś obsłużyć to, że niestety nie da się dzielić przez 0 ;-)

No co ja zrobię, że lubię bity? :-)



Podobne postybeta
Potworność ;-) czyli mnożenie w 90 liniach ;-)
2016 będzie rokiem "nietypowym"
32 bity vs. 64 bity, tym razem C++ ;-)
Przesyłanie "obcych" na odległość, albo uniwersalny format danych ;-)
Java 32 bit vs. Java 64 bit