Cuộc thi ngầm: Cuộc chiến hệ điều hành [đã khép lại]


29

Chúng ta đều biết cuộc thảo luận về hệ điều hành tốt nhất đã gây ra nhiều cuộc chiến nảy lửa như thế nào. Mục tiêu của bạn bây giờ là cung cấp "bằng chứng" quyết định rằng hệ điều hành yêu thích của bạn tốt hơn ... à, không, tốt hơn nhiều, để cung cấp "bằng chứng" quyết định rằng hệ điều hành khác là xấu.

Nhiệm vụ: Viết chương trình, thực hiện một số tính toán và nó hoạt động chính xác trên ít nhất một HĐH và không chính xác trên ít nhất một hệ điều hành khác.

  • chương trình nên thực hiện ít nhất một số tính toán, vì vậy nó phải đọc một số đầu vào đơn giản (tốt nhất là trên đầu vào tiêu chuẩn hoặc nếu từ các tệp nếu bạn muốn, nhưng việc sử dụng sai endian / endian lớn sẽ không chỉ rẻ, mà còn rõ ràng) , và cung cấp một số đầu ra tùy thuộc vào đầu vào. Các tính toán nên có ý nghĩa và hợp lý, ví dụ giải quyết một cuộc sống thực hoặc một vấn đề toán học.
  • bạn nên chỉ định cả hai hệ điều hành, trong đó hệ thống nào sẽ hoạt động chính xác và hệ thống nào sẽ không hoạt động. Cả hai hệ điều hành nên được biết đến và từ cùng một lúc (vì vậy không có DOS 1.0 so với HĐH hiện đại). Bạn nên cung cấp một mô tả ngắn về nguyên nhân của sự khác biệt (đặc biệt nếu bạn nghi ngờ nhiều người sẽ không nhận ra điều đó) trong các thẻ spoiler.

như thế này

  • nguyên nhân của sự khác biệt phải tinh tế, vì vậy không #ifdef _WIN32hoặc tương tự, xin vui lòng! Hãy nhớ rằng, mục tiêu của bạn là "chứng minh" rằng hệ thống cụ thể này là xấu, vì vậy mọi người không thể (ngay lập tức) phát hiện ra mánh khóe của bạn!

  • nếu có một phần rất lạ hoặc rất bất thường trong mã của bạn, bạn phải chứng minh nó trong các bình luận tại sao nó lại ở đó. Tất nhiên, "sự biện minh" này có thể / sẽ là một lời nói dối lớn.

Ghi điểm:

Đây không phải là một sân golf! Mã phải được tổ chức tốt, và giữ đơn giản. Hãy nhớ rằng, mục tiêu của bạn là ẩn một lỗi vào đó để mọi người không nghi ngờ về nó. Mã càng đơn giản, nó càng ít đáng ngờ.

Người chiến thắng sẽ được quyết định bằng phiếu bầu. Nhiều phiếu nhất sau khoảng 10 ngày sau lần gửi hợp lệ đầu tiên sẽ thắng. Nói chung, các câu trả lời nơi mã dễ đọc và dễ hiểu, tuy nhiên lỗi này được ẩn giấu rất kỹ và ngay cả khi được phát hiện, có thể được quy cho một lỗi thay vì ác ý, nên được bỏ phiếu. Tương tự, nó đáng giá hơn nhiều nếu lỗi chỉ gây ra kết quả không chính xác, thay vì chỉ khiến chương trình bị sập hoặc không làm gì cả.

Như thường lệ, tôi không có quyền chọn câu trả lời là người chiến thắng nếu nó không vượt quá 10% hoặc 1 điểm so với câu có nhiều phiếu nhất, trên bất kỳ tiêu chí chủ quan nào.


5
Thú vị make (1)hoạt động đúng trên cơ bản mỗi hộp unix và một số hộp cửa sổ không đúng cách. Không phải vì các hệ điều hành, mà vì các hệ thống tập tin. Bất kỳ hệ thống tệp nào giữ ngày sửa đổi tệp ở độ chính xác thấp có thể không thành công maketrên máy nhanh.
dmckee

1
@dmckee: đây là lý do tại sao tôi vui vì tôi không để mọi thứ mở và bạn phải đọc một số thông tin đầu vào và thực hiện một số phép tính đơn giản.
vsz

10
Bây giờ tôi chỉ mới nhận ra rằng, nhiệm vụ tìm mã ác này có Id là 6666
vsz

3
Đây là hy vọng cho một câu trả lời hoạt động trên Windows và <Chèn phân phối Linux>, nhưng không phải trên Mac.
Casey Kuball

1
Tôi đang bỏ phiếu để đóng câu hỏi này dưới dạng ngoài chủ đề vì các thử thách ngầm không còn thuộc chủ đề trên trang web này. meta.codegolf.stackexchange.com/a/8326/20469
mèo

Câu trả lời:


15

Unix shell + tiện ích tiêu chuẩn

Hãy viết một tập lệnh shell tìm quá trình (thuộc sở hữu của bất kỳ người dùng nào) đã sử dụng nhiều thời gian CPU nhất và giết chết tất cả các quy trình có cùng tên. Tôi cho rằng tính như đọc dữ liệu (từ hệ thống) và thực hiện tính toán. (Hành vi đó có thể hữu ích cho các quy trình tách ra nhiều quy trình, chẳng hạn như bom ngã ba và Google Chromium.)

Sau đây nên là một cách di động để có được tên của quy trình với thời gian CPU lớn nhất (tôi đã cố gắng tránh các chủ nghĩa Linux rõ ràng nhưng chưa thử nghiệm nó trên Solaris):

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

Vì vậy, kịch bản của chúng tôi chỉ đơn giản là

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

Chạy bằng root để có kết quả tốt nhất, để nó có thể giết các tiến trình từ những người dùng khác.

Linux và BSD

Điều này hoạt động trên Linux và sẽ hoạt động trên BSD, vì killall arggiết chết các quy trình được đặt tên arg.

Solaris

Tuy nhiên, trên Solaris, nếu người dùng tình cờ chạy một chương trình có tên 9trong một vòng lặp vô hạn, tập lệnh sẽ đưa hệ thống xuống . Điều này là do:

Trên Solaris, killall argcó nghĩa là tiêu diệt tất cả các quá trình với tín hiệu arg. Vì vậy, dòng lệnh trở thành killall 9. Là 9số của SIGKILL trên Solaris , điều này sẽ giết tất cả các quy trình và do đó làm sập hệ thống.

Lưu ý

Vấn đề tiêm shell này không áp dụng trên Linux, bởi vì mặc dù người dùng độc hại có thể cung cấp một số đối số đặc biệt như -KILLtên quy trình, killall -KILLsẽ vô hại in thông báo sử dụng.


3
killallkhông một ví dụ. Đó chỉ là hai chương trình khác nhau có cùng tên. Mỗi phiên bản đang hoạt động đúng.
dmckee

7
Có, nhưng tập lệnh shell không hoạt động đúng.
Ốc cơ khí

12
Bạn có để ý cách Chromium và bom ngã ba có thể so sánh được không? ;)
kaoD

7
@kaoD: Điểm khác biệt chính là bom ngã ba sử dụng ít bộ nhớ hơn.
Ốc cơ khí

1
Chỉ cần lưu ý rằng không có những điều như "Google Chromium": Sự Google Chrome trình duyệt được dựa trên mã nguồn mở Chromium trình duyệt, nhưng chỉ có cựu chứa mã Google cụ thể và có tên của Google kèm theo.
Anko

18

Con trăn

Chương trình này mở hình ảnh được chỉ định trên dòng lệnh và hiển thị nó.

import Image
import sys

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

Hoạt động trên linux, không hoạt động trên windows.

Điều này là do cách các cửa sổ mở tập tin. Chế độ nhị phân phải được chỉ định để hoạt động đúng trên tất cả các hệ điều hành.


4
Chương trình nên thực hiện một số tính toán và hiển thị kết quả. Trên một hệ điều hành cụ thể, nó cũng sẽ hiển thị một số kết quả, nhưng không chính xác. Vâng, với một số trò chơi chữ thông minh, bạn có thể lập luận rằng đây chính xác là những gì chương trình của bạn đang làm, nhưng tôi nghĩ đó là một sự cố ý diễn giải sai các quy tắc. Tuy nhiên, cuối cùng, các cử tri quyết định.
vsz

5

Little Endian (Intel x86) so với Big Endian (IBM Power7)

Bất kỳ định dạng tệp nào có số lượng nhị phân nhiều byte theo thứ tự không lưu trữ đều có nguy cơ bị hiểu sai. Đây là một chức năng lấy âm thanh thô, giả sử được trích xuất từ ​​tệp WAV (là định dạng tệp cuối nhỏ của Microsoft), giảm một nửa biên độ và xuất ra âm thanh bị suy giảm.

#include <stdio.h>

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

Trong các máy endian nhỏ, điều này hoạt động rất tốt, nhưng trong các máy endian lớn, đó là một thảm họa. Ví dụ

01001101 11001110 -> CE4D (little endian format)

Chuyển sang phải trên endian nhỏ:

00100110 01100111 -> 8726 (correct)

Chuyển sang phải trên endian lớn:

00100110 11100111 -> E726 (not correct)

Lưu ý rằng một số nybble là chính xác! Trên thực tế, đó là cơ hội 50:50 rằng đầu ra sẽ chính xác, tùy thuộc vào việc bit âm ít nhất của mẫu âm thanh là 0 hay 1!

Vì vậy, khi bạn nghe âm thanh này, nó giống như một nửa biên độ nhưng với một số âm thanh chói tai lớn bị che khuất. Khá giật mình nếu bạn không chuẩn bị cho nó!


5

GTB

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

Trên máy tính, nó hoạt động, nhưng trên máy tính TI-84 của tôi thì không. Tại sao?

Trên máy tính, RAM tràn và có khả năng bị xóa, trong khi trên trình giả lập cho Windows, RAM không thể bị tràn bởi trình giả lập do phân bổ hạn chế.


Nó làm gì?
Ilmari Karonen

Có một spoiler (hộp màu vàng) trong câu hỏi mà bạn có thể di chuột qua để xem văn bản ẩn.
TimTech

4
Có, nhưng nó làm gì khi RAM không tràn? Nó thực sự "làm một số tính toán", như câu hỏi yêu cầu, và nếu vậy, cái gì?
Ilmari Karonen

@IlmariKaronen Nó chỉ nối các chuỗi. (Tất nhiên, bạn có thể chỉ định)
Timtech

4

C

Giải pháp cho vấn đề 100 (về trình tự Collatz) được Thẩm phán trực tuyến UVa chấp nhận.

Tuy nhiên, mã này chỉ hoạt động chính xác trên nền tảng * nix do longloại được triển khai dưới dạng số nguyên có chữ ký 64 bit. Trên Windows , mã gọi hành vi không xác định, vì longloại được triển khai dưới dạng số nguyên có chữ ký 32 bit, trong khi một trong các giá trị trung gian trong cyc()hàm cần ít nhất 32 bit để biểu diễn.

#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;
}

Một cách khác để làm cho điều này không tương thích hơn nữa là đặt mảng lbên trong main()và thực hiện các thay đổi tương ứng cho cyc()chức năng. Vì tệp thực thi được đặt thành yêu cầu cho ngăn xếp 2 MB theo mặc định trên Windows, chương trình gặp sự cố ngay lập tức.


2

Con trăn

Tôi đã bắt gặp điều này trên StackOverflow khi tìm kiếm thời gian chờ đầu vào.

 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 

Điều này không hoạt động cho Windows.


Tại sao điều này không hoạt động trong Windows? Tôi có đoán đúng không vì Windows không hỗ trợ POSIX SIG? Sau đó, vấn đề chỉ là các thư viện tiêu chuẩn của Python phơi bày chức năng cho cả hai hệ điều hành. Tôi không nghĩ rằng nó tuân theo tinh thần của thách thức (ví dụ: ngã ba của Python sẽ không hoạt động vì lý do rõ ràng) nhưng đó là lỗ hổng của Python (cộng với thực tế là nó được giải thích), chứ không phải Windows '. Ví dụ: bao gồm conio.hsẽ có tác dụng tương tự, nhưng C thậm chí sẽ không biên dịch.
kaoD

@kaoD: Thành thật mà nói, tôi cũng không chắc tại sao nó không hoạt động trong Windows. Có thể Linux có một số tính năng mà Windows không có, vì vậy điều này có thể được triển khai trong Linux chứ không phải Windows.
beary605

Sau đó, đó là những gì tôi đoán: bạn đang sử dụng chức năng POSIX được hiển thị bởi Python. IMHO điều này không phù hợp như một câu trả lời vì lý do đã nêu trước đây, nhưng này, tôi chỉ là một con kiến ​​khác ở thuộc địa;) Những gì bạn thấy là "lỗi" của Python, không phải Windows. Thấy điều này: docs.python.org/library/signal.html#signal.signal
kaoD

API Windows không cung cấp khả năng đọc có thể hủy trên một đường ống từ trong luồng.
Joshua

0

Linux + bash + GNU coreutils

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

Điều này sẽ xóa thư mục gốc và mọi thứ trong đó không tồn tại trong Windows, ngay cả khi bạn cài đặt bash cho Windows :)


Điều này hoạt động trên Windows ngay bây giờ khi Windows có hệ thống con Linux được tích hợp. (Tôi nghĩ, sẽ không thử nó)
Pavel

@Pavel Khá đơn giản để mở cmd.exevà gõ rmđể thấy rằng nó không hoạt động.
MD XF
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.