Docker 如何助您成为数据科学家
一、说明
在过去的 5 年里,我听到了很多关于 docker 容器的嗡嗡声。似乎我所有的软件工程朋友都在使用它们来开发应用程序。我想弄清楚这项技术如何使我更有效率,但我发现网上的教程要么太详细:阐明我作为数据科学家永远不会使用的功能,要么太肤浅:没有给我足够的信息来帮助我了解如何快速有效地使用 Docker。
我写了这个快速入门,所以你不必解析所有的信息,而是可以学习你需要知道的事情,以便快速入门。
二、什么是 Docker?
您可以将 Docker 视为轻量级虚拟机,其中包含运行应用程序所需的一切。docker 容器可以捕获系统状态的快照,以便其他人可以快速重新创建您的计算环境。这就是本教程需要了解的全部内容,但有关更多详细信息,您可以前往此处。
三、为什么要使用 docker?
- 可重复性:作为一名专业数据科学家,您的工作具有可重复性非常重要。可重复性不仅有助于同行评审,而且确保您构建的模型、应用程序或分析可以毫无摩擦地运行,从而使您的可交付成果更加稳健并经得起时间的考验。例如,如果你在python中构建了一个模型,仅仅运行pip-freeze并将结果的需求.txt文件发送给你的同事通常是不够的,因为这只会封装python特定的依赖项 - 而通常存在存在于python之外的依赖项,例如操作系统,编译器,驱动程序,配置文件或代码成功运行所需的其他数据。即使你可以只共享 python 依赖项,将所有内容包装在 Docker 容器中也可以减轻其他人重新创建环境的负担,并使你的工作更易于访问。
- 计算环境的可移植性:作为数据科学家,尤其是在机器学习领域,能够快速更改计算环境可以极大地影响您的工作效率。数据科学工作通常从原型设计、探索和研究开始——这些工作不一定需要专门的计算资源。这项工作通常发生在笔记本电脑或个人计算机上。但是,经常会出现不同的计算资源会大大加快您的工作流程,例如具有更多 CPU 的机器或用于深度学习等功能的更强大的 GPU。我看到许多数据科学家将自己限制在本地计算环境中,因为在远程计算机上重新创建本地环境存在摩擦。Docker 使移植环境(所有库、文件等)的过程变得非常容易。在 Kaggle 竞赛中,快速移植计算环境也是一个巨大的竞争优势,因为您可以以经济高效的方式利用 AWS 上宝贵的计算资源。最后,创建 docker 文件允许您移植许多您喜欢的本地环境,例如 bash 别名或 vim 插件。
-
增强您的工程能力:熟悉 Docker 可以让您将模型或分析部署为应用程序(例如,作为可以提供预测服务的 REST API 端点),从而使其他人可以访问您的工作。此外,作为数据科学工作流程的一部分,您可能需要与之交互的其他应用程序可能存在于 Docker 容器中,例如数据库或其他应用程序。
四、Docker 术语
在我们深入之前,熟悉 Docker 术语很有帮助:
- 图像:是您想要构建的蓝图。例如:带有 Nvidia 驱动程序和正在运行的 Jupyter 服务器的 Ubuntu + TensorFlow。
- 容器:是您赋予生命的图像的实例。您可以运行同一映像的多个副本。掌握镜像和容器之间的区别非常重要,因为这是新手容易混淆的一个原因。如果图像和容器之间的区别不清楚,请停止并再次阅读。
- Dockerfile:创建映像的配方。Dockerfile 包含特殊的 Docker 语法。来自官方文档:A 是一个文本文档,其中包含用户可以在命令行上调用以组装图像的所有命令。
Dockerfile
- 提交:与 git 一样,Docker 容器提供版本控制。您可以通过提交更改随时将 docker 容器的状态另存为新映像。
- DockerHub/Image Registry:人们可以发布公共(或私有)docker 镜像以促进协作和共享的地方。
- 层:对现有映像的修改,由 Dockerfile 中的指令表示。图层按顺序应用于基础映像以创建最终映像。
我将在帖子的其余部分使用此术语,因此如果您迷路了,请参阅此列表!这些术语之间很容易混淆,尤其是在图像和容器之间——所以在阅读时要保持警惕!
五、创建您的第一个 Docker 镜像
在创建 docker 容器之前,创建一个将定义映像的 Dockerfile 非常有用。让我们慢慢地浏览下面的 Dockerfile。可以在本教程随附的 Github 存储库中找到此文件。
# reference: https://hub.docker.com/_/ubuntu/
FROM ubuntu:16.04# Adds metadata to the image as a key value pair example LABEL version="1.0"
LABEL maintainer="Hamel Husain <youremail@gmail.com>"##Set environment variables
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8RUN apt-get update --fix-missing && apt-get install -y wget bzip2 ca-certificates \build-essential \byobu \curl \git-core \htop \pkg-config \python3-dev \python-pip \python-setuptools \python-virtualenv \unzip \&& \
apt-get clean && \
rm -rf /var/lib/apt/lists/*RUN echo 'export PATH=/opt/conda/bin:$PATH' > /etc/profile.d/conda.sh && \wget --quiet https://repo.continuum.io/archive/Anaconda3-5.0.0.1-Linux-x86_64.sh -O ~/anaconda.sh && \/bin/bash ~/anaconda.sh -b -p /opt/conda && \rm ~/anaconda.shENV PATH /opt/conda/bin:$PATHRUN pip --no-cache-dir install --upgrade \altair \sklearn-pandas# Open Ports for Jupyter
EXPOSE 7745#Setup File System
RUN mkdir ds
ENV HOME=/ds
ENV SHELL=/bin/bash
VOLUME /ds
WORKDIR /ds
ADD run_jupyter.sh /ds/run_jupyter.sh
RUN chmod +x /ds/run_jupyter.sh# Run a shell script
CMD ["./run_jupyter.sh"]
5.1 FROM 语句
FROM ubuntu:16.04
FROM 语句封装了 Docker 最神奇的部分。此语句指定要在其上构建的基础映像。使用 FROM 指定基本映像后,Docker 将在本地环境中查找名为 ubuntu:16.04 的映像 — 如果在本地找不到它,它将搜索您指定的 Docker 注册表,默认情况下为 DockerHub。这种分层机制很方便,因为您经常希望在 Ubuntu 等操作系统之上安装程序。与其担心如何从头开始安装 Ubuntu,不如简单地在官方 Ubuntu 映像之上构建!Dockerhub上托管了各种各样的Docker镜像,包括那些提供的不仅仅是操作系统的镜像,例如,如果你想要一个已经安装了Anaconda的容器,你可以在官方的anaconda docker镜像之上构建一个容器。最重要的是,您还可以随时发布您构建的映像,即使该映像是通过在另一个映像上分层创建的!可能性是无穷无尽的。
在这个例子中,我们指定我们的基础映像是 ubuntu:16.04,它将查找一个名为 ubuntu 的 DockerHub 存储库。冒号 — 16.04 之后的映像名称部分是允许您指定要安装的基础映像版本的标记。如果你导航到 Ubuntu DockerHub 存储库,你会注意到不同版本的 Ubuntu 对应着不同的标签:
例如,在撰写本文时,ubuntu:16.04、ubuntu:xenial-20171201、ubuntu:xenial 和 ubuntu:latest 都引用了 Ubuntu 版本 16.04,并且都是同一映像的别名。此外,此存储库中提供的链接将您链接到用于为每个版本构建映像的相应 Dockerfile。您不会总是在 DockerHub 存储库中找到 Dockerfiles,因为维护者可以选择包含他们如何制作映像的 Dockerfile。我个人发现查看其中几个 Dockerfile 以更多地了解 Dockerfile 很有用(但请等到您完成本教程!
有一个标签值得特别提及 — :latest 标签。此标记指定如果未在 FROM 语句中指定标记,则默认情况下将提取的内容。例如,如果 FROM 语句如下所示:
FROM ubuntu
然后你最终会拉出 ubuntu:16.04 映像。为什么?— 如果你仔细看上面的截图,你会看到 :latest 标签与 16.04 相关联
关于 Docker 镜像的最后一点:从 DockerHub 随机提取 Docker 镜像时,要做出明智的判断。由恶意行为者创建的 Docker 映像可能包含恶意软件。
5.2 标签声明
此语句将元数据添加到映像中,并且是完全可选的。我添加它是为了让其他人知道该联系谁来了解该映像,也可以这样我就可以搜索我的 docker 容器,尤其是当服务器上有许多容器同时运行时。
LABEL maintainer="Hamel Husain <youremail>"
5.3 环境声明
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
这允许您更改环境变量,并且非常简单。您可以在此处阅读有关此内容的更多信息。
5.4 运行语句
这通常是完成构建 Docker 映像所需的工作的主力。您可以运行任意 shell 命令(如 apt-get 和 pip install)来安装所需的包和依赖项。
RUN apt-get update --fix-missing && apt-get install -y wget bzip2 build-essential \ca-certificates \git-core \...
在这种情况下,我正在安装一些我喜欢的实用程序,例如curl,htop,byobu,然后安装anaconda,然后安装基本anaconda安装中没有的其他库(向上滚动到完整的Dockerfile以查看所有RUN语句)。
RUN 语句后面的命令与 Docker 无关,而是您自己安装这些软件包时会运行的普通 linux 命令,因此如果您不熟悉其中一些软件包或 linux 命令,请不要担心。另外,作为进一步的建议——当我第一次开始学习 docker 时,我查看了 Github 或 DockerHub 上的其他 Dockerfile,并将我想要的相关部分复制并粘贴到我的 Dockerfile 中。
关于 RUN 语句,您可能会注意到的一件事是格式设置。每个库或包都整齐地缩进并按字母顺序排列,以提高可读性。这是 Dockerfiles 的普遍约定,所以我建议你采用它,因为它会简化协作。
5.5 暴露语句
如果您尝试公开端口,则此语句很有用 - 例如,如果您从容器或某种 Web 服务内部提供 jupyter 笔记本。Docker的文档在解释EXPOSE 语句方面非常好:
该指令实际上并不发布端口。它充当构建映像的人和运行容器的人员之间的一种文档类型,关于要发布的端口。若要在运行容器时实际发布端口,请使用标志 on 发布和映射一个或多个端口,或使用标志发布所有公开的端口并将其映射到高阶端口。
EXPOSE
-p
docker run
-P
5.6 卷语句
VOLUME /ds
此语句允许您在 docker 容器和主机之间共享数据。VOLUME 语句允许您装入外部装入的卷。主机目录仅在运行容器时声明(因为您可能在不同的计算机上运行此容器),而不是在定义映像时声明*。目前,您只需指定要与主机容器共享的 docker 容器中文件夹的名称。
从 docker 用户指南:
*主机目录在容器运行时声明:主机目录(挂载点)本质上依赖于主机。这是为了保持图像的可移植性。因为无法保证给定的主机目录在所有主机上都可用。因此,您无法从 Dockerfile 中挂载主机目录。该指令不支持指定参数。创建或运行容器时必须指定装入点。
VOLUME
host-dir
此外,这些卷旨在将数据保存在容器的文件系统之外,如果您正在处理不希望使 docker 映像膨胀的大量数据,这通常很有用。保存 docker 映像时,此 VOLUME 目录中的任何数据都不会保存为映像的一部分,但将保存容器中此目录之外的数据。
5.7 工作路径声明
WORKDIR /ds
此语句设置工作目录,以防要在另一个命令中引用没有绝对路径的特定文件。例如,Dockerfile 中的最后一条语句是
CMD [“./run_jupyter.sh”]
假设工作目录为 /ds
5.8 ADD 语句
编辑 8/24/2020:您现在应该使用 COPY 语句而不是 ADD 语句。
ADD run_jupyter.sh /ds/run_jupyter.sh
此命令允许您在运行 docker 容器时将文件从主机复制到 docker 容器中。我使用它来执行 bash 脚本并将有用的东西导入容器中,例如 .bashrc 文件。
请注意,此处未完全指定主机容器的路径,因为主机路径相对于运行容器时指定的上下文目录(稍后将讨论)。
碰巧的是,当我运行这个容器时,我会将文件run_jupyter.sh在上下文目录的根目录中,所以这就是为什么源文件前面没有路径的原因。
从用户指南:
ADD <src>... <dest>
该指令从中复制新文件、目录或远程文件 URL,并将它们添加到路径 中的映像文件系统中。
ADD
<src>
<dest>
5.9 CMD声明
Docker 容器的设计理念是它们是短暂的,只会保持足够长的时间来完成要运行的应用程序。但是,对于数据科学,我们通常希望保持这些容器运行,即使其中没有任何活动运行。许多人通过简单地运行一个 bash shell(除非你杀死它,否则不会终止)来实现这一点的一种方式。
CMD [“./run_jupyter.sh”]
在上面的命令中,我正在运行一个实例化 Jupyter 笔记本服务器的 shell 脚本。但是,如果您没有任何要运行的特定应用程序,但希望容器在不退出的情况下运行 — 则可以使用以下命令简单地运行 bash shell:
CMD ["/bin/bash"]
这是有效的,因为 bash shell 在您退出之前不会终止,因此容器保持正常运行。
从用户指南:
a 中只能有一个指令。如果您列出多个,则只有最后一个会生效。
CMD
Dockerfile
CMD
CMD
a 的主要目的是 为执行容器提供默认值。这些默认值可以包含可执行文件,也可以省略可执行文件,在这种情况下,您还必须指定指令。
CMD
ENTRYPOINT
六、构建您的 Docker 镜像
别担心,从这里开始,其他一切都相当简单。现在我们已经以 DockerFile 的形式创建了我们的配方,是时候构建映像了。您可以通过以下命令完成此操作:
也可在 Github 上使用
这将构建一个 docker 镜像(不是容器,如果你不记得有什么区别,请阅读本文开头的术语!),然后你可以在以后运行它。
七、从 Docker 映像创建并运行容器
现在,您已准备好将所有这些魔力付诸实践。我们可以通过执行以下命令来启动此环境:
也可在 Github 上使用
运行此命令后,您的容器将启动并运行!Jupyter 服务器将运行,因为
CMD [“./run_jupyter.sh”]
命令在 Dockerfile 的末尾。现在,您应该能够在 jupyter 笔记本提供服务的端口上访问它 — 在此示例中,它应该可以通过密码教程从 http://localhost:7745/ 访问。 如果你远程运行这个 docker 容器,你必须设置 local 端口转发,以便你可以从浏览器访问 jupyter 服务器。
八、与容器交互
容器启动并运行后,以下命令将派上用场:
- 将新的终端会话附加到容器。如果您需要安装某些软件或使用 shell,这将非常有用。
- 将容器的状态另存为新映像。即使您一开始使用的是包含要安装的所有库的 Dockerfile,但随着时间的推移,您可能会通过以交互方式添加更多库和包来显著更改容器的状态。将容器的状态另存为稍后可以共享或分层的图像非常有用。您可以使用 docker commit CLI 命令来完成此操作:
docker commit <container_name> new_image_name:tag_name(optional)
例如,如果我想将名为 container1 的容器的状态保存为名为 hamelsmu/tutorial:v2 的图像,我只需运行以下命令:
docker commit container_1 hamelsmu/tutorial:v2
你可能想知道为什么hamelsmu/在镜像名称的前面——这只是让以后更容易地将这个容器推送到DockerHub,因为hamelsmu是我的DockerHub用户名(稍后会详细介绍)。如果您在工作中使用 Docker,则很可能有一个内部私有 Docker 存储库,您可以将 Docker 映像推送到该存储库。
- 列出正在运行的容器。当我忘记当前正在运行的容器的名称时,我经常使用它。
docker ps -a -f status=running
如果您在没有 status=running 标志的情况下运行上述命令,那么您将看到系统上所有容器的列表(即使它们不再运行)。这对于跟踪旧容器很有用。
- 列出已保存在本地的所有图像。
docker images
- 将您的映像推送到 DockerHub(或其他注册表)。如果您想与他人共享您的工作,或方便地将图像保存在云中,这将非常有用。请注意,在执行此操作时不要共享任何私有信息(DockerHub上也有私有存储库)。
首先创建一个 DockerHub 存储库并适当地命名您的映像,如此处所述。这将涉及运行命令docker login以首先连接到DockerHub或其他注册表上的帐户。例如,要将图像推送到此容器,我首先必须将我的本地映像命名为 hamelsmu/tutorial(我可以选择任何标签名称) 例如,CLI 命令:
docker push hamelsmu/tutorial:v2
将上述 docker 映像推送到带有标记 v2 的此存储库。应该注意的是,如果你让你的镜像公开可用,其他人可以简单地在你的镜像上分层,就像我们在本教程中向 ubuntu 镜像添加层一样。这对于寻求复制或扩展您的研究的其他人非常有用。
九、现在你拥有超能力
现在您已经知道如何操作 Docker,您可以执行以下任务:
- 与同事和朋友分享可重复的研究。
- 通过根据需要将代码临时移动到更大的计算环境,在不破产的情况下赢得 Kaggle 比赛。
- 在笔记本电脑上的 docker 容器内本地制作原型,然后将相同的计算无缝移动到服务器而不会出汗,同时随身携带您喜欢的本地环境的许多东西(您的别名、vim 插件、bash 脚本、自定义提示等)。
- 使用 Nvidia-Docker 快速实例化在 GPU 计算机上运行 Tensorflow、Pytorch 或其他深度学习库所需的所有依赖项(如果您从头开始执行此操作,这可能会很痛苦)。有关更多信息,请参阅下面的奖金部分。
- 将模型发布为应用程序,例如作为从 docker 容器提供预测的 rest api。当您的应用程序被 Docker 化时,可以根据需要多次复制它。
十、延伸阅读
我们只是触及了 Docker 的表面,您可以做的还有很多。我专注于Docker的领域,我认为作为数据科学家,你最常遇到的领域,并希望给你足够的信心开始使用它。以下是一些在 Docker 之旅中帮助我的资源:
- 编辑 8/24/2020:以下是我最近在 Docker 上所做的一些更详细的笔记。
- 有用的 Docker 命令
- 更多有用的 Docker 命令
- Dockerfile 参考
- 如何在 DockerHub 上创建并推送到存储库
相关文章:

Docker 如何助您成为数据科学家
一、说明 在过去的 5 年里,我听到了很多关于 docker 容器的嗡嗡声。似乎我所有的软件工程朋友都在使用它们来开发应用程序。我想弄清楚这项技术如何使我更有效率,但我发现网上的教程要么太详细:阐明我作为数据科学家永远不会使用的功能&#…...

机器学习01 -Hello World(对鸢尾花(Iris Flower)进行训练及测试)
什么是机器学习? 机器学习是一种人工智能(AI)的子领域,它探索和开发计算机系统,使其能够从数据中学习和改进,并在没有明确编程指令的情况下做出决策或完成任务。 传统的程序需要程序员明确编写指令来告诉…...

android studio JNI开发
一、JNI的作用: 1.使Java与本地其他类型语言(C、C)交互; 2.在Java代码调用C、C等语言的代码 或者 C、C调用Java代码。 由于JAVA具有跨平台的特点,所以JAVA与本地代码的交互能力弱,采用JNI特性可以增强JA…...

CSS 高频按钮样式
矩形与圆角按钮 正常而言,我们遇到的按钮就这两种 -- 矩形和圆角: 它们非常的简单,宽高和圆角和背景色。 <div classbtn rect>rect</div><div classbtn circle>circle</div>.btn {margin: 8px auto;flex-shrink: 0;…...

系列二、RocketMQ简介
一、概述 RocketMQ是一款阿里巴巴开源的消息中间件。2016年11月28日,阿里巴巴向Apache软件基金会捐赠RabbitMQ,成为Apache孵化项目。2017年9月25日,Apache宣布RocketMQ孵化成为Apache顶级项目(TLP),成为国内…...

论文笔记--Skip-Thought Vectors
论文笔记--Skip-Thought Vectors 1. 文章简介2. 文章概括3 文章重点技术3.1 Skip Thought Vectors3.2 词表拓展 4. 文章亮点5. 原文传送门6. References 1. 文章简介 标题:Skip-Thought Vectors作者:Ryan Kiros, Yukun Zhu, Ruslan Salakhutdinov, Rich…...

1400*B. Karen and Coffee
Examples input 3 2 4 91 94 92 97 97 99 92 94 93 97 95 96 90 100 output 3 3 0 4 input 2 1 1 1 1 200000 200000 90 100 output 0 解析: 题意为,给你多个区间(会有重叠),每个区间的每个值都会为这个值累加…...

【业务功能篇54】Springboot项目常用工具类:HTTP状态码/客户端request
状态码常量类 /*** 返回状态码**/ public class HttpStatus {/*** 操作成功*/public static final int SUCCESS 200;/*** 对象创建成功*/public static final int CREATED 201;/*** 请求已经被接受*/public static final int ACCEPTED 202;/*** 操作已经执行成功࿰…...

Fine Logic
登录—专业IT笔试面试备考平台_牛客网 题目大意:有n个数分别为1~n,有m个数值对(u,v)表示u要排在v左边,问至少要多少个排列才能满足所有数值对至少一次 2<n<1e6;1<m<1e6 思路:如果数值对中要求u在v左边,…...

Neo4j图数据基本操作
Neo4j 文章目录 Neo4jCQL结点和关系增删改查匹配语句 根据标签匹配节点根据标签和属性匹配节点删除导入数据目前的问题菜谱解决的问题 命令行窗口 neo4j.bat console 导入rdf格式的文件 :GET /rdf/ping CALL n10s.graphconfig.init(); //初始化 call n10s.rdf.import.fetch(&q…...

前端JavaScript面试100问(中)
31、http 的理解 ? HTTP 协议是超文本传输协议,是客户端浏览器或其他程序“请求”与 Web 服务器响应之间的应用层通信协议。HTTPS主要是由HTTPSSL构建的可进行加密传输、身份认证的一种安全通信通道。32、http 和 https 的区别 ? 1、https协议需要到ca申请证书&…...

Docker 安全及日志管理与https部署
容器的安全性问题的根源在于容器和宿主机共享内核。如果容器里的应用导致Linux内核崩溃,那么整个系统可能都会崩溃。与虚拟机是不同的,虚拟机并没有与主机共享内核,虚拟机崩溃一般不会导致宿主机崩溃。 Docker 容器与虚拟机的区别 虚拟机通…...

2.3 HLSL常用函数
一、函数介绍 函数图像参考网站:Graphtoy 1.基本数学运算 函数 含义 示例图 min(a,b) 返回a、b中较小的数值 mul(a,b) 两数相乘用于矩阵计算 max(a,b) 返回a、b中较大的数值 abs(a) 返回a的绝对值 round(x) 返回与x最近的整数 sqrt(x) 返回x的…...

互联网的发展
概述 互联网是现代社会中举足轻重的一个领域,它的发展对于人类的生活和工作方式产生了深远的影响。互联网的发展经历了几个阶段,从初创阶段到如今的高度普及和深入应用,本文将详细介绍互联网的发展状况。 第一阶段:互联网的起源…...

STM32 CAN通讯实验程序
目录 STM32 CAN通讯实验 CAN硬件原理图 CAN外设原理图 TJA1050T硬件描述 实验线路图 回环实验 CAN头文件配置 CAN_GPIO_Config初始化 CAN初始化结构体 CAN筛选器结构体 接收中断优先级配置 接收中断函数 main文件 实验现象 补充 STM32 CAN通讯实验 CAN硬件原理图…...

Python代码片段之Django静态文件URL的配置
首先要说明这段python代码并不完整,而且我也没有做过测试,只是我在工作时参考了其中的一些个方法。这是我在找python相关源码资料里看到的一段代码,是Django静态文件URL配置代码片段2,代码中有些方法还是挺技巧的,做其…...

基于飞桨paddle的极简方案构建手写数字识别模型测试代码
基于飞桨paddle的极简方案构建手写数字识别模型测试代码 原始测试图片为255X252的图片 因为是极简方案采用的是线性回归模型,所以预测结果数字不一致 本次预测的数字是 [[3]] 测试结果: PS E:\project\python> & D:/Python39/python.exe e:/pro…...

soft ip与hard ip
ip分soft和hard两种,soft就是纯代码,买过来要自己综合自己pr。hard ip如mem和analog与工艺有关。 mem的lib和lef是memory compiler产生的,基于bitcell,是foundry给的。 我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起…...

MyBatisPlus从入门到精通-2
接着上一讲的Mp的分页功能 下面我们讲解条件查询功能和其他功能 解决一下日志输出和banner问题 每次卞就会输出这些日志 很不美观,现在我们关闭一下 这样建个xml,文件名为logback.xml 文件内容改成这样 配置了logback但是里面什么都没写就不会说有日…...

AI面试官:Asp.Net 中使用Log4Net (一)
AI面试官:Asp.Net 中使用Log4Net (一) 当面试涉及到使用log4net日志记录框架的相关问题时,通常会聚焦在如何在.NET或.NET Core应用程序中集成和使用log4net。以下是一些关于log4net的面试题目,以及相应的解答、案例和代码: 文章目…...

Selenium自动化元素定位方式与浏览器测试脚本
Selenium八大元素定位方法 Selenium可以驱动浏览器完成各种操作,比如模拟点击等。要想操作一个元素,首先应该识别这个元素。人有各种的特征(属性),我们可以通过其特征找到人,如通过身份证号、姓名、家庭住…...

人机交互与人机混合智能的区别
人机交互和人机融合智能是两个相关但不完全相同的概念: 人机交互是指人与计算机之间的信息交流和互动过程。它关注的是如何设计和实现用户友好的界面,以便人们能够方便、高效地与计算机进行沟通和操作。人机交互通常强调用户体验和界面设计,旨…...

【项目】轻量级HTTP服务器
文章目录 一、项目介绍二、前置知识2.1 URI、URL、URN2.2 CGI2.2.1 CGI的概念2.2.2 CGI模式的实现2.2.3 CGI的意义 三、项目设计3.1 日志的编写3.2 套接字编写3.3 HTTP服务器实现3.4 HTTP请求与响应结构3.5 EndPoint类的实现3.5.1 EndPoint的基本逻辑3.5.2 读取请求3.5.3 构建响…...

sketch如何在线打开?有没有什么软件可以辅助
Sketch 在线打开的方法有哪些?这个问题和我之前回答过的「Sketch 可以在线编辑吗?」是一样的答案,没有。很遗憾,Sketch 没有在线打开的方法,Sketch 也做不到可以在线编辑。那么,那些广告里出现的设计软件工…...

CSS Flex 笔记
1. Flexbox 术语 Flex 容器可以是<div> 等,对其设置属性:display: flex, justify-content 是沿主轴方向调整元素,align-items 是沿交叉轴对齐元素。 2. Cheatsheet 2.1 设置 Flex 容器,加粗的属性为默认值 2.1.1 align-it…...

Markdown常用标签及其用途-有示例
Markdown常用标签及其用途 Markdown是一种轻量级标记语言,具有简洁易读的特点。下面是一些常用的Markdown标签以及它们的用途,并附带一些示例: 标题 用于创建不同级别的标题,可通过添加一到六个#符号来表示不同级别的标题。 #…...
25.1 Knife4j-Swagger的增强插件
1.Knife4j概述 Knife4j是一款基于Swagger UI的增强插件,它可以为Spring Boot项目生成美观且易于使用的API文档界面。它是Swagger UI的增强版,提供了更多的功能和定制选项,使API文档更加易读和易于理解。 2.Knife4j使用 Knife4j 集Swagger2…...

用flask run代替flask run --debug
安装python-dotenv依赖。 在项目根目录下新建.flaskenv文件,并作如下配置: FLASK_ENVdevelopment FLASK_DEBUG1...

python_day14_综合案例
文件内容 导包配置 import jsonfrom pyspark import SparkContext, SparkConf import osos.environ["PYSPARK_PYTHON"] "D:/dev/python/python3.10.4/python.exe" os.environ["HADOOP_HOME"] "D:/dev/hadoop-3.0.0" conf SparkC…...

【算法题】2779. 数组的最大美丽值
题目: 给你一个下标从 0 开始的整数数组 nums 和一个 非负 整数 k 。 在一步操作中,你可以执行下述指令: 在范围 [0, nums.length - 1] 中选择一个 此前没有选过 的下标 i 。 将 nums[i] 替换为范围 [nums[i] - k, nums[i] k] 内的任一整…...