devops-exercises

Linux, Jenkins, AWS, SRE, Prometheus, Docker, Python, Ansible, Git, Kubernetes, Terraform, OpenStack, SQL, NoSQL, Azure, GCP, DNS, Elastic, Network, Virtualization. DevOps Interview Questions

OTHER License

Stars
66.2K
Committers
195

ℹ️  此存储库包含有关各种技术主题的问题和练习,有时与 DevOps 和 SRE 相关

📊  当前有 2624 个问题

⚠️  您可以使用这些来准备面试,但大多数问题和练习并不代表实际的面试。请阅读常见问题了解更多详情

📄  不同的面试官专注于不同的事情。 有些人将重点放在你的简历上,而另一些人可能将重点放在方案问题或特定的技术问题上。 在这个仓库,我尽力覆盖各种类型的 DevOps 问题,供你练习和测试你的知识

📝  你可以通过提交拉取请求来添加更多练习:) 在此处阅读贡献指南


网络

  • 一种共同的语言(供两端理解)
  • 与你想要沟通的人交流的方法
  • 一个连接(以便通信内容能够到达接收者)

一组协议,定义了两个或多个设备如何相互通信。

了解更多关于TCP/IP, 阅读 这里

以太网简单地指的是当今最常见的局域网(LAN)类型。与跨越较大地理区域的广域网(WAN)相对,LAN是一个连接在小范围内的计算机网络,比如你的办公室、大学校园或者家庭。

MAC地址是用于识别网络上各个设备的唯一标识号码或代码。

通过以太网发送的数据包始终来自一个 MAC 地址并发送到一个 MAC 地址。如果网络适配器接收到一个数据包,它会将该数据包的目标 MAC 地址与适配器自身的 MAC 地址进行比较。

当设备向广播 MAC 地址(FF:FF:FF:FF:FF:FF)发送数据包时,它会传递给本地网络上的所有站点。以太网广播用于在数据链路层通过 ARP 解析 IP 地址到 MAC 地址。

互联网协议地址(IP 地址)是分配给连接到使用互联网协议进行通信的计算机网络上的每个设备的数字标签。IP地址具有两个主要功能:主机或网络接口识别和位置寻址。

子网掩码是一个32位的数字,用于屏蔽 IP 地址并将 IP 地址分为网络地址和主机地址。子网掩码通过将网络位设置为全部"1",将主机位设置为全部"0"来生成。在给定的网络中,总可用主机地址中始终保留两个用于特定目的,并且不能分配给任何主机。这些是第一个地址,被保留作为网络地址(也称为网络 ID),以及最后一个用于网络广播的地址。

例子

  • 应用程序:用户端( HTTP 在此)。
  • 演示:建立应用层实体之间的上下文(加密在这里)。
  • 会话:建立、管理和终止连接。
  • 传输:将可变长度的数据序列从源主机传输到目标主机( TCP 和 UDP 在此)。
  • 网络:将数据报从一个网络传输到另一个网络( IP 在此)。
  • 数据链路:提供两个直接连接的节点之间的链接(MAC在此)。
  • 物理特性:数据连接的电气和物理规格(位数在此)。

您可以在 penguintutor.com 阅读有关OSI模型的更多信息。

  • 错误更正
  • 数据包路由
  • 电缆和电信号
  • MAC 地址
  • IP 地址
  • 终止连接
  • 3 次握手
  • 错误纠正 - 数据链路
  • 数据包路由 - 网络
  • 电缆和电信号 - 物理
  • MAC 地址 - 数据链路
  • IP 地址 - 网络
  • 终止连接 - 会话
  • 3次握手 - 传输

单播:一对一的通信,其中有一个发送者和一个接收者。

广播:向网络中的所有人发送消息。地址 ff:ff:ff:ff:ff:ff 用于广播。 使用广播的两个常见协议是 ARP 和 DHCP。

多播:向一组订阅者发送消息。它可以是一对多或多对多的。

CSMA/CD 代表载波侦听多路访问冲突检测。 其主要目标是管理对共享介质/总线的访问,每次只有一个主机可以传输。

CSMA/CD 算法:

  1. 在发送帧之前,它会检查是否有另一个主机正在传输帧。
  2. 如果没有人在传输,它就开始传输帧。
  3. 如果两个主机同时传输,就会发生碰撞。
  4. 两个主机都停止发送帧,并向所有人发送一个“干扰信号”,通知大家发生了碰撞。
  5. 他们正在等待一个随机的时间再次发送它。
  6. 一旦每个主机等待了随机时间,它们会再次尝试发送帧,从而重新开始循环。
  • 路由器
  • 交换机
  • 集线器

路由器、交换机和集线器都是用于连接局域网(LAN)中的设备的网络设备。然而,每个设备的操作方式不同,并且具有其特定的使用情况。以下是对每个设备及其之间区别的简要描述:

  1. 路由器:一种网络设备,用于连接多个网络段。它在OSI模型的网络层(第3层)上运行,并使用路由协议来指导网络之间的数据传输。路由器使用IP地址来识别设备并将数据包定向到正确的目标位置。
  2. 交换机:一种网络设备,用于连接局域网上的多个设备。它在OSI模型的数据链路层(第二层)工作,并使用MAC地址来识别设备并将数据包定向到正确的目标。交换机可以使同一网络上的设备更高效地相互通信,并且可以防止多个设备同时发送数据时可能发生的数据碰撞。
  3. 集线器:一种网络设备,通过单根电缆连接多个设备,并用于在不分割网络的情况下连接多个设备。然而,与交换机不同的是,它在OSI模型的物理层(第1层)上运行,并且只是将数据包广播到所有连接到它的设备,无论该设备是否为预期接收者。这意味着可能会发生数据碰撞,并且网络效率可能因此受到影响。由于交换机更高效并提供更好的网络性能,所以现代网络设置通常不使用集线器。

三个冲突域和一个广播域

路由器是一种物理或虚拟设备,用于在两个或多个分组交换的计算机网络之间传递信息。路由器检查给定数据包的目标互联网协议地址(IP地址),计算它到达目的地的最佳路径,然后相应地转发它。

网络地址转换(NAT)是一个过程,其中一个或多个本地IP地址被翻译成一个或多个全局IP地址,反之亦然,以便为本地主机提供互联网访问。

代理服务器充当您和互联网之间的网关。它是一个中介服务器,将最终用户与他们浏览的网站分离开来。

如果您使用代理服务器,互联网流量将通过代理服务器传输到您请求的地址。然后,该请求再次通过相同的代理服务器返回(有一些例外情况),然后代理服务器将从网站接收到的数据转发给您。

代理服务器根据您的使用情况、需求或公司政策提供不同级别的功能、安全性和隐私保护。

TCP 三次握手,又称为三向握手,在 TCP/IP 网络中用于建立服务器和客户端之间的连接的过程。

三次握手主要用于创建 TCP 套接字连接。它在以下情况下起作用:

  • 一个客户节点通过IP网络向同一网络或外部网络上的服务器发送SYN数据包。该数据包的目标是询问/推断服务器是否对新连接开放。
  • 目标服务器必须具有可以接受和发起新连接的开放端口。当服务器从客户节点收到SYN数据包时,它会响应并返回确认收据 - ACK 数据包或 SYN/ACK 数据包。
  • 客户端节点接收到来自服务器的 SYN/ACK,并用一个 ACK数据包作出响应。

摘自 维基百科:"发送信号所需的时间加上收到信号确认所需的时间"。

附加问题:局域网的 RTT 是多少?

  1. 客户端向服务器发送一个Client Hello消息,其中包括客户端的SSL/TLS协议版本、客户端支持的加密算法列表和一个随机值。
  2. 服务器响应一个Server Hello消息,其中包括服务器的SSL/TLS协议版本、一个随机值和会话ID。
  3. 服务器发送一个证书消息,其中包含了服务器的证书。
  4. 服务器发送 Server Hello Done 信息,表示服务器已完成服务器 Hello 阶段的信息发送。
  5. 客户发送包含客户公钥的客户密钥交换信息。
  6. 客户端发送 "更改密码规格 "报文,通知服务器客户端即将发送使用新密码规格加密的报文。
  7. 客户端发送一个加密的握手消息,其中包含使用服务器的公钥加密的预主密钥。
  8. 服务器发送 "更改密码规格 "信息,通知客户端服务器即将发送使用新密码规格加密的信息。
  9. 服务器发送加密握手信息,其中包含用客户机公钥加密的预主密钥。
  10. 客户端和服务器现在可以交换应用数据。

TCP 在客户端和服务器之间建立连接,以保证数据包的顺序,而 UDP 不在客户端和服务器之间建立连接,也不处理数据包顺序。这使得 UDP 比 TCP 更轻便,是流媒体等服务的理想选择。

Penguintutor.com 提供了很好的解释。

默认网关是一个接入点或 IP 路由器,联网计算机利用它将信息发送到另一个网络或互联网上的计算机。

ARP 是地址解析协议(Address Resolution Protocol)的缩写。当您尝试 ping 本地网络上的一个 IP 地址(如 192.168.1.1)时,您的系统必须将 IP 地址 192.168.1.1 转换为 MAC 地址。这就需要使用 ARP 来解析该地址,ARP 也因此而得名。

系统会保存一个 ARP 查找表,其中存储了哪些 IP 地址与哪些 MAC 地址相关联的信息。当试图向某个 IP 地址发送数据包时,系统会首先查询该表,看是否已经知道该 MAC 地址。如果有缓存值,则不使用 ARP。

  • TTL(生存时间)是IP(Internet Protocol,互联网协议)数据包中的一个值,它决定了在被丢弃之前数据包可以经过多少跳或路由器。每次通过路由器转发数据包时,TTL值会减少一。当TTL值达到零时,数据包将被丢弃,并向发送方发送ICMP(Internet Control Message Protocol,互联网控制消息协议)消息以指示该数据包已过期。
  • TTL 用于防止数据包在网络中无限循环,否则会造成拥塞并降低网络性能。
  • 它还有助于防止数据包陷入路由环路,即数据包在同一组路由器之间不断往返而永远无法到达目的地。
  • 此外,TTL 还可用于帮助检测和防止 IP 欺骗攻击,在这种攻击中,攻击者试图通过使用虚假或伪造的 IP 地址来冒充网络上的其他设备。通过限制数据包的跳数,TTL 可以帮助防止数据包被路由到不合法的目的地。

它代表动态主机配置协议,为主机分配 IP 地址、子网掩码和网关。它是这样工作的:

  • 主机在进入网络时广播一条寻找 DHCP 服务器的信息(DHCP DISCOVER)。
  • DHCP 服务器会以数据包的形式发回要约信息,其中包含租用时间、子网掩码、IP 地址等信息(DHCP OFFER)。
  • 根据接受的提议,客户端会发送回复广播,让所有 DHCP 服务器都知道(DHCP 请求)。
  • 服务器发送确认(DHCP ACK)

更多信息 此处

可以在同一网络上安装两个 DHCP 服务器,但不建议这样做,而且必须仔细配置,以防止冲突和配置问题。

  • 在同一网络上配置两个 DHCP 服务器时,两个服务器都有可能为同一设备分配 IP 地址和其他网络配置设置,从而导致冲突和连接问题。此外,如果 DHCP 服务器配置了不同的网络设置或选项,网络上的设备可能会收到冲突或不一致的配置设置。
  • 不过,在某些情况下,可能有必要在同一网络中设置两个 DHCP 服务器,例如在大型网络中,一个 DHCP 服务器可能无法处理所有请求。在这种情况下,可以将 DHCP 服务器配置为不同的 IP 地址范围或不同的子网,这样它们就不会相互干扰。
  • SSL(安全套接字层)隧道是一种技术,用于在互联网等不安全网络上的两个端点之间建立安全的加密连接。SSL 隧道是通过将流量封装在 SSL 连接中创建的,SSL 连接可提供保密性、完整性和身份验证。

下面介绍 SSL 隧道的工作原理:

  1. 客户端启动与服务器的 SSL 连接,其中包括建立 SSL 会话的握手过程。
  2. SSL 会话建立后,客户端和服务器会协商加密参数,如加密算法和密钥长度,然后交换数字证书,以验证彼此的身份。
  3. 客户端随后通过 SSL 隧道将流量发送到服务器,服务器解密流量并将其转发到目标位置。
  4. 服务器通过 SSL 隧道将流量发送回客户端,客户端对流量进行解密并将其转发给应用程序。
  • 套接字是一种软件端点,可使进程之间通过网络进行双向通信。套接字为网络通信提供了一个标准化接口,允许应用程序在网络上发送和接收数据。查看 Linux 系统上打开的套接字列表:
    netstat -an
  • 该命令显示所有打开套接字的列表,以及它们的协议、本地地址、外来地址和状态。
  • IPv6(互联网协议版本 6)是互联网协议(IP)的最新版本,用于识别网络上的设备并与之通信。IPv6 地址是 128 位地址,用十六进制表示,如 2001:0db8:85a3:0000:0000:8a2e:0370:7334。

我们应该考虑使用 IPv6 而不是 IPv4 有几个原因:

  1. 地址空间:IPv4 的地址空间有限,在世界上许多地方已经耗尽。IPv6 提供了更大的地址空间,可提供数万亿个唯一的 IP 地址。
  2. 安全性:IPv6 包含对 IPsec 的内置支持,为网络流量提供端到端加密和身份验证。
  3. 性能:IPv6 包括一些有助于提高网络性能的功能,例如组播路由,它允许将一个数据包同时发送到多个目的地。
  4. 简化网络配置:IPv6 包含可简化网络配置的功能,例如无状态自动配置,它允许设备自动配置自己的 IPv6 地址,而无需 DHCP 服务器。
  5. 更好的移动性支持:IPv6 包含可改进移动性支持的功能,如移动 IPv6,它允许设备在不同网络之间移动时保持其 IPv6 地址。
  • VLAN(虚拟局域网)是一种逻辑网络,它将物理网络上的一组设备组合在一起,而不管它们的物理位置如何。创建 VLAN 的方法是配置网络交换机,为连接到交换机上特定端口或端口组的设备发送的帧分配特定的 VLAN ID。

MTU 是最大传输单元(Maximum Transmission Unit)的缩写。它是指单个事务中可发送的最大 PDU(协议数据单元)的大小。

在 IPv4 协议中,路由器可以对 PDU 进行分片,然后通过事务发送所有已分片的 PDU。

使用 IPv6 协议时,它会向用户计算机发出错误信息。

错。Ping 实际上使用的是 ICMP(互联网控制报文协议),这是一种用于发送与网络通信有关的诊断信息和控制信息的网络协议。

  • SDN 是软件定义网络(Software-Defined Networking)的缩写。它是一种网络管理方法,强调网络控制的集中化,使管理员能够通过软件抽象来管理网络行为。
  • 在传统网络中,路由器、交换机和防火墙等网络设备需要使用专用软件或命令行界面进行单独配置和管理。相比之下,SDN 将网络控制平面与数据平面分开,允许管理员通过集中式软件控制器管理网络行为。
  • ICMP 是 Internet Control Message Protocol 的缩写。它是 IP 网络中用于诊断和控制的协议。它是互联网协议套件的一部分,在网络层运行。

ICMP消息被用于各种目的,包括:

  1. 错误报告:ICMP消息用于报告网络中发生的错误,例如无法将数据包传递到其目的地。
  2. Ping:ICMP 用于发送 ping 信息,该信息用于测试主机或网络是否可连接,并测量数据包的往返时间。
  3. 路径 MTU 发现:ICMP 用于发现路径的最大传输单元(MTU),即无需分片即可传输的最大数据包大小。
  4. 跟踪路由跟踪路由实用程序使用 ICMP 跟踪数据包通过网络的路径。
  5. 路由器发现ICMP 用于发现网络中的路由器。

NAT 是网络地址转换的缩写。它是一种在传输信息前将多个本地专用地址映射到一个公共地址的方法。希望多个设备使用一个 IP 地址的组织和大多数家用路由器一样,都会使用 NAT。 例如,你电脑的私有 IP 可能是 192.168.1.100,但你的路由器会将流量映射到它的公共 IP(如 1.1.1.1)。互联网上的任何设备都会看到来自公共 IP(1.1.1.1)而不是私人 IP(192.168.1.100)的流量。

  • SSH
  • SMTP
  • HTTP
  • DNS
  • HTTPS
  • FTP
  • SFTP
  • SSH - 22
  • SMTP - 25
  • HTTP - 80
  • DNS - 53
  • HTTPS - 443
  • FTP - 21
  • SFTP - 22

有几个因素会影响网络性能,包括:

  1. 带宽:网络连接的可用带宽会极大地影响其性能。带宽有限的网络可能会出现数据传输速率慢、延迟高和响应速度差等问题。
  2. 延迟:延迟是指数据从网络中的一个点传输到另一个点时发生的延迟。高延迟会导致网络性能缓慢,尤其是视频会议和在线游戏等实时应用。
  3. 网络拥塞:当太多设备同时使用网络时,就会出现网络拥塞,导致数据传输速率缓慢和网络性能低下。
  4. 数据包丢失:当数据包在传输过程中丢失时,就会出现丢包现象。这会导致网络速度变慢,整体网络性能降低。
  5. 网络拓扑:网络的物理布局,包括交换机、路由器和其他网络设备的位置,都会影响网络性能。
  6. 网络协议:不同的网络协议具有不同的性能特征,会影响网络性能。例如,TCP 是一种可靠的协议,可以保证数据的传输,但也会因错误检查和重传所需的开销而导致性能降低。
  7. 网络安全:防火墙和加密等安全措施会影响网络性能,尤其是在需要大量处理能力或引入额外延迟的情况下。
  8. 距离:网络设备之间的物理距离会影响网络性能,尤其是无线网络,信号强度和干扰会影响连接性和数据传输速率。

APIPA 是分配给设备的一组 IP 地址 当主 DHCP 服务器无法访问时分配给设备的 IP 地址

APIPA 使用的 IP 范围是169.254.0.1 - 169.254.255.254.

控制平面和数据平面

控制平面是网络的一部分,它决定如何将数据包路由和转发到不同的位置。

数据平面是网络中实际转发数据/数据包的部分。

它指的是监测和管理功能。

控制平面。

OSPF(开放式最短路径优先)是一种路由协议,可在各种类型的路由器上实施。一般来说,大多数现代路由器都支持 OSPF,包括思科、瞻博网络和华为等供应商的路由器。该协议设计用于基于 IP 的网络,包括 IPv4 和 IPv6。此外,它采用分层网络设计,将路由器分组为区域,每个区域都有自己的拓扑图和路由表。这种设计有助于减少路由器之间需要交换的路由信息量,提高网络的可扩展性。

OSPF 4 路由器类型有

  • Internal Router
  • Area Border Routers
  • Autonomous Systems Boundary Routers
  • Backbone Routers

了解有关 OSPF 路由器类型的更多信息: https://www.educba.com/ospf-router-types

延迟是指信息从信息源到达目的地所需的时间。

带宽是通信信道的容量,用于衡量后者在特定时间段内可处理的数据量。带宽越大,意味着处理的流量越多,数据传输量也就越大。

吞吐量是指在一定时间内通过任何传输通道传输的实际数据量。

延迟。要获得良好的延迟,搜索查询应转发到最近的数据中心。

吞吐量。为获得良好的吞吐量,上传数据流应被路由到未充分利用的链路。

  • 保持缓存更新(这意味着请求可能不会被转发到最近的数据中心)

当网络上需要传输的数据过多,而网络容量不足以满足需求时,就会出现网络拥塞。 这会导致延迟和数据包丢失增加。原因可能是多方面的,如网络使用率高、文件传输量大、恶意软件、硬件问题或网络设计问题。 为防止网络拥塞,必须监控网络使用情况,并实施策略来限制或管理需求。

00110011110100011101

  • 超文本传输协议(HTTP)--用于互联网上的网页
  • 简单邮件传输协议(SMTP)--用于电子邮件传输
  • 电信网络(TELNET)--终端模拟,允许客户端访问 telnet 服务器
  • 文件传输协议(FTP)--便于在任何两台机器之间传输文件
  • 域名系统 (DNS) - 域名转换
  • 动态主机配置协议(DHCP)--为主机分配 IP 地址、子网掩码和网关
  • 简单网络管理协议(SNMP)--收集网络设备数据
  • 互联网协议 (IP) - 协助将数据包从一台机器路由到另一台机器
  • 互联网控制消息协议(ICMP)--让人知道发生了什么,如错误信息和调试信息

阅读更多 [此处](https://www.globalsign.com/en/blog/what-is-hsts-and-how-do-i-use-it#:~:text=HTTP%20Strict%20Transport%20Security%20(HSTS,and%20back%20to%20the%20browser.)

网络 - 其他

互联网是一个由网络组成的网络,在全球范围内传输大量数据。 万维网是一个运行在数百万服务器上的应用程序,它位于互联网之上,可通过所谓的网络浏览器访问

ISP(互联网服务提供商)是当地的互联网公司。

DevOps

初级

开发人员经常将代码集成到共享仓库中的一种开发实践。 它的范围可以从每天或每周进行几次更改,到大规模在一个小时内进行几次更改。

验证每段代码(更改/补丁),以使更改可以安全地合并。 如今,使用自动构建来确保代码可以集成的测试更改是一种常见的做法。 它可以是一个运行在不同级别(单元,功能等)的多个测试的构建,也可以是所有或某些必须通过以将更改合并到存储库中的多个单独的构建。

  • CI/CD
  • 基础架构
  • 配置管理
  • 监控 & 报警
  • 日志
  • 代码审查
  • 代码覆盖率
  • 测试集
  • CI/CD - Jenkins, Circle CI, Travis
  • 基础架构 - Terraform, CloudFormation
  • 配置管理 - Ansible, Puppet, Chef
  • 监控 & 报警 - Prometheus, Nagios
  • 日志 - Logstash, Graylog, Fluentd
  • 代码审查 - Gerrit, Review Board
  • 代码覆盖率 - Cobertura, Clover, JaCoCo
  • 测试集 - Robot, Serenity, Gauge

你可以使用以下一项或全部:    * 成熟与尖端    * 社区规模    * 体系结构方面-代理与无代理,主控与无主控等

在可变的基础架构原则中,更改将应用到现有基础架构之上并随着时间的推移而变化 基础架构建立了变化的历史。 Ansible,Puppet和Chef这些工具 遵循可变的基础架构原则。

在不变的基础架构原则中,每项更改实际上都是新的基础架构。 所以改变 到服务器将导致新服务器而不是更新服务器。 Terraform是 遵循不变的基础架构原则的一个例子。

高级

当配置和软件完全相同的服务器环境中的某个服务器上发生配置漂移 或服务器正在应用其他服务器无法获得的更新或配置,并且随着时间的推移,这些服务器将变为 略有不同。

这种情形可能会导致难以识别和重现的错误。

注意:交叉依赖是指你对单独的项目进行了两个或多个更改,并且你希望在相互构建中对其进行测试,而不是分别测试每个更改。

Jenkins

初级

  • Travis
  • Bamboo
  • Teamcity
  • CircleCI
  • Job
  • Build
  • Plugin
  • Slave
  • Executor

高级

  • 测试交叉依赖关系(来自多个项目的变更)
      * 从任何阶段开始构建(尽管cloudbees实现了称为检查点的东西)

Cloud

初级

IAAS PAAS SAAS

  • Public
  • Hybrid
  • Private

AWS

初级

全局基础设施
  • 可用区
  • 区域
  • 边缘位置

边缘位置基本上是内容传递网络,它缓存数据并确保较低的延迟和更快地传递给任何位置的用户。 他们位于世界主要城市。

S3
CloudFront
EC2

停止实例,使其实例类型与所需的RAM匹配,然后启动实例。

网络

初级

应用层:用户端(HTTP在这一层) 表示层:在应用程序层实体之间建立上下文(加密在这一层) 会话层:建立,管理和终止连接 传输层:将可变长度的数据序列从源传输到目标主机(TCP和UDP在这一层) 网络层:将数据报从一个网络传输到另一个网络(IP 层在这里) 数据链接层:提供两个直接连接的节点之间的链接(MAC在这一层) 物理层:数据连接的电气和物理规格(比特在这一一层)

广播:向网络中的所有人发送消息。 地址ff:ff:ff:ff:ff:ff:ff用于广播。             使用广播的两个常见协议是ARP和DHCP。

组播:向一组订户发送消息。 它可以是一对多或多对多。

CSMA / CD代表载波侦听多路访问/冲突检测。 它的主要重点是管理对共享媒体/总线的访问,在该共享媒体/总线上,在给定的时间点只能传输一个主机。

CSMA / CD算法:

  1. 在发送帧之前,它会检查其他主机是否已经在发送帧。
  2. 如果没有人发送,它将开始发送帧。
  3. 如果两个主机同时传输,则发生冲突。
  4. 双方主机均停止发送帧,并向每个人发送“干扰信号”,通知每个人发生冲突
  5. 他们正在等待随机时间,然后再次发送
  6. 一旦每个主机等待一段随机时间,他们就会尝试再次发送帧
  • 路由器
  • 交换机
  • 集线器

高级

00110011110100011101

Linux

初级

  • ls
  • rm
  • rmdir (你能使用 rm完成同样的结果吗?)
  • grep
  • wc
  • curl
  • touch
  • man
  • nslookup or dig
  • df

你能使用命令 cronat. 对于cron,使用以下格式安排任务:

任务存储在cron文件中。

通常,你将安排批处理作业。

权限

使用 chmod 命令.

  • 777
  • 644
  • 750

777 - 所有人有读和写和可执行权限(意味着你很懒) 644 - 拥有者有读和写的权限、其他人只有读权限 750 - 拥有者有所有权限, 组成员可以读和执行权限、其他人没有权限

  • adduser user_name --shell=/bin/false --no-create-home
  • journalctl
调试

dstat -t 非常适合辨别网络和磁盘问题。 netstat -tnlaup 可用于查看哪些进程在哪些端口上运行。 lsof -i -P 可以用于与netstat相同的目的。 ngrep -d any metafilter 用于将正则表达式与数据包的载荷相匹配。 tcpdump 用于捕获数据包 wireshark 与tcpdump相同的概念,但带有GUI(可选)。

dstat -t 非常适合辨别网络和磁盘问题。 opensnoop 可以用来查看正在系统上打开哪些文件(实时)。

strace 非常适合了解你的程序的功能。 它打印你的程序执行的每个系统调用。

top 显示每个进程消耗多少CPU占比 perf 是采样分析器的理想选择,通常来说,找出哪些CPU周期被“浪费”了 flamegraphs 非常适合CPU消耗可视化(http://www.brendangregg.com/flamegraphs.html)

  1. 使用top检查是否有任何资源消耗你的CPU或RAM。
  2. 运行dstat -t来检查它是否与磁盘或网络有关。
  3. 使用iostat检查 I/O 统计信息
  • grep '[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}' some_file
  • grep -E "error|failure" some_file
  • grep '[0-9]$' some_file
  1. 一个 IP 地址
  2. 单词 "error" 或 "failure"
  3. 以数字结尾的行

退出码(或返回码)表示子进程返回其父进程的码。

0是退出码,表示成功,而大于1的码表示错误。 每个数字都有不同的含义,具体取决于应用程序的开发方式。

我认为这是一篇可以了解更多的好博客:https://shapeshed.com/unix-exit-codes

硬链接是使用相同inode的相同文件。 软链接是使用不同inode的另一个文件的快捷方式。

可以在不同的文件系统之间创建软链接,而硬链接只能在同一文件系统内创建。

  • PV
  • VG
  • LV
  • sed "s/1/2/g' /tmp/myFile
  • find . -iname *.yaml -exec sed -i "s/1/2/g" {} ;
  • /tmp
  • /var/log
  • /bin
  • /proc
  • /usr/local
进程

你可以通过在命令末尾指定&来实现。至于为什么,因为一些命令/过程会占用大量的时间来完成执行或永远运行

默认信号为SIGTERM(15)。 该信号可以优雅地终止进程,这意味着它可以保存当前状态配置。

SIGTERM - 终止进程的默认信号 SIGHUP - 常用用法是重新加载配置 SIGKILL - 不能捕获或忽略的信号

运行 kill -l 查看所有可用的信号

Running(运行态) Waiting (等待态)) Stopped(暂停态) Terminated(终止态) Zombie(假死态)

ind /some_dir -iname *.yml -print0 | xargs -0 -r sed -i "s/1/2/g"

你可以使用命令topfree

你可以使用 split 命令就像这样split -l 25 some_file

在 Linux (和 Unix) 前三个描述符是:

  • 0 - 输入的默认数据流
  • 1 - 输出的默认数据流
  • 2 - 与错误相关的输出的默认数据流

这有一篇好的文章关于这个主题的: https://www.computerhope.com/jargon/f/file-descriptor.htm

Linux中的每个文件(和目录)都有一个索引节点,即与文件相关的存储元数据信息的数据结构 ,例如文件的大小,所有者,权限等。

Network
DNS

A记录将域名指向IP地址,而PTR记录则相反,并将IP地址解析为域名。

Packaging

高级

open("/my/file") = 5
read(5, "file content")

系统调用正在读 /my/file文件 以及 5 是文件描述符数字.

Network

这有一些方式去做:

  • dd if=/dev/urandom of=new_file.txt bs=2MB count=1
  • truncate -s 2M new_file.txt
  • fallocate -l 2097152 new_file.txt

这有一篇好的文章关于这个主题的: https://ops.tips/blog/how-linux-creates-sockets

Ansible

初级

  • Task
  • Module
  • Play
  • Playbook
  • Role

任务 – 调用特定的Ansible模块 模块 – Ansible在你自己的主机或远程主机上执行的实际代码单元。 模块按类别(数据库,文件,网络等)编制索引,也称为任务插件。

Play – 在给定主机上执行的一个或多个任务

Playbook – 一个或多个Play。 每个Play可以在相同或不同的主机上执行

角色 – Ansible角色使你可以基于某些功能/服务对资源进行分组,以便可以轻松地重用它们。 在角色中,你具有变量,默认值,文件,模板,处理程序,任务和元数据的目录。 然后,你只需在剧本中指定角色即可使用该角色。

清单文件定义了在其上执行Ansible任务的主机和/或主机组。

一个清单文件的例子

192.168.1.2 192.168.1.3 192.168.1.4

[web_servers] 190.40.2.20 190.40.2.21 190.40.2.22

动态清单文件可跟踪来自一个或多个来源(例如云提供商和CMDB系统)的主机。

应该使用当使用外部源时,尤其是在环境中的主机正在自动启动和关闭,而无需跟踪这些源中的所有更改。

- name: Create a new directory
  file:
      path: "/tmp/new_directory"
      state: directory
---
- name: Print information about my host
  hosts: localhost
  gather_facts: 'no'

  tasks:
      - name: Print hostname
        debug:
            msg: "It's me, {{ ansible_hostname }}"

提供完成的代码后,请始终进行彻底检查。 如果你的回答是“这将失败”,那么你是对的。 我们正在使用一个事实(ansible_hostname), 这是我们正在运行的主机上收集到的信息。 但是在这种情况下,我们禁用了事实收集(gather_facts:no),因此该变量将是未定义的,这将导致失败。

---
- hosts: all
  vars:
      mario_file: /tmp/mario
      package_list:
          - 'zlib'
          - 'vim'
  tasks:
      - name: Check for mario file
        stat:
            path: "{{ mario_file }}"
        register: mario_f

      - name: Install zlib and vim if mario file exists
        become: "yes"
        package:
            name: "{{ item }}"
            state: present
        with_items: "{{ package_list }}"
        when: mario_f.stat.exists
我是 <HOSTNAME> 我的操作系统是 <OS>

替换 以及正在运行的特定主机的实际数据 The playbook 部署system_info文件

---
- name: Deploy /tmp/system_info file
  hosts: all:!controllers
  tasks:
      - name: Deploy /tmp/system_info
        template:
            src: system_info.j2 
            dest: /tmp/system_info

The content of the system_info.j2 template

# {{ ansible_managed }}
I'm {{ ansible_hostname }} and my operating system is {{ ansible_distribution }}
  • 角色默认设置 -> whoami: mario
      * 额外的变量(使用 -e 传递给Ansible CLI的变量)-> whoami: toad
      * 托管事实 -> whoami: luigi
      * 广告资源变量(与哪种类型无关)-> whoami: browser

根据可变优先级,将使用哪个?

正确的答案是 ‘toad’。

变量优先级是关于变量在不同位置设置时如何相互覆盖的。 如果你到目前为止还没有体验过,我相信你会在某个时候确定的,这使它成为一个有用的话题。

在我们的问题上下文中,顺序将是额外的var(始终覆盖任何其他变量)-> 主机事实 -> 库存变量 -> 角色默认值(最弱)。

完整的列表可以在上面的链接中找到。 另外,请注意Ansible 1.x和2.x之间存在显着差异。

  • 模块是任务的集合
      * 最好使用shell或命令而不是特定的模块
      * 主机事实会覆盖 play 变量
      * 角色可能包括以下内容:var,meta 和 handler
      * 通过从外部来源提取信息来生成动态清单
      * 最佳做法是使用2个空格而不是4个缩进
      * 用来触发处理程序的“通知”
      * "hosts:all:!controllers"表示 "仅在控制器组主机上运行

高级

Terraform

初级

这里

  • 供应,修改和删除基础架构的全自动过程
  • 基础结构的版本控制,可让你快速回滚到以前的版本
  • 通过自动化测试和代码审查来验证基础架构的质量和稳定性
  • 减少基础架构任务的重复性

常见的错误答案是说 Ansible 和 Puppet 是配置管理工具而 Terraform 是置备工具。 尽管从技术上讲是正确的,但这并不意味着 Ansible 和 Puppet 不能 用于配置基础结构。 另外,这根本没有解释为什么应该在 CloudFormation上 使用 Terraform。

Terraform与其他工具相比的优势:

  • 它遵循不变的基础架构方法,该方法具有避免配置随时间变化的优势
      * Ansible和Puppet具有更多的过程性(你提到了每个步骤要执行的操作),而Terraform是声明性的,因为你描述的是总体所需的状态,而不是每个资源或任务的状态。 你可以举一个在每个工具中从1台服务器转到2台服务器的示例。 在terrform中,你指定2,在Ansible和puppet中,你仅需配置1个其他服务器,因此你需要明确确保仅配置另一台服务器。
  • Provider
  • Resource
  • Provisioner

它跟踪创建的资源的ID,以便Terraform知道它正在管理什么。

  • terraform init
  • terraform plan
  • terraform validate
  • terraform apply

terraform init 扫描你的代码以查明你正在使用哪些提供程序并下载它们。 terraform plan 可以让你在实际执行操作之前先查看terraform即将执行的操作。 terraform apply 将提供指定的.tf文件资源。

你用这种方式: variable “my_var” {}

这是成功创建的资源,但在配置期间失败。 Terraform将失败,并将该资源标记为“tainted”。

Strimg Integer Map List

高级

Docker

初级

容器和虚拟机之间的主要区别是容器使你可以虚拟化 操作系统上有多个工作负载,而对于VM,则将硬件虚拟化为 在多台计算机上运行各自的操作系统。

在以下情况下,你应该选择虚拟机:    * 你需要运行一个需要操作系统所有资源和功能的应用程序    * 你需要完全隔离和安全

在以下情况下,你应该选择容器:    * 你需要快速启动的轻量级解决方案    * 运行单个应用程序的多个版本或实例

Docker CLI 将你的请求传递给Docker守护程序。 Docker 守护程序从 Docker Hub 下载映像 Docker 守护程序使用下载的映像创建一个新容器 Docker 守护程序将输出从容器重定向到 Docker CLI,后者将其重定向到标准输出

  • docker run
  • docker rm
  • docker ps
  • docker build
  • docker commit
Dockerfile

Docker Hub是一个本地 Docker 注册表服务,可让你运行 pull 和 push 命令以从 Docker Hub 安装和部署 Docker映像。

Docker Cloud构建在Docker Hub之上,因此Docker Cloud提供了 与Docker Hub相比,你拥有更多的可选/功能。 一个例子是 群管理,这意味着你可以在Docker Cloud中创建新的群。

高级

Kubernetes

初级

Users

Coding

初级

Strings

高级

Python

初级

1. 这是一种由 Guido Van Rosum 于1991年创建的高级通用编程语言。
2. 语言被解释为CPython(用C语言编写)最常用/维护的实现。
3. 它是强类型的。 类型系统是鸭子类型和渐进式的。
4. Python注重可读性,并使用空格/缩进代替括号{}
5. python 包管理器称为PIP“ pip install packages”,具有超过200.000可用的软件包。
6. Python 附带安装了pip和一个大的标准库,为程序员提供了许多预置的解决方案。
7. 在python中,“一切”都是一个对象。

还有许多其他特性,但这是每个python程序员都应该知道的主要特性。

可变数据类型是:

List
Dictionary
Set

不可变数据类型是:

Numbers (int, float, ...)
String
Bool
Tuple
Frozenset

通常,你可以使用函数hash()来检查对象的可变性,如果它是可哈希的,则是不可变的,尽管由于用户定义的对象可能是可变的且可哈希的,所以它并不总是按预期工作

PEP8是Python的编码约定和样式指南的列表

5 种样式指南:

  1. 将所有行限制为最多79个字符。
  2. 用两个空行包围顶级函数和类定义。
  3. 制作一个元素的元组时使用逗号
  4. 使用空格(而不是制表符)进行缩进
  5. 每个缩进级别使用4个空格
根据定义,继承是一种机制,其中一个对象充当另一个对象的基础,并保留其所有对象属性。

因此,如果B类继承自A类,那么A类的每个特征也将在B类中提供。A类将是“基类”,B类将是“派生类”。
当你有几个共享相同功能的类时,这很方便。

基本语法:

class Base: pass

class Derived(Base): pass

A more forged example:

class Animal:
    def __init__(self):
        print("and I'm alive!")

    def eat(self, food):
        print("ñom ñom ñom", food)

class Human(Animal):
    def __init__(self, name):
        print('My name is ', name)
        super().__init__()

    def write_poem(self):
        print('Foo bar bar foo foo bar!')

class Dog(Animal):
    def __init__(self, name):
        print('My name is', name)
        super().__init__()

    def bark(self):
        print('woof woof')


michael = Human('Michael')
michael.eat('Spam')
michael.write_poem()

bruno = Dog('Bruno')
bruno.eat('bone')
bruno.bark()

>>> My name is  Michael
>>> and I'm alive!
>>> ñom ñom ñom Spam
>>> Foo bar bar foo foo bar!
>>> My name is Bruno
>>> and I'm alive!
>>> ñom ñom ñom bone
>>> woof woof

调用super()会调用Base方法,因此,调用super().__init__() 就是调用 Animal__init__。

有一个称为 MetaClasses 的更高级的python功能,可帮助程序员直接控制类的创建。


# 请注意,你通常不需要了解编译过程,而只需知道一切都来自哪里
# 并给出完整的答案表明你真正知道你在说什么。

通常,每个编译过程都有两个步骤。
    - 分析
    - 产生代码.
    
    Analysis can be broken into:
        1. 词法分析   (标记源代码)
        2. 语法分析 (如果语法正确,请检查标记是否合法,tldr)
           
               for i in 'foo'
                          ^
             SyntaxError: invalid syntax
        
        We missed ':'
        
        
        3. 语义分析  (上下文分析,合法语法仍然会触发错误,你是否尝试过除以0,哈希可变对象或使用未声明的函数?)
          
                 1/0
                ZeroDivisionError: division by zero
        
    这三个分析步骤负责错误处理。
    
    第二步将负责错误,主要是语法错误,这是最常见的错误。
    第三步将负责异常。
    
    如我们所见,异常是语义错误,有许多内置的异常:

        ImportError
        ValueError
        KeyError
        FileNotFoundError
        IndentationError
        IndexError
        ...
    
    你还可以具有用户定义的异常,这些异常必须直接或间接地从Exception类继承。

    常见例子:
        
    class DividedBy2Error(Exception):
        def __init__(self, message):
            self.message = message
    
    
    def division(dividend,divisor):
        if divisor == 2:
            raise DividedBy2Error('I dont want you to divide by 2!')
        return dividend / divisor
    
    division(100, 2)
    
    >>> __main__.DividedBy2Error: I dont want you to divide by 2!

最简单的是 str[::-1] 但不是效率最高的.

"经典" 方式:

foo = ''

for char in 'pizza':
    foo = char + foo

>> 'azzip'   

首先,你询问用户要使用的数字量。 使用while循环,每个循环将amount_of_numbers减1,直到amount_of_numbers变为0。 在while循环中,你想询问用户一个数字,该数字将在每次循环运行时添加一个变量。

def return_sum():
	amount_of_numbers = int(input("How many numbers? "))
	total_sum = 0
	while amount_of_numbers != 0:
		num = int(input("Input a number. "))
		total_sum += num
		amount_of_numbers -= 1
	return total_sum

  1. i18n中的翻译查询
  2. 将最后执行的表达式或语句的结果保存在交互式解释器中。
  3. 作为通用“可丢弃”变量名。 例如:x,y,_ = get_data()(使用了x和y,但是由于我们不关心第三个变量,因此我们将其“扔掉了”)。
Algorithms Implementation
Files
with open('file.txt', 'w') as file:
    file.write("My insightful comment")

Regex

使用 re 模式

li = [[1, 4], [2, 1], [3, 9], [4, 2], [4, 5]]

sorted(x, key=lambda l: l[1])
brothers_menu =  \
[{'name': 'Mario', 'food': ['mushrooms', 'goombas']}, {'name': 'Luigi', 'food': ['mushrooms', 'turtles']}]

# "经典" 方式
def get_food(brothers_menu) -> set:
    temp = []

    for brother in brothers_menu:
        for food in brother['food']:
            temp.append(food)

    return set(temp)

# 一直先行方式 (Using list comprehension)
set([food for bro in x for food in bro['food']])

最简短的方式是: my_string[::-1] 但是这不是效率最高的. 经典方式是:

def reverse_string(string):
    temp = ""
    for char in string:
        temp =  char + temp
    return temp
  • Static method
  • Class method
  • instance method
Time Complexity
  • Stack
  • Queue
  • Linked List
  • Binary Search Tree
  • Quicksort
  • Mergesort
  • Bucket Sort
  • Radix Sort

高级

Prometheus

初级

  • Prometheus server
  • Push Gateway
  • Alert Manager

负责抓取存储数据的Prometheus服务器推送网关用于短期作业警报管理负责警报 ;)

高级

Git

初级

简单来说, git pull = git fetch + git merge

当你运行git pull时,它会从远程或中央获取所有更改 存储库,并将其附加到本地存储库中的相应分支。

git fetch从远程存储库获取所有更改,将更改存储在 本地存储库中的单独分支

Git目录是Git存储项目的元数据和对象数据库的地方。 这是Git最重要的部分,当你从另一台计算机克隆存储库时,它就是复制的。

工作目录是项目一个版本的单个签出。 这些文件将从Git目录中的压缩数据库中拉出,并放置在磁盘上供你使用或修改。

暂存区是一个简单文件,通常包含在你的Git目录中,用于存储有关下一次提交的内容的信息。 有时称为索引,但将其称为暂存区已成为标准。

答案来自 git-scm.com

git revert 创建一个新的提交,撤消上一次提交的更改。

git reset 根据使用情况,可以修改索引或更改分支头当前指向的提交。

使用 git rebase> 命令

提及两个或三个就足够了,最好提到“递归”作为默认值。

recursive resolve ours theirs

这篇文章解释是最好的: https://git-scm.com/docs/merge-strategies

git diff

git checkout HEAD~1 -- /path/of/the/file

高级

也许不错,它是:

  • 对于合并多个分支的情况(以及此类用例的默认情况)非常有用
      * 主要用于将主题分支捆绑在一起

有一篇文章关于 Octopus merge: http://www.freblogg.com/2016/12/git-octopus-merge.html

Go

初级

  • 强类型和静态类型 - 变量的类型不能随时间更改,必须在编译时进行定义
      * 简单
      * 快速编译时间
      * 内置并发
      * 垃圾回收
      * 平台无关
      * 编译为独立的二进制文件 - 你运行应用程序所需的所有内容都将被编译为一个二进制文件。 对于运行时的版本管理非常有用。

Go 而且有一个很好的社区.

结果相同,变量值为2。

with var x int = 2 we are setting the variable type to integer while with x := 2 we are letting Go figure out by itself the type.

错. 我们不能重新声明变量,必须使用声明的变量。

应该根据你的使用情况回答此问题,一些示例是:

  • fmt - formatted I/O
func main() {
    var x float32 = 13.5
    var y int
    y = x
}
package main

import "fmt"

func main() {
    var x int = 101
    var y string
    y = string(x)
    fmt.Println(y)
}

它看起来在101处设置了什么unicode值,并将其用于将整数转换为字符串。 如果要获取“ 101”,则应使用“ strconv” 软件包,然后替换 y = string(x) with y = strconv.Itoa(x)

package main

func main() {
    var x = 2
    var y = 3
    const someConst = x + y
}
package main

import "fmt"

const (
	x = iota
	y = iota
)
const z = iota

func main() {
	fmt.Printf("%v\n", x)
	fmt.Printf("%v\n", y)
	fmt.Printf("%v\n", z)
}
package main

import "fmt"

const (
	_ = iota + 3
	x
)

func main() {
	fmt.Printf("%v\n", x)
}

Mongo

初级

主要区别在于SQL数据库是结构化的(数据以带有行和列的表格-像是Excel电子表格表格),而NoSQL是 非结构化的,并且数据存储会根据NoSQL DB的设置方式而有所不同,例如 作为键值对,面向文档等

  • 经常变化的异构数据
      * 数据一致性和完整性不是重中之重
      * 最好,如果数据库需要快速扩展
Queries

OpenShift

初级

Shell 脚本

初级

取决于所使用的语言和设置,例如在Bash中,默认情况下,脚本将继续运行。

  • echo $0
  • echo $?
  • echo $$
  • echo $@
  • echo $#

高级

:(){ :|:& };:

使用 if/else 的一种简短方法。 一个例子:

[[ $a = 1 ]] && b="yes, equal" || b="nope"

SQL

初级

Structured Query Language(结构化查询语言)

主要区别在于SQL数据库是结构化的(数据以 带有行和列的表格-像是Excel电子表格表格),而NoSQL是 非结构化的,并且数据存储会根据NoSQL DB的设置方式而有所不同,例如 作为键值对,面向文档等

ACID代表原子性,一致性,隔离性,耐久性。为了符合ACID,数据库必须满足四个标准中的每个标准

原子性 - 数据库发生更改时,它整体上应该成功或失败。

例如,如果你要更新表,则更新应完全执行。如果仅部分执行,则 更新被视为整体失败,并且不会通过-数据库将恢复为原始状态 更新发生之前的状态。还应该提到的是,原子性确保每个 事务以其自身的独立“单元”完成 - 如果任何部分失败,则整个语句都会失败。

一致性 - 对数据库所做的任何更改都应将其从一种有效状态转变为另一种有效状态。

例如,如果你对数据库进行了更改,则不应破坏它。通过检查和约束来保持一致性 在数据库中预定义。例如,如果你尝试将列的值从字符串更改为int 应该是数据类型字符串,一致的数据库将不允许该事务通过,并且该操作将 不执行

隔离 - 确保数据库不会被“更新中”-因为多个事务正在运行 同时,它仍应保持数据库处于与按顺序运行事务相同的状态。

例如,假设有20个人同时对数据库进行了更改。在 当你执行查询时,已完成20项更改中的15项,但仍有5项正在进行中。你应该 仅看到已完成的15个更改 - 随着更改的进行,你将看不到数据库的更新中。

耐用性 - 更改一旦提交,无论发生什么情况都将保持提交状态 (电源故障,系统崩溃等)。这意味着所有已完成的交易 必须记录在非挥发性内存中。

请注意,SQL本质上符合ACID。某些NoSQL DB可能符合ACID,具体取决于 它们的工作方式,但是根据一般经验,NoSQL DB不被视为符合ACID

SQL - 当数据完整性至关重要时,最适合使用。 由于符合ACID,SQL通常由许多业务实现特别是金融领域。

NoSQL - 非常适合你需要快速扩展的情况。 请记住NoSQL是为Web应用程序设计的 ,如果你需要快速将相同信息散布到多台服务器,它将会很好的用 此外,由于 NoSQL 不遵守具有列和行结构的严格表 关系数据库所要求的,你可以将不同的数据类型存储在一起。

笛卡尔积是指第一个表中的所有行都与第二个表中的所有行连接在一起时的结果 表。 这可以通过不定义要联接的键来隐式完成,也可以通过以下方式显式地完成: 在两个表上调用CROSS JOIN,如下所示:

Select * from customers CROSS JOIN orders;

请注意,笛卡尔积也可能是一件坏事 - 执行联接时 在两个都没有唯一键的表上,这可能会导致返回信息 是不正确的。

SQL Specific Questions

对于这些问题,我们将使用下面显示的“客户和订单”表:

Customers

Customer_ID Customer_Name Items_in_cart Cash_spent_to_Date
100204 John Smith 0 20.00
100205 Jane Smith 3 40.00
100206 Bobby Frank 1 100.20

ORDERS

Customer_ID Order_ID Item Price Date_sold
100206 A123 Rubber Ducky 2.20 2019-09-18
100206 A123 Bubble Bath 8.00 2019-09-18
100206 Q987 80-Pack TP 90.00 2019-09-20
100205 Z001 Cat Food - Tuna Fish 10.00 2019-08-05
100205 Z001 Cat Food - Chicken 10.00 2019-08-05
100205 Z001 Cat Food - Beef 10.00 2019-08-05
100205 Z001 Cat Food - Kitty quesadilla 10.00 2019-08-05
100204 X202 Coffee 20.00 2019-04-29

Select * From Customers;

Select Items_in_cart From Customers Where Customer_Name = "John Smith";

Select SUM(Cash_spent_to_Date) as SUM_CASH From Customers;

Select count(1) as Number_of_People_w_items From Customers where Items_in_cart > 0;

你可以加入他们的唯一键。 在这种情况下,唯一键为中的Customer_ID 客户表和订单表

Select c.Customer_Name, o.Item From Customers c Left Join Orders o On c.Customer_ID = o.Customer_ID;

高级

with cat_food as ( Select Customer_ID, SUM(Price) as TOTAL_PRICE From Orders Where Item like "%Cat Food%" Group by Customer_ID ) Select Customer_name, TOTAL_PRICE From Customers c Inner JOIN cat_food f ON c.Customer_ID = f.Customer_ID where c.Customer_ID in (Select Customer_ID from cat_food);

尽管这是一个简单的声明,但“ with”子句在 在连接到另一个表之前,需要在一个表上运行一个复杂的查询。 用语句很好, 因为你在运行查询时会创建一个伪临时文件,而不是创建一个新表。

目前尚无法获得所有猫粮的总和,因此我们使用了with语句来创建 伪表检索每个客户花费的价格总和,然后正常加入该表。

Azure

初级

GCP

初级

OpenStack

初级

  • Nova
  • Neutron
  • Cinder
  • Glance
  • Keystone
网络

中级

网络

安全

初级

Puppet

初级

  • Module
  • Manifest
  • Node

中级

场景

方案是没有口头回答的问题,需要你满足以下条件之一:

  • 设置环境
  • 编写脚本
  • 设计和/或开发基础设施项目

这些问题通常作为应聘者的一项家庭任务作为候选,可以将多个主题结合在一起。 在下面,你可以找到一些场景问题: