Dlaczego sterownik Java MongoDB używa generatora liczb losowych w trybie warunkowym?
Widziałem poniższy kod ww tym zatwierdzeniu dlaSterownika połączenia Java MongoDB i na początku wydaje się to żartem. Do czego służy poniższy kod?
if (!((_ok) ? true : (Math.random() > 0.1))) {
return res;
}
(EDIT: the code has been updated since posting this question)
4 answers
Po zapoznaniu się z historią tej linii, mój główny wniosek jest taki, że w pracy było trochę niekompetentnego programowania.
-
Ta linia jest bezinteresownie zawiła. Forma ogólna
a? true : b
Dla {[4] } jest równoważne prostej
a || b
-
Otaczająca negacja i nadmierne nawiasy splatają sprawy dalej. Mając na uwadze prawa De Morgana jest trywialną obserwacją, że ten fragment kodu wynosi do
if (!_ok && Math.random() <= 0.1) return res;
-
Commit, który pierwotnie wprowadził tę logikę miał
if (_ok == true) { _logger.log( Level.WARNING , "Server seen down: " + _addr, e ); } else if (Math.random() < 0.1) { _logger.log( Level.WARNING , "Server seen down: " + _addr ); }
- kolejny przykład niekompetentnego kodowania, ale zwróć uwagę na odwróconą logikę : tutaj zdarzenie jest rejestrowane, jeśli
_ok
lub w 10% innych przypadków, podczas gdy kod w 2. zwraca 10% razy i rejestruje 90% razy. Tak więc późniejsze zatwierdzenie zrujnowało nie tylko klarowność, ale samą poprawność.Myślę, że w kodzie, który napisałeś, możemy zobaczyć, jak autor zamierzał przekształcić oryginał
if-then
w jakiś sposób dosłownie w jego negację wymaganą dla wczesnegoreturn
warunku. Ale potem schrzanił i wstawił skuteczny "podwójny negatyw", odwracając znak nierówności. Pomijając kwestie stylu kodowania, logowanie stochastyczne jest dość wątpliwą praktyką samą w sobie, zwłaszcza że wpis dziennika nie dokumentuje własnego osobliwego zachowania. Intencją jest oczywiście zmniejszenie tego samego faktu: że serwer obecnie nie działa. Odpowiednim rozwiązaniem jest rejestrowanie tylko zmian stanu serwera, a nie każdej jego obserwacji, nie mówiąc już o losowym doborze 10% takich obserwacji. Tak, to wymaga trochę więcej wysiłku, więc zobaczmy trochę.
Mogę tylko mieć nadzieję, że wszystkie te dowody niekompetencji, zgromadzone po sprawdzeniu tylko trzech linijek kodu , nie mówią rzetelnie o projekcie jako całości, i że ten kawałek pracy zostanie oczyszczony Jak najszybciej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-11 13:15:23
11 godzin temu przez gareth-rees:
Przypuszczalnie chodzi o to, aby logować tylko około 1/10 awarii serwera (a więc uniknąć masowego spamowania dziennika), bez ponoszenia kosztów utrzymania licznika lub timera. (Ale na pewno utrzymanie timera byłoby niedrogie?)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-30 10:05:28
Dodaj członka klasy inicjalizowanego do ujemnego 1:
private int logit = -1;
W bloku try wykonaj test:
if( !ok && (logit = (logit + 1 ) % 10) == 0 ) { //log error
To zawsze rejestruje pierwszy błąd, a następnie co dziesiąty kolejny błąd. Operatory logiczne "zwarcie", więc logit jest zwiększany tylko w przypadku rzeczywistego błędu.
Jeśli chcesz, aby pierwszy i dziesiąty z wszystkich błędów, niezależnie od połączenia, uczyń klasę logit statyczną zamiast członka A.
Jak już wspomniano, powinno to być wątek Bezpieczny:
private synchronized int getLogit() {
return (logit = (logit + 1 ) % 10);
}
W bloku try wykonaj test:
if( !ok && getLogit() == 0 ) { //log error
Uwaga: nie sądzę, aby wyrzucanie 90% błędów było dobrym pomysłem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-02 09:45:55
Widziałem już takie rzeczy.
Był kawałek kodu, który mógł odpowiedzieć na pewne "pytania", które pochodziły z innej "czarnej skrzynki". W przypadku, gdy nie mógł na nie odpowiedzieć, przekazywałby je do innego kawałka kodu "czarnej skrzynki", który był naprawdę powolny.
Tak więc czasami pojawiały się nieznane wcześniej nowe "pytania" i pojawiały się w partii, jak 100 z rzędu.
Programista był zadowolony z działania programu, ale chciał w jakiś sposób poprawić oprogramowanie w przyszłości, jeśli to możliwe, nowe pytania zostały odkryte.
Rozwiązaniem było więc zalogowanie nieznanych pytań, ale jak się okazało, było ich 1000. Dzienniki stały się zbyt duże i nie było korzyści z ich przyspieszenia, ponieważ nie mieli oczywistych odpowiedzi. Ale co jakiś czas pojawiało się mnóstwo pytań, na które można było odpowiedzieć.
Ponieważ logi stawały się za duże, a wyrębki dostały się do sposób zapisywania naprawdę ważnych rzeczy, które dostał do tego rozwiązania:
Tylko Zaloguj losowe 5% , to wyczyści dzienniki, podczas gdy w dłuższej perspektywie nadal pokazuje, jakie pytania/odpowiedzi można dodać.
Tak więc, gdyby miało miejsce nieznane Zdarzenie, w losowej ilości tych przypadków, byłoby ono rejestrowane.
Myślę, że to jest podobne do tego, co widzisz tutaj.
Nie podobał mi się ten sposób działania, więc usunąłem ten fragment kodu i po prostu zarejestrowałem te Wiadomości do a inny plik , więc wszystkie były obecne, ale nie naruszały ogólnego pliku dziennika.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-07 12:06:35