Wczoraj kładę się i myślę o kodzie klasy, nad którą pracuję. Dzisiaj jem zupę i znowu o tym kodzie myślę. A jest to projekt hobbystyczny. To normalne, czy coś tu nie tak?
- Rejestracja:około 4 lata
- Ostatnio:ponad 2 lata
- Postów:791

- Rejestracja:ponad 5 lat
- Ostatnio:18 dni
- Lokalizacja:Wrocław
Miałem do "wskrzeszenia" notebook pysparkowy napisany przez ÜBER programistów z Indii.
Ściana kodu - Jedna funkcja z 270 linijkami bez adnotacji z zagnieżdżonymi 47 ifami <3 Już pomijam, że jakiekolwiek DRY, czy KISS zostało oplute i przekopane na glebie. ÜBER hindus postanowił zrobić ÜBER funkcje :D
Oczywiście nawet nie próbowałem tego sprzątać. Zebrałem wymagania i napisałem notebooka na nowo.
- Rejestracja:około 4 lata
- Ostatnio:ponad 2 lata
- Postów:791
Robię właśnie kalkulator w JS. To jest dopiero WTF (natura JS):
0.1 + 0.2 = 0.30000000000000004


0.1
domyślnie konwertowany na float to po prostu pułapka. Już javowe float x = 0.1f + 0.2f
(zupełnym przypadkiem) przynajmniej pokazuje, że jest coś na rzeczy. (Z tym, że java w ogóle problemu nie rozwiązuje, bo w javie double x = 0.1 + 0.2
przejdzie).

to jest jedno z rozwiązań - IMO średnie
a co jest złego w IEEE 754-2008? Bo jeśli dobrze zrozumiałem jest to właśnie próba zakodowania 0.1
i w pamięci komputera będzie dokładnie 0.1
. Jaki tu jest problem? To że mimo wszystko precyzja jest ograniczona i trzeba by używać liczb nieograniczonej precyzji?

specyficzna
).

- Rejestracja:prawie 7 lat
- Ostatnio:ponad 2 lata
- Lokalizacja:74.7261832, -41.7409518
- Postów:151

- Rejestracja:około 6 lat
- Ostatnio:2 dni
Ciekawostki optymalizacyjne w javascript (V8). Stwórzmy funkcję sumującą propertiesy elementów tablicy i dwie tablice - jedną ze spójnymi elementami, drugą z elementami gdzie kilka ostatnich ma dodatkowe propertiesy i stają się w pamięci instancjami innych obiektów:
function sum(arr) {
let acc = 0;
for (let i = 0; i < arr.length; i++) {
acc += arr[i].val;
}
return acc;
}
const array1 = [];
const array2 = [];
const s = { val: 1 };
for (let i = 0; i < 100_000_000; i++) {
array1.push(s);
array2.push(s);
}
array1.push({ val: 0 }, { val: 1 }, { val: 2 }, { val: 3 });
array2.push({ val: 0, a: 0 }, { val: 1, b: 0 }, { val: 2, c: 0 }, { val: 3, d: 0 });
teraz porównajmy czasy odpalenia na array1 i array2:
for (var i = 0; i < 5; i ++) {
console.time('array1'); sum(array1); console.timeEnd('array1');
}
for (var i = 0; i < 5; i ++) {
console.time('array2'); sum(array2); console.timeEnd('array2');
}
wyniki dla array1 (z elementami jednego typu):
~130ms
~130ms
~130ms
~130ms
~130ms
wyniki dla array2 (z elementami różnych typów):
~130ms
~160ms
~600ms
~600ms
~600ms
Silnik v8 postanowił przeoptymalizować funkcję sum
na megamorficzną. Po "reoptymalizacji" odpala się 4 razy dłużej. NIEZALEŻNIE od danych wejściowych. Odpalając znowu na array1:
wyniki dla array1 po odpaleniu tej funkcji dla array2:
~600ms
~600ms
~600ms
~600ms
~600ms
!! Czas już nigdy nie zejdzie do starego 130ms. Chyba że stworzymy nową funkcję:
function sum2(arr) {
let acc = 0;
for (let i = 0; i < arr.length; i++) {
acc += arr[i].val;
}
return acc;
}
teraz sum2(array1)
działa znowu szybko (dopóki elementy są tego samego typu).
Musiałem sam sprawdzić bo nie uwierzyłem
Źródło: https://twitter.com/SeaRyanC/status/1496273922714902528





- Rejestracja:ponad 21 lat
- Ostatnio:około 14 godzin
Domofony których każdy klawisz "pika" dźwiękiem o innej wysokości podczas wpisywania kodu.
Przecież tak można kod podsłuchać. No kto to wymyślił.



- Rejestracja:około 4 lata
- Ostatnio:ponad 2 lata
- Postów:791
Czytam sobie kolejny rozdział książki dotyczącej JS ES6. I chyba odpuszczę na tym poziomie zaawansowania (początkujący).
Bo chodzi o zagadnienia proxy i refleksji. Używa ktoś tego?

- Rejestracja:ponad 11 lat
- Ostatnio:około godziny
- Postów:362
Połączenie django oraz safari(i pewnie apki). Mamy sobie endpoint z id pod który strzelamy np. endpoint/2
Django zwraca 301 do endpoint/2/
bo wymaga, aby url kończył się /
i w tym momencie następuje wylogowanie z aplikacji bo safari kolejny request robi bez tokenu. Inne przeglądarki to ogarniają.

endpoint/<pk>/
, zaś fronty były pod endpoint/<pk>
Apka jest przejęta po innej firmie i jest tam sporo dziwnych rozwiązań

- Rejestracja:około 7 lat
- Ostatnio:około rok
- Postów:109
Chwila zaćmienia i zamiast zalogować się na LinkedIn utworzyłem konto na Indeed. Dzięki Bing!
A podobno linkedIn został kupiony przez M$ ;P
P.S. zawszę mylę Sing In z Sign Up
- linkedin.PNG (76 KB) - ściągnięć: 12

- Rejestracja:ponad 21 lat
- Ostatnio:około 11 godzin
- Lokalizacja:Kraków
- Postów:1114
Dzisiaj zapuściłem się w jakieś obce rejony kodu, i odkryłem największe stężenie słowników, jakie kiedykolwiek w życiu widziałem, nawet nie chce wiedzieć do czego to służy :D
- screenshot-20220304124222.png (144 KB) - ściągnięć: 19



readonly
...


- Rejestracja:około 17 lat
- Ostatnio:minuta
Na Chrome przesunięcie stronę lekko w dół, a strona w nieskończoność będzie mrugać: na przemian będą się pojawiać i znikać jakieś paski u dołu i góry.
Na Firefox robi się tylko jedna iteracja, na Egde też. Safari nie sprawdzałem.




- Rejestracja:prawie 4 lata
- Ostatnio:około 21 godzin
- Postów:344
Robię code review w międzynarodowym zespole:
l1.retainAll(l2)
Piszę, że „this is qadratic time complexicity and these lists are huge”. Ten mi odpisuje, że racja i jest „open to alternatives”.
Dobrze, że pracujemy zdalnie, bo bym nie wytrzymał w profesjonalnej masce i przy wszystkich zadałbym pytanie, kto go zatrudnił na stanowisko Senior Java Developer. Na LI ma 10 lat doświadczenia. Nie jest Hindusem.
To nie pierwszy raz z tą osobą, że mam „wtf, z kim ja pracuję”. Zadania algorytmiczne na interview mają sens.

Kotlin tak robi
@obscurity patrzyłeś w dalej w kod? Operacja konwersji może się nie udać i i tak dostaniemy listę i złożoność kwadratową is Collection -> if (this.safeToConvertToSet()) toHashSet() else this

private fun <T> Collection<T>.safeToConvertToSet() = brittleContainsOptimizationEnabled() && size > 2 && this is ArrayList
, czyli LinkedListy już odpadły, dlaczego?



- Rejestracja:około 4 lata
- Ostatnio:ponad 2 lata
- Postów:791
Co się stało z developer.mozilla.org? Jak można było zmienić taki fajny i czytelny UI na obecny?

Recenzowałem kod pewnego seniora X, kilkaset linii zmienionych, w tym testy, w sumie nawet nie taki duży ticket. Miałem na początku pozytywne nastawienie, bo obawiałem się bloba spaghetti na 5 tys linii. A tu jednak zaskoczenie - kod ma w sumie nawet niezłą strukturę i w sumie bez większych problemów dość szybko ogarnąłem o co chodzi. Pomyślałem "X robi postępy, może będzie nieźle" . Wcześniej nie było to normą u X.
Znalazłem:
- dwa przypadki wyścigów, w dwóch różnych miejscach, które zaowocowałoby wywaleniem kodu lub zwróceniem złych wyników zapytania pewnie w czarny piątek
- jeden błąd w założeniach do algorytmu i ogólnie algorytm skopany i dający błędne wyniki w pewnej nieskończonej liczbie przypadków brzegowych (deterministyczne)
- kilka przypadków niedokładnie udokumentowanych metod i potencjalnych błędów (trudno ocenić czy błąd czy nie, bo zachowanie nieudokumentowane, ale implementacja "dziwna")
- parę innych drobiazgów
Recenzja zajęła mi dwa dni. Wszystko starałem się jak najdokładniej opisać, w sumie zadowolony byłem że tyle znalazłem, więc będąc w dobrym humorze nawet zawarłem wiele propozycji jak można to poprawić.
Po 10 minutach od wysłania recenzji, czytam odpowiedzi X na moje komentarze:
- "Ten kod skopiowałem z innego miejsca, więc nie może być źle".
- "Interesujące" (brak dalszego wyjaśnienia)
- "Ten komentarz nie ma sensu." (i nic więcej, ani słowa wyjaśnienia)
- Komentarz oznaczony jako Resolved. Brak zmiany w kodzie.
WTF?



- Rejestracja:prawie 14 lat
- Ostatnio:około 7 godzin
- Postów:3169
Takie mnie spotkalo: https://bugs.openjdk.java.net/browse/JDK-8177809
W polaczeniu z tym: https://github.com/apache/cassandra/commit/c9ba33c334c813ece786dff57a853589852a1b65
- Rejestracja:około 4 lata
- Ostatnio:ponad 2 lata
- Postów:791
Pomysł: użyj webpacka, aby ogarnąć lepiej projekt składający się z wielu modułów
Rzeczywistość: doinstaluj ponad 10 różnych modułów i utwórz podobną ilość dodatkowych plików konfiguracyjnych, dzięki czemu projekt jest 100x bardziej skomplikowany




Ale brońcie się dalej jsowcy. Z was świat się śmieje tak samo jak z phpa
- nie no, zdecydowanie bardziej. Już nawet ja nie śmieję się phpa.

- Rejestracja:prawie 15 lat
- Ostatnio:około 13 godzin
- Lokalizacja:Laska, z Polski
- Postów:10053
kosmonauta80 napisał(a):
Pomysł: użyj webpacka, aby ogarnąć lepiej projekt składający się z wielu modułów
Rzeczywistość: doinstaluj ponad 10 różnych modułów i utwórz podobną ilość dodatkowych plików konfiguracyjnych, dzięki czemu projekt jest 100x bardziej skomplikowany
"Doinstaluj"? Do czego? Bo na pewno nie do projektu. Twój kalkulator nadal będzie się składał tylko i wyłącznie z tego kodu który napisałeś.
Te "dodatkowych 10 modułów" nie są dodawane do projektu, tylko do Twojej lokalnej instalacji - to jest bundler, narzędzie developerskie służące do budowania projektu. Jak już zbudujesz projekt to to co jest w dist/
to jest Twój projekt, bundler możesz wyrzucić. To podobne jak ściągasz przeglądarkę Firefox która ma 300 MB żeby pokazać index.html
który ma 1Kb
.
Poza tym, w innych technologiach jest tak samo, javowy Maven/Gradle i pluginy, pythonowy pip
/py
, ruby gem
/bundle
, phpowy Composer. To jest standard że narzędzia developerskie zajmują bardzo często dużo więcej miejsca i konfiguracji niż wynikowy projekt. Visual Studio Redistributables C++ 2015 zajmuje 6GB żeby zbudować binarkę mającą pół MB.
Im szybciej się z tym pogodzisz tym lepiej.

- Rejestracja:prawie 14 lat
- Ostatnio:5 dni
- Postów:2512
Pewien rejestrator chińskiego producenta kamer wysyła zdarzenia asynchronicznie. Odbiera się je przez http long polling. Zgłoszono mi problemy z działaniem mojego programu. Patrzę - no błąd deserializacji XML (C#). No ok włączam poszerzone logowanie i co ja patrzę? No XML się poprawnie nie deserializuje, bo to co dostaję to JSON. Ale zaraz, zaraz. W innym miejscu nadal widzę XML. No tak bo w ramach jednego strumienia (multi part mixed) dostaję raz XML, a raz JSON. Jaki trzeba mieć burdel w kodzie, żeby robić coś takiego? YAFUD.




- Rejestracja:około 4 lata
- Ostatnio:ponad 2 lata
- Postów:791
Naprawdę, te wszystkie tutoriale prowadzone w India-English to jeden wielki WTF...




- Rejestracja:prawie 15 lat
- Ostatnio:około 13 godzin
- Lokalizacja:Laska, z Polski
- Postów:10053
W PHP do funkcji preg_replace_callback()
został dodany opcjonalny argument int $flags
, trzymający flagi bitowe (te oldschoolowe, typu a | b | c
). Tylko że zostały użyte te same flagi co do preg_match()
oraz preg_match_all()
.
Co w tym złego zapytacie, a no to że w PHP jest konwencja sprawdzania czy feature istnieje albo tak class_exists(WeakReference::class)
, albo function_exists('preg_last_error')
albo defined(PREG_UNMATCHED_AS_NULL)
. I to działa nawet, w końcu słabo typowany język.
Ale teraz jak dodali te flagi które są tymi samymi flagami to siłą rzeczy nie ma jak sprawdzić czy istnieją czy nie. Jak feature jest, to jest. Jak nie ma, to w defined()
załapią się flagi z preg_match()
z poprzedniej wersji. Nie ma możliwości teraz sprawdzić czy ta funkcjonalność istnieje. Jedyne co można zrobić teraz to porównać wersję PHP: if (PHP_VERSION > '7.2.0')
:| Albo refleksją sprawdzić czy funkcja ma argument.
Dlaczego Ci goście jak dodają nowy feature to nie używają za grosz mózgu? ;|
Ale teraz jak dodali te flagi które są tymi samymi flagami to siłą rzeczy nie ma jak sprawdzić czy istnieją czy nie
, Nie ma możliwości teraz sprawdzić czy ta funkcjonalność istnieje.
ale jaka funkcjionalnosc i czy co istnieje. Napisz o co ci chodzi bo z tego tekstu nic nie mozna zrozumiec

preg_replace_callback()
umie zwrócić nulla.
- Rejestracja:ponad 11 lat
- Ostatnio:około godziny
- Postów:362
Kiedy jesteś fanem pythona, ale kazali pisać w nodeJS.
foo(x) {
const self = this;
......
self.doSomethigh(x)
}
I tak w większej ilości miejsc.


=>
weszło w życie) mieć dostęp do zewnętrznego this
;-)


- Rejestracja:prawie 15 lat
- Ostatnio:około 13 godzin
- Lokalizacja:Laska, z Polski
- Postów:10053
- screenshot-20220406231406.png (67 KB) - ściągnięć: 6

1+2
=== (1+2)
-> echo foo
=== echo (foo)

echo
nie jest funkcją. Tzn wszystko co działa z funkcjami, nie działa z echo
. Np nie można zrobić array_map('echo', $values);
.


print
była instrukcją (i pisało się bez nawiasów print 123
), a w Pythonie 3 już jest normalną funkcją.

- Rejestracja:prawie 15 lat
- Ostatnio:około 13 godzin
- Lokalizacja:Laska, z Polski
- Postów:10053
Wchodzimy na stronę "Apache" w dokumentacji PHP: i jest Predefined constants
:
Klikamy a tam: https://www.php.net/manual/en/apache.constants.php
To po co ta strona w ogóle? :|
Dodali pustą stronę po nic.
- screenshot-20220420010911.png (18 KB) - ściągnięć: 3
- screenshot-20220420010931.png (9 KB) - ściągnięć: 77



folder
czy katalog
i na pewno na takie rzeczy siły nie mam.

- Rejestracja:ponad 12 lat
- Ostatnio:7 miesięcy
- Postów:6610
tak mi się przypomniało czytając temat o algorytmice vs pisanie CRUDów. Pracuję w firmie z własnym produktem. Nie jest istotne co to jest a jedynie fakt, że rozwijany jest od ponad 35 lat (pierwsze wersje były jeszcze DOSowe). Wiele rzeczy zostało napisanych od nowa, niektóre nawet kilka razy - ot zwykła rzecz w takich projektach.
Jedną z jego korowych funkcji jest porównanie dwóch projektów, wyświetlenie różnic i zaaplikowanie ich. Czasami te różnice idą w miliony przy jednym porównaniu. Różnice te mają też swoje kategorie, których jest ok. 150. Co ważne, dla usera, różnice wyświetlane są pogrupowane w formie drzewka (dwa poziomy - kategoria - lista różnic z kategorii).
Klienci zgłaszają, że na dużych projektach porównanie i wyświetlenie wyników potrafi trwać i kilka godzin i zjadać ok 20GB RAMu. No to patrzymy do kodu a tam wyświetlanie zrealizowane w ten sposób:
forech kategoria in wszystkie_kategorie
{
dodaj_kategorie_do_drzewka(kategoria);
if (różnica.kategoria = kategoria)
dodaj_różnicę_do_drzewka(różnica);
}
i teraz zakładając 10 000 000 różnic i 150 kategorii to if wykona się 1 500 000 000 razy.
Żeby było ciekawiej to cała ta operacja działa się na styku kodu niezarządzalnego i zarządzalnego a obiekty latały jako COMy (różnica.kategoria
była po jednej stronie a porównanie po drugiej stronie). Więc dochodził dodatkowy narzut na tworzenie obiektów RCW przez c# (i to narzut dość znaczny, zarówno na pamięć jak i czas).
Finalnie, po zamianie listy na dictionary<kategoria, List<różnica>>
do trzymania różnic oraz pobranie różnica.kategoria
tylko raz i zapamiętanie lokalnie przyśpieszyło całą operację do 10 minut a zapotrzebowanie na RAM spadło do 700MB.
Także tego jeśli chodzi o logiczne myślenie to się jednak przydaje i twierdzenie, że maszyny mamy szybkie a RAMu dużo nie do końca się sprawdza.

- Rejestracja:ponad 6 lat
- Ostatnio:6 dni
- Lokalizacja:Silesia/Marki
- Postów:5505
Pracowałem raz w firmie która uparcie używała OSGi.
no bo może kiedyś będziemy chcieli wymienić dynamicznie biblioteki na produkcji bez restartu aplikacji
Oczywiście apka była zdockeryzowana przez co dynamiczna podmiana traciła sens. Oczywiście nie mieliśmy dostępu do produkcji, bo klient samodzielnie apke instalował na swoich serwerach. Po dwóch lata pracy tam i próbie zrozumienia sensu OSGi dostałem pozwolenie na zaczęcie usuwania go :D BTW dalej nie wiem po co jest OSGi

zarządzanie zależnościami idzie ogarnąć za pomocą modułów.
o,to można mieć już tę samą bibliotekę w dwóch różnych niekompatybilnych wersjach na raz w jednym programie?

- Rejestracja:prawie 15 lat
- Ostatnio:około 13 godzin
- Lokalizacja:Laska, z Polski
- Postów:10053
Tutorial o enkapsulacji: https://www.geeksforgeeks.org/encapsulation-in-java/
Autor tam pisze że enkapsulację można uzyskać dodając gettery i settry
Encapsulation can be achieved by Declaring all the variables in the class as private and writing public methods in the class to set and get the values of variables
It is more defined with setter and getter method.
I z tego tutoriala się potem uczą inni.






- Rejestracja:prawie 15 lat
- Ostatnio:około 13 godzin
- Lokalizacja:Laska, z Polski
- Postów:10053
Instalator GnuWin32 na Windowsie wywala poza skalę (procentów):
- screenshot-20220522142211.png (81 KB) - ściągnięć: 4

- Rejestracja:prawie 15 lat
- Ostatnio:około 13 godzin
- Lokalizacja:Laska, z Polski
- Postów:10053
Czytam sobie artykuł: https://www.pythoncentral.io/pyside-pyqt-tutorial-qlistview-and-qstandarditemmodel/ I gość tam korzysta z biblioteki która nie do końca ogarnia wcięcia, więc mamy takie coś:
# Loop through the items until you get None, which
# means you've passed the end of the list
i = 0
while model.item(i):
if not model.item(i).checkState():
return
i += 1
app.quit()
model.itemChanged.connect(on_item_changed)
# Apply the model to the list view
list.setModel(model)
# Show the window and run the app
list.show()
app.exec_()
Gdyby to był inny normalny język z klamerkami, albo chociaż z end
(jak w Rubym) to spoko, ale teraz to się tego nawet nie da odpalić bez zgadywania czy coś jest w czy poza funkcją.


- Rejestracja:prawie 15 lat
- Ostatnio:około 13 godzin
- Lokalizacja:Laska, z Polski
- Postów:10053
kosmonauta80vpiotr