2012-12-12 13 views
7

Während meines Interviews, ich gebeten wurde, eine Zustandsmaschine für ein System mit 100 Staaten, in denen jeder Staat wiederum zu implementieren 100 Veranstaltungen hat, antwortete ich 3 folgende Ansätze:Interview: Funktionszeiger vs Schaltergehäusen

  • wenn -else
  • switch-case
  • Funktionszeiger

If-sonst ist offensichtlich nicht für eine solche Zustandsmaschine geeignet, daher Haupt Vergleich war zwischen switch-case vs Funktionszeiger, hier t Der Vergleich nach meinem Verständnis:

  • Geschwindigkeit weise beide sind fast gleich.
  • Switch-Case ist weniger modular als Funktionszeiger
  • Funktion-Zeiger hat mehr Speicheraufwand.

Könnte jemand bestätigen, wenn über das Verständnis korrekt ist?

+4

Funktion Zeiger scheint der einzige gültige Ansatz in diesem Fall. Ja, es ist ein schneller Zugriff, aber es ist eine modulare und flexible Lösung. –

+2

Ich kann mir nicht vorstellen, 100 Zustände hart zu kodieren, ich würde sie lieber bei der Initialisierung einer Zustandsmaschine hinzufügen. Dies vermeidet 10 Bildschirme lange if-else/switch-case leiter und macht das Testen und Modifizieren * viel * einfacher –

+1

Nicht sicher, ob das den Interviewer zufriedenstellen würde, aber bei der Arbeit würde ich einfach [Ragel] (http: //www.complan.org/ragel/). Sie erhalten blitzschnelle Geschwindigkeit (z. B. 'goto'-basiert) * und * einfacheres Debuggen (Ragel kann den Zustandsübergangsgraphen in ein Punktformat ablegen, um von Graphviz konsumiert zu werden). – unthought

Antwort

1

Es könnte eine Variante des Funktionszeiger Ansatz: eine Struktur, die einen Funktionszeiger sowie weitere Informationen enthält. Sie könnten also eine Funktion mehrere Fälle behandeln lassen.

Neben dieser, ich glaube, Sie haben Recht. Außerdem würde ich den Overhead in Bezug auf Speicher und Geschwindigkeit in Betracht ziehen, aber hoffentlich klein genug, um am Ende ignoriert zu werden.

+0

Haben Sie nicht genau das bekommen, was Sie mit struct mit dem Funktionszeiger-Ansatz meinten, wenn alle Funktionen unabhängige Funktionen ausführen, wie könnten Sie dann eine Funktion haben, um mehrere Fälle zu bedienen? – user1897724

+0

@ user1897724 Wenn zwei Zustände fast gleich sind, sich aber in einem Aspekt unterscheiden, könnte dies eine Überlegung wert sein. – glglgl

+0

@glglgl Kennen Sie eine gute Lektüre zu diesem Thema? – Blackninja543

0

Ich weiß nicht, was Ihre Interviewer hören wollten und ich hoffe, das ist kein Thema, aber wenn ich jemanden interviewe, würde ich Punkte für das Wissen über die Vor- und Nachteile von bestehenden Frameworks geben, bevor Sie Ihre eigenen rollen, besonders in diesem Maßstab.

C++ Alternativen (wenn Sie sie verwenden können, vielen Dank für den Hinweis auf glglgl, dass Sie scheinen C zu wollen) wären:

Boost.MSM obwohl unglaublich schnell ist bei diesem Maßstab nicht in Frage. Gründe sind die Kompilierzeit, mpl :: vector/list constraints und weil Sie eine gigantische Quelldatei haben würden.

Boost.Statecharts mit 100 Staaten arbeiten, aber 100 Veranstaltungen pro Zustand würde max aus dem mpl :: vector/Liste Einschränkungen. Persönlich, wenn ich 100 Ereignisse in einem Zustand hätte, würde ich versuchen, sie trotzdem zu gruppieren und benutzerdefinierte Reaktionen zu verwenden, aber das hängt natürlich von der Anwendung ab.

Ich sehe keinen Grund, warum Zustandsmaschine Qt nicht so groß skaliert würde (bitte korrigiert mich wenn ich falsch liege), aber seine Größenordnung langsamer, damit ich es nie verwenden.

Die einzige gute C Alternative, die ich kenne, ist:

QP, die in C und C++ verfügbar ist und so groß skaliert werden kann, hat eine gute Organisation und ist „mehr als eine Zustandsmaschine“, dass es Ereignis behandelt Warteschlangen, Nebenläufigkeit und Speicherverwaltung usw. Das eigene Rollen kann eine bessere Leistung bringen (abhängig von Ihrer Geschicklichkeit und wie viel Zeit Sie hineinlegen), aber es sollte angemerkt werden, dass die Speicherverwaltung der Ereignisse wahrscheinlich mehr Optimierung benötigt als die Implementierung der Zustandsmaschine ist es selbst. QP macht das für dich und ganz gut.

+0

Boost ist C++ und Qt auch, oder? – glglgl

+0

korrekt, ich habe das C-Tag des OPs übersehen, Qt ist auch C++, so dass nur QP übrig bleibt (was auch in C und C++ möglich ist) – odinthenerd

0

Sie könnten nähere Angaben zu Ihren Zuständen und Ereignissen machen. Angenommen, Ihr Status ist eine fortlaufende ganze Zahl.Dann können Sie

  1. Schreiben Sie eine Tabelle, um alle Zustände und pro Zustandshandler-Funktion enthalten. Wenn Sie ein Ereignis empfangen, verweisen Sie auf diese Tabelle und rufen Sie die entsprechende Handler-Funktion auf.

  2. Schreiben Sie für jeden Status eine Tabelle, die alle Ereignisse und ihre Ereignisbehandlungsfunktion enthält. Suchen Sie in dieser Tabelle nach, wenn Sie das Ereignis im Status verarbeiten.

Die Zeitkomplexität dieser 2 Tabelle ist aufzublicken O (1), und Raumkomplexität O (m * n)

jedoch, wie Sie FSM mit 100 Staaten und Ereignis mit 100 haben Arten? Ich empfehle Ihnen, Ihre FSM-Design zu vereinfachen und die 1 ~ 100-Nummer kann Parameter eines bestimmten Ereignisses sein.