Programistyczne WTF jakie Was spotkały

0

W pracy wzięliśmy się za przerzucanie danych z bazy MySQL do MSSQL aby dane były widoczne na nowym portalu. Stara baza i portal były pisane przez firmę zewnętrzną.

I tutaj zaczynają się schody. W zasadzie tyle schodów, że można by śpiewać "Stairway to heaven".

  1. Baza jest 2-językowa. Tak na równi 50% nazw jest angielskich, a 50% polskich. Są tabele nazwane po angielsku, mające pola po polsku, i odwrotnie.

  2. Nie ma praktycznie żadnych relacji pomiędzy tabelami. Wszystkie dane są ściągane przez skrypty PHP a później łączone.

  3. Z województwami to są dopiero cyrki. W każdej tabeli id_woj jest innym typem, raz tinyIntem, raz Varcharem. Nie ma tabeli województwa z odpowiednimi Id, tylko w aplikacji jest stworzona tablica i po ściągnięciu z bazy id wyciąga się z tej tabeli dane województwo. Dodatkowo, aby zapewnić na pierwszym miejscu tablicy pole "wszystkie" (potrzebne do sortowania) to robią tak:

$wojew = getAllProvinces();
$wojew = array_reverse($wojew , true);
$wojew[0] = '-- wszystkie --';
$wojew = array_reverse($wojew , true);
  1. Tabela oferta zawiera kolumnę 'id_zatrudnienia' i 'zatrudnienie'. To pierwsze w każdym rekordzie jest puste (na początku szukałem nawet odpowiedniej tabeli, gdyż patrzyłem na sam schemat bez danych). To drugie oznacza ilość osób zatrudnionych, jednak typ kolumny to Varchar, więc już widzę tą dodatkową robotę z parsowaniem w programie.

  2. Kolumna branż jest typu Varchar, a kolejne Id są wpisywane po średniku - tak się wykonuje relację N-N.

  3. Zapytanie do bazy o wyszukanie oferty ma 280 linii kodu.

  4. Przeczesywałem całą bazę, a później kod programu żeby znaleźć, gdzie następuje mapowanie rodzaju oferty do inta. Dopiero po jakiejś godzinie szef powiedział, abym spojrzał do configa, bo oni tam podobno zmienne definiowali. I ukazał mi się plik mający ponad 300 linii z samymi definicjami zmiennych globalnych. Dodatkowo połowa zmiennych nazywana po angielsku, a połowa po polsku.

0

Moje dzisiejsze WTF w moim kodzie. Trochę sobie przeszeregowałem mój backend do SOAP Allegro i powstało mi takie coś https://gist.github.com/2984484 - abstrakcyjna klasa z samymi statycznymi elementami...

0

W cssie pewnej strony:

/* Globalne klasy
---------------------------------------------------------------------------------------------------- */

.hide		   { display: none; }
.clear         { clear: both; }
.float-left    { float: left; }
.float-right   { float: right; }
.inline		   { display: inline; }
.block		   { display: block; }

.text-left     { text-align: left; }
.text-right    { text-align: right; }
.text-center   { text-align: center; }
.text-justify  { text-align: justify; }

.valign-top  { vertical-align: top; }

.bold          { font-weight: bold; }
.orange          { color: orange; }
.italic        { font-style: italic; }
.underline     { border-bottom: 1px solid; }
.highlight     { background: #FDFF0F; }

.img-left      { float: left; margin: 4px 10px 4px 0; }
.img-right     { float: right; margin: 4px 0 4px 10px; }

.nopadding     { padding: 0; }
.nomargin      { margin: 0; }
.noindent      { margin-left: 0; padding-left: 0; }
.nobullet      { list-style: none; list-style-image: none; }

.width100      { width: 100px; }
.width118      { width: 118px; }
.width120      { width: 120px; }
.width200      { width: 200px; }
.width220      { width: 245px; }
.width450      { width: 450px; }
.height150      { height: 160px; }

Ostatnia linijka szczególnie ciekawa.

0
winerfresh napisał(a):

Moje dzisiejsze WTF w moim kodzie. Trochę sobie przeszeregowałem mój backend do SOAP Allegro i powstało mi takie coś https://gist.github.com/2984484 - abstrakcyjna klasa z samymi statycznymi elementami...

A wlasciwie dlaczego to jest WTF? (Pomijam, ze nie lubie staticow, to moze byc WTF w 21 wieku ;d) Jest to klasa ktorej instancji nie mozna utworzyc, ktora mozna jednak uzywac jako helpera. Brakuje tylko prywatnego konstruktora aby nikt nie mogl dziedziczyc.

0

Dzisiaj znowu jedno wielkie WTF mnie spotkało. Otóż, dowiedziałem się że wszystkie cracki i keygeny są przygotowywane przez producentów crackowanego oprogramowania i wyciekają tejemniczo do sieci. Przygotowanie cracka/keygena przez osoby trzecie jest jest:

  • zupełnie niemożliwe dla aplikacji nie napisanej w .net. Bo (tu cytat): "Przecież nikt nie będzie siedział i wklepywał wszystkich możliwych kodów żeby przygotować keygena a Reflector ci tego nie zdekompiluje i nic nie podejrzysz"
  • zupełnie niemożliwe dla aplikacji .net zaciemnionej w CodeFort - bo (tu cytat): "A co, myślisz że ktoś będzie przegryzać się przez krzaczki które pokazuje Reflector?"

Oczywiście, cały reversee engineering to pies, nikt nigdy nie słyszał o tym że w ogóle coś takiego istnieje. Chciałoby się powiedzieć "prostytutka, z kim ja pracuję...", no ale... cóż. 3 osoby mnie wyśmiało że się nie znam. Czasami mi się wydaje że pracuję nie z informatykami tylko z (nie wiem kim). Klepacze kodu a nie programiści, na żaden temat nie widzą zupełnie nic.

0

Pocieszę cię, ze ja mam to samo. W Nemcach zachodnych, a ony sa tacy zajebiscy. Szczególnie jeden kolo mnie rozsierdza na potęge, [CIACH!] banialuki tylko żeby gadać, szczególnie na jakichś zebraniach. O dziwo, ma status mastaha wyjebacha, a moja polemika działa na moją niekorzyść, jako że jestem nowy i na pewno nie mam racji.

0

pisze sobie kod, dodaje lomboka i eclipse wywala mi błąd. Porównuje z innymi klasami, patrze oglądam, "cleanuje" a błąd ciągle jest. Wkurzyłem się usunułem @data i napisałem ręcznie getery i setery, clean na projektcie.
Buduje i wywala mi sie error jak w załączniku :D

0
  • dla programistów Allegro.pl:

[...] będą działać na stronach Allegro. Darmowe liczniki możesz znaleźć np. tutaj. [...]

A czym jest magiczne "tutaj"? Odnośnikiem do google.pl :D

0

Nudzi mi się właśnie, bo czekam na pociąg, więc wchodzę sobie na 4p i czytam. W algorytmach jakiś gościu nie ogarnia flooda, a jako, że pisałem ostatnio coś w tej tematyce (dokładnie trzy kody) to myślę sobie "oj tam, wrzucę". Wchodzę na themisa, otwieram sobie te trzy kody w nowych kartach (WP7, HTC 7 Mozart) i już chcę wklejać, a tu mały zonk, bo mi każe znowu sie logować. W pierwszej karcie, w drugiej... w trzeciej zalogowałem się na konto znajomej. Działa. Wracam do poprzednich kart, działa. Na każdej karcie można zalogować się na tą samą stronę różnymi loginami. Osobne cookies dla każdej karty? WTF?

1

Znalezione na stackoverfolw:

String hasPhone = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));

if ( hasPhone.equalsIgnoreCase("1"))
    hasPhone = "true";
else
    hasPhone = "false" ;

if (Boolean.parseBoolean(hasPhone)) { 
    // coś do zrobienia
0

W Java można zrobić tak:

void test() 
{
  if (true)
   return;
  System.out.println("To sie nie moze wyswietlic"); 
}

Ale tak już nie:

void test() 
{
  return;
  System.out.println("To sie nie moze wyswietlic"); 
}

Chociaż obydwie metody działają tak samo, to dozwolona jest tylko ta pierwsza. Trochę to dziwne, ale to nie ja projektowałem ten dziwny język ;)

0

Niedawno zrobiłem tzw. "przywracanie do ustawień fabrycznych" na starszym laptopie Lenovo. No i pierwsze co po przywróceniu trzeba zrobić to wywalić ten cały preinstalowany zbiór syfnych programów. Odinstalowałem już większość, dochodzę do ostatniej pozycji - Windows Media Connect. Kilkam "odinstaluj" a tu moim oczom ukazuje się taki komunikat:
bez tytułu.JPG
Super...

0

MSI nie tylko nie rozwiązuje żadnych zależności, ale i nie obsługuje w ogóle żadnych zależności. Programista musi sam zadbać o sprawdzenie czy odpowiedni komponent jest zainstalowany (musi to zrobić ręcznie np przez sprawdzenie klucza rejestru) i jedyne co może to rzucić komunikatem i przerwać instalację. Nie można np uruchomić automatycznie innej instalacji, bo dopóki nie zakończy się pierwsza instalacja, nie może zostać rozpoczęta kolejna.

Nie można także uzależnić jednego msi od innego msi, można tylko dodać wymagane do zainstalowania komponenty do bootstrappera (to ten Setup.exe, który sprawdza wymagane komponenty, instaluje po kolei a na samym końcu uruchamia właściwy plik .msi). Samo MSI dość ułomne jest w porównaniu z pakietami znanymi z Linuksów, jak .deb czy .rpm.

Także zapomnijmy o drzewie zależności automatycznie rozwiązywanych - w systemach Windows to jest niemożliwe do zrealizowania. Prymitywną namiastką tego jest bootstrapper.

Chyba, żeby nie korzystać z Instalatora Windows i wszystko robić od zera, łącznie z rejestrowaniem programu w rejestrze (wtedy pojawi się w Dodaj/Usuń programy jako nowy wpis) i wieloma jeszcze rzeczami wymaganymi do prawidłowego osadzenia aplikacji jako zainstalowanej w systemie.

0

Ja mam wyczesany WTF - właśnie przydał mi się do pracy algorytm sprawdzania czy na liście łączonej występuje cykl [rotfl] Kto by pomyślał, że to popularne pytanie rekrutacyjne można kiedyś wykorzystać? [rotfl]

0

Mi sie zdarzylo WTF podczas robienia rekurencji:

long silnia(int n) _nawias
  return silnia(n - 1) * n;
_nawias
0

Niezły WTF to Twój opis.

Java czy C++? Nie ma jednoznacznej odpowiedzi na to pytanie, używaj Javy do aplikacji mobilnych, C++ do programów na komputery.
(Visual) BASIC czy C++? Oczywiście że C++.
OpenGL czy DirectX? OpenGL i kropka!

0

WTF od każdej strony: jest sobie pilne zlecenie, robione na świra, bo klient musi mieć na "natychmiast". Dziś rozmowa z klientem stwierdzając że musi poczekać do poniedziałku, bo jeden moduł odmawia posłuszeństwa. Odpowiedź klienta (cytat bez przekleństw): "Ale [...] panowie, co wy [...] tak się przejmujecie [...], ważne żeby było to [...] logo tej [...] unii, i tak [...] nikt normalny z tego [...] nie będzie korzystać". A pomyśleć że projekt miał być na serio. Wychodzi z tego że na 99.9% nikt tego nigdzie nie wdroży, tylko ktoś zainkasuje dotacje a my % z dotacji.

1

Dział supportu zgłosił ostatnio problem, że klientowi w logach leci bardzo dużo komunikatów "Connection reset by peer" i "Broken pipe". Pierwsze skojarzenie - mają jakiś problem z siecią bądź sprzętem. Ale nie, sieć ok, sprzęt ok. Generalnie wszystko działa, ale te komunikaty ich martwią, że to coś poważnego. No nic, sprawdzamy, czego się nie robi dla klienta płacącego dużo $$$$ na rok za support. Co się okazało:

Dwa węzły (nazwijmy je A i B) w klastrze komunikują się w taki oto sposób:

  1. węzeł A wyniki swojej pracy umieszcza w pliku na serwerze HTTP
  2. węzeł B dostaje URL do tego pliku i otwiera połączenie w trybie GET
  3. węzeł B czyta nagłówki w których jest zapisana ilość danych w pliku (bynajmniej nie Content-Length, ale to szczegół), węzeł A przy tym rozpoczyna dosyć agresywny readahead pliku
  4. węzeł B sprawdza czy ma wystarczająco dużo pamięci, aby obronić dane "w locie" - test przechodzi pozytywnie
    5a. węzeł B wchodzi do procedury alokującej pamięć, która oprócz ilości pamięci bierze referencję do otwartego strumienia (WTF, podejrzane...)
    5b. zaraz za wywołaniem alokacji pamięci jest kod ponownie otwierający połączenie opatrzony komentarzem "reopen stream if we need to" (tak jakbym nie widział, ale WTF, przecież jest otwarty...)
  5. procedura alokująca pamięć stwierdza, że nie ma teraz jednak wystarczająco dużo pamięci (WTF a to czemu teraz?) i zamyka strumień bez czytania danych powodując wyjątek w węźle A i... oczekuje aż więcej pamięci się zwolni "później"
  6. jeśli pamięc się w końcu pojawi, zostaje zaalokowana i dopiero po tym węzeł B ponownie otwiera połączenie w trybie GET i przetwarza dane już bez zatrzymywania.

Gdzie to tak? Hadoop 0.23.

Innym WTF w tym kodzie jest notoryczne wstawianie operacji otwierania / zamykania strumieni w różnych przypadkowych miejscach i to w kodzie, który ma czasem po 4k linii na klasę. Ustalenie, który close jest do którego strumienia i czy na pewno w każdej sytuacji strumień się zamknie poprawnie graniczy z cudem. Podobnie ma się sprawa z wait i notify (hmm, deadlocki w tym kodzie istnieją naprawdę, tylko nikt się za bardzo nie przejmuje bo filozofia "let it break" ratuje im d*). Serio, tego kodu się chyba nie da naprawić :D

1

Jestem w trakcie (właściwie już w 95% drogi) pisania serwisu dla kolegi. Napisałem sobie wszystko ładnie na lokalnym serverze na laptopie po czym załadowałem na ftp. A tu zonk, flashowy odtwarzacz nie działa. Nie działał tak przez około miesiąc. Za chiny ludowe nie wiedziałem czemu. Przeczytałem po stokroć manuale, nawet przejrzałem kod źródłowy tego odtwarzacz, bez skutku.

W końcu postanowiłem zmienić odtwarzacz (na jwplayer bodajże), i wtedy dostałem olśnienia. Aż się trochę zacząłem z tego powodu śmiać. Okazało się że ten oto odtwarzacz nie był kompatybilny z plikami które miały spację w nazwie (%20).

0

Nie do końca mnie to spotkało, ale patrząc na to pytanie na StackOverflow:
http://stackoverflow.com/questions/11774099/legal-identifiers-in-java

To jest poprawny warunek w Javie: if ( ︳ ︳| ︳!= ︳ ︳ ︳|| ︴) :D

0

Niby moja wina przez niedopatrzenie, z drugiej strony nie pomyślałbym, że coś może się tak bezsensownie zachowywać.

Zadzwonił wczoraj do mnie klient, że mu się Chrome zawiesza przy próbie zatwierdzenia danych w formularzu. Zrobiłem taką minę: :|, no ale nic, testuję i faktycznie tak jest.
Formularz jest dość nietypowy - wyświetla kierownikowi czas pracy podległych mu pracowników w danym tygodniu z podziałem na projekty i dni. Przy 7 projektach i 10 pracownikach, powstaje w ten sposób 500 inputów (tylko do odczytu). Poza nimi formularz zawiera sporo pól hidden (do każdej wartości trzeba zapamiętać jej ID z bazy, wersję, itp.), łącznie jest ich 2500.
Moim błędem było omyłkowe dołączenie jQuery validate do tego formularza. Skrypt usiłował to walidować wszystkie te inputy, co pewno trwało tak długo, że przeglądarka go ubijała. Ale po co w ogóle walidować pola tylko do odczytu czy wręcz w ogóle niewidoczne, to ja nie rozumiem? :/
Ponadto, view engine domyślnie renderuje inputy (wszystkie, także te readonly i hidden) z szeregiem atrybutów opisujących komunikaty błędów, coś w tym rodzaju:

<input data-val="true" data-val-number="The field UserId must be a number." data-val-required="The UserId field is required." id="Projects_0__UserRows_0__UserId" name="Projects[0].UserRows[0].UserId" type="hidden" value="2" />

Na szczęście łatwo było to wyłączyć (łatwo, bo chciałem zupełnie, gdybym chciał dla pojedynczych pól, nie byłoby już łatwo), dzięki czemu rozmiar strony zmniejszył się o 1/3. Teraz zastanawiam się, czy nie uciąć następnej 1/5 zmieniając nazwy właściwości z Projects na P, UserRows na UR i Days na D. ;)

0

Tak sobie czytam i przypomniała mi się sytuacji chyba sprzed 2 tygodni. Robię pewien program w Qt, miałem się wybrać około południa do klienta u którego chciałem zrobić kolejny etap wdrożenia. Oczywiście zamiast dzień wcześniej to kompilowałem program z 2h przed wyjściem :] Sytuacja jest o tyle ciekawa, że piszę aplikacja pod Linuksem, a docelowo ma działać pod Windows. Z rana zgrałem repozytorium z Linuksa na pendrive'a i odpaliłem sobie laptopa bo tam mam Win 7. Oczywiście źle sobie kliknąłem i na lapku odpalił mi się Linux - uruchomiłem go ponownie, tym razem wybrałem Windows. Zgrałem repozytorium na dysk, włączam Qt Creator i odpalam qmake. Ok - wszystko działa. Klikam na Przebuduj i... w kółko komunikat że odpalane jest qmake dla projektu. Czekam chwilę i dalej to samo. Ciągle są generowane Makefile. Padaka totalna - czas leci, a nie mogę skompilować programu do exe. Ciśnienie podskoczyło. Kombinowałem różne rzeczy i nić. W końcu zapytałem Google - przejrzałem parę wyników i co? Okazało się, że na Windows miałem czas przesunięty o 2h wstecz - to się stało podczas uruchomienia Linuksa, który ustawił czas UTC na płycie, a Windows traktuje go jako lokalny(czy na odwrót). Zmieniłem czas na aktualny, odpaliłem builda i poszło :]

0

WTF w "plikacji kasy enterprise" z którą mam do czynienia, czyli jak wkurwić do cna 10 000 klientów: po update przestały działać zamówienia i usługi klientów. 3 dni walczenia z supportem, developerami aplikacji itp o to przyczyna błędu:

"Skrypt synchronizujący pomijał usługi, w których w nazwach [wszystkich możliwych nazwach, tj. nazwa usługi, usługobiorcy, adresu usługobiorcy lub dostawcy usług] znajdowały się literki 'e', 't' lub 's'."

Delikatnie rzecz ujmując, z literek "zabronionych" układa się ślicznie "test"... Pomyśleć że taki kod wszedł do produkcji, nikt nic nie zauważył, a my jesteśmy jednymi z mniejszych użytkowników... Super.

0

Dzisiaj widziałem taki kod:
if(!!v)
:)

0
simonnam napisał(a):

Dzisiaj widziałem taki kod:
if(!!v)
:)

w ifie raczej bez sensu ale ogólnie w C++ konstrukcja !! może być przydatna. Dodaj do zmiennej x jeden jeżeli y jest różna od zera.
Można tak:
if(y) x++;
lub tak:
x += !!y
Pierwsza wersja w po skompilowaniu to cmp i jump druga wersja to tylko operacja bitowa - a więc szybciej niż jump.

0

Podsumowując, pogłoski o głupocie kompilatorów są mocno przesadzone.

Zależy jakich. W VS2010:

x += !!y;
00401012 F7 D8                neg         eax  
00401014 1B C0                sbb         eax,eax  
00401016 F7 D8                neg         eax  
00401018 03 F0                add         esi,eax 

		if(y) x++;
00401012 85 C0                test        eax,eax  
00401014 74 01                je          main+17h (401017h)  
00401016 46                   inc         esi
0

Nawiązując do poprzednich dwóch:
Kod, wersja 1:

#include <stdio.h>

int main()
{
    int a;
    scanf("%d", &a);
    int b = !!a; // <-- 
    printf("%d", a);
}

Wygenerowany kod, interesująca część:

xor     eax, eax
mov     edx, [esp+20h+var_4]
test    edx, edx
setnz   al
mov     [esp+20h+var_1C], eax

Kod, wersja 2:

#include <stdio.h>

int main()
{
    int a;
    scanf("%d", &a);
    int b = 0;
    if (a) b++; // <--
    printf("%d", b);
}

Wygenerowany kod, interesująca część (to samo):

xor     eax, eax
mov     edx, [esp+20h+var_4]
test    edx, edx
setnz   al
mov     [esp+20h+var_1C], eax

Podsumowując, pogłoski o głupocie kompilatorów są mocno przesadzone.
Kompilowane za pomocą GCC 4.6.2 z -O3

Edit: dla wszystkich którzy przeczytali wersję przed edycją - pomyliłem się przy wklejaniu kodu w poście (dwa razy ten sam, hmm) - poprawiono...

Edit2: można też prościej (podobnie na -O2):

D:\>g++ a.cpp -o a.exe -O3

D:\>g++ b.cpp -o b.exe -O3

D:\>fc a.exe b.exe
Porównywanie plików a.exe i B.EXE
00000088: 1F 22
000000D8: 7C 80
00007DDE: 61 62
0

Jeżeli chodzi o różnicę pomiędzy kodem z if a bez to jest:

void f1(int test, int &x) {
  if(test) {
    x++;
  }
}
_Z2f1iRi:
.LFB1006:
	.cfi_startproc
	test	edi, edi
	je	.L1
	inc	DWORD PTR [rsi]
.L1:
	rep
	ret
	.cfi_endproc

Natomiast:

void f2(int test, int &x) {
  x += !!test;
}
_Z2f2iRi:
.LFB1007:
	.cfi_startproc
	xor	eax, eax
	test	edi, edi
	setne	al
	add	DWORD PTR [rsi], eax
	ret
	.cfi_endproc

GCC 4.6.3 z -O2.

2 użytkowników online, w tym zalogowanych: 1, gości: 1