Questions d'entretiens pour le poste de Data Engineer avec Python – Real Python

By | décembre 11, 2019

python pour débutant

Aller aux entretiens peut être un processus long et fatigant, et les entretiens techniques peuvent être encore plus stressants! Ce didacticiel vise à vous préparer à certaines questions courantes que vous rencontrerez lors de votre entretien avec un ingénieur de données. Vous apprendrez à répondre aux questions sur les bases de données, Python et SQL.

À la fin de ce didacticiel, vous serez en mesure de:

  • Comprendre les questions d'entrevue courantes des ingénieurs de données
  • Distinguer les bases de données relationnelles et non relationnelles
  • Configurer des bases de données à l'aide de Python
  • Utiliser Python pour interroger des données

Devenir ingénieur de données

Le rôle d'ingénierie des données peut être vaste et varié. Vous devrez avoir une connaissance pratique de plusieurs technologies et concepts. Les ingénieurs de données sont flexibles dans leur façon de penser. En conséquence, ils peuvent maîtriser plusieurs sujets, tels que les bases de données, le développement de logiciels, DevOps et les Big Data.

Que fait un ingénieur de données?

Compte tenu de ses compétences variées, un rôle d'ingénierie des données peut couvrir de nombreuses descriptions de travail différentes. Un ingénieur de données peut être responsable de la conception de la base de données, de la conception du schéma et de la création de plusieurs solutions de base de données. Ce travail peut également impliquer un administrateur de base de données.

Comme un ingénieur de données, vous pourriez servir de pont entre la base de données et les équipes de science des données. Dans ce cas, vous serez également responsable du nettoyage et de la préparation des données. Si le Big Data est impliqué, alors c'est votre travail de trouver une solution efficace pour ces données. Ce travail peut chevaucher le rôle DevOps.

Vous devrez également effectuer des requêtes de données efficaces pour la création de rapports et l'analyse. Vous devrez peut-être interagir avec plusieurs bases de données ou écrire des procédures stockées. Pour de nombreuses solutions comme les sites Web ou les services à fort trafic, il peut y en avoir plus que sur la base de données présente. Dans ces cas, l'ingénieur de données est responsable de la configuration des bases de données, de leur maintenance et du transfert de données entre elles.

Comment Python peut-il aider les ingénieurs de données?

Python est connu pour être le couteau suisse des langages de programmation. Il est particulièrement utile dans la science des données, les systèmes dorsaux et les scripts côté serveur. C'est parce que Python a un typage fort, une syntaxe simple et une abondance de bibliothèques tierces à utiliser. Pandas, SciPy, Tensorflow, SQLAlchemy et NumPy sont parmi les bibliothèques les plus utilisées en production dans différentes industries.

Plus important encore, Python réduit le temps de développement, ce qui signifie moins de dépenses pour les entreprises. Pour un ingénieur de données, la plupart de l'exécution de code est liée à la base de données et non à l'unité centrale. Pour cette raison, il est logique de capitaliser sur la simplicité de Python, même au prix de performances plus lentes par rapport aux langages compilés tels que C # et Java.

Questions d'entretiens pour le poste de Data Engineer chez Answering

Maintenant que vous savez en quoi pourrait consister votre rôle, il est temps d'apprendre à répondre à quelques questions d'entrevue d'ingénieur de données! Bien qu'il y ait beaucoup de chemin à parcourir, vous verrez des exemples pratiques de Python tout au long du didacticiel pour vous guider tout au long du processus.

Questions sur les bases de données relationnelles

Les bases de données sont l'un des composants les plus cruciaux d'un système. Sans eux, il ne peut y avoir d'État ni d'histoire. Bien que vous n'ayez peut-être pas considéré la conception de base de données comme une priorité, sachez qu'elle peut avoir un impact significatif sur la vitesse de chargement de votre page. Au cours des dernières années, plusieurs grandes sociétés ont introduit plusieurs nouveaux outils et techniques:

  • NoSQL
  • Mettre en cache les bases de données
  • Bases de données graphiques
  • Prise en charge de NoSQL dans les bases de données SQL

Ces techniques et d'autres ont été inventées pour essayer d'augmenter la vitesse à laquelle les bases de données traitent les demandes. Vous aurez probablement besoin de parler de ces concepts dans votre entretien avec l'ingénieur de données, alors passons en revue quelques questions!

Q1: Bases de données relationnelles vs non relationnelles

UNE base de données relationnelle est celui où les données sont stockées sous la forme d'une table. Chaque table a un schéma, qui sont les colonnes et les types qu'un enregistrement doit avoir. Chaque schéma doit avoir au moins une clé primaire qui identifie de façon unique cet enregistrement. En d'autres termes, il n'y a pas de lignes en double dans votre base de données. De plus, chaque table peut être liée à d'autres tables à l'aide de clés étrangères.

Un aspect important des bases de données relationnelles est qu'une modification d'un schéma doit être appliquée à tous les enregistrements. Cela peut parfois provoquer des ruptures et de gros maux de tête lors des migrations. Bases de données non relationnelles aborder les choses d'une manière différente. Ils sont intrinsèquement sans schéma, ce qui signifie que les enregistrements peuvent être sauvegardés avec différents schémas et avec une structure imbriquée différente. Les enregistrements peuvent toujours avoir des clés primaires, mais une modification du schéma se fait entrée par entrée.

Vous devez effectuer un test de comparaison de vitesse en fonction du type de fonction effectuée. Tu peux choisir INSÉRER, MISE À JOUR, SUPPRIMERou une autre fonction. La conception du schéma, les indices, le nombre d'agrégations et le nombre d'enregistrements affecteront également cette analyse, vous devrez donc effectuer des tests approfondis. Vous en apprendrez plus sur la façon de procéder plus tard.

Les bases de données diffèrent également évolutivité. Une base de données non relationnelle peut être moins compliquée à distribuer. En effet, une collection d'enregistrements associés peut être facilement stockée sur un nœud particulier. D'un autre côté, les bases de données relationnelles nécessitent plus de réflexion et utilisent généralement un système maître-esclave.

Un exemple SQLite

Maintenant que vous avez répondu aux bases de données relationnelles, il est temps de creuser dans du Python! SQLite est une base de données pratique que vous pouvez utiliser sur votre machine locale. La base de données est un fichier unique, ce qui la rend idéale à des fins de prototypage. Tout d'abord, importez la bibliothèque Python requise et créez une nouvelle base de données:

importation sqlite3

db = sqlite3.relier(':Mémoire:')  # Utilisation d'une base de données en mémoire
cabot = db.le curseur()

Vous êtes maintenant connecté à une base de données en mémoire et votre objet curseur est prêt à être utilisé.

Ensuite, vous allez créer les trois tableaux suivants:

  1. Client: Ce tableau contiendra une clé primaire ainsi que les prénom et nom du client.
  2. Articles: Ce tableau contiendra une clé primaire, le nom de l'article et le prix de l'article.
  3. Articles achetés: Ce tableau contiendra un numéro de commande, une date et un prix. Il se connectera également aux clés primaires des tables Articles et Clients.

Maintenant que vous avez une idée de l'apparence de vos tables, vous pouvez les créer:

cabot.exécuter('' 'CRÉER UN TABLEAU SI IL N'EXISTE PAS Client (
                                                                id entier PRIMARY KEY,
                                                                prénom varchar (255),
                                                                nom varchar (255)) '' '
            )
cabot.exécuter('' 'CRÉER UN TABLEAU SI IL N'EXISTE PAS
                                                                id entier PRIMARY KEY,
                                                                titre varchar (255),
                                                                prix décimal) '' '
            )
cabot.exécuter('' 'CRÉER UN TABLEAU SI IL N'EXISTE PAS BoughtItem (
                                                                ordernumber integer PRIMARY KEY,
                                                                entier customerid,
                                                                entier itemid,
                                                                prix décimal,
                                                                CONSTRAINT customerid
                                                                                CLÉ ÉTRANGÈRE (id_client) RÉFÉRENCES Client (id),
                                                                CONTRAINT itemid
                                                                                CLÉ ÉTRANGÈRE (itemid) RÉFÉRENCES Item (id)) '' '
            )

Vous avez transmis une requête à cur.execute () pour créer vos trois tables.

La dernière étape consiste à remplir vos tables avec des données:

cabot.exécuter('' 'INSÉRER DANS le client (prénom, nom)
                                                            VALEURS («Bob», «Adams»),
                                                                                        («Amy», «Smith»),
                                                                                        ('Rob', 'Bennet'); '' ')
cabot.exécuter('' 'INSÉRER DANS l'article (titre, prix)
                                                            VALEURS («USB», 10.2),
                                                                                        ('Souris', 12.23),
                                                                                        ('Moniteur', 199,99); '' ')
cabot.exécuter('' 'INSÉRER DANS BoughtItem (customerid, itemid, price)
                                                            VALEURS (1, 1, 10.2),
                                                                                        (1, 2, 12.23),
                                                                                        (1, 3, 199,99),
                                                                                        (2, 3, 180,00),
                                                                                        (3, 2, 11.23); '' ') # Prix réduit

Maintenant qu'il y a quelques enregistrements dans chaque table, vous pouvez utiliser ces données pour répondre à quelques autres questions d'entrevue avec un ingénieur de données.

Q2: Fonctions d'agrégation SQL

Fonctions d'agrégation sont ceux qui effectuent une opération mathématique sur un ensemble de résultats. Quelques exemples: AVG, COMPTER, MIN, MAX, et SOMME. Souvent, vous aurez besoin PAR GROUPE et AYANT pour compléter ces agrégations. Une fonction d'agrégation utile est AVG, que vous pouvez utiliser pour calculer la moyenne d'un ensemble de résultats donné:

>>>

cur.execute ('' 'SELECT itemid, AVG (price) FROM BoughtItem GROUP BY itemid' '')
imprimer (cur.fetchall ())
>>> [([([([(1, 10.2), (2, 11,73), (3, 189,995)]

Ici, vous avez récupéré le prix moyen de chacun des articles achetés dans votre base de données. Vous pouvez voir que l'élément avec un ID de l'article de 1 a un prix moyen de 10,20 $.

Pour faciliter la compréhension de la sortie ci-dessus, vous pouvez afficher le nom de l'élément au lieu de ID de l'article:

>>>

cur.execute ('' 'SELECT item.title, AVG (purchaseitem.price) FROM BoughtItem as achetéitem
                                                            INNER JOIN Article en tant qu'article sur (item.id = a achetéitem.itemid)
                                                            GROUPE PAR chose achetée.itemide '' ')
imprimer (cur.fetchall ())
>>> [([([([('USB', 10.2), ('Souris', 11,73), ('Moniteur', 189,995)]

Maintenant, vous voyez plus facilement que l'article au prix moyen de 10,20 $ est le USB.

Une autre agrégation utile est SOMME. Vous pouvez utiliser cette fonction pour afficher le montant total que chaque client a dépensé:

>>>

cur.execute ('' 'SELECT customer.firstname, SUM (purchaseitem.price) FROM BoughtItem as paiditem
                                                            INNER JOIN Client en tant que client sur (customer.id = achatsitem.customerid)
                                                            GROUP BY customer.firstname '' ')
imprimer (cur.fetchall ())
>>> [([([([(«Amy», 180), ('Bob', 222.42000000000002), ('Rob', 11.23)]

En moyenne, le client nommé Amy a dépensé environ 180 $, tandis que Rob n'a dépensé que 11,23 $!

Si votre intervieweur aime les bases de données, vous souhaiterez peut-être revoir les requêtes imbriquées, les types de jointure et les étapes qu'une base de données relationnelle prend pour effectuer votre requête.

Q3: Accélération des requêtes SQL

La vitesse dépend de divers facteurs, mais dépend principalement du nombre de chacun des éléments suivants:

  • Se joint
  • Agrégations
  • Traversées
  • Records

Plus le nombre de jointures est élevé, plus la complexité est élevée et plus le nombre de traversées dans les tables est élevé. Les jointures multiples sont assez coûteuses à effectuer sur plusieurs milliers d'enregistrements impliquant plusieurs tables car la base de données doit également mettre en cache le résultat intermédiaire! À ce stade, vous pourriez commencer à réfléchir à la façon d'augmenter la taille de votre mémoire.

La vitesse dépend également de la présence ou non de indices présent dans la base de données. Les indices sont extrêmement importants et vous permettent de rechercher rapidement dans un tableau et de trouver une correspondance pour une colonne spécifiée dans la requête.

Les indices trient les enregistrements au prix d'un temps d'insertion plus long, ainsi que d'un certain stockage. Plusieurs colonnes peuvent être combinées pour créer un seul index. Par exemple, les colonnes rendez-vous amoureux et prix peut être combiné car votre requête dépend des deux conditions.

Q4: débogage des requêtes SQL

La plupart des bases de données incluent un EXPLIQUER LE PLAN DE REQUÊTE qui décrit les étapes de la base de données pour exécuter la requête. Pour SQLite, vous pouvez activer cette fonctionnalité en ajoutant EXPLIQUER LE PLAN DE REQUÊTE devant un SÉLECTIONNER déclaration:

>>>

cur.execute ('' 'EXPLAIN QUERY PLAN SELECT customer.firstname, item.title, 
                                                            article.prix, article acheté.prix de BoughtItem comme article acheté
                                                            INNER JOIN Client en tant que client sur (customer.id = achatsitem.customerid)
                                                            INNER JOIN Article en tant qu'article sur (item.id = a achetéitem.itemid)
                                                '' ')
imprimer (cur.fetchall ())

>>>
[(400'SCANTABLEBoughtItemASboughtitem')[(400'SCANTABLEBoughtItemASboughtitem')[(400'SCANTABLEBoughtItemASboughtitem')[(400'SCANTABLEBoughtItemASboughtitem')
(6, 0, 0, 'TABLEAU DE RECHERCHE Client COMME client UTILISANT LA CLÉ PRIMAIRE ENTIER (rowid =?)'), 
(9, 0, 0, 'TABLEAU DE RECHERCHE Article COMME article UTILISANT LA TOUCHE PRIMAIRE ENTIER (rowid =?)')]

Cette requête essaie de répertorier le prénom, le titre de l'article, le prix d'origine et le prix acheté pour tous les articles achetés.

Voici à quoi ressemble le plan de requête:

BALAYAGE TABLE BoughtItem COMME acheté
CHERCHER TABLE Client COMME client EN UTILISANT ENTIER PRIMAIRE CLÉ (rowid=?)
CHERCHER TABLE Article COMME article EN UTILISANT ENTIER PRIMAIRE CLÉ (rowid=?)

Notez que l'instruction fetch dans votre code Python ne renvoie que l'explication, mais pas les résultats. C'est parce que EXPLIQUER LE PLAN DE REQUÊTE n'est pas destiné à être utilisé dans la production.

Questions sur les bases de données non relationnelles

Dans la section précédente, vous avez expliqué les différences entre les bases de données relationnelles et non relationnelles et utilisé SQLite avec Python. Vous allez maintenant vous concentrer sur NoSQL. Votre objectif est de mettre en évidence ses forces, ses différences et ses cas d'utilisation.

Un exemple MongoDB

Vous utiliserez les mêmes données qu'auparavant, mais cette fois, votre base de données sera MongoDB. Cette base de données NoSQL est basée sur des documents et évolue très bien. Tout d'abord, vous devrez installer la bibliothèque Python requise:

Vous pouvez également souhaiter installer la communauté MongoDB Compass. Il comprend un IDE local parfait pour visualiser la base de données. Avec lui, vous pouvez voir les enregistrements créés, créer des déclencheurs et agir en tant qu'administrateur visuel pour la base de données.

Voici comment créer la base de données et insérer des données:

importation pymongo

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

# Remarque: Cette base de données n'est pas créée tant qu'elle n'est pas remplie par certaines données
db = client[[[["exemple_database"]

les clients = db[[[["les clients"]
articles = db[[[["articles"]

customer_data = [{[{[{[ "Prénom": "Bob", "nom de famille": "Adams" ,
                   "Prénom": "Amy", "nom de famille": "Forgeron" ,
                   "Prénom": "Rob", "nom de famille": "Bennet" ,]
items_data = [{[{[{[ "Titre": "USB", "prix": 10.2 ,
               "Titre": "Souris", "prix": 12.23 ,
               "Titre": "Moniteur", "prix": 199,99 ,]

les clients.insert_many(customer_data)
articles.insert_many(items_data)

Comme vous l'avez peut-être remarqué, MongoDB stocke les enregistrements de données dans collections, qui sont l'équivalent d'une liste de dictionnaires en Python. En pratique, MongoDB stocke les documents BSON.

Q5: Requête de données avec MongoDB

Essayons de reproduire le BoughtItem table d'abord, comme vous l'avez fait dans SQL. Pour ce faire, vous devez ajouter un nouveau champ à un client. La documentation de MongoDB spécifie que l'opérateur de mot clé ensemble peut être utilisé pour mettre à jour un enregistrement sans avoir à écrire tous les champs existants:

# Il suffit d'ajouter des "articles achetés" au client dont le prénom est Bob
bob = les clients.update_many(
        "Prénom": "Bob",
        
            "$ set": 
                "articles achetés": [[[[
                    
                        "Titre": "USB",
                        "prix": 10.2,
                        "devise": "EUR",
                        "Remarques": "Le client souhaite qu'il soit livré via FedEx",
                        "original_item_id": 1
                    
                ]
            ,
        
    )

Remarquez comment vous avez ajouté des champs supplémentaires au client sans définir explicitement le schéma au préalable. Nifty!

En fait, vous pouvez mettre à jour un autre client avec un schéma légèrement modifié:

amy = les clients.update_many(
        "Prénom": "Amy",
        
            "$ set": 
                "articles achetés":[[[[
                    
                        "Titre": "Moniteur",
                        "prix": 199,99,
                        "original_item_id": 3,
                        "à prix réduit": Faux
                    
                ]
             ,
        
    )
impression(type(amy))  # pymongo.results.UpdateResult

Semblables à SQL, les bases de données basées sur des documents permettent également d'exécuter des requêtes et des agrégations. Cependant, la fonctionnalité peut différer à la fois syntaxiquement et dans l'exécution sous-jacente. En fait, vous avez peut-être remarqué que MongoDB se réserve le $ pour spécifier une commande ou une agrégation sur les enregistrements, telle que $ groupe. Vous pouvez en savoir plus sur ce comportement dans les documents officiels.

Vous pouvez effectuer des requêtes comme vous l'avez fait dans SQL. Pour commencer, vous pouvez créer un index:

>>>

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

C'est facultatif, mais cela accélère les requêtes qui nécessitent des recherches de nom.

Ensuite, vous pouvez récupérer les noms de clients triés par ordre croissant:

>>>

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

Vous pouvez également parcourir et imprimer les articles achetés:

>>>

pour l'article dans les articles:
                print (item.get ('items achetés'))

>>> Aucun
    ['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]

Vous pouvez même récupérer une liste de noms uniques dans la base de données:

>>>

customers.distinct ("prénom")
>>> [[[['Bob', «Amy», 'Rob']

Maintenant que vous connaissez les noms des clients dans votre base de données, vous pouvez créer une requête pour récupérer des informations à leur sujet:

>>>

pour i dans customers.find ("$ or":['prénom':'Bob'['prénom':'Bob'['firstname':'Bob'['firstname':'Bob'
                                                                                                                                    'prénom': 'Amy'], 
                                                                                                'prénom': 1, 'articles achetés': 1, '_id': 0):
                imprimer (i)

>>> {'Prénom': 'Bob', «articles achetés»: [{[{[['Titre': 'USB', 'prix': 10.2, 'devise': 'EUR', 'Remarques': «Le client souhaite qu'il soit livré via FedEx», 'original_item_id': 1]
                'prénom': 'Amy', 'articles achetés': ['title': 'Monitor', 'price': 199.99, 'original_item_id': 3, 'discounted': False]

Voici la requête SQL équivalente:

SÉLECTIONNER Prénom, articles achetés DE les clients  Prénom COMME ('Bob', «Amy»)

Notez que même si la syntaxe ne diffère que légèrement, il existe une différence drastique dans la façon dont les requêtes sont exécutées sous le capot. Ceci est à prévoir en raison des différentes structures de requête et des cas d'utilisation entre les bases de données SQL et NoSQL.

Q6: NoSQL vs SQL

Si vous avez un schéma en constante évolution, tel que des informations réglementaires financières, NoSQL peut alors modifier les enregistrements et imbriquer les informations associées. Imaginez le nombre de jointures que vous auriez à faire en SQL si vous aviez huit ordres d'imbrication! Cependant, cette situation est plus courante que vous ne le pensez.

Maintenant, que se passe-t-il si vous souhaitez exécuter des rapports, extraire des informations sur ces données financières et déduire des conclusions? Dans ce cas, vous devez exécuter des requêtes complexes et SQL a tendance à être plus rapide à cet égard.

La vitesse n'est cependant pas la seule mesure. Vous souhaiterez également prendre en compte des éléments tels que les transactions, l'atomicité, la durabilité et l'évolutivité. Transactions sont importantes dans les applications financières, et de telles fonctionnalités ont priorité.

Puisqu'il existe un large éventail de bases de données, chacune avec ses propres fonctionnalités, c'est le travail de l'ingénieur des données de prendre une décision éclairée sur la base de données à utiliser dans chaque application. Pour plus d'informations, vous pouvez consulter les propriétés ACID relatives aux transactions de base de données.

Il peut également vous être demandé quelles autres bases de données vous connaissez dans votre entretien avec un ingénieur de données. Il existe plusieurs autres bases de données pertinentes utilisées par de nombreuses entreprises:

  • Recherche élastique est très efficace dans la recherche de texte. Il tire parti de sa base de données documentaire pour créer un puissant outil de recherche.
  • Newt DB combine ZODB et la fonction JSONB PostgreSQL pour créer une base de données NoSQL compatible Python.
  • InfluxDB est utilisé dans les applications de séries chronologiques pour stocker des événements.

La liste est longue, mais cela illustre comment une grande variété de bases de données disponibles s'adressent toutes à leur industrie de niche.

Questions sur les bases de données de cache

Mettre en cache les bases de données contenir des données fréquemment consultées. Ils vivent aux côtés des principales bases de données SQL et NoSQL. Leur objectif est d'alléger la charge et de répondre plus rapidement aux demandes.

Un exemple Redis

Vous avez couvert les bases de données SQL et NoSQL pour des solutions de stockage à long terme, mais qu'en est-il du stockage plus rapide et plus immédiat? Comment un ingénieur de données peut-il modifier la vitesse de récupération des données d'une base de données?

Les applications Web typiques récupèrent très souvent les données couramment utilisées, comme le profil ou le nom d'un utilisateur. Si toutes les données sont contenues dans une base de données, le nombre de les coups le serveur de base de données va être excessif et inutile. En tant que tel, une solution de stockage plus rapide et plus immédiate est nécessaire.

Bien que cela réduise la charge du serveur, cela crée également deux maux de tête pour l'ingénieur des données, l'équipe backend et l'équipe DevOps. Tout d'abord, vous aurez désormais besoin d'une base de données dont le temps de lecture est plus rapide que votre base de données SQL ou NoSQL principale. Cependant, le contenu des deux bases de données doit finalement correspondre. (Bienvenue sur le problème de cohérence des états entre les bases de données! Prendre plaisir.)

Le deuxième casse-tête est que DevOps doit désormais se soucier de l'évolutivité, de la redondance, etc. pour la nouvelle base de données de cache. Dans la section suivante, vous vous plongerez dans de tels problèmes avec l'aide de Redis.

Q7: Comment utiliser les bases de données de cache

Vous avez peut-être obtenu suffisamment d'informations de l'introduction pour répondre à cette question! UNE base de données de cache est une solution de stockage rapide utilisée pour stocker des données de courte durée, structurées ou non structurées. Il peut être partitionné et mis à l'échelle en fonction de vos besoins, mais il est généralement beaucoup plus petit que votre base de données principale. Pour cette raison, votre base de données de cache peut résider en mémoire, vous permettant de contourner la nécessité de lire à partir d'un disque.

Lorsqu'une demande arrive, vous vérifiez d'abord la base de données du cache, puis la base de données principale. De cette façon, vous pouvez empêcher toute demande inutile et répétitive d'atteindre le serveur de la base de données principale. Puisqu'une base de données de cache a un temps de lecture inférieur, vous bénéficiez également d'une augmentation des performances!

Vous pouvez utiliser pip pour installer la bibliothèque requise:

Maintenant, considérez une demande pour obtenir le nom de l'utilisateur à partir de son ID:

importation redis
de datetime importation timedelta

# Dans une application Web réelle, la configuration est obtenue à partir de paramètres ou d'utilitaires
r = redis.Redis()

# Supposons que c'est un getter qui gère une demande
def get_name(demande, *args, **kwargs):
    id = demande.obtenir('id')
    si id dans r:
        revenir r.obtenir(id)  # Supposons que nous avons un magasin id: name
    autre:
        # Obtenez les données de la base de données principale ici, supposons que nous l'avons déjà fait
        prénom = 'Bob'
        # Définissez la valeur dans la base de données du cache, avec un délai d'expiration
        r.setex(id, timedelta(minutes=60), valeur=prénom)
        revenir prénom

Ce code vérifie si le nom est dans Redis en utilisant le id clé. Sinon, le nom est défini avec un délai d'expiration, que vous utilisez car le cache est de courte durée.

Maintenant, que se passe-t-il si votre intervieweur vous demande quel est le problème avec ce code? Votre réponse devrait être qu'il n'y a pas de gestion des exceptions! Les bases de données peuvent avoir de nombreux problèmes, comme des connexions interrompues, c'est donc toujours une bonne idée d'essayer de détecter ces exceptions.

Questions sur les modèles de conception et les concepts ETL

Dans les grandes applications, vous utiliserez souvent plusieurs types de base de données. En fait, il est possible d'utiliser PostgreSQL, MongoDB et Redis dans une seule application! Un problème difficile consiste à gérer les changements d'état entre les bases de données, ce qui expose le développeur à des problèmes de cohérence. Considérez le scénario suivant:

  1. Une valeur dans la base de données # 1 est mise à jour.
  2. Cette même valeur dans la base de données n ° 2 reste la même (non mise à jour).
  3. Une requête est exécuté sur la base de données # 2.

Maintenant, vous obtenez un résultat incohérent et obsolète! Les résultats renvoyés par la deuxième base de données ne refléteront pas la valeur mise à jour dans la première. Cela peut se produire avec deux bases de données, mais cela est particulièrement fréquent lorsque la base de données principale est une base de données NoSQL et que les informations sont transformées en SQL à des fins de requête.

Les bases de données peuvent avoir des employés de fond pour résoudre ces problèmes. Ces travailleurs extrait les données d'une seule base de données, transformer en quelque sorte, et charge dans la base de données cible. Lorsque vous convertissez une base de données NoSQL en une base de données SQL, le processus d'extraction, de transformation et de chargement (ETL) prend les mesures suivantes:

  1. Extrait: Il existe un déclencheur MongoDB chaque fois qu'un enregistrement est créé, mis à jour, etc. Une fonction de rappel est appelée de manière asynchrone sur un thread séparé.
  2. Transformer: Des parties de l'enregistrement sont extraites, normalisées et placées dans la structure de données (ou ligne) correcte pour être insérées dans SQL.
  3. Charge: La base de données SQL est mise à jour par lots ou en tant qu'enregistrement unique pour les écritures à volume élevé.

Ce flux de travail est assez courant dans les applications financières, les jeux et les rapports. Dans ces cas, le schéma en constante évolution nécessite une base de données NoSQL, mais les rapports, analyses et agrégations nécessitent une base de données SQL.

Q8: Défis ETL

Il existe plusieurs concepts difficiles dans ETL, notamment les suivants:

  • Big Data
  • Problèmes avec état
  • Travailleurs asynchrones
  • Correspondance de type

La liste continue! Cependant, étant donné que les étapes du processus ETL sont bien définies et logiques, les ingénieurs des données et du backend s'inquiètent généralement davantage des performances et de la disponibilité que de la mise en œuvre.

Si votre application écrit des milliers d'enregistrements par seconde dans MongoDB, votre collaborateur ETL doit suivre la transformation, le chargement et la livraison des données à l'utilisateur sous la forme demandée. La vitesse et la latence pouvant devenir un problème, ces employés sont généralement écrits dans des langages rapides. Vous pouvez utiliser du code compilé pour l'étape de transformation pour accélérer les choses, car cette partie est généralement liée au processeur.

Si vous avez affaire à de nombreuses fonctions gourmandes en ressources processeur, vous voudrez peut-être consulter Numba. Cette bibliothèque compile des fonctions pour les rendre plus rapides à l'exécution. Mieux encore, cela est facilement implémenté en Python, bien qu'il existe certaines limitations sur les fonctions qui peuvent être utilisées dans ces fonctions compilées.

Q9: Design Patterns in Big Data

Imaginez qu'Amazon a besoin de créer un système de recommandation proposer des produits adaptés aux utilisateurs. L'équipe de science des données a besoin de beaucoup de données! Ils s'adressent à vous, l'ingénieur des données, et vous demandent de créer un entrepôt de bases de données intermédiaire distinct. C’est là qu’ils nettoieront et transformeront les données.

Vous pourriez être choqué de recevoir une telle demande. Lorsque vous disposez de téraoctets de données, vous aurez besoin de plusieurs machines pour gérer toutes ces informations. Une fonction d'agrégation de base de données peut être une opération très complexe. Comment pouvez-vous interroger, agréger et utiliser des données relativement volumineuses de manière efficace?

Apache avait initialement introduit MapReduce, qui suit le carte, mélanger, réduire workflow. L'idée est de cartographier différentes données sur des machines distinctes, également appelées clusters. Ensuite, vous pouvez effectuer un travail sur les données, regroupées par une clé, et enfin, agréger les données à l'étape finale.

Ce flux de travail est toujours utilisé aujourd'hui, mais il s'est estompé récemment en faveur de Spark. Le modèle de conception, cependant, constitue la base de la plupart des flux de travail de Big Data et est un concept très intrigant. Vous pouvez en savoir plus sur MapReduce sur IBM Analytics.

Q10: Aspects communs du processus ETL et des flux de travail Big Data

Vous pensez peut-être que cette question est plutôt étrange, mais il s'agit simplement d'une vérification de vos connaissances en informatique, ainsi que de vos connaissances et de votre expérience globales en conception.

Les deux workflows suivent Producteur-consommateur modèle. Un travailleur (le producteur) produit des données d'une certaine sorte et les transmet à un pipeline. Ce pipeline peut prendre de nombreuses formes, notamment des messages réseau et des déclencheurs. Une fois que le producteur a sorti les données, le consommateur les consomme et les utilise. Ces travailleurs travaillent généralement de manière asynchrone et sont exécutés dans des processus distincts.

Vous pouvez comparer le producteur aux étapes d'extraction et de transformation du processus ETL. De même, dans les mégadonnées, mappeur peut être considéré comme le producteur, tandis que réducteur est effectivement le Consommateur. Cette séparation des préoccupations est extrêmement importante et efficace dans le développement et la conception d'architecture d'applications.

Conclusion

Toutes nos félicitations! Vous avez parcouru beaucoup de terrain et répondu à plusieurs questions d'entrevue avec un ingénieur de données. Vous en savez maintenant un peu plus sur les nombreux chapeaux différents qu'un ingénieur de données peut porter, ainsi que sur vos responsabilités en matière de bases de données, de conception et de flux de travail.

Fort de ces connaissances, vous pouvez désormais:

  • Utiliser Python avec des bases de données SQL, NoSQL et cache
  • Utiliser Python dans les applications ETL et de requête
  • Planifiez vos projets à l'avance, en gardant à l'esprit la conception et le flux de travail

Bien que les questions d'entrevue puissent varier, vous avez été exposé à plusieurs sujets et avez appris à sortir des sentiers battus dans de nombreux domaines différents de l'informatique. Vous êtes maintenant prêt à avoir une super interview!