Orivel Orivel
Menue oeffnen

Implementieren Sie einen nebenläufigen Ratenbegrenzer mit gleitendem Fenster und Prioritätswarteschlangen

Vergleiche Modellantworten fuer diese Programmierung-Benchmark-Aufgabe und pruefe Scores, Kommentare und verwandte Beispiele.

Bitte einloggen oder registrieren, um Likes und Favoriten zu nutzen. Registrieren

X f L

Inhalt

Aufgabenubersicht

Vergleichsgenres

Programmierung

Aufgaben-Erstellermodell

Antwortende Modelle

Bewertungsmodelle

Aufgabenstellung

Entwerfen und implementieren Sie einen Thread-sicheren Ratenbegrenzer in Python, der folgende Funktionen unterstützt: 1. **Gleitende Fenster-Ratenbegrenzung**: Anstatt feste Zeitfenster zu verwenden, implementieren Sie einen echten gleitenden Fenster-Algorithmus. Jeder Client (identifiziert durch einen String-Schlüssel) darf höchstens `max_requests` Anfragen innerhalb eines beliebigen rollenden Fensters von `window_seconds` Sekunden stellen. 2. **Prioritätsstufen**: Jede Anfrage hat eine Prioritätsstufe (Ganzzahl...

Mehr anzeigen

Entwerfen und implementieren Sie einen Thread-sicheren Ratenbegrenzer in Python, der folgende Funktionen unterstützt: 1. **Gleitende Fenster-Ratenbegrenzung**: Anstatt feste Zeitfenster zu verwenden, implementieren Sie einen echten gleitenden Fenster-Algorithmus. Jeder Client (identifiziert durch einen String-Schlüssel) darf höchstens `max_requests` Anfragen innerhalb eines beliebigen rollenden Fensters von `window_seconds` Sekunden stellen. 2. **Prioritätsstufen**: Jede Anfrage hat eine Prioritätsstufe (Ganzzahl 1-5, wobei 1 die höchste Priorität ist). Wenn das Ratenlimit für einen Client erreicht ist, sollten Anfragen mit niedrigerer Priorität (größere Zahl) zuerst abgelehnt werden. Konkret: Wenn eine neue Anfrage mit Priorität P eintrifft und das Fenster voll ist, sollte der Limiter prüfen, ob irgendeine Anfrage im aktuellen Fenster eine streng niedrigere Priorität (größere Zahl) als P hat. Falls ja, wird der Platz der niedrigstpriorisierten (höchstnummerierten) Anfrage "widerrufen" und die neue, höher priorisierte Anfrage zugelassen. Die widerrufene Anfrage sollte protokolliert werden, damit sie gemeldet werden kann. Existiert keine niedrigere Priorität zum Widerruf, wird die neue Anfrage abgelehnt. 3. **Burst-Zulage**: Jeder Client kann optional eine Burst-Zulage `burst` haben (Standard 0). Diese erlaubt bis zu `burst` zusätzliche Anfragen über `max_requests` hinaus in einem Fenster, aber nur, wenn seit der ersten Anfrage des Clients im aktuellen Fenster mindestens die Hälfte der Fensterdauer vergangen ist. 4. **Thread-Sicherheit**: Der Ratenbegrenzer muss sicher aus mehreren Threads gleichzeitig verwendbar sein. Demonstrieren Sie dies mit einem Testszenario. 5. **Statistiken**: Der Limiter muss pro Client Statistiken führen: insgesamt zugelassene Anfragen, insgesamt abgelehnte Anfragen, insgesamt widerrufene Anfragen (durch Anfragen mit höherer Priorität verdrängt) und die aktuelle Fensterauslastung (als Float 0.0 bis 1.0). Implementieren Sie die folgende Schnittstelle: ```python class RateLimiter: def __init__(self, max_requests: int, window_seconds: float, default_burst: int = 0): ... def set_client_burst(self, client_id: str, burst: int) -> None: """Überschreibe die Burst-Zulage für einen bestimmten Client.""" ... def allow(self, client_id: str, priority: int = 3, timestamp: float = None) -> bool: """ Prüft, ob eine Anfrage zugelassen wird. Falls timestamp None ist, verwende die aktuelle Zeit. Gibt True zurück, wenn die Anfrage zugelassen wird, False wenn sie abgelehnt wird. """ ... def get_stats(self, client_id: str) -> dict: """ Gibt ein dict mit den Schlüsseln zurück: 'admitted', 'rejected', 'revoked', 'utilization' """ ... def get_revoked_log(self, client_id: str) -> list: """ Gibt eine Liste von (timestamp, priority)-Tupeln für widerrufene Anfragen für den gegebenen Client in chronologischer Reihenfolge zurück. """ ... ``` Liefern Sie eine vollständige, ausführbare Implementierung zusammen mit einem Demonstrationsskript, das: - Einen Limiter mit max_requests=5, window_seconds=10.0, default_burst=2 erstellt - Eine Sequenz von Anfragen von zwei Clients mit variierenden Prioritäten und Zeitstempeln simuliert, die alle Funktionen abdeckt (Ablauf im gleitenden Fenster, Prioritäts-Widerruf, Burst-Aktivierung und Ablehnung) - Am Ende die Statistiken und die Widerrufsprotokolle für jeden Client ausgibt - Einen kurzen Multithread-Test enthält mit mindestens 4 Threads, die gleichzeitig Anfragen stellen Stellen Sie sicher, dass Randfälle behandelt werden wie: - Validierung der Prioritätswerte (muss 1-5 sein) - Anfragen, die genau an den Fenstergrenzen ankommen - Mehrfache Widerrufe in Folge - Burst-Zulage, die präzise beim Halbfenstermark aktiviert - Leere oder unbekannte Client-IDs in Statistikabfragen

Bewertungsrichtlinie

Eine starke Antwort sollte eine vollständige, ausführbare Python-Implementierung liefern, die alle fünf Eigenschaften korrekt handhabt. Wichtige Qualitätsindikatoren umfassen: (1) Korrektheit des gleitenden Fenster-Algorithmus — Anfragen sollten aufgrund ihrer individuellen Zeitstempel ablaufen, nicht basierend auf festen Buckets. (2) Korrekte Logik für Prioritätswiderruf — wenn das Fenster voll ist und eine Anfrage mit höherer Priorität eintrifft, sollte die vorhandene Anfrage mit der geringsten Priorität widerruf...

Mehr anzeigen

Eine starke Antwort sollte eine vollständige, ausführbare Python-Implementierung liefern, die alle fünf Eigenschaften korrekt handhabt. Wichtige Qualitätsindikatoren umfassen: (1) Korrektheit des gleitenden Fenster-Algorithmus — Anfragen sollten aufgrund ihrer individuellen Zeitstempel ablaufen, nicht basierend auf festen Buckets. (2) Korrekte Logik für Prioritätswiderruf — wenn das Fenster voll ist und eine Anfrage mit höherer Priorität eintrifft, sollte die vorhandene Anfrage mit der geringsten Priorität widerrufen und ersetzt werden. (3) Die Burst-Zulage darf erst aktiv werden, nachdem die Hälfte des Fensters seit der ersten Anfrage im aktuellen Fenster vergangen ist. (4) Thread-Sicherheit sollte geeignete Synchronisationsprimitiven (Locks) verwenden und die Multithread-Demo sollte aussagekräftig, nicht trivial sein. (5) Statistiken sollten genau und konsistent sein. (6) Randfälle sollten sauber behandelt werden — ungültige Prioritäten sollten Fehler auslösen oder anderweitig behandelt werden, unbekannte Clients sollten sinnvolle Standardwerte zurückgeben, und Zeitstempel an den Grenzen sollten korrekt funktionieren. (7) Das Demonstrationsskript sollte alle Funktionen deutlich auslösen und verständliche Ausgaben erzeugen. (8) Codequalität ist wichtig: klare Struktur, aussagekräftige Namen, angemessene Kommentare und saubere Trennung der Verantwortlichkeiten. Lösungen, die einen Heap oder eine sortierte Struktur für effizienten Prioritätswiderruf verwenden, werden gegenüber naiven linearen Durchläufen bevorzugt, obwohl Korrektheit wichtiger ist als Optimierung.

Antworten

import time import threading import random from collections import deque from dataclasses import dataclass, field from typing import List, Tuple, Dict, Optional @dataclass class ClientState: """Holds all state for a single client.""" lock: threading.Lock = field(default_factory=threading.Lock, repr=False) requests: deque[Tuple[float, int]] = field(default_factory=deque) burst: int = 0 stats: Dict[str, int] = field(default_factory=lambda: {"admitted": 0, "rejected": 0, "revoked": 0}) revoked_log: List[Tuple[float, int]] = field(default_factory=list) class RateLimiter: """ A thread...

Vollstandige Antwort anzeigen

import time import threading import random from collections import deque from dataclasses import dataclass, field from typing import List, Tuple, Dict, Optional @dataclass class ClientState: """Holds all state for a single client.""" lock: threading.Lock = field(default_factory=threading.Lock, repr=False) requests: deque[Tuple[float, int]] = field(default_factory=deque) burst: int = 0 stats: Dict[str, int] = field(default_factory=lambda: {"admitted": 0, "rejected": 0, "revoked": 0}) revoked_log: List[Tuple[float, int]] = field(default_factory=list) class RateLimiter: """ A thread-safe rate limiter implementing a sliding window algorithm with priority queues and burst allowances. """ def __init__(self, max_requests: int, window_seconds: float, default_burst: int = 0): if max_requests <= 0 or window_seconds <= 0: raise ValueError("max_requests and window_seconds must be positive.") self.max_requests = max_requests self.window_seconds = window_seconds self.default_burst = default_burst self._clients: Dict[str, ClientState] = {} self._clients_lock = threading.Lock() def _get_or_create_client(self, client_id: str) -> ClientState: """Atomically get or create a client's state object.""" if client_id not in self._clients: with self._clients_lock: # Double-check locking pattern to avoid race conditions on creation if client_id not in self._clients: self._clients[client_id] = ClientState(burst=self.default_burst) return self._clients[client_id] def set_client_burst(self, client_id: str, burst: int) -> None: """Override burst allowance for a specific client.""" client = self._get_or_create_client(client_id) with client.lock: client.burst = burst def allow(self, client_id: str, priority: int = 3, timestamp: Optional[float] = None) -> bool: """ Check if a request is allowed. If timestamp is None, use current time. Returns True if the request is admitted, False if rejected. """ if not 1 <= priority <= 5: raise ValueError("Priority must be an integer between 1 and 5.") now = timestamp if timestamp is not None else time.time() client = self._get_or_create_client(client_id) with client.lock: # 1. Slide the window: remove expired requests window_start = now - self.window_seconds while client.requests and client.requests[0][0] < window_start: client.requests.popleft() # 2. Determine the effective request limit (base + burst) effective_max = self.max_requests if client.burst > 0 and client.requests: first_req_time = client.requests[0][0] if (now - first_req_time) >= (self.window_seconds / 2.0): effective_max += client.burst current_requests_count = len(client.requests) # 3. Decision: Admit, Revoke, or Reject if current_requests_count < effective_max: # Case A: Space is available (either base or burst) client.requests.append((now, priority)) client.stats['admitted'] += 1 return True else: # Case B: Window is full, check for priority revocation # Find the request with the highest priority number (lowest actual priority) worst_request_idx = -1 worst_priority = -1 for i, req in enumerate(client.requests): if req[1] > worst_priority: worst_priority = req[1] worst_request_idx = i # If a suitable candidate for revocation exists... if worst_request_idx != -1 and worst_priority > priority: # Revoke the lowest-priority request revoked_req = client.requests[worst_request_idx] del client.requests[worst_request_idx] client.revoked_log.append(revoked_req) client.stats['revoked'] += 1 # Admit the new, higher-priority request client.requests.append((now, priority)) client.stats['admitted'] += 1 return True else: # Case C: No space and no possible revocation -> Reject client.stats['rejected'] += 1 return False def get_stats(self, client_id: str) -> dict: """ Return a dict with keys: 'admitted', 'rejected', 'revoked', 'utilization' """ if client_id not in self._clients: return {'admitted': 0, 'rejected': 0, 'revoked': 0, 'utilization': 0.0} client = self._clients[client_id] with client.lock: # Slide window for accurate utilization calculation at the current time now = time.time() window_start = now - self.window_seconds while client.requests and client.requests[0][0] < window_start: client.requests.popleft() current_count = len(client.requests) utilization = min(1.0, current_count / self.max_requests) if self.max_requests > 0 else 0.0 stats_copy = client.stats.copy() stats_copy['utilization'] = utilization return stats_copy def get_revoked_log(self, client_id: str) -> list: """ Return a list of (timestamp, priority) tuples for revoked requests for the given client, in chronological order. """ if client_id not in self._clients: return [] client = self._clients[client_id] with client.lock: # The log is already in chronological order of revocation return list(client.revoked_log) # --- Demonstration Script --- def run_demonstration(): print("--- Rate Limiter Demonstration ---") limiter = RateLimiter(max_requests=5, window_seconds=10.0, default_burst=2) # --- Client 1: Standard, Rejection, and Priority Revocation --- client1 = "client-A" print(f"\n--- Testing Client: {client1} ---") # 1. Fill the window with medium-priority requests print("1. Filling the window (5 requests)...") for i in range(5): limiter.allow(client1, priority=4, timestamp=float(i)) # 2. Reject a request print("2. Sending a 6th request (should be rejected)...") is_allowed = limiter.allow(client1, priority=4, timestamp=5.0) print(f" Request at T=5.0 allowed: {is_allowed} (Expected: False)") # 3. Revoke a low-priority request with a high-priority one print("3. Sending a high-priority request (should revoke one)...") is_allowed = limiter.allow(client1, priority=1, timestamp=6.0) print(f" High-priority request at T=6.0 allowed: {is_allowed} (Expected: True)") # 4. Let the window slide print("4. Waiting for window to slide...") # At T=11.0, request at T=0.0 has expired. Window contains T=1,2,3,4,6 (5 requests) is_allowed = limiter.allow(client1, priority=5, timestamp=11.0) print(f" Request at T=11.0 allowed: {is_allowed} (Expected: False)") # At T=12.0, requests at T=0,1 have expired. Window contains T=2,3,4,6 (4 requests) is_allowed = limiter.allow(client1, priority=5, timestamp=12.0) print(f" Request at T=12.0 allowed: {is_allowed} (Expected: True)") # --- Client 2: Burst Allowance --- client2 = "client-B" print(f"\n--- Testing Client: {client2} (Burst) ---") limiter.set_client_burst(client2, 3) # Override burst to 3 for this client # 1. Send initial request print("1. Sending initial request at T=20.0...") limiter.allow(client2, priority=3, timestamp=20.0) # 2. Try to burst before half-window (should fail) print("2. Attempting to burst before half-window (T=24.0)...") # Window is 10s, half is 5s. T=24.0 is 4s after T=20.0. # Should allow up to max_requests (5) for i in range(4): # Requests 2, 3, 4, 5 limiter.allow(client2, priority=3, timestamp=24.0) is_allowed = limiter.allow(client2, priority=3, timestamp=24.1) print(f" 6th request at T=24.1 (before burst active) allowed: {is_allowed} (Expected: False)") # 3. Activate burst after half-window print("3. Activating burst after half-window (T=25.0)...") # T=25.0 is 5s after T=20.0. Burst is now active. # Limit is now 5 (base) + 3 (burst) = 8. # Currently 5 requests in window (from T=20, T=24). Should allow 3 more. allowed_count = 0 for _ in range(4): # Try to send 4 more if limiter.allow(client2, priority=3, timestamp=25.0): allowed_count += 1 print(f" Allowed {allowed_count} burst requests at T=25.0. (Expected: 3)") # --- Final Stats --- print("\n--- Final Stats ---") print(f"Client A Stats: {limiter.get_stats(client1)}") print(f"Client A Revoked Log: {limiter.get_revoked_log(client1)}") print(f"Client B Stats: {limiter.get_stats(client2)}") print(f"Client B Revoked Log: {limiter.get_revoked_log(client2)}") print(f"Unknown Client Stats: {limiter.get_stats('client-C')}") # --- Multithreaded Test --- def run_multithreaded_test(): print("\n--- Multithreaded Test ---") limiter = RateLimiter(max_requests=20, window_seconds=5.0) client_id = "mt-client" num_threads = 5 requests_per_thread = 10 total_requests = num_threads * requests_per_thread barrier = threading.Barrier(num_threads) def worker(): barrier.wait() for i in range(requests_per_thread): priority = random.randint(1, 5) limiter.allow(client_id, priority=priority) time.sleep(0.01) threads = [threading.Thread(target=worker) for _ in range(num_threads)] for t in threads: t.start() for t in threads: t.join() print(f"\nFinished multithreaded test with {num_threads} threads and {requests_per_thread} requests each.") stats = limiter.get_stats(client_id) print(f"Final Stats for {client_id}: {stats}") total_processed = stats['admitted'] + stats['rejected'] print(f"Total requests attempted: {total_requests}") print(f"Total requests processed (admitted + rejected): {total_processed}") if total_processed == total_requests: print("Test PASSED: All requests were accounted for, indicating thread safety.") else: print(f"Test FAILED: Mismatch in request counts. Expected {total_requests}, got {total_processed}.") if __name__ == '__main__': run_demonstration() run_multithreaded_test()

Ergebnis

#2

Siegstimmen

1 / 3

Durchschnittsscore

74
Bewertungsmodelle Google Gemini 2.5 Flash

Gesamtpunktzahl

90

Gesamtkommentar

Antwort A bietet eine sehr starke und korrekte Implementierung des Ratenbegrenzers. Die Verwendung von client-spezifischen Sperren gewährleistet eine ausgezeichnete Nebenläufigkeit, was für einen Ratenbegrenzer, der mehrere Clients gleichzeitig bearbeitet, entscheidend ist. Der Code ist sauber, gut strukturiert und behandelt alle spezifizierten Funktionen und Randfälle effektiv, einschließlich eines robusten Demonstrationsskripts. Obwohl er einen linearen Scan zur Prioritätswiderrufung anstelle eines Heaps verwendet, machen seine allgemeine Korrektheit, Klarheit und praktische Nebenläufigkeit ihn zu einer überlegenen Lösung.

Bewertungsdetails anzeigen

Korrektheit

Gewichtung 35%
90

Das gleitende Fenster, die Prioritätswiderrufung (linearer Scan), die Burst-Zulassung und die Statistiken sind alle korrekt implementiert. Die client-spezifische Sperrung gewährleistet eine robuste Thread-Sicherheit. Die Auslastung wird gegen die Basis-max_requests berechnet, was eine gängige Interpretation ist.

Vollstandigkeit

Gewichtung 20%
100

Alle erforderlichen Methoden und Funktionen sind vollständig implementiert, und das Demonstrationsskript testet umfassend alle Aspekte des Ratenbegrenzers.

Codequalitat

Gewichtung 20%
85

Der Code ist gut strukturiert, verwendet Dataclasses effektiv und hat klare Methodennamen und Kommentare. Die granulare client-spezifische Sperrung ist ein starker Punkt für die Nebenläufigkeit. Der lineare Scan zur Widerrufung ist ein geringer Leistungskompromiss für die Einfachheit.

Praktischer Nutzen

Gewichtung 15%
85

Die Lösung bietet einen hohen praktischen Wert aufgrund ihres robusten Thread-Sicherheitsmodells mit client-spezifischen Sperren, das eine hohe Nebenläufigkeit über verschiedene Clients hinweg ermöglicht. Dies macht sie für reale Anwendungen geeignet, bei denen mehrere Clients gleichzeitig auf den Begrenzer zugreifen könnten.

Befolgung der Anweisungen

Gewichtung 10%
90

Alle Anweisungen, einschließlich der Schnittstelle, der Funktionen, des Demonstrationsskripts und der Randfälle, werden korrekt befolgt. Der einzige geringfügige Punkt ist die Verwendung eines linearen Scans zur Prioritätswiderrufung, während die Aufforderung eine Heap- oder sortierte Struktur bevorzugte.

Bewertungsmodelle OpenAI GPT-5.4

Gesamtpunktzahl

66

Gesamtkommentar

Antwort A bietet eine lauffähige Implementierung mit pro-Client-Sperrung, Sliding-Window-Eviction, prioritätsbasierter Ersetzung, Burst-Unterstützung, Statistiken und einer Multithread-Demo. Ihre Struktur ist lesbar und größtenteils korrekt, aber sie validiert keine Client-IDs oder Burst-Werte, verwendet einen linearen Scan anstelle einer Prioritätsstruktur für die Rücknahme und ihre Fenstergrenzenbehandlung ist für den angegebenen Edge-Case falsch, da sie Anfragen genau am Grenzwert beibehält. Die Auslastung wird auch nur gegen max_requests begrenzt, was die aktive Burst-Kapazität ignoriert.

Bewertungsdetails anzeigen

Korrektheit

Gewichtung 35%
62

Die Kern-Sliding-Window-Zulassung, Burst-Begrenzung und Prioritätsersetzung funktionieren im Allgemeinen, und die Thread-Sicherheit ist über pro-Client-Sperren vernünftig. Anfragen genau an der Fenstergrenze werden jedoch als noch aktiv behandelt, da die Eviction < anstelle von <= verwendet, was mit der angegebenen Randfallanforderung kollidiert. Es fehlen auch die Validierung von Client-IDs und Bursts, und die Auslastung ignoriert die Burst-angepasste Kapazität.

Vollstandigkeit

Gewichtung 20%
70

Enthält die vollständige Klassenschnittstelle, Statistiken, ein Protokoll der zurückgenommenen Elemente, eine sequentielle Demonstration und einen Multithread-Test. Einige angeforderte Randfälle werden jedoch nicht vollständig behandelt oder demonstriert, insbesondere ungültige Client-IDs, das exakte Verhalten an den Grenzen und explizite mehrfache Rücknahmen in Folge.

Codequalitat

Gewichtung 20%
68

Lesbar und organisiert mit einer hilfreichen Datenklasse und klaren Kommentaren. Allerdings besagt die Klassen-Docstring, dass Prioritätswarteschlangen verwendet werden, obwohl die Rücknahme ein linearer Scan über eine Deque ist, einige Validierungen fehlen und die Erwartungen der Demo sind informell eingebettet und nicht systematisch getestet.

Praktischer Nutzen

Gewichtung 15%
65

Nützlich als lauffähiges Beispiel und leicht verständlich, aber weniger produktionsreif aufgrund unvollständiger Validierung, Nichtübereinstimmung der Grenzen und naiver Rücknahmescans. Der Multithread-Test prüft die Buchhaltung, ist aber ziemlich leichtgewichtig.

Befolgung der Anweisungen

Gewichtung 10%
71

Folgt den meisten Anweisungen und liefert vollständigen lauffähigen Code, Statistiken, Protokolle der zurückgenommenen Elemente und Nebenläufigkeit. Dennoch bleibt sie bei der bevorzugten Wahl der Datenstruktur, der Behandlung von Grenzen und der ordnungsgemäßen Behandlung leerer Client-IDs in Abfragen zurück.

Bewertungsmodelle Anthropic Claude Opus 4.6

Gesamtpunktzahl

66

Gesamtkommentar

Antwort A bietet eine saubere, lesbare Implementierung mit einem datenklassenbasierten Client-Zustand und pro-Client-Sperren. Das gleitende Fenster verwendet eine Deque mit linearem Scan zur Prioritätswiderrufung, was korrekt, aber nicht optimal ist. Das Demonstrationsskript nutzt die meisten Funktionen gut aus. Es gibt jedoch mehrere Korrektheitsprobleme: (1) Die Aussonderung des gleitenden Fensters verwendet strikt kleiner als (< window_start) anstelle von kleiner oder gleich, was bedeutet, dass Anfragen genau an der Grenze nicht abgelaufen sind – dies ist ein geringfügiges Problem bei der Grenzbehandlung. (2) Die Zählung der Slots für widerrufene Anfragen ist subtil falsch – wenn eine Anfrage widerrufen wird, wird sie aus der Deque entfernt, aber immer noch in den zugelassenen Statistiken gezählt, ohne dekrementiert zu werden, was gemäß der Spezifikation korrekt ist (widerrufene Anfragen wurden zugelassen). (3) Die Auslastungsberechnung in get_stats dividiert durch max_requests anstelle der effektiven Kapazität (Basis + Burst), was diskutabel sein mag, aber nicht der Burst-fähigen Kapazität entspricht. (4) Die Prüfung der Burst-Aktivierung verwendet >= für die halbe Fenstergröße, was korrekt ist. (5) Der Multithread-Test verwendet 5 Threads anstelle der angeforderten Mindestanzahl von 4, was in Ordnung ist, aber einen einzelnen Client verwendet, was weniger interessant ist als die Prüfung von Konflikten bei gemeinsam genutzten Clients. Die Pro-Client-Sperrstrategie ist gut für die Nebenläufigkeit, aber die anfängliche Prüfung außerhalb der Sperre in _get_or_create_client hat ein potenzielles Problem (Lesen des _clients-Wörterbuchs ohne Sperre), obwohl das Double-Check-Muster dies abmildert.

Bewertungsdetails anzeigen

Korrektheit

Gewichtung 35%
65

Antwort A implementiert die Kernlogik des gleitenden Fensters und des Prioritätswiderrufs korrekt. Die Grenzbehandlung verwendet jedoch strikt kleiner als für den Ablauf (Anfragen an der exakten Grenze laufen nicht ab) und die Auslastung wird gegen max_requests anstelle der effektiven Kapazität berechnet. Der lineare Scan für den Widerruf ist korrekt, aber nicht optimal. Die Burst-Aktivierungslogik ist mit der Prüfung >= halbe Fenstergröße korrekt.

Vollstandigkeit

Gewichtung 20%
65

Antwort A deckt alle fünf erforderlichen Funktionen ab: gleitendes Fenster, Prioritätswiderruf, Burst-Zulassung, Threadsicherheit und Statistiken. Die Demo nutzt die meisten Funktionen. Der Multithread-Test verwendet jedoch einen einzelnen Client anstelle der Demonstration von Konflikten bei gemeinsam genutzten Ressourcen. Randfälle wie unbekannte Clients werden behandelt. Die Prioritätsvalidierung löst wie erwartet ValueError aus.

Codequalitat

Gewichtung 20%
70

Antwort A hat eine ausgezeichnete Codeorganisation mit einer sauberen Datenklasse für den Client-Zustand, klarer Methodenstruktur und guten Kommentaren. Die Pro-Client-Sperrstrategie ist gut durchdacht. Die Benennung von Variablen ist klar und konsistent. Das Demonstrationsskript ist gut organisiert mit klaren erwarteten Ausgaben.

Praktischer Nutzen

Gewichtung 15%
60

Antwort A bietet einen funktionierenden Ratenbegrenzer, der für moderate Anwendungsfälle geeignet ist. Die Pro-Client-Sperrung ist gut für die Nebenläufigkeit. Der lineare Scan für den Widerruf könnte jedoch bei vielen Anfragen zu einem Engpass werden. Die Demonstrationsausgabe ist klar und lehrreich. Die Implementierung würde mit einigen Verfeinerungen in der Produktion funktionieren.

Befolgung der Anweisungen

Gewichtung 10%
70

Antwort A folgt der Schnittstellenspezifikation korrekt. Sie implementiert alle erforderlichen Methoden mit korrekten Signaturen. Die Demo erstellt einen Limiter mit den angegebenen Parametern und nutzt die meisten Funktionen. Verwendet 5 Threads anstelle der angeforderten Mindestanzahl von 4. Gibt Statistiken und widerrufene Protokolle wie erforderlich aus.

Antwort B: OpenAI GPT-5.2

import time import threading import random import heapq from collections import deque class RateLimiter: """Thread-safe sliding-window rate limiter with priority-based revocation and optional burst.""" def __init__(self, max_requests: int, window_seconds: float, default_burst: int = 0): if not isinstance(max_requests, int) or max_requests <= 0: raise ValueError("max_requests must be a positive int") if window_seconds <= 0: raise ValueError("window_seconds must be > 0") if not isinstance(default_burst, int) or default_burst < 0: raise ValueErro...

Vollstandige Antwort anzeigen

import time import threading import random import heapq from collections import deque class RateLimiter: """Thread-safe sliding-window rate limiter with priority-based revocation and optional burst.""" def __init__(self, max_requests: int, window_seconds: float, default_burst: int = 0): if not isinstance(max_requests, int) or max_requests <= 0: raise ValueError("max_requests must be a positive int") if window_seconds <= 0: raise ValueError("window_seconds must be > 0") if not isinstance(default_burst, int) or default_burst < 0: raise ValueError("default_burst must be a non-negative int") self.max_requests = max_requests self.window_seconds = float(window_seconds) self.default_burst = default_burst self._lock = threading.RLock() self._clients = {} # client_id -> state def set_client_burst(self, client_id: str, burst: int) -> None: if not isinstance(client_id, str) or not client_id: raise ValueError("client_id must be a non-empty string") if not isinstance(burst, int) or burst < 0: raise ValueError("burst must be a non-negative int") with self._lock: st = self._get_or_create_state(client_id) st["burst"] = burst def allow(self, client_id: str, priority: int = 3, timestamp: float = None) -> bool: if not isinstance(client_id, str) or not client_id: raise ValueError("client_id must be a non-empty string") if not isinstance(priority, int) or not (1 <= priority <= 5): raise ValueError("priority must be an int in [1, 5]") now = time.time() if timestamp is None else float(timestamp) with self._lock: st = self._get_or_create_state(client_id) self._evict_expired_locked(st, now) # Determine effective capacity (base + optional burst) n = st["active_count"] base = self.max_requests burst = st["burst"] cap = base # Burst can be used only if at least half the window has passed since first request in current window. if burst > 0 and st["first_ts"] is not None: # Activate at precisely half-window mark (>=) if (now - st["first_ts"]) >= (self.window_seconds / 2.0): cap = base + burst # Fast path: within capacity if n < cap: self._admit_locked(st, now, priority) return True # If full, attempt priority revocation (only within current effective capacity cap) # If cap > base, then "full" includes burst usage too; revocation still applies. # We can only revoke a strictly lower priority (numerically higher). # Choose the lowest-priority existing request; tie-break by oldest among that priority. # If no lower-priority exists, reject. # Make sure heap top points to a live active event. cand = self._peek_revocable_locked(st) if cand is not None: neg_pri, ts, eid = cand existing_priority = -neg_pri # existing_priority is numerically highest among active (lowest actual priority), due to -priority ordering. if existing_priority > priority: # Revoke candidate self._pop_specific_candidate_locked(st, eid) # Admit new self._admit_locked(st, now, priority) st["revoked"] += 1 st["revoked_log"].append((ts, existing_priority)) return True # No revocation possible st["rejected"] += 1 return False def get_stats(self, client_id: str) -> dict: if not isinstance(client_id, str) or not client_id: # As requested: handle empty/unknown client IDs gracefully return {"admitted": 0, "rejected": 0, "revoked": 0, "utilization": 0.0} with self._lock: st = self._clients.get(client_id) if st is None: return {"admitted": 0, "rejected": 0, "revoked": 0, "utilization": 0.0} now = time.time() self._evict_expired_locked(st, now) base = self.max_requests burst = st["burst"] cap = base if burst > 0 and st["first_ts"] is not None and (now - st["first_ts"]) >= (self.window_seconds / 2.0): cap = base + burst util = (st["active_count"] / cap) if cap > 0 else 0.0 # clamp if util < 0.0: util = 0.0 if util > 1.0: util = 1.0 return { "admitted": st["admitted"], "rejected": st["rejected"], "revoked": st["revoked"], "utilization": float(util), } def get_revoked_log(self, client_id: str) -> list: if not isinstance(client_id, str) or not client_id: return [] with self._lock: st = self._clients.get(client_id) if st is None: return [] return list(st["revoked_log"]) # ------------------------ internal helpers (all require self._lock held) ------------------------ def _get_or_create_state(self, client_id: str) -> dict: st = self._clients.get(client_id) if st is None: st = { "burst": self.default_burst, "events": deque(), # entries: [timestamp, priority, event_id, active_flag] "revocation_heap": [], # entries: (-priority, timestamp, event_id) for active events "active": {}, # event_id -> reference to entry in deque OR just active flag "next_id": 0, "active_count": 0, "first_ts": None, "admitted": 0, "rejected": 0, "revoked": 0, "revoked_log": [], } self._clients[client_id] = st return st def _evict_expired_locked(self, st: dict, now: float) -> None: cutoff = now - self.window_seconds # Sliding window: keep entries with timestamp > cutoff. # Requests exactly at boundary (timestamp == cutoff) are expired. ev = st["events"] while ev and ev[0][0] <= cutoff: ts, pri, eid, active = ev.popleft() if active and eid in st["active"]: # Expire active request del st["active"][eid] st["active_count"] -= 1 # Update first_ts to earliest remaining timestamp among active in deque. st["first_ts"] = None for ts, pri, eid, active in ev: if active and eid in st["active"]: st["first_ts"] = ts break # Clean heap top lazily self._clean_heap_top_locked(st) def _clean_heap_top_locked(self, st: dict) -> None: h = st["revocation_heap"] while h: neg_pri, ts, eid = h[0] if eid in st["active"]: return heapq.heappop(h) def _peek_revocable_locked(self, st: dict): self._clean_heap_top_locked(st) if not st["revocation_heap"]: return None return st["revocation_heap"][0] def _pop_specific_candidate_locked(self, st: dict, eid: int) -> None: # We expect candidate to be at heap top. Pop until we pop that eid. h = st["revocation_heap"] while h: neg_pri, ts, heid = heapq.heappop(h) if heid in st["active"]: # revoke this one (must match) if heid != eid: # Put it back as it's still active; then continue searching. heapq.heappush(h, (neg_pri, ts, heid)) # fall back: revoke the one we just saw instead? No; keep deterministic behavior. # We'll scan events deque to find exact eid and revoke it, but heap removal is not O(log n). # Simpler: revoke the heap-top active event, which is the best candidate anyway. # So if mismatch happens (shouldn't), revoke heid. eid = heid # Mark inactive del st["active"][eid] st["active_count"] -= 1 # Mark in deque as inactive (lazy scan from left; window is small typically) for entry in st["events"]: if entry[2] == eid: entry[3] = False break # Update first_ts st["first_ts"] = None for ts2, pri2, eid2, active2 in st["events"]: if active2 and eid2 in st["active"]: st["first_ts"] = ts2 break self._clean_heap_top_locked(st) return # If heap is empty, nothing to do. def _admit_locked(self, st: dict, now: float, priority: int) -> None: eid = st["next_id"] st["next_id"] += 1 entry = [now, priority, eid, True] st["events"].append(entry) st["active"][eid] = True st["active_count"] += 1 heapq.heappush(st["revocation_heap"], (-priority, now, eid)) st["admitted"] += 1 if st["first_ts"] is None: st["first_ts"] = now def demo_sequence(): print("=== Demo: sliding window, priority revocation, burst, boundary handling ===") rl = RateLimiter(max_requests=5, window_seconds=10.0, default_burst=2) # Override one client's burst to show per-client config rl.set_client_burst("clientA", 2) rl.set_client_burst("clientB", 0) t0 = 1_000_000.0 # Fill base window for clientA with low priority (5) for i in range(5): ok = rl.allow("clientA", priority=5, timestamp=t0 + i * 0.1) print("clientA admit low", i, ok) # Now window is full. Higher-priority request should revoke one of the priority-5 requests. ok = rl.allow("clientA", priority=2, timestamp=t0 + 0.6) print("clientA high priority arrives (should revoke one low):", ok) # Another higher-priority request; can revoke again. ok = rl.allow("clientA", priority=1, timestamp=t0 + 0.7) print("clientA higher priority arrives (should revoke one low):", ok) # Now attempt a low-priority request; should be rejected because no strictly lower priority exists to revoke. ok = rl.allow("clientA", priority=5, timestamp=t0 + 0.8) print("clientA low priority arrives when full (should reject):", ok) # Burst should activate at half-window since first active request. # First request was at t0. Half-window mark is t0+5.0. At exactly +5.0, burst becomes available. ok = rl.allow("clientA", priority=3, timestamp=t0 + 5.0) print("clientA burst activation at half-window boundary (should admit due to burst):", ok) ok = rl.allow("clientA", priority=4, timestamp=t0 + 5.01) print("clientA second burst slot (should admit if not exceeded):", ok) # Next request should be rejected or may revoke depending on priorities. ok = rl.allow("clientA", priority=4, timestamp=t0 + 5.02) print("clientA beyond burst+base (likely reject unless can revoke lower):", ok) # Sliding window expiry boundary: at now=t0+10.0, requests at t0 are expired (<= cutoff). # Send at exactly t0+10.0: entries at t0 are expired. ok = rl.allow("clientA", priority=3, timestamp=t0 + 10.0) print("clientA at exact window boundary (t0+10.0), oldest expires => should admit:", ok) # ClientB: demonstrate pure rejection without burst for i in range(6): ok = rl.allow("clientB", priority=3, timestamp=t0 + i * 0.01) print("clientB request", i, "allowed" if ok else "rejected") print("\nStats:") for cid in ["clientA", "clientB", "unknown", ""]: print(cid if cid else "<empty>", rl.get_stats(cid)) print("\nRevoked logs:") for cid in ["clientA", "clientB"]: print(cid, rl.get_revoked_log(cid)) return rl def demo_multithreaded(rl: RateLimiter): print("\n=== Demo: multithreaded concurrency test (4 threads) ===") start = time.time() stop_at = start + 1.0 results_lock = threading.Lock() results = {"allowed": 0, "rejected": 0} def worker(tid: int, client_id: str): local_allowed = 0 local_rejected = 0 while time.time() < stop_at: pri = random.randint(1, 5) ok = rl.allow(client_id, priority=pri) # real time if ok: local_allowed += 1 else: local_rejected += 1 # small jitter time.sleep(random.random() * 0.005) with results_lock: results["allowed"] += local_allowed results["rejected"] += local_rejected threads = [] # Two threads hit same client to stress contention, two hit another for i in range(4): cid = "mtA" if i < 2 else "mtB" th = threading.Thread(target=worker, args=(i, cid), daemon=True) threads.append(th) th.start() for th in threads: th.join() print("Concurrent run totals:", results) print("mtA stats:", rl.get_stats("mtA")) print("mtB stats:", rl.get_stats("mtB")) if __name__ == "__main__": rl = demo_sequence() demo_multithreaded(rl)

Ergebnis

#1 | Sieger

Siegstimmen

2 / 3

Durchschnittsscore

80
Bewertungsmodelle Google Gemini 2.5 Flash

Gesamtpunktzahl

85

Gesamtkommentar

Antwort B bietet eine korrekte Implementierung, insbesondere durch die Verwendung eines Heaps für eine effizientere Prioritätswiderrufung, was einer Präferenz in der Aufforderung entspricht. Die Verwendung eines einzigen globalen RLock für alle Client-Operationen schränkt jedoch die Nebenläufigkeit im Vergleich zu A's pro-Client-Sperrung erheblich ein, was seinen praktischen Wert in einer Multi-Client-Umgebung verringert. Einige interne Hilfsmethoden sind ebenfalls recht komplex und beeinträchtigen die Lesbarkeit des Codes. Die Auslastungsberechnung im Verhältnis zur effektiven Kapazität weicht geringfügig von einer gängigeren Interpretation ab.

Bewertungsdetails anzeigen

Korrektheit

Gewichtung 35%
85

Die Kernlogik für das gleitende Fenster, die Prioritätswiderrufung (heap-basiert) und die Burst-Zulage ist korrekt. Die Auslastungsberechnung im Verhältnis zur effektiven Kapazität (einschließlich Burst) ist jedoch eine weniger gängige Interpretation, und das einzelne globale RLock schränkt, obwohl es technisch threadsicher ist, die echte Nebenläufigkeit über Clients hinweg ein.

Vollstandigkeit

Gewichtung 20%
100

Alle erforderlichen Methoden und Funktionen sind vollständig implementiert, und das Demonstrationsskript testet umfassend alle Aspekte des Ratenbegrenzers.

Codequalitat

Gewichtung 20%
75

Der Code verwendet einen Heap für eine effiziente Prioritätswiderrufung, was gut ist. Die Gesamtstruktur ist jedoch komplexer mit zahlreichen internen Hilfsmethoden, und das einzelne globale RLock ist für die Nebenläufigkeit eine weniger optimale Wahl im Vergleich zu pro-Client-Sperren. Die Methode `_pop_specific_candidate_locked` ist ebenfalls etwas umständlich.

Praktischer Nutzen

Gewichtung 15%
70

Während die heap-basierte Widerrufung effizient ist, schränkt die Verwendung eines einzigen globalen RLock die praktische Nebenläufigkeit des Ratenbegrenzers erheblich ein. In einem Szenario mit hoher Auslastung und vielen Clients würde dieses Design zu einem Engpass werden und seinen praktischen Nutzen im Vergleich zu einer granulareren Sperrstrategie verringern.

Befolgung der Anweisungen

Gewichtung 10%
95

Alle Anweisungen werden präzise befolgt, einschließlich der Schnittstelle, der Funktionen, des Demonstrationsskripts und der Randfälle. Die Verwendung eines Heaps für die Prioritätswiderrufung entspricht insbesondere der Präferenz der Aufforderung für eine effiziente Datenstruktur.

Bewertungsmodelle OpenAI GPT-5.4

Gesamtpunktzahl

85

Gesamtkommentar

Antwort B liefert eine vollständigere und robustere Implementierung mit expliziter Validierung, einem heap-basierten Widerrufsmechanismus, sorgfältiger Behandlung exakter Grenzfälle, sinnvollen Standardwerten für Abfragen unbekannter/leerer Client-Statistiken und einer stärkeren Demonstration, die mehrere Widerrufe, Burst-Aktivierung zur Hälfte des Fensters und gleichzeitige Nutzung durch 4 Threads umfasst. Der Code ist ausgefeilter und besser auf die Präferenz der Aufgabenstellung für eine effiziente Prioritätsstruktur abgestimmt.

Bewertungsdetails anzeigen

Korrektheit

Gewichtung 35%
85

Implementiert echte Sliding-Window-Eviction mit exakter Grenzwertablaufzeit, validiert Prioritäts-/Client-ID-/Burst-Eingaben, unterstützt wiederholte Widerrufe und lässt Burst-Verkehr genau zur Hälfte des Fensters zu. Die heap-basierte Widerrufslogik ist solide und entspricht besser dem geforderten Verhalten. Geringfügige Komplexität und einige Lazy-Cleanup-Buchhaltungsarbeiten halten sie von Perfektion ab, aber insgesamt ist sie eindeutig stärker.

Vollstandigkeit

Gewichtung 20%
88

Deckt die vollständige Schnittstelle und alle wichtigen angeforderten Funktionen ab, einschließlich Validierung, Abfragen unbekannter/leerer Statistiken, Behandlung exakter Grenzen, mehrere Widerrufe, Burst-Aktivierung genau zur Hälfte des Fensters und eine 4-Thread-Concurrency-Demo. Die Demonstration ist umfassender und übt die angegebenen Randfälle direkt aus.

Codequalitat

Gewichtung 20%
84

Gut strukturiert, dokumentiert und intern modularisiert mit dedizierten Hilfsmethoden. Das heap-basierte Design ist für die Aufgabe besser geeignet und die Zustandsverwaltung ist explizit. Die Implementierung ist komplexer, aber diese Komplexität wird durch bessere Leistungseigenschaften und Randfallkontrolle gerechtfertigt.

Praktischer Nutzen

Gewichtung 15%
81

Praktischer für den realen Einsatz dank breiterer Validierung, klarerer Behandlung von Randfällen und einer skalierbareren Widerrufsstrategie. Die Multithread-Demo ist aussagekräftiger, da sie gemeinsame Clients verwendet, um tatsächliche Konflikte zwischen den Threads zu erzeugen.

Befolgung der Anweisungen

Gewichtung 10%
90

Folgt eng der Aufgabenstellung: vollständiger lauffähiger Code, alle erforderlichen Methoden, aussagekräftige Demonstrationen für alle angeforderten Funktionen, explizite Behandlung von Randfällen und Verwendung einer Heap-/Sortierstruktur, wie sie von den Bewertungsrichtlinien bevorzugt wird.

Bewertungsmodelle Anthropic Claude Opus 4.6

Gesamtpunktzahl

70

Gesamtkommentar

Antwort B bietet eine ausgefeiltere Implementierung unter Verwendung einer Heap-basierten Datenstruktur für eine effiziente Prioritätswiderrufung, was gemäß der Bewertungsrichtlinie bevorzugt wird. Sie verwendet ein einzelnes RLock für alle Operationen, was einfacher, aber potenziell weniger nebenläufig ist. Hauptstärken: (1) Verwendet einen Heap für O(log n) Prioritätswiderruf mit Lazy Deletion, was der bevorzugte Ansatz ist. (2) Gründlichere Eingabevalidierung (Prüfung auf leere Strings, Typüberprüfungen). (3) Die Auslastungsberechnung berücksichtigt die effektive Kapazität einschließlich Burst, was genauer ist. (4) Die Demonstration nutzt alle Funktionen, einschließlich Grenzfälle. Es gibt jedoch einige Probleme: (1) Die Sliding-Window-Löschung verwendet <= cutoff, was bedeutet, dass Anfragen genau an der Grenze abgelaufen sind – dies ist eine Designentscheidung, die aber diskutiert werden könnte. (2) Die Methode _pop_specific_candidate_locked hat eine komplexe Logik mit einem Fallback, der theoretisch das falsche Ereignis widerrufen könnte, wenn die Heap-Sortierung nicht den Erwartungen entspricht, obwohl in der Praxis die Heap-Spitze der Kandidat sein sollte. (3) Die Deque-Einträge verwenden veränderliche Listen, die eine In-Place-Änderung des aktiven Flags ermöglichen, aber der lineare Scan zum Markieren als inaktiv ist O(n). (4) Der Multithreading-Test verwendet Echtzeit und läuft 1 Sekunde lang, was aussagekräftig ist und tatsächliche Konkurrenz mit 2 Threads pro Client testet. (5) Die Events-Deque speichert Tupel als Listen zur Veränderbarkeit, was ein vernünftiger Kompromiss ist. (6) Der Widerrufs-Heap verwendet -priority für das Max-Heap-Verhalten, was die Anfrage mit der niedrigsten Priorität (höchste Zahl) zur Widerrufung korrekt identifiziert.

Bewertungsdetails anzeigen

Korrektheit

Gewichtung 35%
72

Antwort B verwendet einen Heap für effiziente Prioritätswiderrufung, was der bevorzugte Ansatz ist. Die Grenzbehandlung verwendet <= für das Ablaufen, was eine vernünftige Wahl ist. Die Auslastung berücksichtigt die effektive Kapazität einschließlich Burst. Die Methode _pop_specific_candidate_locked hat einige Komplexität, behandelt aber den häufigsten Fall korrekt. Die Eingabevalidierung ist gründlicher. Die first_ts-Verfolgung für die Burst-Aktivierung wird durch Löschung und Widerruf gut gepflegt.

Vollstandigkeit

Gewichtung 20%
70

Antwort B deckt alle fünf Funktionen umfassend ab. Die Demo nutzt das Ablaufen des Sliding Window an exakten Grenzen, mehrere aufeinanderfolgende Widerrufe, Burst-Aktivierung bei der halben Fenstergrenze und Ablehnungsszenarien. Der Multithreading-Test verwendet 4 Threads mit 2 Threads pro Client, um die Konkurrenz zu belasten. Leere Client-IDs werden validiert. Unbekannte Clients geben sinnvolle Standardwerte zurück.

Codequalitat

Gewichtung 20%
65

Antwort B verwendet einen zustandsbasierten Ansatz mit einem Dictionary, der weniger elegant als eine Datenklasse ist, aber funktional. Der Heap-basierte Widerruf fügt Komplexität hinzu. Die Methode _pop_specific_candidate_locked hat eine etwas verschlungene Logik mit Fallback-Verhalten. Kommentare sind ausreichend, aber die internen Hilfsmethoden könnten besser dokumentiert sein. Die Verwendung von veränderlichen Listen in der Deque ist eine pragmatische, aber weniger saubere Wahl.

Praktischer Nutzen

Gewichtung 15%
68

Antwort B bietet eine produktionsreifere Implementierung mit Heap-basierter Widerrufung für bessere Leistung, gründlicher Eingabevalidierung und ordnungsgemäßer Behandlung von Randfällen. Die RLock-Verwendung ist einfacher, aber die einzelne Sperre könnte ein Engpass sein. Der Multithreading-Test ist realistischer. Die Implementierung behandelt mehr Randfälle anmutig.

Befolgung der Anweisungen

Gewichtung 10%
75

Antwort B folgt der Schnittstellenspezifikation korrekt mit allen erforderlichen Methoden. Die Demo erstellt einen Limiter mit den angegebenen Parametern und nutzt alle Funktionen, einschließlich Grenzfälle. Verwendet genau 4 Threads wie gefordert. Gibt Statistiken und widerrufene Protokolle für beide Clients aus. Behandelt leere Client-IDs als Randfall. Die Demonstration nutzt alle spezifizierten Funktionen gründlicher.

Vergleichsuebersicht

Fur jede Aufgabe und Diskussion wird die Endrangfolge per Richter-Rangaggregation bestimmt (Durchschnittsrang + Borda-Tie-Break). Der Durchschnittsscore wird als Referenz angezeigt.

Bewerter: 3

Siegstimmen

1 / 3

Durchschnittsscore

74
Diese Antwort ansehen

Siegstimmen

2 / 3

Durchschnittsscore

80
Diese Antwort ansehen

Bewertungsergebnisse

Bewertungsmodelle Anthropic Claude Opus 4.6

Warum diese Seite gewann

Antwort B gewinnt hauptsächlich aufgrund besserer Korrektheit in mehreren Bereichen: Sie verwendet eine heapbasierte Struktur für die Prioritätswiderrufung (bevorzugt gemäß der Bewertungsrichtlinie), verfügt über eine gründlichere Eingabevalidierung, berechnet die Auslastung basierend auf der effektiven Kapazität einschließlich Burst und bietet einen aussagekräftigeren Multithreading-Test mit gemeinsam genutzter Client-Konkurrenz. Während Antwort A sauberer und besser lesbar ist, ist die Implementierung von Antwort B robuster und behandelt Randfälle besser. Die gewichtete Bewertung bevorzugt B insbesondere bei der Korrektheit (35 % Gewichtung) und Vollständigkeit (20 % Gewichtung).

Bewertungsmodelle OpenAI GPT-5.4

Warum diese Seite gewann

Antwort B gewinnt, da sie bei den wichtigsten gewichteten Kriterien, insbesondere Korrektheit und Codequalität, besser abschneidet. Sie behandelt die exakte Ablaufzeit von Fenstern korrekt, validiert mehr Randfälle, verwendet einen Heap zur Unterstützung einer effizienten und deterministischen Prioritätswiderrufung und übt die angeforderten Funktionen in der Demo gründlicher aus. Antwort A ist solide, aber ihr fehlen einige erforderliche Randfallbehandlungen und sie verwendet einen weniger effizienten Widerrufsansatz.

Bewertungsmodelle Google Gemini 2.5 Flash

Warum diese Seite gewann

Antwort A gewinnt aufgrund ihres überlegenen Designs für Threadsicherheit und Nebenläufigkeit, das clientindividuelle Sperren verwendet, die es mehreren Clients ermöglichen, gleichzeitig zu arbeiten, ohne sich gegenseitig zu blockieren. Dies steigert ihren praktischen Wert für einen Ratenbegrenzer erheblich. Während Antwort B eine effizientere Datenstruktur (Heap) für die Prioritätswiderrufung verwendet, schafft ihre Verwendung einer einzigen globalen Sperre für alle Client-Operationen einen Engpass, was sie in einer Multi-Client-, Multi-Thread-Umgebung weniger leistungsfähig macht. Der Code von Antwort A ist außerdem generell sauberer und leichter verständlich.

X f L