Programistyczne WTF jakie Was spotkały

Programistyczne WTF jakie Was spotkały
Azarien
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 godziny
6
Azarien
@MarekR22: "System, pomimo wysokiej skuteczności szacowanej na 90%, nie zauważa jednej z irackich rakiet Scud, która trafia w koszary i zabija 28 amerykańskich żołnierzy." — no zaraz, 90% znaczy że raz na dziesięć nie pomoże, więc to nie żaden błąd tylko ficzer.
Shalom
Wbrew pozorom clock-drift to jest spory problem w niektórych systemach ;) Bo system sterowania opiera się o wewnętrzny zegar i o deltę czasu od ostatniej synchronizacji. Wyobraź sobie że chcesz dokować do stacji kosmicznej i jej pozycję określasz na podstawie informacji GPS którą ci wysyła. Dość istotny jest znacznik czasu bo musisz oszacować kiedy stacja była w tym miejscu, szczególnie kiedy musisz dokować z bardzo dużą precyzją. A teraz wyobraź sobie że po kilku dniach lotu masz kilka sekund różnicy :D
msm
Administrator
  • Rejestracja:prawie 16 lat
  • Ostatnio:4 miesiące
3

<font size="6">WTFy administracyjne.</span>

Afterthought: nie wiem czy mi się wydaje, czy ostatnio moje posty osiągają średnią długość typowego posta @bswierczynskiego. Swoją drogą ciężko było pisać tego posta spokojnie, pamiętając ile czasu zostało zmarnowane przez to co opisuje :P.

<font size="4">MySQL: pierwsza krew</span>
Z jakiegoś dziwnego powodu, podczas przenoszenia serwera zapytanie SQLowe w module mikroblogów wykonywało się w nieskończoność. Konkretnie zapytanie odpowiedzialne za polecanie podobnych mikroblogów do już obserwowanych.

Co dziwne, bo dokładnie to samo zapytanie na dokładnie tej samej wersji SQL na poprzednim serwerze wykonywało się ~~0.3 sekundy.
Więc próbujemy debugować, wklejamy to zapytanie do konsoli mysqlowej:

Kopiuj
SELECT t1.*, GROUP_CONCAT(skill_name ORDER BY skill_order) AS skills
FROM (
        SELECT user.user_id, user.user_name, user_photo, user_bio, COUNT(uf1.follower_id) AS followers
        FROM `user`
        LEFT JOIN user_follower uf1 ON uf1.user_id = user.user_id
        WHERE user.user_id IN(SELECT microblog_user FROM microblog WHERE microblog_parent IS NULL GROUP BY microblog_user)
        GROUP BY user.user_id
        ORDER BY followers) AS t1
JOIN user_skill ON skill_user = t1.user_id
LEFT JOIN user_follower uf2 ON uf2.follower_id = 37200 AND uf2.user_id = t1.user_id
WHERE uf2.user_id IS NULL AND t1.user_id != 37200
GROUP BY skill_user
ORDER BY RAND()
LIMIT 5;

Czas wykonania: nieskończoność (ok, czekałem tylko kilka minut).

Dlaczego? Zapytajmy MySQL!

Kopiuj
EXPLAIN SELECT t1.*, GROUP_CONCAT(skill_name ORDER BY skill_order) AS skills
FROM (
        SELECT user.user_id, user.user_name, user_photo, user_bio, COUNT(uf1.follower_id) AS followers
        FROM `user`
        LEFT JOIN user_follower uf1 ON uf1.user_id = user.user_id
        WHERE user.user_id IN(SELECT microblog_user FROM microblog WHERE microblog_parent IS NULL GROUP BY microblog_user)
        GROUP BY user.user_id
        ORDER BY followers) AS t1
JOIN user_skill ON skill_user = t1.user_id
LEFT JOIN user_follower uf2 ON uf2.follower_id = 37200 AND uf2.user_id = t1.user_id
WHERE uf2.user_id IS NULL AND t1.user_id != 37200
GROUP BY skill_user
ORDER BY RAND()
LIMIT 5;

Czas wykonania: nieskończoność.
Tak, EXPLAIN wykonuje się nieskończona ilość czasu. Jeśli mysql nie potrafi nawet ułożyć planu zapytania, to prawdopodobnie samego zapytania szybko nie wykona ;).

No to co, upraszczamy zapytanie.

Kopiuj
EXPLAIN SELECT t1.*
FROM (
    SELECT user.user_id
    FROM `user`
    LEFT JOIN user_follower uf1 ON uf1.user_id = user.user_id
    WHERE user.user_id IN(SELECT microblog_user FROM microblog WHERE microblog_parent IS NULL GROUP BY microblog_user)) AS t1;

Czas wykonania: nieskończoność.
Tak, EXPLAIN takiego prostego zapytania wykonuje się nieskończona ilość czasu.

Ale:

Kopiuj
EXPLAIN SELECT user.user_id
    FROM `user`
    LEFT JOIN user_follower uf1 ON uf1.user_id = user.user_id
    WHERE user.user_id IN(SELECT microblog_user FROM microblog WHERE microblog_parent IS NULL GROUP BY microblog_user)

Czas wykonania: natychmiastowo.

Czyli EXPLAIN SELECT * FROM (X) powoduje timeout, ale samo X już nie.

Co jeszcze ciekawsze, jeśli w timeoutującym zapytaniu:

  • usunąć WHERE IS NULL
  • albo zamienić (SELECT microblog_user FROM microblog WHERE microblog_parent IS NULL GROUP BY microblog_user) na (SELECT DISTINCT microblog_user FROM microblog WHERE microblog_parent IS NULL)

Wszystko działa błyskawicznie.

Nie mieliśmy siły (z @Adam Boduch) walczyć z mysqlem.
Rozwiązanie problemu: usunięcie feature polecanych mikroblogów ;). Nikt tego nawet nie zauważył więc pomysł uznaję za dobry.

<font size="4">iptables.up</span>

A to z kolei psuło krew @Revowi. Napisaliśmy sobie mały skrypt automatycznie wykonujący pewne operacje na iptables. Jest 24 marca, godzina 23:25

rev napisał(a)

[2015-03-24 23:25:02] iptables.up -> /etc/iptables.up

rev napisał(a)

[2015-03-24 23:29:17]
teraz zróbmy sztuczkę
i wykonajmy reboot
zobaczymy co domyślnie wstanie

I skrypt ten się nie wykonał:

rev napisał(a)

[2015-03-25 22:20:42] po prostu w ogóle iptables.up nie zawołało się przy eth0 up

rev napisał(a)

[2015-03-29 22:19:11] ani nie wywołuje /etc/iptables.up ani nie dodaje tej route'y

Rozpoczynamy debugowanie, bo kiedyś trzeba:

rev napisał(a)

[2015-04-17 20:30:05] do /etc/iptables.up dodałem echo date >> /root/iptables-log na koniec

rev napisał(a)

[2015-04-17 20:50:33] root@4p ~ # cat iptables-log
pusto :/

rev napisał(a)

[2015-04-17 22:45:22] nie utworzył /root/iptables_stdout

rev napisał(a)

[2015-04-17 22:52:22] root@4p ~ # /etc/iptables.up
root@4p ~ # cat iptables_stdout
root@4p ~ #

I rozwiązanie problemu (o pierwszej w nocy): z dokumentacji run-parts (wykorzystywane przez runnera tego czegoś):

If the −−lsbsysinit option is not given then the names must consist entirely of upper and lower case letters, digits, underscores, and hyphens.

Kto to wymyślił. Jeśli do run-parts nie zostanie przekazany parametr --lsbsysinit, to po cichu ignoruje każdy plik z kropką gdziekolwiek w nazwie.
Nie potrafię oddać jak bardzo absurdalne to jest (albo było, o 1 w nocy po 4 godzinach szukania błędu). Równie dobrze mógłby ignorować pliki zaczynające się na 'a', o ile nie dostanie parametru --donotignore.

A co robi opcja --lsbsysinit? Ustala jeszcze fajniejsze zasady!

If the --lsbsysinit option is given, then the names must not end in
.dpkg-old or .dpkg-dist or .dpkg-new or .dpkg-tmp, and must belong to
one or more of the following namespaces: the LANANA-assigned namespace
(^[a-z0-9]+$); the LSB hierarchical and reserved namespaces
(^?([a-z0-9.]+-)+[a-z0-9]+$); and the Debian cron script namespace
(^[a-z0-9][a-z0-9-]*$).

Poważnie, co to za program, kto to wymyślił :P.

http://manpages.ubuntu.com/manpages/gutsy/man8/run-parts.8.html

(Nie tylko my się nacieliśmy - http://askubuntu.com/questions/406126/why-is-ifup-not-running-all-of-the-if-pre-up-d-scripts)

<font size="4">MySQL powraca</span>

Na koniec honorable mention dla mysqla:

  1. apt-get upgrade mysqla się nie udaje i rzuca błędami. Usługa mysqla przestaje odpowiadać na jakiekolwiek prośby i groźby.
  2. z braku innej opcji trzeba ubić proces
  3. po restarcie serwera container lxc z mysqlem w ogóle odmawia posłuszeństwa, i nie chce sie podnieść żadnym sposobem (tylko container z mysql, na 9 containerów łącznie).
  4. stworzyliśmy nowy container i skopiowaliśmy dane mysqla tam wszystkie. Dokładnie ta sama wersja mysqla, etc. Niestety, mysql nie zamierza ich wczytać, bo upiera się że dane są uszkodzone nienaprawialnie, kompletnie bezwartościowe i ogólnie FUBAR'd.
  5. Tak, jedno upgrade i zabicie procesu mysql kompletnie zniszczyło 10 GB danych (oraz cały system przy okazji).
  6. dobrze że mieliśmy świeży backup, bo inaczej trzeba by pisać posty od zera ;).

Nie wiem czy tylko ja mam takie problemy z mysql (inni jakoś z nim żyją i nawet lubią chyba). W każdym razie od tego momentu boję się go dotykać :P.

edytowany 4x, ostatnio: msm
Zobacz pozostałe 5 komentarzy
abrakadaber
abrakadaber
to cóż takiego jest w coyote, że nie zadziała z postgresem?
msm
Cała logika bazodanowa (eventy, triggery, etc, etc), róznice składniowe między mysql i postgres, funkcje które są w mysql a nie ma w postgres, subtelne róznice w działaniu niektórych ficzerów/funkcji, problemy wydajnościowe po migracji, pewnie zmiany w coyote przy łączeniu się z bazą, itd (pierwsze rzeczy jakie mi przyszły do głowy). Nic czego by sie nie dało rozwiązać, ale ktoś by musiał nad tym posiedzieć.
Sarrus
Odnośnie problemów z mysql to wystarczy powiedzieć, że któraś z wersji mysql (nie wiem czy wszystkie) miała w domyślnych ustawieniach włączoną replikację. Polegało to na tym, że pluł do pliku wszystkie inserty i update'y. Dość dynamiczna baza to była więc na drugi dzień skończyło się miejsce na dysku. Gratuluję pomysłowości.
vpiotr
Ja też miałem ciekawy problem z MySQL. Zawieszał się na jakimś konkretnym rekordzie (bieda-hosting = zero możliwości zarządzania procesami). Pomagało skasowanie bazy i odbudowanie z backupu.
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Laska, z Polski
  • Postów:10051
1

Korzystam z aplikacji Messanger facebooka na telefonie. Dzisiaj zmieniłem hasło, ii przy próbie uruchomienia apki dostaję komunikat "Sejsa wygasła. Zaloguj się ponownie", klikam OK, myślę zaloguję się i będzie git.

"Wylogowywanie..."

Bam.

"Sesja wygasła. Zaloguj się ponownie". I tak w kółko. Restart apki nie pomaga. Reinstall apki nie pomaga :| Przywrócenie starego hasła nie pomaga (w sumie czemu miałoby, ale byłem zdesperowany). Nawet nie wiem czy jestem ciągle zalogowany czy nie.

Zobacz pozostałe 13 komentarzy
Marooned
@TomRiddle - która opcja zadziałała?
Riddle
@Marooned Usunięcie konta nie zadziałało, wyczyszczenie danych aplikacji zadziałało (jednak musiałem wyczyścić dane Messanger oraz Facebooka, ubić obie apki, i odpalić Messangera za pośrednictwem Facebooka - odpalenie osobno powodowało kolejne info o wygaśnięciu sesji).
Riddle
Wtf jak dla mnie, skoro Messanger wie że sesja wygasła czemu nie wylogował się/pozwolił mi się wylogować? :/
Marooned
Zgłoś to ;-)
vpiotr
@TomRiddle: brzmi jak horror, a co by było gdyby zablokowało Ci konto? ;-) Jak dobrze jest nie mieć FB...
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Laska, z Polski
  • Postów:10051
12

b1e8e7fe2d.png

fasadin
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
  • Postów:4882
0

Moze mi ktos wytlumaczyc dlaczego tak?

Pracuje obecnie w embedded. Urzadzenie nie ma twardego dysku wiec nie moze nigdzie nic zapisac/odczytac. Ale nadal to nie wyjasnia jednej rzeczy

Jest 15 plikow SearchTableXX.c Gdzie XX to numer. jest 00 jest 10 jest 61 jest 99.

Porownalem plik 60 z 61. przynajmniej 60% jest takie same. Wiec patrze dalej... a roznica jest tylko w danych!
Tak czasami jest
0, 0, 0, 0, 0
a czasami
0, 1, 0, 1, 0

Kazdy plik ma dokladnie te same metody, jedynie co sie rozni to zestaw danych.

Zobacz pozostałe 6 komentarzy
AL
@fasadin, a jest system operacyjny czy to bare-metal? I druga sprawa - może to ma być z racji wydajności zrobione jako look-up table i koniec, nie ma gadki że inaczej? Fakt, nawalenie LUTów wszędzie to jest wtf ale może ktoś miał fantazję optymalizacyjną?
fasadin
jest tam linuks, ale sa tez dwa procesory. Nie wiem dokladnie jak to dziala. Wiem ze nie ma harddrive wiec nie mozna zapisywac tych danych. Tak to jest Look-up table, ale mozna to rozwiazac po prostu lepiej... I tak jak wspominalem. To na pewno nie jest optymalizacja (jakbys zobaczyl kod, to bys zrozumial ;))
AL
@fasadin jak się dowiesz po co tak to zrobili to daj znać, zawsze czegoś nowego się można dowiedzieć [;
fasadin
watpie zebym sie dowiedzial, bo autor tutaj nie pracuje juz. Dodatkowo nikt nie wie po co to tak... wiele zlych rzeczy moglbym opowiadac o tej firmie, ale... to bezsensu ;)
fasadin
dowiedzialem sie. Ten kto pisal byl slabym programista ;) (mimo ze pracowal tam jako senior developer...)
MarekR22
Moderator C/C++
  • Rejestracja:około 17 lat
  • Ostatnio:27 minut
1

Nie ma to jak dobrze nadane nazwy properties.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 1x, ostatnio: MarekR22
2
Sarrus
Dla mnie nazwy metod są prawdziwym wtfem. Używam na co dzień log4net i nie mam problemu z pisaniem Debug, Info, Warn, Error. Żadnego
KU
  • Rejestracja:prawie 10 lat
  • Ostatnio:ponad 9 lat
  • Postów:21
0

Apropos dzisiejszej debaty : www.mamprawowiedziec.pl czyli strona podana przez kandydata podobno zawiesiła się niemal natychmiastowo :D i nie działa do teraz

Azarien
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 godziny
9

Bug który denerwował od kilku tygodni przestał się reprodukować akurat dnia, w którym postanowiłem się za niego zabrać.

Koziołek
Nie dość, że wkurzający to jeszcze cwaniak
KA
dużą masz kolejkę ;]
Olamagato
Albo się skurczybyk bunkruje, albo wiedział, że ma przesrane...;D
vpiotr
Klasyczny Heisenbug.
fasadin
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
  • Postów:4882
8

przegladam kod w obecnej pracy i widze takie cos

Kopiuj
void hack_interesting() 

ehh a oni nadal twierdza ze code review nie jest potrzebne...

edytowany 1x, ostatnio: fasadin
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
14

W ramach tego artykułu (błąd w systemie PKP Intercity umożliwiający przejazdy za darmo) - kod źródłowy JSów do stronki zakupu biletów na przejazdy pekape intersiti:
https://bilet.intercity.pl/irez/js/irez.js

W tym kodzie jest wszystko: od getStationNameByIbnr, po sprTylkoLiteryICyfry.

Bonus:

komentarz na Niebezpiecznik.pl napisał(a)

Najbardziej mi się podoba skrupulatność przy upewnianiu się, czy w ciągu nie występuje czwórka i bardzo liberalne podejście do szóstki:

(…) && wyraz.charAt(i) != “3” && wyraz.charAt(i) != “4” && wyraz.charAt(i) != “4” && wyraz.charAt(i) != “5” && wyraz.charAt(i) != “7” && wyraz.charAt(i) != “8” && (…)


szalonyfacet
ogolnie caly ten javascript z ktorego ten kwaitek pochodzi jest magicznym WTF: https://bilet.intercity.pl/irez/js/irez.js funkcja kompletnosc_danych ma az 8 werjis ( anazwa rozni sie cyfra z tylu lub literka:P
flowCRANE
Najlepsze są lokalne zmienne NO i OK - występują w każdej funkcji i zawsze posiadają takie same wartości;
satirev
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 4 lata
7

W robocie piszemy bibliotekę dla programistów gier. Dokumentujemy ją dość skrupulatnie poza tym standardowy use case jest podany "na tacy". No ale to nie wystarcza ; < Nie ma tygodnia żebyśmy nie dostali maila od jakiś magika, który:

  1. Nie czyta dokumentacji i dziwi się, że mu nie działa
  2. Czyta dokumentację bez zrozumienia i dziwi się, że mu nie działa
  3. Czyta dokumentację ale i tak robi po swojemu i dziwi się, że mu nie działa
  4. Miesza runtimy i dziwi się, że mu nie działa
  5. Nie zna podstaw C++/C# i dziwi się, że mu nie działa
  6. Pisze swój kod w oparciu o UB i dziwi się, że mu nie działa

Bardzo rzadko dostajemy zgłoszenia o faktycznych bugach w naszej bibliotece (a jak podeślą nam core dumpa to w ogóle mamy święto ; > ).
Konkluzja, nie tylko newbie na tym forum nie czytają dokumentacji ; /

Zobacz pozostały 1 komentarz
abrakadaber
abrakadaber
Ja sie zawsze zastanawialem co taki delikwent potem mowi - "ja wiem, ale myslalem, ze zadziala..."?
vpiotr
może warto dodać tryb kompilacji HIGH_PERFORMANCE (zastępujący obecny RELEASE), a w RELEASE dodać wszystkie możliwe walidacje w API zgłaszane wyjątkami? Może się przydać: http://www.apibook.com/blog/
HI
vpiotr czyli dla wyjątku XXX mogę zwrócić coś w stylu "Spójrz na drugą stronę manuala" ;) ?
vpiotr
czyli zamiast pisania manuala "parametr x powinien być > a i < b" zwracasz taki wyjątek. A jeśli funkcja A musi być wywołana przed B to zwracasz "B wywołane bez A". itd. Nie wiem jakie dokładnie case'y ma Satirev, ale jeden z rozdziałów ww książki to "Difficult to Misuse".
satirev
@vpiotr dzięki za link z info nt tej książki, jak gdzieś ją znajdę to z chęcią poczytam.
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
13

WTF z dzisiaj. Dostaje taska żeby popatrzeć na pewien skrypt pythonowy który ponoć ślimaczy się dla dużych plików wejściowych (XML). Sugestia jest taka że to pewnie minidom zamula i może warto użyć innej biblioteki. Co mówi profiler? Że getElementsByTagName jest wołane kilkadziesiąt milionów razy. Co widzę w kodzie? 3 linijki odpowiedzialne za usunięcie danych z pewnej sekcji pliku XML:

Kopiuj
header_end = int(table.getAttribute("ss:HeaderEnd"))
while len(table.getElementsByTagName("Row")) > header_end:
    table.removeChild(table.getElementsByTagName("Row")[header_end])

Warto wspomnieć że getElementsByTagName musi przelecieć przez wszystkie dzieci danego elementu żeby je odszukać...

Edit: dla jasności, ten kod przegląda XMLa żeby znaleźć wszystkie elementy Row, jeśli nadal jest ich za dużo to znów przegląda XMLa żeby znaleźć wszystkie elementy Row, usuwa jeden i powtarza cały proces od nowa.

Więc jeśli Rowów było do usunięcia 10 to najpierw przeglądamy 2 razy 10 elementów, potem 2 razy 9 elementów potem... czyli O(2*n2) podczas gdy w rzeczywistości można O(n).


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
Zobacz pozostałe 2 komentarze
Koziołek
A ty myślisz jak to działa? Przelecisz raz i potem zero pewności, czy aby ten raz to nie było za mało, a tak eliminacja na podstawie wielu pomiarów.
OK
"przelecieć wszystkie dzieci"
Freerider
Jak w tańcu z gwiazdami. W każdym odcinku ktoś odpada, ale tańczą wszyscy co tydzień.
somekind
Przelatywania wszystkich bardziej bym się w Holandii niż Szwajcarii spodziewał. ;)
datdata
Komentarze do tego wpisu <3
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
12

Opowieści ciąg dalszy :D Lead powiedział żebym spróbował ten pythonowy kod troche ogarnąć bo "jakby co" to my go niestety supportujemy. O tym że mam przed sobą plik na 4k linii ze zmiennymi globalnymi i bez jednej klasy to nawet nie wspominam, ot życie ;] Ale z ciekawostek:

  • Ziomek, nie wiedząc czemu, napisał własny "logger", gorszy od najgorszego loggera ;] Nie zrobił żadnego enuma do rozpoznawania poziomu logowania. Po prostu na pałe dokleja zawsze jeden z globalnych stringów z prefixami, a potem ten jego logger robi drabinkę takich oto cudów:
Kopiuj
    if message.startswith(DEBUG_PREFIX):
        if not globals()["DEBUG_MODE"]:
            flagPrintMessage = False
        pMessage = "[DEBUG] " + message[6:]
    if pMessage.startswith(WARNING_PREFIX):
        if globals()["NO_WARNING"]:
            flagPrintMessage = False
        pMessage = "[WARNING] " + message[8:]
...

Dostanę raka oczu od patrzenia na to ;] I żeby ktoś nie miał wątpliwości, ten kod powstał dużo później niż dodano do pythona pakiet logging...

  • Gość miał jakąś awersje do tworzenia nowych metod. Są tu takie po ~1k linii kodu. Co ciekawe chyba zauważył że źle mu sie to czyta ale zamiast podzielic na metody wstawiał w kodzie takie oto ramki:

=============================================

#  CREATE A LIST WITH PLUGINS TO USE AND ASSOCIATED DATA
# =============================================

cośtam cośtam...
# =============================================
# READ DATA USING THE APPROPRIATE PLUG-IN
# =============================================
cośtam cośtam

Przynajmniej jest mi łatwiej wyszukać miejsca gdzie trzeba zrobić extract-method ;]

edit: Widzę w historii commitów że robił jakiś "code refactoring". W opisie taska na jirze widnieją ładne rzeczy -> sensowne nazwy dla zmiennych, podzielenie funkcji na mniejsze, wydzielenie klas, unit testy. A co widzę w zmianach podczepionych pod tego taska? Zmianę w nazwach zmiennych w stylu pluginName -> plgName. Powoli zaczynam podejrzewać że ten gość to jakiś troll był i on tak celowo... ;]


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
fasadin
1k+ funkcji to ja mam kilka... jedna z nich jest main. na szczescie dzisiaj dostalem maila z innej firmy ze przygotowywuja dla mnie oferte ;)
several
@fasadin to długo Ty tam miejsca nie zagrzałeś ;p
fasadin
no bedzie 5 miesiecy. W piatek ide podpisywac umowe z nowa firma. Wpadlem z deszczu pod rynne. Mam nadzieje ze teraz bedzie lepiej...
RE
Moderator
  • Rejestracja:około 18 lat
  • Ostatnio:11 miesięcy
5

Podczas analizowania kodu związanego z działaniem wielowątkowości i asynchroniczności w .NET:

Kopiuj
#undef SleepEx
status = SleepEx(0,TRUE);    
#define SleepEx(a,b) Dont_Use_SleepEx(a,b)

https://github.com/dotnet/coreclr/blob/4cf8a6b082d9bb1789facd996d8265d3908757b2/src/vm/win32threadpool.cpp#L2980
Pierwszy hack miał na celu zablokowanie użycia SleepEx, ale później się jednak okazało, że w kilku miejscach trzeba go użyć i nic sensownego nie chciało im się już z tym robić ;).

grzesiek51114
grzesiek51114
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:2442
0

Kiedyś, jak moja siostra była na studiach to dostali zadanie w grupie: narysuj choinkę korzystając w pętli i z funkcji printf. Wiadomo takie tam standardowe zadanie w C. No i siedzi ta moja siostra i pisze te pętle i pisze i pisze, a ja się pytam "Co Ty tam robisz?" No to ona mi na to, że zadanie mają na studiach, że taką choineczkę mają narysować :) No to ja mówię, że to chyba łatwe jest prawda? Po tym wszystkim zapytała: "A Ty umiesz?" No to odpowiedziałem: "Pewnie!"

Hehe to pokaż:

Kopiuj
#include <stdio.h>

int main(){
    printf("    *    \n");
    printf("   ***   \n");
    printf("  *****  \n");
    printf(" ******* \n");
    printf("*********\n");
    printf("   ***   \n");
    return 0;
}

Naturalnie g**no znałem się na programowaniu jak tylko w basicu input i print umiałem, a to samo w C :P

Zobacz pozostałe 4 komentarze
grzesiek51114
grzesiek51114
Straszne. A to już nie mogę napisać w tym temacie nawet jak zajmuję się pisaniem programów hobbystycznie? :) Może ja też spotkałem jakieś WTF, którymi chciałbym się podzielić etc.
LukeJL
Wg mnie to nie jest aż tak istotne. Programowanie to czynność. Trochę jak kierowanie samochodem. Czasem każdego, kto kieruje samochodem nazywa się kierowcą, mimo że nie musi wcale być zawodowym kierowcą.
HE
ale pętli to to nie widzę ;p
unikalna_nazwa
@several: "programistyczne" a nie "programistów"; czyli związane z programowaniem. Tak czy inaczej post średni ;)
grzesiek51114
grzesiek51114
No trudno :-) Rzecz jasna to ja popełniłem tez zacny kod. A poziom jak poziom.
Wizzie
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 7 lat
8

Kod ma za zadanie wylosować datę urodzenia. W kodzie ręcznie wpisane tabele:

Kopiuj
new Array(
'01 ',
'02 ',
'03 ',
'04 ',
'05 ',
'06 ',
'07 ',
'08 ',
'09 ',
'10',
'11',
'12',
// itd. aż do 30
)

Tak samo z miesiącami (także zapisane cyframi) i latami.

abrakadaber
abrakadaber
a jak daleko w przyszłość i przeszłość wybiegł ten mędrzec i czy uwzględnił lata przestępne?
Wizzie
niestety, ktoś może urodzić się 30 lutego, ale dla tych z 31 lipca mam już złe wiadomości :D
HI
"// itd. aż do 30" - aż albo tylko do 30 ;)
Wizzie
w tym kodzie jest kilka więcej wtfów, może kiedyś opiszę
katelx
  • Rejestracja:prawie 10 lat
  • Ostatnio:4 miesiące
  • Lokalizacja:Hong Kong
6

zasada ograniczonego zaufania wobec generatora identifykatorow (useId to hash z identyfikatorami w uzyciu):

Kopiuj
public int GetNewUniqueId(UniqueIdGenerator g)
{
    int cnt = 0;
    int newId = 0;
    while(cnt < 15)
    {
        newId = g.GenerateNewUniqueId();
        if(newId != 0 && !useId.Contains(newId)) { cnt = 15; useId.Add(newId); }
        cnt++;
        
    }
    if(newId != 0) return newId;
    else return -1;
}
HI
Tylko troszkę "ograniczone" bo założył, że w tym "paru" razach generator da radę ;
unikalna_nazwa
dla mnie największym WTFem tutaj mimo wszystko jest sposób wyjścia z pętli
KR
A to UUID nie można było użyć czy co? Ludzie to mają dziwne problemy.
katelx
jako drobny smaczek dodam ze GenerateNewUniqueId() pobieralo nowy id z bazy danych :)
vpiotr
Sposób wyjścia z pętli w stylu COBOL. cnt mogło mieć na początku wartość 15 to było by krótsze. Pytanie w ilu miejscach obsłużone jest (-1)...
fasadin
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
  • Postów:4882
7

Przyszedl Project Leader.

Mowi czy moglbym zrobic jakis dokument na temat jak unikac bledow w C++.
Ja sie pytam "ale, ze jak, ze co?"
"No bo byl blad bo zmienna byla nie zainicjalizowana" (w c++ jak sie nie zainicializuje zmiennej to ma "randomowa" wartosc co wie chyba kazdy programista C/C++)
"aaahaa... oookeeej moge zrobic"

Nie, nie pisal to zadnej stazysta/junior. W firmie sa sami "seniorzy".

Na moja rade
"to czemu nie sprawdzane sa warningi, a IDE nie jest ustawione tak by krzyczalo o tym? No i co z Code-review? Dzieki temu kod bedzie duzo lepszej jakosci i nie bedzie takich bledow"
"no wlasnie jakbys mogl napisac taki dokument ze trzeba usuwac warningi... a code review zabierze za duzo czasu"

No tak... bo debugowanie przez X dni glupiego problemu nie bierze WCALE czasu...

Zobacz pozostałe 5 komentarzy
fasadin
dzieki grzesiek :)
grzesiek51114
grzesiek51114
Nie musisz pisać papierów. Daj im linka i już ;-)
fasadin
Ty chyba zartujesz. To jest robota na kilka godzin ;) Uwierz mi wole robic to przez 3 godziny niz przekopywac sie przez kopalnie WTFow... Jak to moj znajomy powiedzial "kurt cobain code. shoot yourself, but not in leg... in head!" zreszta jutro ide podpisywac umowe z nowym pracodawca...
twonek
jak się przegląda wątki w C++ i Newbie (z tagiem C++) z dowolnego okresu 2 tygodni, to też się ma taki dokument ;)
Koziołek
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:około miesiąc
  • Lokalizacja:Stacktrace
  • Postów:6821
1

Asynchroniczne przetwarzanie plików excela. Kolega stwierdził, że to zrobi i będzie śmigało na wątkach i będzie super. Podpowiedziałem, żeby użył @Async na metodzie przetwarzającej, bo w ten sposób zrobi część biznesową, a technikaliami zajmie się spring... Poniżej efekt prac:

Kopiuj
        @Async
public Future<Boolean> uploadAllWorkingDocumentsForReportGeneration(byte[] workingDocument, Long reports, Long userId) throws ParseException {
    if (processingReportNumber != null) {
        throw new IllegalStateException("Processing is busy. Please wait until its finished. Current processing report number is: " + processingReportNumber.get());
    }

    ///... walidacje parametrów
    // Reset counter and apply "lock"
    logger.info("Start processing multiple reports upload");
    processingReportNumber = new AtomicInteger(0);

    for (Report report : reports.getReports()) {

        processingReportNumber.addAndGet(1);
        logger.info("Processing report number " + processingReportNumber.get() + " with id " + report.getReportId());
// okreslanie sheet name i innych takich
        logger.info("Fetching sheet: " + sheetName);

        Workbook singleWorkbook = createWorkbookFromExcelSheetByReport(workingDocument, sheetName);
        // trochę kodu nieistotnego dla nas pobiera dodatkowe dane dla parsera
        for (RCG rcg: rcgs ) {
               documentParser.parse(report, user, rcg, singleWorkbook);
        }
    }
    // Release "lock"
    logger.info("Multiple reports processing finished");
    processingReportNumber = null;
    return new AsyncResult<>(true);
}

metoda oczywiście wykona się w osobnym wątku, ale po pierwsze będzie można ją tylko odpalić raz na system co oznacza, że dwóch userów nie będzie mogło na raz parsować swoich arkuszy. po drugie samo procesowanie nadal jest jednowątkowe i jak trwało godzinę tak będzie trwać godzinę...

// edit: kod został jedynie pozbawiony elementów pozwalających na łatwe odgadnięcie do czego służy. Wyciąłem też nieznaczące elementy, które swoją drogą nie powinny tam być, ale to inna bajka...


Sięgam tam, gdzie wzrok nie sięga… a tam NullPointerException
edytowany 1x, ostatnio: Koziołek
niezdecydowany
niezdecydowany
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 9 lat
  • Lokalizacja:Bieszczady
0

@Koziołek czy to jest kod żywcem wyjęty z kontrolera/serwisu czy go przerobiłeś ? jeżeli nie, to dlaczego kolega w czymś co może być wywołane z wielu wątków robi:

dzikiego locka, bo co to jest ???

Kopiuj
///... walidacje parametrów
    // Reset counter and apply "lock"
    logger.info("Start processing multiple reports upload");
    processingReportNumber = new AtomicInteger(0);

przecież to jest podręcznikowy race condition...


"Perhaps surprisingly, concurrent programming isn’t so much about threads or
locks, any more than civil engineering is about rivets and I-beams."
edytowany 1x, ostatnio: niezdecydowany
Koziołek
Nie mnie pytaj a jego. To, że jest to RC to ja wiem, ale jako, że piątek to nie mam ani siły ani ochoty w tym grzebać. Paradoksalnie przeróbka tego na np. Akkę była by prosta. BTW czy do ciebie się odzywali ode mnie?
niezdecydowany
niezdecydowany
@KolegaKoziołka proszę się poprawić :D tak z ciekawości,@KolegaKoziołka autor tego kodu to junior(strzelam)/middle(mało prawdopodobne)/senior(to nie możliwe) ?? BTW: nie, nikt nie pisał :) chyba się nie podobam ;)
Koziołek
Ok. kolega jest Señor. Jak nikt nie pisał to muszę się przejść do naszego haremu (dział rekrutacji to same dziewczyny).
niezdecydowany
niezdecydowany
puść mu film z Seligą.
somekind
Ilość gównianego kodu produkowanego przez juniorów i seniorów jest taka sama, po prostu seniorzy produkują g**no w trudniejszych taskach.
Zellus
  • Rejestracja:prawie 13 lat
  • Ostatnio:około 4 lata
  • Lokalizacja:Wrocław
  • Postów:474
0

Kochany Javascript :)
W komentarzu rezultat wyświetlony w przeglądarce:

Kopiuj
alert(true&&null&&true); //null
alert(true&&0&&true);	 //0
alert(true&&1&&true);	 //true

Jest na to jakieś sensowne wytłumaczenie?
Tzn. nie zmienia to niby tak dużo, ale jeżeli ktoś dalej da result != resultOfSthElse, to ciężko to wychwycić...

edytowany 1x, ostatnio: Zellus
Zobacz pozostałe 24 komentarze
LukeJL
swoją drogą - jak przetłumaczyć mental overhead na polski? To jeden z tych zwrotów, których znaczenie rozumiem, ale nie znam polskiego odpowiednika.
LukeJL
hmm, może "wysiłek umysłowy"?
Zellus
Tak w sumie, to już od drugiego komentarza użytkownika @Koziołek, gdy zrozumiałem jak ten mechanizm działa, jestem przekonany co do akceptowalności takiego rozwiązania i nie traktuję już tego jako wtf. Ale usuwanie postów jest złem, a przenoszenie go gdzieś poza wątek przez moderatora chyba też mija się z celem.
twonek
bardziej mi pasuje "narzut umysłowy"
Koziołek
@LukeJL "nadmierny wysiłek umysłowy", albo "narzut myślowy". W naszym języku chyba nie ma odpowiedniego tłumaczenia. Najbliższym pojęciem jest "przekombinowanie", ale to potoczne określenie.
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około godziny
  • Lokalizacja:Wrocław
1

jQuery validation, uznaje 123,456.781 za liczbę, ale jednocześnie twierdzi, że jest ona mniejsza niż 1.

Kopiuj
// http://jqueryvalidation.org/number-method/
number: function( value, element ) {
	return this.optional( element ) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value );
},
// http://jqueryvalidation.org/range-method/
range: function( value, element, param ) {
	return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );
},

Czemu w jednym przypadku uznają przecinki jako separator tysięczny, a w drugim o tym zapomnieli?


Po dopracowaniu rozwiązania każdy będzie mógł założyć własny drzewiasty wątek.
spartanPAGE
  • Rejestracja:prawie 12 lat
  • Ostatnio:około 16 godzin
1

Nie wiem co o tym myśleć.
rly.png

  • rly.png (25 KB) - ściągnięć: 118
edytowany 2x, ostatnio: spartanPAGE
Patryk27
Mylić czasowniki.
spartanPAGE
@Patryk27 Nie tylko komputer przegrzewa się w upalne dni :P
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około godziny
  • Lokalizacja:Wrocław
12

Jest sobie pewne forum internetowe (nie mogę napisać jakie) z funkcją raportowania. Moderator na podglądzie zgłoszonego raportu widzi:

  1. Id
  2. link do zgłaszanego posta
  3. treść raportu
  4. nazwę użytkownika zgłaszającego raport - jest ona jednocześnie linkiem do profilu tego użytkownika
  5. adres IP użytkownika zgłaszającego raport - jest on jednocześnie linkiem do jego zbanowania. (Jego - zgłaszającego raport, nie autora postu.)

Po dopracowaniu rozwiązania każdy będzie mógł założyć własny drzewiasty wątek.
edytowany 1x, ostatnio: somekind
szopenfx
Najbardziej użyteczne funkcje po 1 kliku nic tylko pozazdrościć :P
szopenfx
aa to zmienia postać rzeczy... ale przynajmniej drugi raz nie będzie tyłka zawracał
flowCRANE
Donosicielstwo nie opłaca się ;)
EroSanin
CO to za forum? Antykonfident.pl ?:D
CI
  • Rejestracja:prawie 11 lat
  • Ostatnio:prawie 6 lat
  • Postów:5
0
Kopiuj
    if (rc) and (TotalDoc>0) then
    begin
      //!!!!!!!!!!!!!!!!!!!!!pętla prawdopodobnie do usunięcia!!!!!!!!!!!!!!!!!!
      For i:=0 to impStat.Count-1 do
      begin
        isi:=impStat.ImpStat[i];
        STOO.Caption:='Tworzenie raportu importu';
        EDate:=Now;
        Desc:='1'+#13#10;
        Desc:=Desc+' Import dokument/oddział :  '+ImpData.ImpDocTypeName+' / '+ImpData.ImpOddzialNr+#13#10;
        Desc:=Desc+' Data zbiorów            :  '+DateToStr(ImpData.ImpDate)+#13#10 ;
        Desc:=Desc+' Zbiór                   :  '+ImpData.ImpNAme+#13#10 ;
        Desc:=Desc+' Początek / koniec       :  '+DateTimeToStr(SDate)+' / '+DateTimeToStr(EDate)+#13#10;
        Desc:=Desc+' Dokumentów łącznie      :  '+Format('%0.6d',[isi.TotalDoc])+#13#10;
        Desc:=Desc+' Stron łącznie           :  '+Format('%0.6d',[isi.TotalPages])+#13#10;
        Desc:=Desc+' Dokumentów poprawnych   :  '+Format('%0.6d',[isi.ValidDoc])+#13#10;
        Desc:=Desc+' Dokumentów błędnych     :  '+Format('%0.6d',[isi.InValidDoc])+#13#10;
      end;
      if not rc then
         Writeln( lgo.FileHandle^,Desc);

(...)

end; 

No ale chociaż jest komentarz, że do usunięcia.

Edycja: Komentarz dopisał później ktoś inny, przy przeglądaniu kodu.

edytowany 1x, ostatnio: cinkiwonsz
dzek69
chociaż todo by wpisał
4
Riddle
w sumie to +10% to tak na prawdę *1.1.. więc nie ma się czego czepiać w trzecim.
xxx_xx_x
obstawiam że procent jest liczony z ostatniej wartości na stosie, jeżeli jej nie ma to brane jest "1". Więc masz 100 + 10% => 100 + 100 * 0,1 = 110, następnie 100 + 10% + 10% => 100 + 100 * 0,1 + 1 * 0,1 => 110.1 i ostatnie 10% + 10% + 100 => 10,1 + 10,1 + 100 => 100,2. Dodatkowo stałe są dodawane osobno wiec np 10%+5 + 10%+3 + 10% + 200 => 1 * 0,1 + 5 + 50,1 + 3 + 30,1 + 200 => 208,9
Zellus
I jakby nie patrzeć, ma to praktyczny sens. Zapewne jakieś 80% zapytań wykorzystujących procenty to coś w stylu 59.90+23%, tj. ile będzie wynosiła cena produktu po dodaniu VAT albo po odjęciu rabatu. A tak naprawdę zatrważająco mało osób wie jak działają procenty...
0

@TomRiddle
Chodziło mi o to, że wg. googla 10%+10%+100 != 100+10%+10%
Tzn wyniki z linków 2 i 3 są różne.

flowCRANE
Normalne dodawanie jest przemienne, ale jak zapodasz procenty, to Google coś z nimi kombinuje; Trzeba to wybadać ;)
vpiotr
pierwsza wersja nie ma sensu. 10% z czego?
Koziołek
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:około miesiąc
  • Lokalizacja:Stacktrace
  • Postów:6821
7

Działanie google nie jest WTF-kiem, a wynika ze sposobu ewaluacji i późniejszej interpretacji wyrażeń w języku słabotypowanym. Podobnie jak w Javascript. Problemem jest, podobnie jak w Javascript, nasza nielogiczna intuicja, która wychodzi ze szkolnych regułek o przemienności działań, ale ignoruje różnice typów w operandach. Inaczej mówiąc w czasie nauki przyswoiliśmy sobie, że dodawanie jest przemienne, konwersja typów zmiennoprzecinkowych (ułamków) i całkowitych robiona jest przez nas w locie, a jednocześnie ignorujemy inne typy w działaniach np. procenty albo, czego też byłem świadkiem, waluty.

I, żeby nie było, że post bez WTF-ka spłodziłem...

Kopiuj
public class UploadedReport{

    //... różne pola m.in. to
    @ManyToOne
    @JoinColumn(/*....*/)
    private Blob blob;
}

Klasa Blob to jest nasza klasa, która w środku ma kolekcję raportów do których się odwołuje. W ramach jednego bloba możemy mieć wiele raportów więc mapowanie wygląda jak wygląda. Generalnie wszystko jest OK, bo klient chce mieć te bloby w swoim systemie od razu (by wyglądało, że pobieranie jest szybkie)...

Ruszamy na produkcji i zgłoszenie od klienta "ekran z UploadedReport nie działa". Rzucamy okiem do loga i tam OutOfMemory... WTF??? @ManyToOne jest Eager, ale takie było wymaganie, żeby odsyłać od całą listę z blobami...

Rozwiązanie zagadki:

  1. Stacja deweloperska ma na serwer 4GB RAM
  2. Środowisko testowe ma 1GB RAM na apkę.
  3. Produkcja ma 512MB RAM na całość....

Terminator w kinach, Dragonball w kinach i serwer ma 512MB RAM... który mamy rok?


Sięgam tam, gdzie wzrok nie sięga… a tam NullPointerException
edytowany 1x, ostatnio: Koziołek
Zobacz pozostałe 5 komentarzy
Koziołek
To od sierpnia będzie zrobione... I mówię tu na serio.
flowCRANE
Ja dalej mam 512MiB i na większość rzeczy wystarcza bez problemu ;) @Koziołek - a na jakim oesie stoi produkcja?
Koziołek
Na jakimś customowym linuxie, ale by nie było my tam dość duże excele przewalamy :)
Azarien
to co to musi być za egzotyczna maszyna żeby więcej RAM-u nie można było wsadzić... albo zastąpić nowszym kompem.
Koziołek
@Azarien, maszyna jest zapewne wirtualką w wielkiej serwerowni wielkiego banku. Poszedł mail z prośbą o rekonfigurację... za 3 miesiące pewno będzie zrobione...
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Laska, z Polski
  • Postów:10051
5

paczcie co znalazłem

Kopiuj
if (imageURL == null) {
    try {
      throw new IOException("Resource not found: " + path);
    } catch (IOException ex) {
      ex.printStackTrace();
    }
} else {
    return (new ImageIcon(imageURL, description)).getImage();
}
vpiotr
Logowanie błędnych parametrów i (jakaś) kontynuacja. Może to ten kod z anegdoty (z życia): pytanie: "dlaczego ta aplikacja nie ma logów?" odpowiedź admina: "bo za dużo logowała".
katelx
@vpiotr ja takie cos slyszalam od programistow GUI w poprzedniej firmie, ograniczyli logi o 90% bo duzo miejsca na dysku zajmowaly i klienci narzekali. logow bylo parenascie MB miesiecznie...
Riddle
Tu bardziej chodziło o throw new IOException w blocku catch (IOException).
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)