Soci (Soczó Zsolt) szakmai blogja

2015.02.27.

.NET fejtörő 6. – megoldás

Filed under: .NET,Security,Szakmai élet,Teaser — Soczó Zsolt @ 13:36

Feladat.

Nincs mit írnom a megoldásról, Varga Tamás kolléga (ezek köszönet érte) annyira részletesen, alaposan kielemezte a témát a kommentek között, hogy ennél én csak kevesebbet tudnék írni, övé a szó, olvassátok.

TDD akció újra

Filed under: .NET,Felhívás,Szakmai élet,Test Driven Development,Unit Test — Soczó Zsolt @ 13:30

Tavaly már volt egy ilyen akcióm, az megtöltötte a termet (150k < 200k). Gyere, ne maradj le róla.

2015.02.22.

.NET fejtörő 5. – megoldás

Filed under: .NET,C#,Szakmai élet,Teaser — Soczó Zsolt @ 18:18

A fejtörő.

Molnár Csaba olyan teljesen megválaszolta a kérdést (köszönet érte), hogy a kommentjét egy az egyben bepasztázom:

C#-ban az idexer egy indexelt property, aminek alapértelmezetten Item a neve. Ezért fordítási hibát kapunk ennél a kódnál, hogy már van definíció az Item-re.
Ezt kétféle módon tudjuk elkerülni:
1. Az Item property-t átnevezzük valami másra.
2. Használjuk az indexeren az IndexerNameAttribute-ot, amivel megadhatjuk, hogy milyen néven jöjjön létre az indexer (ne Item néven).

Én személy szerint nem erőltetném a névütközést, inkább választanék más nevet.

Ami pluszként érdekes a példában (nekem nem volt magától értetődő), hogy lehet használni a params módosítót indexer esetén is.

SQL fejtörő 7. – megoldás

Filed under: Adatbázisok,SQL Server,SQL Server 2014,Szakmai élet,Teaser — Soczó Zsolt @ 18:00

Kérdés: meg tudom-e nézni egy hosszan futó SQL DML lekérdezésnél, hogy a mögötte futó operátorok (join, index seek, stb.) hány százaléknál járnak?

SQL Server 2014-től igen!

Nézzük a következő (buta) lekérdezést:

SET STATISTICS PROFILE ON;
GO
--Next, run your query in this session
select * from [dbo].[Nums] n1 cross join dbo.Nums n2;

Ez egy lassú, sok soros cross join, csak demó célra. A vizsgálandó lekérdezést olyan sessionben kell futtatni, amiben a STATISTICS PROFILE be van kapcsolva.

Így néz ki a végrehajtási terve:

CrossJoinPlan

A terv fontos a következőkhöz, azért raktam ide. És most jön a lényeg: sys.dm_exec_query_profiles. Ő mutatja meg, belül mi zajlik:

SELECT  
   node_id,physical_operator_name, SUM(row_count) row_count, SUM(estimate_row_count) AS estimate_row_count, 
   CAST(SUM(row_count)*100 AS float) / SUM(estimate_row_count) PercentComplete
FROM sys.dm_exec_query_profiles 
--WHERE session_id=54
GROUP BY node_id,physical_operator_name
ORDER BY node_id;

A végrehajtás kezdetén így néz ki a kimenete (ha valaki tud tippet adni, hogy lehet ezt SyntaxHighlighterrel jól formázni megköszönöm):

node_id	physical_operator_name	row_count	estimate_row_count	PercentComplete
0	Parallelism		1320422		4294967295		0.030743470422631
1	Nested Loops		1323284		4294967296		0.0308101065456867
2	Clustered Index Scan	15		100000			0.015
3	Table Spool		1323284		1410065408		0.0938455757082157
4	Clustered Index Scan	400000		400000			100

Egy perccel később:

node_id	physical_operator_name	row_count	estimate_row_count	PercentComplete
0	Parallelism	15917761	4294967295	0.370614254002137
1	Nested Loops	15920504	4294967296	0.370678119361401
2	Clustered Index Scan	161	100000	0.161
3	Table Spool	15920504	1410065408	1.12906138322911
4	Clustered Index Scan	400000	400000	100

Mit jelen ez? A terv alapján van két clustered index scanünk. Az egyik felolvasta a táblában található 400000 sort, azzal ő végzett is. Aztán a cilusos join elkezdi hozzávenni a tábla sorait, minden sorhoz 400000-et. Az egész eredménye belekerül a Table Spoolba, majd csurog ki a Parallelism operátoron keresztül (ami Gather Stream műveletet hajt végre, azaz összegyűjti a több szál által összerakott sorokat egy streambe, mivel párhuzamos a terv).

Lássuk be, marha érdekes látni, hogy áll belül egy nagyobb DML művelet, nem?

2015.02.14.

.NET fejtörő 4. – megoldás

Filed under: .NET,IIS7,Security,Szakmai élet,Teaser — Soczó Zsolt @ 16:23

Kérdés: miért nem jó, ha az ASP.NET Machine Key-emet Random.NextBytes()-szal generálom?

A Machine Key-t alapban viewstate validálásra használja az ASP.NET. HMAC algoritmussal csinál egy hasht, amihez a Machine Key-t mint kulcsot is felhasználja. Ez a kevésbé problémás dolog. Ami sokkal veszettebb, hogy amikor beléptetünk valakit az ASP.NET forms security-vel, akkor a beléptetett felhasználót azonosító adatot ezzel a Machine Key-jel titkosítják. Ha valaki megismeri ezt a kulcsot, akkor tud generálni kamu kukit, amibe azt a user id-t ír be, amit csak akar. Azaz meg tud személyesíteni másokat. Ebből aztán lesz spoofing, vagy akár elevation of privilege. Magyarul senki nem szeretné, ha bárki más beléphetne a nevében egy védett website-on. Például az internetes bankjába.

Szóval, talán most már érthető, a Machine Key-t nem szeretnénk, ha bárki megszerezné vagy kitalálná. Megszerezni csak a site feltörésével lehet, és admin jogokkal, tegyük fel ez nem történt meg. Ha azonban a véletlen sorozat generátorunk kiszámítható, akkor más is ugyanazzal az algoritmussal tud generálni egy olyan kulcsot, amit én is generáltam. És már jönnek is be más nevében.

A .NET Random pszeudo-random generátor, azonos seed-del mindig ugyanaz a sorozat jön ki belőle. Azt mondjátok de én ravasz vagyok, és beadom a DateTime.Now.Ticket neki inputként, az úgysem tudja a támadó. Nem tudja, de pörgetni ő is tudja ezt a számot addig, amíg ki nem találja a megfelelő seedet.

Mi a megoldás? Olyan random generátor kell, ami teljesen kiszámíthatatlan. Pl. a termikus zaj digitalizálva tökéletesen jó erre a célra. Ha ilyen modul nincs a gépben, akkor a Windows megpróbál valami nagyon randommal kijönni, például összerakva olyan vad perf counter értékeket, mint a proci ventilátor sebessége és egyebek.

A lényeg, hogy ha cripto szinten random érték kell, akkor az RNGCryptoServiceProvider típust kell használni erre a célra.

Egyébként meg IIS 7.5-től machine key-t tud generálni az IIS Manager GUI is. :)

2015.02.13.

SQL fejtörő 9.

Filed under: Adatbázisok,SQL Server,Szakmai élet,Teaser — Soczó Zsolt @ 09:00

Van egy táblánk, amiben számokat tárolunk. A számok nem teljesen folytonosak, az összefüggő részeket kell azonosítani.

use tempdb;

IF OBJECT_ID('dbo.Tabla', 'U') IS NOT NULL DROP TABLE dbo.Tabla;
GO
CREATE TABLE dbo.Tabla
(
	szam INT NOT NULL CONSTRAINT PK_Tabla PRIMARY KEY
);
INSERT INTO dbo.Tabla(szam)
VALUES(12),(13),(111),(112),(113),(237),(238),(340),(350),(351);
GO

select * from Tabla;

-- Ezt szeretnénk kinyerni, az összefüggő tartományokat
--tartomanyeleje	tartomanyvege
--12				13
--111				113
--237				238
--340				340
--350				351

A megfejtéseket szokás szerint kommentben várom, amelyeket 2 nap múlva engedek ki.

2015.02.11.

.NET fejtörő 6.

Filed under: Szakmai élet — Soczó Zsolt @ 09:00

Miért fogják feltörni könnyen az alábbi jelszó ellenőrzőt? Ne csak a nyilvánvaló okokat írjátok meg.

private static bool PassValidator(string pass)
{
    string passInDb = "password";   //az eredeti implementációban valahonnan memória cacheből jön az adat

    int i;
    for (i = 0; i < pass.Length; i++)
    {
        if (pass[i] != passInDb[i])
        {
            break;
        }
    }
    return i == passInDb.Length;
}

2015.02.10.

.NET fejtörő 3. – megoldás

Filed under: .NET,Szakmai élet,Teaser — Soczó Zsolt @ 17:45

Íme a kiírás.

Álljon itt újra a kód is:

struct Counter
{
    int counter;
    public override string ToString()
    {
        return counter++.ToString(CultureInfo.InvariantCulture);
    }
}

[TestMethod]
public void Teaser3()
{
    var sb = new StringBuilder();
            
    var sz = new Counter();
            
    sb.Append(sz);
    Object p = sz;
    Object o = p;
    sb.Append(sz);
    sb.Append(o);
    sb.Append(p);
    sb.Append(o);

    Assert.AreEqual("01234", sb.ToString());
}

Először lemaradt a feladatból a Counter struktúra, anélkül nem volt sok értelme a feladatnak, ezért az első pár választ nyilván félre mehetett.
A feladatban az a trükk, hogy nem class, hanem struktúra a Counter típus. A StringBuilderben a végén 00012 lesz. Miért?

Az sz egy a veremben tárolt struktúra. Az sb.Append() (ebben az esetben) objektumot vár paraméterül (ami reference type), amin meghívja a ToString() metódust, és ennek kimenetét rakja bele az építendő stringbe. Azonban az sz egy struktúra, value type, így azt a CLR-nek fel kell másolnia a heapre. Ezt hívják boxingnak. Ezen pont után a ToString() már a másolaton hívódik meg, az eredeti sz counter mezeje érintetlen marad.
Mivel postfix ++ operátort használunk, a kifejezés kimenete a növelés előtti érték lesz, azaz 0. Ez az első számunk.
Az Object p = sz explicit felboxolja sz-t a heapre. Az Object o = p pusztán egy másik referencia lesz ugyanerre az értékre.
Ezek után sb.Append(sz) újra boxol és kiírja a 0-t, mint a korábbi esetben. Ez a 2. számunk. Sokan szerintem itt már 1-et vártak, ami így is lenne, ha a Counter classként lenne definiálva.
Az sb.Append(o) az eddig még érintetlen felboxolt példányon hívódik meg. Mivel megint csak postfix ++ van, ez is 0 lesz. Ez a 3. 0.
Az sb.Append(p) ugyanezen példányra mutat, így végre ő már megnövelheti a számlálót 2-re, és visszaadhatja az 1-et. Ez a 4. számunk, ami végre 1.
Az sb.Append(o) pedig újra végigjátssza a növelést a más ismerős példánnyal, így jön ki belőle 2.

Ha a típusunk class lett volna, akkor jött volna ki belőle 01234.

A példának látszólag nincs jelentősége, a generikus típusok óta valóban kevesebb baj van a struktúrákkal. De még .NET 1.0-ban láttam olyat, amikor HashTable[“valami”]++ után a x = HashTable[“valami”] változatlan értéket adott vissza, meglepve a kollégákat. Most már talán érthető, miért.

SQL fejtörő 8.

Filed under: Adatbázisok,Szakmai élet,Teaser — Soczó Zsolt @ 09:00

SQL Serveren dolgozva van egy agresszív lekérdezés, amely szétzúzza a diszket, így a többi lekérdezés nem kap elég időt, kiéhezteti őket. Mit tudok tenni?

2015.02.09.

.NET fejtörő 5.

Filed under: Szakmai élet — Soczó Zsolt @ 09:00

Mi a gond az alábbi kóddal?

class Teaser4
{
    int Item = 0;

    public int this[params int[] arr]
    {
        get
        {
            return Item;
        }
    }
}

2015.02.06.

.NET fejtörő 3. hiánypótlás

Filed under: .NET,Szakmai élet,Teaser — Soczó Zsolt @ 12:38

Elnézést azoktól, akik filóztak a 3. .NET feladaton, elfelejtettem belerakni a Counter típust, anélkül semmi értelme a feladatnak. Így már érthető, miért nem jött rá megoldás. :)

Most akkor neki lehet esni még egyszer.

SQL fejtörő 7.

Filed under: Adatbázisok,SQL Server,Szakmai élet,Teaser — Soczó Zsolt @ 09:00

Meg tudom-e nézni egy hosszan futó SQL DML lekérdezésnél, hogy a mögötte futó operátorok (join, index seek, stb.) hány százaléknál járnak?

2015.02.05.

.NET fejtörő 4.

Filed under: .NET,Szakmai élet,Teaser — Soczó Zsolt @ 21:54

Ez most egy elméleti kérdés lesz. Van egy web farmom. Az ASP.NET Machine Key-emet legeneráltam a Random.NextBytes() segítségével, és beraktam minden gép machine.configjába. Mi a probléma a megoldásommal?

.NET fejtörő 3 – nincs megoldás?

Filed under: .NET,Szakmai élet,Teaser — Soczó Zsolt @ 21:48

Itt volt ez a fejtörő, de nem jött rá megoldás. Ennyire nem nehéz. Valaki?

.NET fejtörő 2. megoldás

Filed under: .NET,Szakmai élet — Soczó Zsolt @ 21:44

Feladat itt.

Emlékeztetőűl a feladat:

var sb = new StringBuilder();

for (int i = 0; i < 10; i++)
{
    sb.Append(i + ' ');
}

A művelet kimenete:
32333435363738394041

Miért?

i integer, ‘ ‘ char. A char nem más, mint egy 16-bites numeric (ordinal) érték, mi implicit konvertálható más, nagyobb vagy azonos méretű egészekké.
Azaz a ‘ ‘ szóköz karakter 32-es kódját kell hozzáadni a ciklusváltozóhoz, ezért jön ki egy számsorozat végeredményként.

Powered by WordPress