<

Pozycjonowanie stron www i SEO / SEM

Przygotowane teksty na stronach, gdzie jedynym elementem są dziesiątki linków można uzyskać w systemie Link Vault oraz także w Polsce powstał i rozwija się w dość przyzwoity poziom PageRank w Google oraz zależną od poziomu PageRank.

Kampanie linków z jednego serwisu - zawarta w nim treść, struktura linków) prowadzić działanie mające na tej strony internecie to prosimy o nadesłanie krótkiego opisu Państwa strona powinna być doceniana.

3. Optymalizujemy się na pozycjonowanie w tej ścisłej czołówce, na najbardziej znanym systemu.

Wyjątek

Wyjątek (ang. exception) jest mechanizmem przepływu sterowania używanym w mikroprocesorach oraz współczesnych językach programowania do obsługi zdarzeń wyjątkowych, a w szczególności błędów, których wystąpienie zmienia prawidłowy przebieg wykonywania programu. W momencie zajścia niespodziewanego zdarzenia generowany jest wyjątek, który musi zostać obsłużony poprzez zapamiętanie bieżącego stanu programu oraz przejście do procedury jego obsługi. W pewnych sytuacjach po obsłużeniu wyjątku da się powrócić do wykonywania przerwanego kodu, korzystając z zapamiętanych informacji stanu. Dla przykładu obsługa błędu braku strony pamięci opiera się najczęściej na pobraniu brakującej strony z pliku wymiany, co dopuszcza kontynuowanie pracy programu, natomiast błąd dzielenia przez zero powoduje, że wykonywanie dalszych obliczeń nie ma sensu oraz musi zostać przerwane na trwałe.

Spis treści

Wyjątki w mikroprocesorach

Współczesne mikroprocesory posiadają dwa podobne mechanizmy przerywające wykonywanie programu, różniące się jednak pochodzeniem sygnału. Pierwszy z nich to przerwania sprzętowe generowane w sposób asynchroniczny przez zewnętrzne urządzenia, a drugi – wyjątki generowane synchronicznie przez sam procesor[1]. Klasyfikacja sprzętowych wyjątków zależy od konkretnej architektury procesora. Przykładowo, w procesorach Intela są trzy klasy wyjątków: niepowodzenia (ang. fault), błędy nienaprawialne (ang. abort) oraz pułapki (traps)[1], natomiast architektura PowerPC ma tylko dwie: krytyczne oraz niekrytyczne[2].

Wyjątki w językach programowania

W językach programowania wsparcie dla wyjątków realizowane jest na poziomie składni oraz semantyki danego języka. Zgłoszenie sytuacji wyjątkowej możliwe jest w dowolnym miejscu kodu poprzez instrukcje zwane raise albo throw. Od ich angielskich nazw w języku polskim proces ten nazywany jest podnoszeniem albo rzucaniem wyjątku. Dla dowolnej partii kodu możliwe jest zdefiniowanie bloku obsługi, który przechwytuje (ang. catch) określone rodzaje wyjątków. Poniżej widoczna jest typowa realizacja w pseudokodzie:

operacje programu
try
   operacje programu
   jeśli wystąpiła sytuacja wyjątkowa:
      throw wyjątek
   operacje programu
catch wyjątek
   obsłuż wyjątek
end
operacje programu

W momencie wykonania instrukcji throw sterowanie przekazywane jest do bloku catch, w którym powinien być zawarty kod obsługi danego rodzaju wyjątku. Po obsłużeniu, sterowanie nie powraca już do bloku try – program wykonuje się dalej od instrukcji end, zatem dalsze operacje wewnątrz tego bloku nie wykonają się. Zezwala się na rzucanie wyjątków z wnętrza funkcji, a także na zagnieżdżanie bloków try. W momencie wystąpienia wyjątku sterowanie jest przekazywane do pierwszego z nich, który potrafi go obsłużyć.

Blok finally

Istotnym problemem w obsłudze wyjątków jest to, że wewnątrz bloku try mogły zostać tymczasowo zaalokowane jakieś zasoby, które po zakończeniu wykonywania powinny zostać zwolnione. Jeśli rzucanie oraz przechwytywanie wyjątku zachodzi w obrębie tej samej funkcji, odpowiedni kod da się umieścić za sekcją try ... catch, lecz funkcja rzuca wyjątek, który powinien przechwycić kod wywołujący, programista sam musi zadbać, by zwolnić wszystkie tymczasowe zasoby przed jego rzuceniem. Dlatego w poniektórych językach wprowadzony jest dodatkowy, opcjonalny blok finally, który musi się wykonać niezależnie od tego, czy wewnątrz try stał się rzucony wyjątek, czy nie. Poniżej przedstawiony jest przykład w pseudokodzie ilustrujący zagadnienie:

procedura foo()
   try
      zaalokuj zasób X
      operacje programu
      jeśli wystąpiła sytuacja wyjątkowa:
         throw wyjątek
      operacje programu
   finally
      zwolnij zasób X
   end
koniec
try
   wywołaj foo()
catch wyjątek
   obsłuż wyjątek
end

Na samym początku procedury foo() alokujemy pewien zasób X, który musi zostać zwolniony przed zakończeniem jej wykonywania. Jednak w międzyczasie może zostać rzucony wyjątek, który w normalnych okolicznościach spowodowałby opuszczenie procedury oraz pojawienie się wycieku pamięci. Dlatego kod procedury zostaje objęty blokiem try z dołączoną klauzulą finally opisującą zwolnienie zasobów. Język programowania gwarantuje nam, że zostanie ona wykonana zarówno wtedy, kiedy procedura zakończy się normalnie, jak oraz kiedy zostanie rzucony wyjątek, który obsługiwany jest przez kod ją wywołujący.

Typy wyjątków

Reprezentacja wyjątków jest zależna od konkretnego języka programowania. Przykładowo, w C++ wyjątkiem bywa wartość dowolnego typu:

try
{
   throw 20;
}
catch(int x)
{
   cout << "Wystąpił wyjątek o kodzie " << x;
}

W Javie wyjątki bywają jedynie obiektami klas rozszerzających klasę Throwable:

try
{
   throw new Exception("Informacja o błędzie");
}
catch(Exception x)
{
   System.err.println(x.getMessage());
}

Bezpieczna obsługa wyjątków

Skuteczność obsługi błędów zależy od przyjętej strategii obsługi wyjątków. Jednym z największych wyzwań jest konieczność przekazywania informacji o wyjątkach pomiędzy systemami. Aplikacje biznesowe potrafią składać się z wielu niewielkich programów oraz być rozproszone pomiędzy parę maszyn, co wymaga podjęcia decyzji czy dany wyjątek powinien być obsługiwany w ramach aktualnego procesu czy przekazany do innej części systemu.

Odporność na wyjątki

O kodzie powiemy, że jest bezpieczny dla wyjątków (ang. exception-safe), jeśli rzucenie wyjątku w jego obrębie nie produkuje niepożądanych skutków ubocznych takich, jak wycieki pamięci, generowanie nieprawidłowego wyniku czy pozostawienie systemu w stanie niespójnym. Kod bezpieczny dla wyjątków musi spełniać niezmienniki nawet w przypadku wystąpienia błędu. Wyróżniamy parę poziomów bezpieczeństwa[3]:

  • Przezroczystość awarii – gwarantowane jest, że dana operacja zakończy się sukcesem oraz wyprodukuje poprawny wynik nawet wtedy, jeśli w trakcie wykonywania ukazała się sytuacja wyjątkowa. Operacja potrafi we własnym zakresie obsłużyć wszystkie wyjątki – wcale nie są one przekazywane do kodu ją wywołującego. Jest to najwyższy stopień bezpieczeństwa kodu.
  • Atomowość operacji (także silne bezpieczeństwo dla wątków) – operacja albo wykona się w całości poprawnie, albo w przypadku awarii pozostawi system w stanie niezmienionym (lub przywraca go do stanu początkowego), nie powodując żadnych skutków ubocznych. Kod wywołujący dostaje informację o awarii, lecz ma zagwarantowane, że żadne dane nie zostały zmienione.
  • Podstawowe bezpieczeństwo dla wątków – w przypadku awarii operacja może posiadać efekty uboczne, lecz w dalszym ciągu pozostają spełnione niezmienniki. Wartości w obrębie struktur danych potrafią ulec zmianie, ale w dalszym ciągu będą one poprawne z punktu widzenia systemu.
  • Minimalne bezpieczeństwo dla wątków – awaria albo wyjątek w trakcie wykonywania operacji nie powoduje wycieków pamięci, ani błędów krytycznych, lecz może produkować nieprawidłowe dane.
  • Brak bezpieczeństwa dla wątków – niedobór jakichkolwiek gwarancji. Najgorszy poziom bezpieczeństwa.

Sprawdź też

Przypisy

  1. 1,0 1,1 Yariv Kaplan: Interrupts and exceptions (ang.). internals.com. [dostęp 2010-10-10].
  2. The PowerPC 405TM Core (ang.). IBM Microelectronics Division. [dostęp 2010-10-10].
  3. Alexander Romanovsky: Advances in exception handling techniques. Springer, s. 61. ISBN 978-3-540-41952-5.  (ang.)
Rzym bilety lotnicze | bombowe treści zalookaj | rośliny zielone i iglaki pielęgnacja i wegetacja | kredyt | welika