Showing posts with label Quiz. Show all posts
Showing posts with label Quiz. Show all posts

02/12/2014

Zabawy z domenami aplikacyjnymi

Home

Proponuję zabawę z serii co zostanie wypisana na ekran. Mamy dwie klasy jak poniżej. Pierwsza z nich przekazywana jest pomiędzy domenami przez referencję, a druga przez wartość. Interfejs ITest ma charakter pomocniczy i nie ma znaczenia.
public interface ITest
{
   int Value { get; set; }
   void Start();
}

public class MarshalByRefObjectClass : MarshalByRefObject, ITest
{
   public int Value { get; set; }

   public void Start()
   {
      Console.WriteLine(AppDomain.CurrentDomain.FriendlyName);
      Value++;
   }
}

[Serializable]
public class MarshalByValueClass : ITest
{
   public int Value { get; set; }

   public void Start()
   {
      Console.WriteLine(AppDomain.CurrentDomain.FriendlyName);
      Value++;
   }
}
Mamy również następujący kod, w którym testuję jak zachowuja się:
  • Obiekty przekazywane przez wartość i przez referencję.
  • Utworzone w bieżącej (przy pomocy konstruktora) oraz w innej domenie (przy pomocy AppDomain.CreateInstanceFromAndUnwrap).
  • Przy wywołaniu na nich metody bezpośrednio oraz przy pomocy AppDomain.Callback.
Co daje łączenie 2 x 2 x 2 = 8 możliwości. Do testowania używam takiej metody pomocniczej:
private static void Test(AppDomain app, ITest test, bool doCallBack)
{
   if (doCallBack)
      app.DoCallBack(test.Start);
   else
      test.Start();

   Console.WriteLine(test.Value);
}
A to właściwy test, w którym najpierw tworzę obiekty przekazywane przez wartość/referencję lokalnie i w nowej domenie. Następnie wywołuję dla nich metodę Start i odczytuję właściwość Value.
var app = AppDomain.CreateDomain("TestDomain");

var asm = Assembly.GetExecutingAssembly();
var byRef = new MarshalByRefObjectClass();
var byRef1 = new MarshalByRefObjectClass();
var byRef2 = (MarshalByRefObjectClass)app.CreateInstanceFromAndUnwrap(asm.CodeBase, typeof(MarshalByRefObjectClass).FullName);
var byRef3 = (MarshalByRefObjectClass)app.CreateInstanceFromAndUnwrap(asm.CodeBase, typeof(MarshalByRefObjectClass).FullName);

var byValue = new MarshalByValueClass();
var byValue1 = new MarshalByValueClass();
var byValue2 = (MarshalByValueClass)app.CreateInstanceFromAndUnwrap(asm.CodeBase, typeof(MarshalByValueClass).FullName);
var byValue3 = (MarshalByValueClass)app.CreateInstanceFromAndUnwrap(asm.CodeBase, typeof(MarshalByValueClass).FullName);

Test(app, byRef, true);
Test(app, byRef1, false);
Test(app, byRef2, true);
Test(app, byRef3, false);

Test(app, byValue, true);
Test(app, byValue1, false);
Test(app, byValue2, true);
Test(app, byValue3, false);
Pytanie brzmi co zostanie wypisane na ekranie? Pokaż/Ukryj odpowiedź

Obiekty przekazywane przez referencję wypiszą na ekran nazwę domeny w jakiej zostały utworzone. Nawet jeśli wywołanie jest inicjowane w innej domenie to zostanie przekazne do domeny orginalej ponieważ pracujemy z proxy do obiektu. W przypadku obiektów przekazywanych przez wartość na ekran zostanie wypisana nazwa domeny w jakiej następuje wywołanie.

Jeśli chodzi o wartość wypisaną na ekran to obiekty przekazywane przez referencję zawsze wypiszą ten sam wynik = 1 ponieważ zarówno wywołanie metody Start jak i odczyt Value dotyczy tego samego obiektu. W przypadku obiektów przekazywanych przez wartość w niektórych przypadkach możemy otrzymać zero. Stanie się tak kiedy wywołanie Start nastąpi w innej domenie niż ta, w której odczytujemy właściwość Value. A dzieje sie tak ponieważ obie czynność dotyczą de facto innych obiektów.
Sandbox.vshost.exe
1
Sandbox.vshost.exe
1
TestDomain
1
TestDomain
1
TestDomain
0
Sandbox.vshost.exe
1
TestDomain
0
Sandbox.vshost.exe
1

26/04/2014

Jeśli nie na tabela tymczasowa to co?

Home

W poście Quiz - coś do poduszki opublikowałem zestaw pytań z Quiz'u jaki zorganizowałem dla kolegów z pracy. Od czasu do czasu wpadają mi do głowy różne zagadki dlatego postanowiłem, że co ciekawsze będę wrzucał ku pamięci na bloga. Oto pierwsza z nich.

Po wykonaniu poniższego kodu na ekran zostanie wypisana wartość 0. Czego należy użyć zamiast tabeli tymczasowej aby aby na ekran została wypisana wartość 2?
CREATE TABLE #Temp (
Id INT IDENTITY,
Value VARCHAR(10)
);

BEGIN TRANSACTION;
INSERT INTO #Temp VALUES('aaa');
INSERT INTO #Temp VALUES('bbb');
ROLLBACK;

SELECT COUNT(1) FROM #Temp;

DROP TABLE #Temp;
Pokaż/Ukryj odpowiedź

Zamiast tabeli tymczasowej należy użyć zmiennej tabelarycznej.
DECLARE @Temp TABLE (
Id INT IDENTITY,
Value VARCHAR(10)
);

BEGIN TRANSACTION;
INSERT INTO @Temp VALUES('aaa');
INSERT INTO @Temp VALUES('bbb');
ROLLBACK;

SELECT COUNT(1) FROM @Temp;

15/07/2013

Quiz - coś do poduszki

Home

W poprzednim poście napisałem o zorganizowanym przez siebie Quiz'ie wiedzy o .NET i szeroko pojętym programowaniu. Jeden z czytelników poprosił o udostępnienie pytań i odpowiedzi. Nie zrobiłem tego od razu ale w ostatni weekend znalazłem chwilę czasu na zebranie wszystkich pytań/odpowiedzi do kupy, ujednolicenie formatowania itp. Dokument w formacie PDF dostępny jest na moim dysku SkyDrive:



Przy okazji będę wdzięczny ze wszelkie komentarze. Czy treść pytań jest zrozumiała? Czy pytania były łatwe, trudne, a może w sam raz? Czy ich tematyka podoba się Wam? Czy wzięlibyście udział w takim Quiz'ie? Zwróćcie również uwagę na pytanie 23 przy którym niestety zaliczyłem wpadkę i zdecydowałem się je anulować. Jeśli ktoś z Was potrafi wyjaśnić moje wątpliwości zapraszam do komentowania.

06/07/2013

Quiz - rozruszaj towarzystwo

Home

Czy Wasza praca jest zawsze ciekawa i pełna wyznań, a może czasami Was nuży i zastanawiacie się jak ją urozmaicić?

Byłoby super gdyby każdy z nas mógł odpowiedzieć na to pytanie "Tak moja praca jest bardzo ciekawa i nigdy mnie nie nuży", ale w rzeczywistości bywa różnie. Zawsze można zmienić pracę, ale można również próbować zmienić coś w obecnej. Sceptycy pewnie powiedzą, a co ja mały trybik w wielkiej machinie mogę zrobić. Dużo zależy od firmy i bywają przypadki beznadziejne. Ja na rozruszanie zespołu proponuję zorganizować Quiz.

Ja postanowiłem coś takiego zrobić już po raz drugi w swojej karierze i jestem bardzo zadowolony z efektów. Odgórnym celem Quiz'u była zabawa i nauka. Zasady były proste:
  • 10 tur po 3 pytania (łatwe, średnie i trudne) dotyczące szeroko pojętego programowania.
  • Pytania przygotowałem za wczasu, tak aby nie musieć ich wymyślać co tydzień.
  • Starałem się, aby odpowiedzi można było udzielić w jednym zdaniu, czasem wręcz jednym słowem, ewentualnie napisać kilka linijek kodu.
  • Pytania rozsyłałem w poniedziałek rano i czekałem na odpowiedzi do końca dnia. Następnego dnia oceniałem wyniki, rozsyłałem odpowiedzi z komentarzami i aktualną statystykę (anonimowa lista).
  • Udział był dobrowolny.
  • Udział był anonimowy, każdy uczestnik miał przypisany identyfikator i tylko ja znałem mapowanie.
  • Zwycięzca mógł wybrać sobie nagrodę ufundowaną przez firmę (wybrał przenośny dysk).
Do Quiz'u zgłosiło się 20 osób. Łącznie zadałem 9 łatwych pytań, 12 średnich oraz 9 trudnych za łącznie 60 punktów. Zwycięzca zdobył 52.5 punkty i walka trwała do ostatniej tury ponieważ druga osoba w rankingu miała 52 punkty, a trzecia i czwarta 51. Zebrane w całości pytania i odpowiedzi utworzyły 22 stronicowy dokument!

Quiz spodobał się i spotkał się z bardzo dobrym odbiorem również ze strony przełożonego, który dał pieniądze na nagrodę. Najbardziej cieszy mnie jednak to, że już kilkukrotnie słyszałem od kolegów, że w trakcie Quiz'u nauczyli się czegoś nowego.

Organizacja Quiz'u to również nauka dla mnie. Aby przygotować pytania i nie zaliczyć wpadki wiele zagadnień musiałem przestudiować dużo dokładniej. Nauczyłem się również jak, wbrew pozorom, trudne jest układanie pytań w taki sposób, aby były zrozumiałe dla wszystkich. Pomimo, że każde zadanie czytałem wielokrotnie zdarzało się, że musiałem odpowiadać na pytania i rozsyłać dodatkowe informacje.

Na koniec kilka przykładów pytań:

Łatwe

We have to measure an execution time with the maximum possible resolution/precision. It was implemented in the following way. Does this code meet this requirement? If yes, why? If not, propose a better solution.
var start = DateTime.Now;
//...
var end = DateTime.Now;
Średnie

.NET 4.5 introduces a new, easy and elegant way to retrieve a name of a method (caller) which executed/called a given method (calle).
public void Fun()
{
//Here, I want to get a name of a method that executed/called Fun method
}
Trudne

We want to use a class called  Fun, that  is defined in an external library. Unfortunately, a constructor of this class contains a bug which causes an exception. In other words, we can't create a new instance of Fun class, but we have to. You have to find a workaround. You mustn't modify Fun class.