sql >> Databasteknik >  >> RDS >> Database

Dataingenjörsintervjufrågor med Python

Att gå på intervjuer kan vara en tidskrävande och tröttsam process, och tekniska intervjuer kan vara ännu mer stressande! Denna handledning syftar till att förbereda dig för några vanliga frågor du kommer att stöta på under din dataingenjörsintervju. Du lär dig hur du svarar på frågor om databaser, Python och SQL.

I slutet av den här självstudien kommer du att kunna:

  • Förstå vanliga dataingenjörsintervjufrågor
  • Skillnad mellan relationella och icke-relationella databaser
  • Konfigurera databaser med Python
  • Använd Python för att söka efter data

Gratis nedladdning: Få ett exempelkapitel från Python Tricks:The Book som visar dig Pythons bästa praxis med enkla exempel som du kan använda direkt för att skriva vackrare + Pythonic kod.


Bli dataingenjör

Dataingenjörsrollen kan vara omfattande och varierande. Du behöver ha praktisk kunskap om flera tekniker och koncept. Dataingenjörer är flexibla i sitt tänkande. Som ett resultat kan de vara skickliga i flera ämnen, som databaser, mjukvaruutveckling, DevOps och big data.


Vad gör en dataingenjör?

Med tanke på dess varierande kompetens kan en dataingenjörsroll sträcka sig över många olika arbetsbeskrivningar. En dataingenjör kan ansvara för databasdesign, schemadesign och skapa flera databaslösningar. Detta arbete kan även involvera en databasadministratör.

Som dataingenjör , kan du fungera som en brygga mellan databasen och datavetenskapsteamen. I så fall kommer du också att ansvara för datarensning och förberedelse. Om big data är inblandat är det din uppgift att komma med en effektiv lösning för den datan. Detta arbete kan överlappa DevOps-rollen.

Du måste också göra effektiva datafrågor för rapportering och analys. Du kan behöva interagera med flera databaser eller skriva lagrade procedurer. För många lösningar som webbplatser eller tjänster med hög trafik kan det finnas mer än en databas. I dessa fall är dataingenjören ansvarig för att sätta upp databaserna, underhålla dem och överföra data mellan dem.



Hur kan Python hjälpa dataingenjörer?

Python är känt för att vara programmeringsspråkens schweiziska armékniv. Det är särskilt användbart inom datavetenskap, backend-system och server-side scripting. Det beror på att Python har stark skrivning, enkel syntax och ett överflöd av tredjepartsbibliotek att använda. Pandas, SciPy, Tensorflow, SQLAlchemy och NumPy är några av de mest använda biblioteken i produktion inom olika branscher.

Det viktigaste är att Python minskar utvecklingstiden, vilket innebär färre kostnader för företagen. För en dataingenjör är den mesta kodexekveringen databasbunden, inte CPU-bunden. På grund av detta är det vettigt att dra nytta av Pythons enkelhet, även till priset av långsammare prestanda jämfört med kompilerade språk som C# och Java.




Svara dataingenjörsintervjufrågor

Nu när du vet vad din roll kan bestå av är det dags att lära dig hur du svarar på några dataingenjörsintervjufrågor! Även om det finns mycket att täcka, kommer du att se praktiska Python-exempel genom hela handledningen för att guida dig på vägen.



Frågor om relationsdatabaser

Databaser är en av de mest avgörande komponenterna i ett system. Utan dem kan det inte finnas någon stat och ingen historia. Även om du kanske inte har ansett databasdesign vara en prioritet, vet att det kan ha en betydande inverkan på hur snabbt din sida laddas. Under de senaste åren har flera stora företag introducerat flera nya verktyg och tekniker:

  • NoSQL
  • Cachedatabaser
  • Diagramdatabaser
  • NoSQL-stöd i SQL-databaser

Dessa och andra tekniker uppfanns för att försöka öka hastigheten med vilken databaser behandlar förfrågningar. Du kommer förmodligen att behöva prata om dessa begrepp i din dataingenjörsintervju, så låt oss gå igenom några frågor!


Fråga 1:Relationella vs icke-relationella databaser

En relationsdatabas är en där data lagras i form av en tabell. Varje tabell har ett schema , vilket är de kolumner och typer som en post måste ha. Varje schema måste ha minst en primärnyckel som unikt identifierar posten. Det finns med andra ord inga dubbletter av rader i din databas. Dessutom kan varje tabell relateras till andra tabeller med hjälp av främmande nycklar.

En viktig aspekt av relationsdatabaser är att en ändring i ett schema måste tillämpas på alla poster. Detta kan ibland orsaka brott och stor huvudvärk under migrationer. Icke-relationella databaser hantera saker på ett annat sätt. De är i sig schemalösa, vilket innebär att poster kan sparas med olika scheman och med en annan, kapslad struktur. Poster kan fortfarande ha primärnycklar, men en ändring av schemat görs på en post-för-post-basis.

Du skulle behöva utföra ett hastighetsjämförelsetest baserat på vilken typ av funktion som utförs. Du kan välja INSERT , UPDATE , DELETE eller annan funktion. Schemadesign, index, antalet aggregationer och antalet poster kommer också att påverka denna analys, så du måste testa det noggrant. Du kommer att lära dig mer om hur du gör detta senare.

Databaser skiljer sig också i skalbarhet . En icke-relationell databas kan vara mindre svår att distribuera. Det beror på att en samling relaterade poster enkelt kan lagras på en viss nod. Å andra sidan kräver relationsdatabaser mer eftertanke och använder sig vanligtvis av ett master-slave-system.



Ett SQLite-exempel

Nu när du har svarat på vad relationsdatabaser är, är det dags att gräva i lite Python! SQLite är en bekväm databas som du kan använda på din lokala dator. Databasen är en enda fil, vilket gör den idealisk för prototypsyften. Importera först det nödvändiga Python-biblioteket och skapa en ny databas:

import sqlite3

db = sqlite3.connect(':memory:')  # Using an in-memory database
cur = db.cursor()

Du är nu ansluten till en databas i minnet och har ditt markörobjekt redo att gå.

Därefter skapar du följande tre tabeller:

  1. Kund: Den här tabellen kommer att innehålla en primärnyckel samt kundens för- och efternamn.
  2. Artiklar: Den här tabellen kommer att innehålla en primärnyckel, artikelns namn och artikelns pris.
  3. Köpta varor :Den här tabellen kommer att innehålla ett ordernummer, datum och pris. Den kommer också att ansluta till primärnycklarna i tabellerna Objekt och Kund.

Nu när du har en uppfattning om hur dina tabeller kommer att se ut kan du gå vidare och skapa dem:

cur.execute('''CREATE TABLE IF NOT EXISTS Customer (
                id integer PRIMARY KEY,
                firstname varchar(255),
                lastname varchar(255) )''')
cur.execute('''CREATE TABLE IF NOT EXISTS Item (
                id integer PRIMARY KEY,
                title varchar(255),
                price decimal )''')
cur.execute('''CREATE TABLE IF NOT EXISTS BoughtItem (
                ordernumber integer PRIMARY KEY,
                customerid integer,
                itemid integer,
                price decimal,
                CONSTRAINT customerid
                    FOREIGN KEY (customerid) REFERENCES Customer(id),
                CONSTRAINT itemid
                    FOREIGN KEY (itemid) REFERENCES Item(id) )''')

Du har skickat en fråga till cur.execute() för att skapa dina tre tabeller.

Det sista steget är att fylla i dina tabeller med data:

cur.execute('''INSERT INTO Customer(firstname, lastname)
               VALUES ('Bob', 'Adams'),
                      ('Amy', 'Smith'),
                      ('Rob', 'Bennet');''')
cur.execute('''INSERT INTO Item(title, price)
               VALUES ('USB', 10.2),
                      ('Mouse', 12.23),
                      ('Monitor', 199.99);''')
cur.execute('''INSERT INTO BoughtItem(customerid, itemid, price)
               VALUES (1, 1, 10.2),
                      (1, 2, 12.23),
                      (1, 3, 199.99),
                      (2, 3, 180.00),
                      (3, 2, 11.23);''') # Discounted price 

Nu när det finns några få poster i varje tabell kan du använda dessa data för att svara på några fler dataingenjörsintervjufrågor.



Fråga 2:SQL-aggregationsfunktioner

Aggregationsfunktioner är de som utför en matematisk operation på en resultatuppsättning. Några exempel inkluderar AVG , COUNT , MIN , MAX och SUM . Ofta behöver du GROUP BY och HAVING klausuler för att komplettera dessa sammanställningar. En användbar aggregeringsfunktion är AVG , som du kan använda för att beräkna medelvärdet av en given resultatuppsättning:

>>>
>>> cur.execute('''SELECT itemid, AVG(price) FROM BoughtItem GROUP BY itemid''')
>>> print(cur.fetchall())
[(1, 10.2), (2, 11.73), (3, 189.995)]

Här har du hämtat det genomsnittliga priset för var och en av de köpta föremålen i din databas. Du kan se att objektet har ett itemid av 1 har ett genomsnittspris på 10,20 USD.

För att göra ovanstående utdata lättare att förstå kan du visa objektets namn istället för itemid :

>>>
>>> cur.execute('''SELECT item.title, AVG(boughtitem.price) FROM BoughtItem as boughtitem
...             INNER JOIN Item as item on (item.id = boughtitem.itemid)
...             GROUP BY boughtitem.itemid''')
...
>>> print(cur.fetchall())
[('USB', 10.2), ('Mouse', 11.73), ('Monitor', 189.995)]

Nu ser du lättare att varan med ett genomsnittspris på 10,20 USD är USB .

En annan användbar aggregering är SUM . Du kan använda den här funktionen för att visa det totala beloppet som varje kund spenderade:

>>>
>>> cur.execute('''SELECT customer.firstname, SUM(boughtitem.price) FROM BoughtItem as boughtitem
...             INNER JOIN Customer as customer on (customer.id = boughtitem.customerid)
...             GROUP BY customer.firstname''')
...
>>> print(cur.fetchall())
[('Amy', 180), ('Bob', 222.42000000000002), ('Rob', 11.23)]

I genomsnitt spenderade kunden vid namn Amy cirka 180 USD, medan Rob bara spenderade 11,23 USD!

Om din intervjuare gillar databaser kanske du vill fräscha upp kapslade frågor, kopplingstyper och de steg som en relationsdatabas tar för att utföra din fråga.



F3:Snabbare SQL-frågor

Hastigheten beror på olika faktorer, men påverkas mest av hur många av vart och ett av följande som finns:

  • Gå med
  • Aggregationer
  • Övergångar
  • Rekord

Ju större antal kopplingar, desto högre komplexitet och desto större antal genomgångar i tabeller. Multiple joins är ganska dyra att utföra på flera tusen poster som involverar flera tabeller eftersom databasen också behöver cache mellanresultatet! Vid det här laget kanske du börjar fundera på hur du ska öka ditt minne.

Hastigheten påverkas också av om det finns index eller inte finns i databasen. Index är extremt viktiga och låter dig snabbt söka igenom en tabell och hitta en matchning för någon kolumn som anges i frågan.

Index sorterar posterna till priset av högre insättningstid, samt viss lagring. Flera kolumner kan kombineras för att skapa ett enda index. Till exempel kolumnerna date och price kan kombineras eftersom din fråga beror på båda villkoren.



F4:Felsökning av SQL-frågor

De flesta databaser innehåller en EXPLAIN QUERY PLAN som beskriver de steg som databasen tar för att köra frågan. För SQLite kan du aktivera den här funktionen genom att lägga till EXPLAIN QUERY PLAN framför en SELECT uttalande:

>>>
>>> cur.execute('''EXPLAIN QUERY PLAN SELECT customer.firstname, item.title, 
...                item.price, boughtitem.price FROM BoughtItem as boughtitem
...                INNER JOIN Customer as customer on (customer.id = boughtitem.customerid)
...                INNER JOIN Item as item on (item.id = boughtitem.itemid)''')
...
>>> print(cur.fetchall())
[(4, 0, 0, 'SCAN TABLE BoughtItem AS boughtitem'), 
(6, 0, 0, 'SEARCH TABLE Customer AS customer USING INTEGER PRIMARY KEY (rowid=?)'), 
(9, 0, 0, 'SEARCH TABLE Item AS item USING INTEGER PRIMARY KEY (rowid=?)')]

Den här frågan försöker lista förnamn, artikeltitel, originalpris och köppris för alla köpta varor.

Så här ser själva frågeplanen ut:

SCAN TABLE BoughtItem AS boughtitem
SEARCH TABLE Customer AS customer USING INTEGER PRIMARY KEY (rowid=?)
SEARCH TABLE Item AS item USING INTEGER PRIMARY KEY (rowid=?)

Observera att fetch-satsen i din Python-kod endast returnerar förklaringen, men inte resultaten. Det beror på att EXPLAIN QUERY PLAN är inte avsedd att användas i produktionen.




Frågor om icke-relationella databaser

I det föregående avsnittet angav du skillnaderna mellan relationella och icke-relationella databaser och använde SQLite med Python. Nu ska du fokusera på NoSQL. Ditt mål är att lyfta fram dess styrkor, skillnader och användningsfall.


Ett MongoDB-exempel

Du kommer att använda samma data som tidigare, men den här gången kommer din databas att vara MongoDB. Denna NoSQL-databas är dokumentbaserad och skalas mycket bra. Först och främst måste du installera det nödvändiga Python-biblioteket:

$ pip install pymongo

Du kanske också vill installera MongoDB Compass Community. Den innehåller en lokal IDE som är perfekt för att visualisera databasen. Med den kan du se de skapade posterna, skapa utlösare och fungera som visuell administratör för databasen.

Obs! För att köra koden i det här avsnittet behöver du en körande databasserver. För att lära dig mer om hur du ställer in det, kolla in Introduktion till MongoDB och Python.

Så här skapar du databasen och infogar lite data:

import pymongo

client = pymongo.MongoClient("mongodb://localhost:27017/")

# Note: This database is not created until it is populated by some data
db = client["example_database"]

customers = db["customers"]
items = db["items"]

customers_data = [{ "firstname": "Bob", "lastname": "Adams" },
                  { "firstname": "Amy", "lastname": "Smith" },
                  { "firstname": "Rob", "lastname": "Bennet" },]
items_data = [{ "title": "USB", "price": 10.2 },
              { "title": "Mouse", "price": 12.23 },
              { "title": "Monitor", "price": 199.99 },]

customers.insert_many(customers_data)
items.insert_many(items_data)

Som du kanske har märkt lagrar MongoDB dataposter i samlingar , som motsvarar en lista över ordböcker i Python. I praktiken lagrar MongoDB BSON-dokument.



F5:Fråga efter data med MongoDB

Låt oss försöka replikera BoughtItem tabellen först, som du gjorde i SQL. För att göra detta måste du lägga till ett nytt fält till en kund. MongoDB:s dokumentation anger att sökordsoperatorn set kan användas för att uppdatera en post utan att behöva skriva alla befintliga fält:

# Just add "boughtitems" to the customer where the firstname is Bob
bob = customers.update_many(
        {"firstname": "Bob"},
        {
            "$set": {
                "boughtitems": [
                    {
                        "title": "USB",
                        "price": 10.2,
                        "currency": "EUR",
                        "notes": "Customer wants it delivered via FedEx",
                        "original_item_id": 1
                    }
                ]
            },
        }
    )

Lägg märke till hur du lade till ytterligare fält till customer utan att uttryckligen definiera schemat i förväg. Snyggt!

Faktum är att du kan uppdatera en annan kund med ett något ändrat schema:

amy = customers.update_many(
        {"firstname": "Amy"},
        {
            "$set": {
                "boughtitems":[
                    {
                        "title": "Monitor",
                        "price": 199.99,
                        "original_item_id": 3,
                        "discounted": False
                    }
                ]
            } ,
        }
    )
print(type(amy))  # pymongo.results.UpdateResult

I likhet med SQL tillåter dokumentbaserade databaser också frågor och aggregering att utföras. Funktionaliteten kan dock skilja sig både syntaktisk och i den underliggande exekveringen. Faktum är att du kanske har märkt att MongoDB reserverar $ tecken för att specificera något kommando eller aggregering på posterna, såsom $group . Du kan lära dig mer om detta beteende i de officiella dokumenten.

Du kan utföra frågor precis som du gjorde i SQL. Till att börja med kan du skapa ett index:

>>>
>>> customers.create_index([("name", pymongo.DESCENDING)])

Detta är valfritt, men det snabbar upp frågor som kräver namnsökningar.

Sedan kan du hämta kundnamnen sorterade i stigande ordning:

>>>
>>> items = customers.find().sort("name", pymongo.ASCENDING)

Du kan också gå igenom och skriva ut de köpta föremålen:

>>>
>>> for item in items:
...     print(item.get('boughtitems'))    
...
None
[{'title': 'Monitor', 'price': 199.99, 'original_item_id': 3, 'discounted': False}]
[{'title': 'USB', 'price': 10.2, 'currency': 'EUR', 'notes': 'Customer wants it delivered via FedEx', 'original_item_id': 1}]

Du kan till och med hämta en lista med unika namn i databasen:

>>>
>>> customers.distinct("firstname")
['Bob', 'Amy', 'Rob']

Nu när du känner till namnen på kunderna i din databas kan du skapa en fråga för att hämta information om dem:

>>>
>>> for i in customers.find({"$or": [{'firstname':'Bob'}, {'firstname':'Amy'}]}, 
...                                  {'firstname':1, 'boughtitems':1, '_id':0}):
...     print(i)
...
{'firstname': 'Bob', 'boughtitems': [{'title': 'USB', 'price': 10.2, 'currency': 'EUR', 'notes': 'Customer wants it delivered via FedEx', 'original_item_id': 1}]}
{'firstname': 'Amy', 'boughtitems': [{'title': 'Monitor', 'price': 199.99, 'original_item_id': 3, 'discounted': False}]}

Här är motsvarande SQL-fråga:

SELECT firstname, boughtitems FROM customers WHERE firstname LIKE ('Bob', 'Amy')

Observera att även om syntaxen bara kan skilja sig något, finns det en drastisk skillnad i hur frågor exekveras under huven. Detta kan förväntas på grund av de olika frågestrukturerna och användningsfallen mellan SQL- och NoSQL-databaser.



F6:NoSQL vs SQL

Om du har ett schema som ständigt förändras, såsom finansiell regulatorisk information, kan NoSQL modifiera posterna och kapslingsrelaterad information. Föreställ dig hur många anslutningar du skulle behöva göra i SQL om du hade åtta beställningar av kapsling! Den här situationen är dock vanligare än du tror.

Vad händer nu om du vill köra rapporter, extrahera information om den finansiella informationen och dra slutsatser? I det här fallet måste du köra komplexa frågor, och SQL tenderar att vara snabbare i detta avseende.

Obs! SQL-databaser, särskilt PostgreSQL, har också släppt en funktion som gör att frågebara JSON-data kan infogas som en del av en post. Även om detta kan kombinera det bästa av två världar, kan hastigheten vara ett problem.

Det är snabbare att fråga ostrukturerad data från en NoSQL-databas än det är att fråga JSON-fält från en kolumn av JSON-typ i PostgreSQL. Du kan alltid göra ett hastighetsjämförelsetest för ett definitivt svar.

Icke desto mindre kan den här funktionen minska behovet av en extra databas. Ibland lagras inlagda eller serialiserade objekt i poster i form av binära typer och avserialiseras sedan vid läsning.

Hastighet är dock inte det enda måttet. Du vill också ta hänsyn till saker som transaktioner, atomicitet, hållbarhet och skalbarhet. Transaktioner är viktiga i finansiella tillämpningar, och sådana funktioner har företräde.

Eftersom det finns ett brett utbud av databaser, var och en med sina egna funktioner, är det dataingenjörens uppgift att fatta ett välgrundat beslut om vilken databas som ska användas i varje applikation. För mer information kan du läsa om ACID-egenskaper relaterade till databastransaktioner.

Du kan också få frågan om vilka andra databaser du känner till i din dataingenjörsintervju. Det finns flera andra relevanta databaser som används av många företag:

  • Elastisk sökning är mycket effektiv i textsökning. Den använder sin dokumentbaserade databas för att skapa ett kraftfullt sökverktyg.
  • Newt DB kombinerar ZODB och PostgreSQL JSONB-funktionen för att skapa en Python-vänlig NoSQL-databas.
  • InfluxDB används i tidsserieapplikationer för att lagra händelser.

Listan fortsätter, men detta illustrerar hur en mängd olika tillgängliga databaser alla vänder sig till deras nischindustri.




Frågor om cachedatabaser

Cachedatabaser hålla data som du använder ofta. De lever tillsammans med de viktigaste SQL- och NoSQL-databaserna. Deras mål är att minska belastningen och betjäna förfrågningar snabbare.


Ett Redis-exempel

Du har täckt SQL- och NoSQL-databaser för långsiktiga lagringslösningar, men hur är det med snabbare och mer omedelbar lagring? Hur kan en dataingenjör ändra hur snabbt data hämtas från en databas?

Typiska webbapplikationer hämtar ofta använd data, som en användares profil eller namn. Om all data finns i en databas, då antalet träffar databasservern kommer att bli överdriven och onödig. Som sådan behövs en snabbare, mer omedelbar lagringslösning.

Även om detta minskar serverbelastningen skapar det också två huvudvärk för dataingenjören, backend-teamet och DevOps-teamet. För det första behöver du nu någon databas som har en snabbare lästid än din huvudsakliga SQL- eller NoSQL-databas. Men innehållet i båda databaserna måste så småningom matcha. (Välkommen till problemet med statlig konsekvens mellan databaser! Njut.)

Den andra huvudvärken är att DevOps nu behöver oroa sig för skalbarhet, redundans och så vidare för den nya cachedatabasen. I nästa avsnitt kommer du att dyka ner i problem som dessa med hjälp av Redis.



F7:Hur man använder cachedatabaser

Du kanske har fått tillräckligt med information från introduktionen för att svara på den här frågan! En cachedatabas är en snabb lagringslösning som används för att lagra kortlivad, strukturerad eller ostrukturerad data. Den kan partitioneras och skalas efter dina behov, men den är vanligtvis mycket mindre i storlek än din huvuddatabas. På grund av detta kan din cachedatabas finnas i minnet, vilket gör att du kan kringgå behovet av att läsa från en disk.

Obs! Om du någonsin har använt ordböcker i Python, följer Redis samma struktur. Det är en nyckel-värde butik, där du kan SET och GET data precis som en Python dict .

När en förfrågan kommer in kontrollerar du först cachedatabasen, sedan huvuddatabasen. På så sätt kan du förhindra att onödiga och upprepade förfrågningar når huvuddatabasens server. Eftersom en cachedatabas har en lägre lästid, drar du också nytta av en prestandaökning!

Du kan använda pip för att installera det nödvändiga biblioteket:

$ pip install redis

Överväg nu en begäran om att få användarens namn från deras ID:

import redis
from datetime import timedelta

# In a real web application, configuration is obtained from settings or utils
r = redis.Redis()

# Assume this is a getter handling a request
def get_name(request, *args, **kwargs):
    id = request.get('id')
    if id in r:
        return r.get(id)  # Assume that we have an {id: name} store
    else:
        # Get data from the main DB here, assume we already did it
        name = 'Bob'
        # Set the value in the cache database, with an expiration time
        r.setex(id, timedelta(minutes=60), value=name)
        return name

Denna kod kontrollerar om namnet finns i Redis med id nyckel. Om inte, ställs namnet in med en utgångstid, som du använder eftersom cachen är kortlivad.

Vad händer nu om din intervjuare frågar dig vad som är fel med den här koden? Ditt svar bör vara att det inte finns något undantagshantering! Databaser kan ha många problem, som avbrutna anslutningar, så det är alltid en bra idé att försöka fånga upp dessa undantag.




Frågor om designmönster och ETL-koncept

I stora applikationer använder du ofta mer än en typ av databas. Faktum är att det är möjligt att använda PostgreSQL, MongoDB och Redis allt inom bara en applikation! Ett utmanande problem är att hantera tillståndsförändringar mellan databaser, vilket utsätter utvecklaren för problem med konsekvens. Tänk på följande scenario:

  1. Ett värde i Databas #1 uppdateras.
  2. Samma värde i databas #2 hålls densamma (inte uppdaterad).
  3. En fråga körs på databas #2.

Nu har du fått ett inkonsekvent och föråldrat resultat! Resultaten som returneras från den andra databasen återspeglar inte det uppdaterade värdet i den första. Detta kan hända med två valfria databaser, men det är särskilt vanligt när huvuddatabasen är en NoSQL-databas och information omvandlas till SQL för frågeändamål.

Databaser kan ha bakgrundsarbetare för att ta itu med sådana problem. Dessa arbetare extraherar data från en databas, omvandla det på något sätt och ladda det till måldatabasen. När du konverterar från en NoSQL-databas till en SQL-databas tar processen Extrahera, transformera, ladda (ETL) följande steg:

  1. Extrahera: Det finns en MongoDB-utlösare när en post skapas, uppdateras och så vidare. En återuppringningsfunktion anropas asynkront på en separat tråd.
  2. Omvandla: Delar av posten extraheras, normaliseras och placeras i rätt datastruktur (eller rad) för att infogas i SQL.
  3. Ladda: SQL-databasen uppdateras i omgångar, eller som en enda post för skrivningar med hög volym.

Detta arbetsflöde är ganska vanligt i ekonomi-, spel- och rapporteringsapplikationer. I dessa fall kräver det ständigt föränderliga schemat en NoSQL-databas, men rapportering, analys och aggregering kräver en SQL-databas.


Fråga 8:ETL-utmaningar

Det finns flera utmanande koncept i ETL, inklusive följande:

  • Big data
  • Statliga problem
  • Asynkrona arbetare
  • Typmatchning

Listan fortsätter! Men eftersom stegen i ETL-processen är väldefinierade och logiska, kommer data- och backendingenjörerna vanligtvis att oroa sig mer om prestanda och tillgänglighet snarare än implementering.

Om din applikation skriver tusentals poster per sekund till MongoDB, måste din ETL-arbetare hålla jämna steg med att transformera, ladda och leverera data till användaren i den begärda formen. Hastighet och latens kan bli ett problem, så dessa arbetare är vanligtvis skrivna på snabba språk. Du kan använda kompilerad kod för transformeringssteget för att påskynda saker och ting, eftersom denna del vanligtvis är CPU-bunden.

Obs! Multibearbetning och separation av arbetare är andra lösningar som du kanske vill överväga.

Om du har att göra med många CPU-intensiva funktioner, kanske du vill kolla in Numba. Detta bibliotek kompilerar funktioner för att göra dem snabbare vid exekvering. Det bästa av allt är att detta enkelt implementeras i Python, även om det finns vissa begränsningar för vilka funktioner som kan användas i dessa kompilerade funktioner.



Fråga 9:Designmönster i Big Data

Föreställ dig att Amazon behöver skapa ett rekommendationssystem att föreslå lämpliga produkter för användarna. Datavetenskapsteamet behöver data och mycket av det! De går till dig, dataingenjören, och ber dig skapa ett separat mellanlagringsdatabaslager. Det är där de kommer att rensa upp och omvandla data.

Du kan bli chockad över att få en sådan begäran. När du har terabyte med data behöver du flera maskiner för att hantera all den informationen. En databasaggregationsfunktion kan vara en mycket komplex operation. Hur kan du fråga, sammanställa och använda relativt stor data på ett effektivt sätt?

Apache hade från början introducerat MapReduce, som följer kartan, blanda, reducera arbetsflöde. Tanken är att kartlägga olika data på separata maskiner, även kallade kluster. Sedan kan du utföra arbete på data, grupperade efter en nyckel, och slutligen aggregera data i slutskedet.

Det här arbetsflödet används fortfarande idag, men det har bleknat nyligen till förmån för Spark. Designmönstret utgör dock grunden för de flesta big data-arbetsflöden och är ett mycket spännande koncept. Du kan läsa mer om MapReduce på IBM Analytics.



F10:Vanliga aspekter av ETL-processen och Big Data-arbetsflöden

Du kanske tycker att detta är en ganska udda fråga, men det är helt enkelt en kontroll av dina datavetenskapliga kunskaper, såväl som din övergripande designkunskap och erfarenhet.

Båda arbetsflödena följer Producent-Konsument mönster. En arbetare (producenten) producerar data av något slag och matar ut det till en pipeline. Denna pipeline kan ta många former, inklusive nätverksmeddelanden och triggers. Efter att producenten matat ut data, konsumerar och använder konsumenten den. Dessa arbetare arbetar vanligtvis på ett asynkront sätt och exekveras i separata processer.

Du kan likna producenten med extrakt- och transformeringsstegen i ETL-processen. På liknande sätt, i big data, kartläggningen kan ses som producenten, medan reduceraren är faktiskt konsumenten. Denna åtskillnad av problem är extremt viktig och effektiv i utvecklingen och arkitekturdesignen av applikationer.




Slutsats

Grattis! Du har täckt mycket mark och svarat på flera dataingenjörsintervjufrågor. Du förstår nu lite mer om de många olika hattar en dataingenjör kan bära, såväl som vad ditt ansvar är med avseende på databaser, design och arbetsflöde.

Beväpnad med denna kunskap kan du nu:

  • Använd Python med SQL, NoSQL och cachedatabaser
  • Använd Python i ETL- och frågeapplikationer
  • Planera projekt i förväg och ha design och arbetsflöde i åtanke

Även om intervjufrågor kan variera, har du blivit utsatt för flera ämnen och lärt dig att tänka utanför ramarna inom många olika områden inom datavetenskap. Nu är du redo för en fantastisk intervju!



  1. SQL Server Texttyp kontra varchar datatyp

  2. Det effektivaste sättet att lagra IP-adress i MySQL

  3. Fundamentals of table expressions, Del 4 – Härledda tabeller, optimeringsöverväganden, fortsättning

  4. Hur man listar tabell främmande nycklar