Konkurs podstępny: Wojna OS [zamknięta]


29

Wszyscy wiemy, w jaki sposób dyskusja o tym, który system operacyjny jest najlepszy, wywołała wiele wojen ogniowych. Twoim celem jest teraz dostarczenie decydującego „dowodu”, że twój ulubiony system operacyjny jest lepszy ... ach, nie, znacznie lepiej, dostarczenie decydującego „dowodu”, że inny system operacyjny jest zły.

Zadanie: Napisz program, który wykonuje pewne obliczenia i działa poprawnie na co najmniej jednym systemie operacyjnym, a niepoprawnie na co najmniej innym.

  • program powinien wykonać co najmniej kilka obliczeń, więc musi odczytać proste dane wejściowe (najlepiej na standardowym wejściu, lub jeśli z plików, jeśli chcesz, ale niewłaściwe użycie małego endiana / dużego endiana byłoby nie tylko tanie, ale także oczywiste) , i zapewniają pewną moc wyjściową w zależności od danych wejściowych. Obliczenia powinny być znaczące i uzasadnione, na przykład rozwiązanie prawdziwego życia lub problemu matematycznego.
  • powinieneś określić oba systemy operacyjne, wskazując, na którym będzie działał poprawnie, a na którym nie. Oba systemy operacyjne powinny być dobrze znane i mniej więcej w tym samym czasie (więc nie ma DOS 1.0 w porównaniu do nowoczesnego systemu operacyjnego). Zaleca się krótki opis przyczyny różnicy (zwłaszcza jeśli podejrzewasz, że wiele osób nie zdaje sobie z tego sprawy) w tagach spoiler.

lubię to

  • przyczyna różnicy musi być subtelna, więc nie, #ifdef _WIN32lub podobna, proszę! Pamiętaj, że Twoim celem jest „udowodnienie”, że ten konkretny system jest zły, więc ludzie nie powinni (natychmiast) dostrzegać twojej sztuczki!

  • jeśli w twoim kodzie jest bardzo dziwna lub bardzo nietypowa część, musisz uzasadnić to w komentarzach, dlaczego tak jest. Oczywiście to „uzasadnienie” może / będzie wielkim kłamstwem.

Punktacja:

To nie jest golf! Kod powinien być dobrze zorganizowany i prosty. Pamiętaj, że Twoim celem jest ukrywanie w nim błędu, aby ludzie go nie podejrzewali. Im prostszy kod, tym mniej podejrzliwy.

Zwycięzca zostanie wyłoniony w drodze głosowania. Najwięcej głosów po około 10 dniach od pierwszego ważnego zgłoszenia wygrywa. Ogólnie rzecz biorąc, odpowiedzi, w których kod jest łatwy do odczytania i zrozumienia, ale błąd jest dobrze ukryty, a nawet jeśli zostanie wykryty, można przypisać błędowi, a nie złośliwości, należy głosować. Podobnie, powinno być warte znacznie więcej, jeśli błąd powoduje tylko niepoprawny wynik, a nie tylko powoduje awarię programu lub nic nie robi.

Jak zwykle odmawiam sobie prawa wyboru odpowiedzi jako zwycięzcy, jeśli nie będzie ona wyższa niż 10% lub 1 punkt poniżej tej z największą liczbą głosów, według dowolnych subiektywnych kryteriów.


5
Co ciekawe make (1)działa poprawnie na zasadniczo każdym pudełku unixowym i nieprawidłowo na niektórych oknach Windows. Nie z powodu systemów operacyjnych, ale z powodu systemów plików. Każdy system plików, który utrzymuje daty modyfikacji plików z niską precyzją, może nie działać makepoprawnie na szybkim komputerze.
dmckee,

1
@dmckee: dlatego cieszę się, że nie zostawiłem wszystkiego otwartego, a ty musisz przeczytać jakieś dane wejściowe i wykonać proste obliczenia.
vsz

10
Doszedłem do wniosku, że to poszukiwanie złego kodu ma identyfikator 6666
vsz

3
Oto nadzieja na odpowiedź, która działa w systemie Windows i <Insert Linux Distribution>, ale nie na Macu.
Casey Kuball

1
Głosuję za zamknięciem tego pytania jako nie na temat, ponieważ słabe wyzwania nie są już na ten temat na tej stronie. meta.codegolf.stackexchange.com/a/8326/20469
kot

Odpowiedzi:


15

Powłoka Unix + standardowe narzędzia

Napiszmy skrypt powłoki, który znajdzie proces (należący do dowolnego użytkownika), który wykorzystał najwięcej czasu procesora, i zabije wszystkie procesy o tej samej nazwie. Przypuszczam, że liczy się to jako wczytywanie danych (z systemu) i wykonywanie obliczeń. (Takie zachowanie może być przydatne w przypadku procesów, które dzielą wiele procesów, takich jak bomby widełkowe i Google Chromium).

Poniższy opis powinien być przenośnym sposobem na uzyskanie nazwy procesu o największym czasie procesora (starałem się unikać oczywistych Linuxism, ale nie testowałem go na Solarisie):

ps -A -o time= -o comm= | sort | tail -n 1 | cut -d ' ' -f 2

Więc nasz skrypt jest po prostu

killall `ps -A -o time= -o comm= | sort | tail -n 1 | cut -d ' ' -f 2`

Uruchom jako root, aby uzyskać najlepsze wyniki, aby mógł zabijać procesy innych użytkowników.

Linux i BSD

Działa to w systemie Linux i powinno działać na BSD, ponieważ killall argzabija nazwane procesy arg.

Solaris

Jednak w systemie Solaris, jeśli użytkownik uruchamia program o nazwie 9w nieskończonej pętli, skrypt spowoduje wyłączenie systemu . To dlatego, że:

W systemie Solaris killall argoznacza zabicie wszystkich procesów za pomocą sygnału arg. Tak więc wiersz poleceń staje się killall 9. Podobnie 9jak liczba SIGKILL w systemie Solaris , spowoduje to zabicie wszystkich procesów, a tym samym spowolnienie systemu.

NB

Ten problem wstrzykiwania powłoki nie dotyczy systemu Linux, ponieważ nawet jeśli złośliwy użytkownik może podać jakiś specjalny argument, taki -KILLjak nazwa procesu, killall -KILLnieszkodliwie wydrukuje komunikat o użyciu.


3
killallto nie przykład. To tylko dwa różne programy o tej samej nazwie. Każda wersja działa poprawnie.
dmckee,

7
Tak, ale skrypt powłoki nie działa poprawnie.
Ślimak mechaniczny

12
Czy zauważyłeś, że bomby chromu i widelca są porównywalne? ;)
kaoD

7
@kaoD: Kluczowa różnica polega na tym, że bomby widłowe zużywają mniej pamięci.
Ślimak mechaniczny

1
Wystarczy zauważyć, że nie ma czegoś takiego jak „Google Chrom”: w Google Chrome przeglądarka jest oparta na open source Chromium przeglądarki, ale tylko dawny zawiera kod dla Google i ma nazwę Google załączeniu.
Anko

18

Pyton

Ten program otwiera obraz określony w wierszu poleceń i wyświetla go.

import Image
import sys

with open(sys.argv[1]) as f:
    im = Image.open(f)
    im.show()

Działa na systemie Linux, nie działa na systemie Windows.

Wynika to ze sposobu, w jaki system Windows otwiera pliki. Należy określić tryb binarny, aby działał poprawnie we wszystkich systemach operacyjnych.


4
Program powinien wykonać pewne obliczenia i wyświetlić wyniki. W określonym systemie operacyjnym powinien także wyświetlać niektóre wyniki, ale niepoprawne. Tak, przy sprytnej grze słów można argumentować, że to właśnie robi Twój program, ale myślę, że jest to celowa błędna interpretacja zasad. Jednak ostatecznie wyborcy decydują.
vsz

5

Little Endian (Intel x86) vs. Big Endian (IBM Power7)

Każdy format pliku, w którym występują wielobajtowe ilości binarne w kolejności innej niż host, może zostać źle zinterpretowany. Oto funkcja, która pobiera surowy dźwięk, powiedzmy wyodrębniony z pliku WAV (który jest formatem Microsoft Endian), zmniejsza o połowę amplitudę i wysyła tłumiony dźwięk.

#include <stdio.h>

int main()
{
    short audio;
    while (fread(&audio, sizeof(short), 1, stdin))
    {
        audio >>= 1;
        fwrite(&audio, sizeof(short), 1, stdout);
    }
    return 0;
}

W małych maszynach Endian działa to świetnie, ale w dużych maszynach Endian jest to katastrofa. Na przykład

01001101 11001110 -> CE4D (little endian format)

Przesuń w prawo na małym endianie:

00100110 01100111 -> 8726 (correct)

Przesuń w prawo na big endian:

00100110 11100111 -> E726 (not correct)

Pamiętaj, że niektóre z nybbles są poprawne! W rzeczywistości jest szansa 50:50, że wyjście będzie poprawne, w zależności od tego, czy najmniej znaczący fragment próbki dźwięku ma wartość 0 czy 1!

Więc kiedy słuchasz tego dźwięku, jest to jak połowa amplitudy, ale z szumem głośnym, wysokim tonem. Zaskakujące, jeśli nie jesteś na to przygotowany!


5

GTB

:"-→_[_+_→_]

Na komputerze to działa, ale na moim kalkulatorze TI-84 tak nie jest. Czemu?

W kalkulatorze pamięć RAM przepełnia się i jest potencjalnie usuwana, podczas gdy w emulatorze dla systemu Windows pamięć RAM nie może zostać przepełniona przez emulator z powodu ograniczonego przydziału.


Co to robi?
Ilmari Karonen

W pytaniu znajduje się spoiler (żółte pole), który można najechać myszką, aby zobaczyć ukryty tekst.
Timtech

4
Tak, ale co robi to, czego nie przepełnia pamięć RAM ? Czy faktycznie „wykonuje pewne obliczenia”, takie jak pytanie, a jeśli tak, to co?
Ilmari Karonen

@IlmariKaronen Po prostu łączy łańcuchy. (Możesz oczywiście określić)
Timtech

4

do

To rozwiązanie problemu 100 (o sekwencji Collatza) jest akceptowane przez UVa Online Judge.

Jednak ten kod działa poprawnie tylko na platformie * nix , ponieważ longtyp jest implementowany jako 64-bitowa liczba całkowita ze znakiem. W systemie Windows kod wywołuje niezdefiniowane zachowanie, ponieważ longtyp jest implementowany jako 32-bitowa liczba całkowita ze znakiem, podczas gdy jedna z wartości pośrednich w cyc()funkcji musi reprezentować co najmniej 32-bit.

#include <stdio.h>

#define swap(a, b, t) t __tmp__ = a; a = b; b = __tmp__;
#define M 1000000

short l[M] = {0, 1};

int cyc(long n) { // HERE
    if (n < M && l[n]) return l[n];
    n = n & 0x1 ? 3 * n + 1 : n >> 1;
    return n < M ? (l[n] = cyc(n)) + 1 : cyc(n) + 1;
}

int max(int a, int b) { return a > b ? a : b; }

int main() {
    #ifndef ONLINE_JUDGE
    // freopen("input.txt", "r", stdin);
    #endif
    int i, j, m;
    while (scanf("%d %d", &i, &j) == 2) {
          printf("%d %d ", i, j);
          if (i > j) { swap(i, j, int); }
          for (m = 0; i <= j; i++)
              m = max(m, cyc(i));
          printf("%d\n", m);
    }

    return 0;
}

Innym sposobem uczynienia tego bardziej niezgodnym jest umieszczenie tablicy w lśrodku main()i dokonanie odpowiednich zmian w cyc()funkcji. Ponieważ plik wykonywalny jest domyślnie ustawiony tak, aby żądał stosu 2 MB w systemie Windows, program natychmiast ulega awarii.


2

Pyton

Natknąłem się na to na StackOverflow, kiedy szukałem limitów wejściowych.

 import signal 
 TIMEOUT = 5

 def interrupted(signum, frame): 
     print 'interrupted!' 
 signal.signal(signal.SIGALRM, interrupted) 

 def input(): 
     try: 
         print 'You have 5 seconds to type in your stuff...' 
         foo = raw_input() 
         return foo 
     except: 
         return

 signal.alarm(TIMEOUT) 
 s = input()
 signal.alarm(0) 
 print 'You typed', s 

To nie działa w systemie Windows.


Dlaczego to nie działa w systemie Windows? Czy zgaduję, że to dlatego, że Windows nie obsługuje POSIX SIG? To tylko kwestia standardowych bibliotek Pythona udostępniających funkcjonalność dla obu systemów operacyjnych. Nie sądzę, że podąża za duchem wyzwania (np. Widelec Pythona nie będzie działał z oczywistych powodów), ale to wada Pythona (plus fakt, że jest interpretowany), a nie Windows. Np .: włączenie conio.hmiałoby taki sam efekt, ale C nawet się nie skompiluje.
kaoD

@kaoD: Szczerze mówiąc, nie jestem pewien, dlaczego nie działa również w systemie Windows. Być może Linux ma pewne funkcje, których nie ma w systemie Windows, więc można to zaimplementować w systemie Linux, a nie Windows.
beary605

Zgaduję: używasz funkcjonalności POSIX ujawnionej przez Python. IMHO to nie pasuje do odpowiedzi z powodu wcześniej podanego powodu, ale hej, jestem tylko kolejną mrówką w kolonii;) To, co widzisz, to „wina” Pythona, a nie Windows. Zobacz: docs.python.org/library/signal.html#signal.signal
kaoD

Interfejs API systemu Windows nie zapewnia możliwości anulowania odczytu na potoku z poziomu wątku.
Joshua,

0

Linux + bash + GNU coreutils

rm --no-preserve-root -R -dir /

Spowoduje to usunięcie folderu głównego i wszystkiego, co nie istnieje w systemie Windows, nawet jeśli zainstalujesz bash dla systemu Windows :)


Działa to w systemie Windows teraz, gdy system Windows ma wbudowany podsystem Linux. (Myślę, że nie spróbuję)
Pavel

@Pavel Całkiem proste do otwarcia cmd.exei pisania, rmaby zobaczyć, że to nie działa.
MD XF,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.