1. logstash脚本编写(采用单文件对应单表实例) 新建脚本文件夹
cd /usr/local/logstash mkdir sql & cd sql
vim 表名称.conf
#如: znyw_data_gkb_logstash.conf 建立文件夹,保存资源文件更新Id
mkdir -p /data/logstash/data/last_run_metadata 脚本JDBC插件参数说明:
增加新脚本步骤: 修改statement 查询执行SQL脚本(对应数据库表)可以通过代码工具生成。地址: 增量同步字段,建议使用更新时间字段 tracking_column => "updateDate" tracking_column_type => timestamp(类型成对出现) 修改数据存储文件路径,红色为索引名称,每个脚本对应一个。 last_run_metadata_path => "xxx_last_update_time.txt" 同步频率(可以通过在线表达式进行生成)在线Cron表达式生成器 第一步要做的事情,配置logstasht同步脚本文件,内容如下:
input { jdbc { type => "jdbc" # 数据库连接地址 jdbc_connection_string => "jdbc:mysql://172.168.9.131:3306/gffp_om?characterEncoding=UTF-8&autoReconnect=true&serverTimezone=CTT" # 数据库连接账号密码 jdbc_user => "znyg" jdbc_password => "hTORRp86!7" # MySQL依赖包路径 jdbc_driver_library => "/usr/local/logstash/mysql-connector-java-8.0.22.jar" # the name of the driver class for mysql jdbc_driver_class => "
1. Logstash介绍 Logstash是一个数据流引擎:
它是用于数据物流的开源流式ETL引擎,在几分钟内建立数据流管道,具有水平可扩展及韧性且具有自适应缓冲,不可知的数据源,具有200多个集成和处理器的插件生态系统,使用Elastic Stack监视和管理部署
Logstash包含3个主要部分: 输入(inputs),过滤器(filters)和输出(outputs)。 inputs主要用来提供接收数据的规则,比如使用采集文件内容; filters主要是对传输的数据进行过滤,比如使用grok规则进行数据过滤; outputs主要是将接收的数据根据定义的输出模式来进行输出数据,比如输出到ElasticSearch中.
示例图:
2. Logstash安装使用 Logstash采用JRuby语言编写,运行在jvm中,因此安装Logstash前需要先安装JDK,Ruby。
Logstash需要以下版本之一:
Java 8Java 11Java 14 版本选择
https://www.elastic.co/downloads/past-releases#logstash
7.1.1版本下载地址
https://artifacts.elastic.co/downloads/logstash/logstash-7.1.1.tar.gz
2.1部署服务 $ tar xf logstash-7.1.1.tar.gz -C /usr/local/src/ ln -s /usr/local/src/logstash-7.1.1 /usr/local/logstash $ mkdir -p /data/logstash/{logs,data} 配置文件说明
logstash.yml
包含Logstash配置标志。您可以在此文件中设置标志,而不是在命令行中传递标志。您在命令行上设置的所有标志都将覆盖logstash.yml文件中的相应设置。有关更多信息,请参见logstash.yml。 pipelines.yml
包含用于在单个Logstash实例中运行多个管道的框架和说明。有关更多信息,请参见多管道。 jvm.options
包含JVM配置标志。使用此文件设置总堆空间的初始值和最大值。您也可以使用此文件设置Logstash的语言环境。在单独的行上指定每个标志。此文件中的所有其他设置都被视为专家设置。 log4j2.properties
包含log4j2库的默认设置。有关更多信息,请参见Log4j2配置。 startup.options (Linux)
包含使用的选项system-install在脚本中/usr/share/logstash/bin建立相应的启动脚本为您的系统。当您安装Logstash软件包时,该system-install脚本将在安装过程结束时执行,并使用中指定的设置startup.options来设置选项,例如用户,组,服务名称和服务描述。默认情况下,Logstash服务安装在用户下logstash。该startup.options文件使您可以更轻松地安装Logstash服务的多个实例。您可以复制文件并更改特定设置的值。请注意,startup.options启动时不会读取文件。如果要更改Logstash启动脚本(例如,要更改Logstash用户或从其他配置路径读取),则必须重新运行system-install 脚本(以root用户身份)以传入新设置。 修改logstash配置
vim /usr/local/logstash/config/logstash.yml
path.data: /data/logstash/data
path.logs: /data/logstash/logs 2.2测试服务 #进入目录
$ cd /usr/local/logstash
#启动测试
$ bin/logstash -e ‘input { stdin { } } output { stdout {} }’输入hello,显示hello安装成功 2.
需求:
使用iframe嵌入一个外部链接,并修改该页面中的css样式。
参考文章:在Vue中优雅的更改iframe嵌入页面的样式
实现逻辑:
若要实现能够修改iframe中嵌入页面的样式,首先要保证嵌入的链接和当前页面是同域的,若不是,需要先做跨域配置,具体可参考我的另一篇文章:vue跨域实现:proxy配置
这篇文章主要讲述对iframe中css样式的修改:
页面结构代码:
<iframe id="iframeId" :src="iframeUrl" width="100%" height="100%" frameborder="0" @load="loadFrame" /> 主要方法:
methods: { // iframe加载完成后的回调函数 loadFrameFn() { const iframe = document.getElementById("iframeId"); const body = iframe.contentWindow.document.body; const cssLink = document.createElement("link"); cssLink.href = "/vue项目名称/iframe-css/iframe.css"; cssLink.rel = "stylesheet"; cssLink.type = "text/css"; body.appendChild(cssLink); }, }, 其中iframe.css为自己创建的css文件,内容为我们想要实现的css样式,该文件需要放置在静态资源文件中。我在public文件中创建了一个iframe-css文件夹,用来放置该文件
import cv2 是 Python 中的一个库函数,用于加载和使用 OpenCV 库。OpenCV 是一个开源的计算机视觉库,可以用来进行图像处理、计算机视觉和机器学习等操作。
import cv2 是 Python 中的一个库函数,用于加载和使用 OpenCV 库。OpenCV 是一个开源的计算机视觉库,可以用来进行图像处理、计算机视觉和机器学习等操作。
代码示例:
# 导入cv2库
import cv2
# 读取图片
img = cv2.imread('image.jpg')
# 显示图片
cv2.imshow('Image', img)
# 等待按键按下
cv2.waitKey(0)
目录
一、目标检测概述
1.1 数据集介绍
1.2 性能指标 1.2.1 混淆矩阵
1.2.2 IOU(边界框回归)
1.2.3 AP&mAP
1.2.4 检测速度
1.3 YOLO发展史
1.3.1 算法思想
1.3.2 YOLOv5网络架构
博主创建了一个科研互助群Q:772356582,欢迎大家加入讨论。 一、目标检测概述 1.1 数据集介绍 PASCAL VOC MS COCO 1.2 性能指标 1.2.1 混淆矩阵 1.2.2 IOU(边界框回归) IOU=1 是完全重叠
根据IOU设置的阈值来判断是TP还是FP ,比如重叠为0.5
1.2.3 AP&mAP AP是衡量学习出来的模型在每个类别上的好坏
mAP是衡量学习出来的模型在所有类别上的好坏是AP的平均值
不同数据集对于AP和mAP的概念还是不同的 AP计算 1.2.4 检测速度 1.3 YOLO发展史 1.3.1 算法思想 yolov3框架图 先经过卷积神经网络得到特征图像,之后对图像进行网格划分,每个网格单独进行画框检测和类别的概率图,最终得到结果。
每个小框内包含了边界框坐标、目标得分和类别得分
多尺度融合 经过卷积神经网络可以得到不同大小的特征图,对不同大小的特征图进行融合利于小目标的检测。
图片卷积经过32倍下采样得到19*19的图片,每个网格都会单独预测和画锚框 预先设定一些边界框的大小 ,每个尺度都有若干个锚框
损失函数 1.3.2 YOLOv5网络架构 一个网络往往有主干网络(Backbone)+颈部(Neck)+头部(Head)组成 可视化 pip install onnx>=1.7.0 -i https://pypi.tuna.tsinghua.edu.cn/simple pip install coremltools==4.
1. 旋转图像操作(90°、180°、270°) # -*- coding: UTF-8 -*- from PIL import Image import os # 获得文件夹下所有文件 filePath = 'F:/1213bag/test_transforms/0912/2/' filenames = os.listdir(filePath) # 指定保存的文件夹 outputPath = 'F:/1213bag/test_transforms/0912/3/' # 迭代所有图片 for filename in filenames: # 读取图像 im = Image.open(filePath + filename) # 指定逆时针旋转的角度 im_rotate = im.transpose(Image.ROTATE_90) # im_rotate = im.transpose(Image.ROTATE_180) # im_rotate = im.transpose(Image.ROTATE_270) # 保存图像 im_rotate.save(outputPath + filename) 2. jpg 和png相互转换、resize尺寸大小 import os import cv2 import sys import numpy as np path1 = r'F:\1213bag\test_transforms\0912\3' path2 = r'F:\1213bag\test_transforms\0912\4' for filename in os.
今天启动一个一个服务的时候,总是报端口被占用的错误,所以就需要找一下是哪个程序占用了端口,查看的命令是:
netstat -anp tcp -v | grep 8082 那这个命令出来的那个是进程id呢,很显然我画框的就是了,前面的131072不是的。
还有一个lsof - i的命令,但这个我执行之后,说是找不到端口,不管黑猫白猫,能解决问题的就是好猫。
接着使用:
kill 8361 杀掉这个进程,再次启动就好了。
这个博客有点水,但我就是记录下来给自己看的,以后万一再遇到了呢
再补充一下,Mac本查看自己本机的ip地址的命令:
ifconfig en0 | grep inet | grep -v inet6 | awk '{print $2}'\n ----------------你知道的越多,不知道的越多------------
1、使用Post异步发送请求(发送短信),离焦事件触发时判断 <script src="layer/layer.js"></script> <!--离焦事件--> <script type="text/javascript" th:inline="javascript"> $("#username").blur(function(){ //判断用户名谁否符合手机号的格式,正则 if(/^1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}$/.test($("#username").val())){ //如果符合,发短信,$.post (ajax) var telephone = $("#username").val() $.post( //url 给/sendSMS权限放行 [[@{~/sendSMS}]], //参数 {"telephone":telephone}, //回调函数 function(data){ alert("success") }, //数据格式 "json" ) } else{ //不符合,给出提示信息 layer.msg("手机号格式有误!!") } }) $("#repassword").blur(function(){ alert("repassword") }) $("#SMS").blur(function(){ alert("SMS") }) </script> package com.zzz.blog.controller; import ... @Controller public class VisitorController { //ajax @RequestMapping("/sendSMS") @ResponseBody public String sendSMS(String telephone) { //给手机号发信息 System.out.println(telephone); return ""; } } 2、发送手机验证码(使用腾讯云短信服务,注册方法搜索之前文章) 复制qcloudsms-1.0.5.jar到工程bin文件夹下,并build path一下。
修改sendSMS方法
一,什么是SSL? 1.SSL的全称是Secure Sockets Layer,指安全套接字协议;SSL及其继任者传输层安全是为网络通信提供安全及数据完整性的一种安全协议;TLS与SSL在传输层与应用层之间对网络连接进行加密。
二,什么是SSH? 1.SSH 为 Secure Shell 的缩写,SSH 为建立在应用层基础上的安全协议。SSH 是较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。
三,总结 区别:SSH可以让用户以某个主机用户的身份登录主机,并对主机执行操作(即执行一些命令),目前用的最多的就是远程登录和SFTP(还有简易版的SCP),而SSL和主机用户名登录没有任何关系,它本身并不实现主机登录的功能,它只的一个单纯的加密功能。
通俗易懂一点来说 ssl是给内容加密 ssh是给服务器会话加密。
项目打包报错:程序包com.sun.image.codec.jpeg不存在
原因:使用了com.sun包下的类库,一些老的Java代码在高于JDK1.6下编译会报错,JPEGCodec类已经在JDK1.7 及后面的版本中已移除
解决方案:
这个类文件的位置在jre/lib/rt.jar,而我们设置的java_home下面的lib/dt.jar中没有这个文件,导致编译失败。通过配置maven-compiler-plugin插件可以解决此问题。
<plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.5.1</version> <configuration> <source>1.7</source> <target>1.7</target> <encoding>UTF-8</encoding> <compilerArguments> <verbose /> <bootclasspath>${java.home}\lib\rt.jar;${java.home}\lib\jce.jar</bootclasspath> </compilerArguments> </configuration> </plugin>
桌面应用开发的现状
在过去,桌面应用程序的开发通常需要使用特定于操作系统的工具和语言,如C++、C#、Java等。这导致了高昂的开发成本和维护困难。尽管有一些跨平台桌面开发工具,如Electron和Qt,但它们在性能、用户体验和开发效率方面存在一些限制。Flutter的出现改变了这一格局,为桌面应用程序开发带来了新的希望。
Flutter桌面应用的优势
跨平台性 Flutter的最大优势之一是其跨平台性。您可以使用相同的代码库构建Windows、macOS和Linux上的桌面应用程序。这意味着您不再需要为每个平台单独开发和维护应用程序,从而大大减少了工作量和成本。
美观的用户界面 Flutter提供了丰富的UI组件和自定义绘制能力,使开发者能够轻松创建漂亮且高度定制的用户界面。无论是设计精美的按钮、平滑的动画还是复杂的图表,Flutter都能满足您的需求。
高性能 Flutter的渲染引擎(Skia)是高性能的,能够实现流畅的动画和快速的用户界面响应。这使得Flutter桌面应用在性能方面能够与传统桌面应用媲美,甚至超越。
快速迭代和热重载 Flutter提供了热重载功能,使开发者能够快速预览和调试应用程序的变化。这极大地加速了开发周期,使开发者能够更快地迭代和优化应用程序。
社区支持和插件生态系统 Flutter拥有一个活跃的开发者社区,这意味着您可以轻松找到解决方案和第三方插件,以满足各种需求。无论是需要与本地操作系统交互还是集成第三方服务,Flutter社区都为您提供了丰富的资源。
使用场景
那么,什么样的应用程序适合使用Flutter来开发桌面版本呢?以下是一些适合的场景:
跨平台应用程序 如果您的目标是一次开发,多平台部署,那么Flutter是一个理想的选择。您可以使用相同的代码库构建Windows、macOS和Linux上的桌面应用,以及移动平台上的应用,从而最大程度地减少了开发成本和工作量。
创新性用户界面 如果您的应用程序需要具有创新性的用户界面,包括动画、复杂的自定义绘制或独特的交互方式,Flutter提供了强大的工具和库,帮助您实现这些目标。
跨平台移动应用的桌面补充 如果您已经使用Flutter开发了跨平台移动应用,那么使用Flutter开发桌面应用可以轻松实现桌面版本,无需重新学习其他桌面开发框架。
原型和快速开发 Flutter的热重载功能使其成为原型设计和快速开发的理想工具。您可以实时查看应用程序的变化,快速迭代和优化。
技术对比:Flutter vs. 传统桌面应用开发框架
为了更清楚地了解Flutter在桌面应用开发中的优势,让我们将其与传统的桌面应用开发框架进行比较。
跨平台性 Flutter:
支持Windows、macOS和Linux。 使用相同的代码库构建多个平台。 减少开发和维护成本。 传统桌面开发框架:
需要分别使用不同的开发工具和语言。 增加了开发成本和工作量。 2. 用户界面美观度 Flutter:
提供丰富的UI组件和自定义绘制能力。 可以创建漂亮且高度定制的用户界面。 传统桌面开发框架:
取决于使用的框架和工具,可能需要更多的努力来实现相同的美观度。 3. 性能 Flutter:
使用高性能的渲染引擎(Skia)。 实现流畅的动画和快速的用户界面响应。 传统桌面开发框架:
性能取决于所选框架和编程语言,可能不如Flutter高效。 4. 快速迭代和热重载 Flutter:
提供热重载功能,快速预览和调试应用程序的变化。 缩短开发周期,增加开发效率。 传统桌面开发框架:
多数传统桌面开发框架不支持热重载,开发过程可能较为繁琐。 5. 社区支持和插件生态系统 Flutter:
拥有活跃的社区和丰富的插件生态系统。
轻松找到解决方案和第三方插件。
传统桌面开发框架:
社区支持和插件生态系统可能不如Flutter丰富。
如何开始使用Flutter开发桌面应用
现在,让我们来了解如何开始使用Flutter开发桌面应用。以下是一些基本步骤:
安装Flutter 如果您还没有安装Flutter,可以访问Flutter的官方网站(https://flutter.dev/)获取安装说明。安装完成后,确保您已经设置好了Flutter的环境变量。
创建Flutter桌面应用项目 使用Flutter的命令行工具,您可以创建一个新的Flutter桌面应用项目。命令如下:
1、网课自动暂停解决方法、挂课后台播放方法、解决继续教育自动暂停 使用的浏览器 Edge
1、按 F12 打开开发工具页面,如下图所示 2、按下图依次点击 元素 --> 事件侦听器 ---> blur, 然后找到 Window(如下图红色框内),点击删除即可,然后按F12关闭调试页面。这样在这个切换其他页面后,这个页面播放视频就不会自动暂停了 3、有的学习页面是检测鼠标所在位置区域,可以再事件监听器里面尝试删除mouse
1.导入 redis-cli 工具可以通过管道 (--pipe) 快速导入数据到 Redis 中。管道模式可以在一次网络往返中批量传输多个命令,从而提高导入数据的效率。
以下是使用 redis-cli --pipe 导入数据的基本步骤:
创建一个文本文件,格式为 Redis 命令行协议(RESP)。每个命令使用单独的一行,并以 \r\n 结尾。例如,要导入键值对 "key1" 和 "value1",将文件内容设置为以下格式:
SET key1 value1\r\n 打开终端或命令提示符,并进入存储了导入数据文件的目录。
运行以下命令来导入数据到 Redis:
cat data.txt | redis-cli --pipe data.txt 是包含要导入数据的文件名(或路径)。
等待导入过程完成。redis-cli 将读取输入文件并将所有命令发送到 Redis 服务器。在导入期间,你将看到正在执行的命令数量。
请注意以下几点:
导入的数据文件应该具有有效的 Redis 命令格式,否则可能导致导入失败或数据损坏。在导入大量数据时,建议按需使用管道模式。较小的数据集可能不需要使用管道模式。如果数据集非常大,导入过程可能需要一些时间,请耐心等待导入完成。 2.删除 UNLINK 命令是 Redis 中用于删除键的非阻塞版本。与常规的 DEL 命令不同,UNLINK 命令在删除键时不会阻塞服务器,因此可以在大型数据集上使用,而不会导致服务器在删除键时停滞。
UNLINK 命令的语法与 DEL 命令相同,都需要提供要删除的键。例如,要删除键 "mykey",可以使用以下命令:
UNLINK mykey UNLINK 命令与 DEL 命令的不同之处在于,它将将要删除的键放入一个专门的队列中,Redis 服务器将在后台异步地处理这些删除任务。这意味着,当 UNLINK 命令被调用时,键并没有立即从内存中删除,而是通过使用后台线程异步地删除。
UNLINK 命令的使用场景包括:
在大型数据集中删除多个键,以避免服务器长时间阻塞。在调用 DEL 命令时因删除某个键而出现阻塞时,可以考虑使用 UNLINK 命令,从而避免服务器的停滞。 需要注意的是,在使用 UNLINK 命令时,由于键仍将保留在内存中,因此 Redis 内存使用情况可能会增加。因此,在删除大量键时,建议在删除任务完成后检查内存使用情况,并在需要时手动释放内存。
前端JavaScript设计模式探秘:理论与实践 在前端开发领域,JavaScript设计模式是一种重要的软件开发方法,可以帮助开发者解决常见的Web界面开发问题,提高代码的可维护性、可扩展性和可重用性。本文将详细探讨JavaScript设计模式的基本概念、常见类型以及应用场景,并通过实际案例展示模式的实现细节和代码示例。
一、JavaScript设计模式概述 JavaScript设计模式是一种经过反复验证的、解决特定问题的最佳实践。它们提供了一套标准的框架,帮助开发者在Web应用中解决常见问题,如事件处理、数据操作和DOM编程等。设计模式不仅提供了高效的解决方案,还可以提高代码的可读性和可维护性,降低项目风险。
二、常见JavaScript设计模式 1. 模块模式(Module Pattern) 模块模式是一种封装JavaScript代码的方式,可以避免全局变量的污染,提高代码的可重用性和可维护性。它通过自执行函数将变量和函数限制在局部范围内,达到隐藏实现细节的目的。
// 模块模式示例 var myModule = (function () { var privateData = "Hello World"; function displayMessage() { console.log(privateData); } return { message: privateData, display: displayMessage }; })(); // 使用示例 console.log(myModule.message); // "Hello World" myModule.display(); // "Hello World" 2. 原型模式(Prototype Pattern) 原型模式是一种创建对象的方式,通过将基类的原型指向一个新对象,达到节省内存和提高性能的目的。它适用于创建大量相似的对象,但需要修改其某些属性或方法的场景。
// 原型模式示例 function Car(make, model, year) { this.make = make; this.model = model; this.year = year; } Car.prototype.getInfo = function () { return this.
安装 Vue CLI 可以通过 npm 全局安装的方式来完成。请按照以下步骤进行操作:
(注意:以下命令是基于使用 npm 作为包管理器,如果你使用的是 yarn,可以将相应的命令替换为 yarn 命令。)
1.正常安装启动 1.首先,请确保你的电脑已经安装了 Node.js。你可以在命令行窗口中输入以下命令来确认是否已安装:
node -v
如果已经安装了 Node.js,你会看到 Node.js 的版本号。否则,请前往 Node.js 的官方网站下载并安装。
2.安装 Vue CLI。在命令行窗口中输入以下命令:
npm install -g @vue/cli
这会将 Vue CLI 全局安装到你的系统中。
3.创建一个新的 Vue 项目。在命令行窗口中进入你想要创建项目的目录,然后输入以下命令:
vue create my-project
其中 my-project 是你想要创建的项目名称,你也可以自定义名称。
4.进入项目目录。在命令行窗口中输入以下命令:
cd my-project
其中 my-project 是你创建的项目名称。
5.安装项目的依赖包。在命令行窗口中输入以下命令:
npm install
这会自动下载并安装项目所需的所有依赖包。
6.启动项目。在命令行窗口中输入以下命令:
npm run serve
这会启动开发服务器,会在浏览器中打开项目。
elementui官方文档 Element - The world's most popular Vue UI framework
阅读官网 发现主要通过filt-list来进行回显 要把后端的传回来的数据改为 有url的格式 如下图
代码展示
<el-upload :action="upurl" :headers="upheaders" :limit="10" list-type="picture-card" :on-preview="handlePreview" :on-remove="handleRemove" :on-success="handleSuccess" :on-error="handleError" :file-list="fileList" :class="{ disabled: uploadDisabled }" ref="upload"> </el-upload> 我们在页面获取接口数据的地方 ,改为 有url的格式来进行回显
this.fileList = res.data.list.item_image.map(t => { var obj = {} obj.url = t return obj }) res.data.list.item_image 为接口返回的图片数组 页面就可以进行回显了
图片回显后我们要对个别图片进行删除 主要是 :on-remove="handleRemove"
他有两个参数 如果我们只需要把图片的url 都放在一个数组里,传给后端
handleRemove(file, fileList) { let arr = [] for (let i of fileList) { arr.
插件化技术和热修复技术都属于动态加载,从普及率的角度来看,插件化技术还没有热修复的普及率高,主要原因是占大多数的中小型应用很少也没有必要去采用插件化技术。
Android P preview(Android 9)开始限制调用隐藏 API,也出现了一些绕过限制的方案。无论采用何种方案,插件化的原理还是需要理解的。
1 动态加载技术 动态加载技术是插件化的前身。
在 Android 传统开发中,一旦应用的代码被打包成 APK 并被上传到各个渠道市场,就不能修改应用的源码了。只能通过服务器来控制应用中预留的分支代码。但是很多时候我们无法提前预知需求和突发的情况,也就不能提前在应用代码中预留分支代码,这时就需要采用动态加载技术。
在应用程序运行时,动态加载一些程序中原本不存在的可执行文件并运行这些文件里的代码逻辑。可执行文件总的来说分为两种,一种是动态链接库 so,另一种是 dex 相关文件(dex 以及包含 dex 的 jar/apk 文件)。
随着应用的发展,动态加载技术派生出两个技术,分别是热修复技术和插件化技术:
其中热修复技术主要用来修复 Bug,插件化技术则主要用于解决应用越来越庞大以及功能模块的解耦,围绕着两个技术出现了很多的热修复框架和插件化框架。 需要注意的是,动态加载技术本身并没有被官方认可,并且是一个非常规的技术,在国外这门技术关注度并不高,它的产生更多的是国内的业务需求和产品驱动。
2 插件化的产生 在 Android 开发早起很少用到动态加载技术,因为这个时候业务需求和应用开发的复杂度不是很大高,但随着互联网的发展会出现以下几种情况:
1 业务复杂,模块耦合
随着业务越来越复杂越来越多,导致应用体积越来越大,应用程序的工程和功能模块数量越来越多,一个应用可能是由几十、几百人协同开发的,很多工程和功能模块都是由一个小组进行开发维护的,如果功能模块间的耦合度比较高,修改一个功能模块会影响其他的功能模块,势必会极大地增加沟通成本。
2 应用间的接入
一个应用不再是单独的应用,它可能需要接入其他的应用。拿手机淘宝来说,它的流量非常大,其他的淘宝应用或者业务比如:聚划算、菜鸟、淘票票、饿了么等都希望接入到淘宝客户端,这样既能获取到流量,同时也可以将用于引流到自己的应用中,如果使用常规的技术手段,会产生两个问题:
比如饿了么需要接入到淘宝客户端中,那么饿了么团队可能需要维护两个版本,一个是自身版本,另一个是淘宝客户端版本,这样维护成功和沟通成本会比较高。况且饿了么不止是接入淘宝客户端,它还可以接入到其他应用中,比如支付宝应用,那么饿了么团队维护的就不仅仅是两个版本了;比如淘宝客户端接入很多其他的应用,势必会使应用的体积急剧变大,编译时间会变得非常长,一个 Bug 和功能就会由组内的开发协作变为组与组之间甚至是部门之间的开发协作,极大地增加了开发测试成本和沟通成本,新功能的添加会牵扯的越多,版本发布的时间变得不可控; 3 65536 限制,内存占用大
随着应用功能越来越复杂,代码量不断的增大,引入的库也越来越多,可能会在编译时提示如下异常:
com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536 这说明应用引用的方法超过了最大数 65536 个,产生这一问题的原因就是系统的 65536 限制,65536 限制的主要原因是 DVM Bytecode 的限制,DVM 指令集的方法调用指令 invoke-kind 索引为 16bits,最多能引用 65535 个方法。
应用代码量的增加同时也导致应用占用大量的内存。
QM 9dataset unit: property_unit_dict = { QM9.A: "GHz", QM9.B: "GHz", QM9.C: "GHz", QM9.mu: "Debye", QM9.alpha: "a0 a0 a0", QM9.homo: "Ha", QM9.lumo: "Ha", QM9.gap: "Ha", QM9.r2: "a0 a0", QM9.zpve: "Ha", QM9.U0: "Ha", QM9.U: "Ha", QM9.H: "Ha", QM9.G: "Ha", QM9.Cv: "cal/mol/K", } 如果做3D分子性质预测的时候,需要用HAR2EV=27.211386246进行转换,然后1000meV = EV, 因此最后MAE的loss 应该*1000.
HAR2EV = 27.211386246 KCALMOL2EV = 0.04336414 conversion = torch.tensor([ 1., 1., HAR2EV, HAR2EV, HAR2EV, 1., HAR2EV, HAR2EV, HAR2EV, HAR2EV, HAR2EV, 1., KCALMOL2EV, KCALMOL2EV, KCALMOL2EV, KCALMOL2EV, 1.
一,命名规范
1.项目命名【全部小写中横线分割】
2.目录命名 【全部小写中横线分割,用复数,缩写不用复数】
3.文件命名 【小写中横线分割】
4.css命名
类名:小写中横线分割id:驼峰式命名scss中变量函数混合采用驼峰选择器使用直接子选择器 【例如:.content > .title {
font-size: 2rem;}】
尽量使用复合缩写类型【font: 100%/1.6 palatino, georgia, serif; 】
省略0后面的单位【0px】避免嵌套过多层级【小于4层】 5.js
小驼峰不使用下划线方法名:动+名增删改统一【add / update / delete / detail / get 】常量命名都大写下划线分割字符串统一用单引号不用双引号下列关键字后必须有大括号(即使代码块的内容只有一行):if, else, for, while, do, switch, try,catch, finally, with。永远不要直接使用 undefined 进行变量判断;使用 typeof 和字符串’undefined’对变量进行判断。对上下文 this 的引用只能使用 ’self’ 来命名。 6.vue
组件名应该始终是多个单词组成(大于等于 2)【大驼峰】 二. 使用语义化标签,避免一整个页面都是div和p
<header></header> <footer></footer>
语义化标签参考
https://blog.csdn.net/RogerQianpeng/article/details/124766995
三, 使用双引号
阿里代码规范参考
https://blog.51cto.com/u_15295057/5002198
因为使用gradle管理springboot,本文需用到旧版腾讯云SDK资源:传送门
如果使用maven,新版的腾讯云SDK可以很方便引用,后面会提到SDK。
1、注册微信公众号 百度搜索微信公众号,进入网站后,点注册,注册类型选订阅号(个人)。注册成功后保存后台“账号详情”的截图,用于后面申请腾讯云短信签名。
2、注册腾讯云账号 使用qq号登录注册腾讯云,完成个人实名认证流程。
3、设置短信签名和短信正文 进入腾讯云后台,搜索框内搜“短信”,确认开通。
在短信管理后台里,找到SDK,下载Java SDK。用于后期开发。(新版SDK对gradle不友好,建议使用上面旧版下载)
先申请签名,等待审核通过后再申请短信正文。
申请短信正文模板:
4、在gradle demo项目中测试 先把旧版核心包qcloudsms-1.0.5.jar导入到bin文件夹下,然后build path构建一下:
创建对应包下的测试类:com.zzz.ssjpa.controller.UserController(包结构看前面关于springboot文章),代码如下:
package com.zzz.ssjpa.controller; import java.io.IOException; import org.json.JSONException; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.github.qcloudsms.SmsSingleSender; import com.github.qcloudsms.SmsSingleSenderResult; import com.github.qcloudsms.httpclient.HTTPException; @RestController public class UserController { /** * @Title: test * @Description: 给手机发送短信 * @param: @return 参数 * @return: String 返回类型 * @throws */ @RequestMapping("/test") public String test() { //appid appkey int appid = xxx; String appkey = "
一.vue分为选项式和组合式
1.选项式就是一般vue2 的写法,包含多个选项来描述组件的逻辑,例如data,methods和生命周期函数。选项式多定义的属性会暴露在函数内部的this上,他会指向组件实例
<script> export default { // data() 返回的属性将会成为响应式的状态 // 并且暴露在 `this` 上 data() { return { count: 0 } }, // methods 是一些用来更改状态与触发更新的函数 // 它们可以在模板中作为事件处理器绑定 methods: { increment() { this.count++ } }, // 生命周期钩子会在组件生命周期的各个不同阶段被调用 // 例如这个函数就会在组件挂载完成后被调用 mounted() { console.log(`The initial count is ${this.count}.`) } } </script> <template> <button @click="increment">Count is: {{ count }}</button> </template> 2.组合式就是一般vue3 的写法,单个文件中组合式一般和<script setup>搭配使用
<script setup> import { ref, onMounted } from 'vue' // 响应式状态 const count = ref(0) // 用来修改状态、触发更新的函数 function increment() { count.
1、Postman中post的数据类型 post中有以下数据类型
1、form-data
2、x-www-form-urlencoded
3、raw
4、binary
2、Postman请求不同的post数据类型 from-data multipart/form-data,它将表单的数据组织成Key-Value形式,也可以上传文件,当上传的字段是文件时,会有 content-type 来说明文件类型;content-disposition,用来说明字段的一些信息;由于有 boundary 隔离,所以 multipart/form-data 既可以上传文件,也可以上传键值对,它采用了键值对的方式,所以可以上传多个文件。
正常数据
输入post请求地址,选择form-data请求类型,输入对应参数,点击Send发送请求
form-data上传文件
选择File格式
点击上传文件,发送请求
这里我选择了上传二进制文件,其他的都是一样的内容
现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。 如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受 可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛 分享他们的经验,还会分享很多直播讲座和技术沙龙 可以免费学习!划重点!开源的!!! qq群号:110685036 x-www-form-urlencoded application/x-www-from-urlencoded,将表单内的数据转换为Key-Value
可以通过返回内容看出来,我们需要请求的数据类型是否正确
raw 可以通过raw进行传输txt,json xml,html的数据
xml方法
查看返回内容
json数据 我们通过请求后,继续查看返回后的内容,发现现实的数据类型也是json的
binary 表示只可以上传二进制数据,用来上传文件,一次只能上传1个数据
给大家举个小栗子,桌面创建二进制文件,保存在桌面,后缀名为.bin格式
上传创建好的二进制文件,查看返回内容
最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走!
软件测试面试文档 我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
MySQL死锁是在多个并发事务同时请求相同资源时发生的一种情况,其中每个事务都在等待对方释放资源,从而导致数据库无法继续执行。死锁的排查和解决通常需要以下步骤:
1. 检测死锁:
MySQL通常会在错误日志中记录死锁信息。可以通过以下方式检测死锁:
SHOW ENGINE INNODB STATUS;
查找"InnoDB"部分,寻找"LATEST DETECTED DEADLOCK"或类似的标题,下面会列出最近的死锁信息。
2. 确认死锁:
确保实际遇到了死锁问题,而不只是普通的阻塞。死锁的特点是多个事务相互等待对方释放资源。
解决死锁:
一旦确认存在死锁,可以采取以下方法来解决它:
等待超时: 让其中一个事务等待一段时间后再尝试,以希望其他事务会在这段时间内完成。这通常不是最佳解决方案,因为它会引入延迟,并且不一定会成功。
终止一个事务: 您可以手动终止其中一个事务,以解除死锁。通常选择终止最小程度影响系统的事务。
优化查询: 通过优化查询,降低死锁发生的可能性,例如通过合理使用索引、减少事务中锁的范围等。
调整事务顺序: 如果可能的话,可以通过按照相同的顺序访问资源来降低死锁的风险。
4. 预防死锁:
为了预防死锁,可以采取以下步骤:
使用合适的事务隔离级别: 在开发时选择适当的事务隔离级别,以确保事务在并发执行时不会频繁地发生死锁。
使用索引和合适的查询方式: 通过为数据库表添加合适的索引,可以降低锁的范围,从而减少死锁的可能性。
批量处理: 尽量将多个操作放在一个事务中,而不是多个小事务,以减少锁的竞争。
监控和日志: 定期监控数据库性能,以及记录潜在的死锁情况,以便及时发现和解决问题。
使用数据库锁定机制: MySQL提供了不同类型的锁定机制,如行级锁和表级锁,根据需求选择合适的锁定机制。
死锁是一个复杂的问题,需要仔细的分析和解决。在生产环境中,建议与数据库管理员一起处理死锁问题,并确保数据库的配置和性能优化是合适的。
html部分
<div class="announcements12" style="display: flex">
<el-input v-model="url"></el-input>
<el-upload
ref="upload"
:action="uploadUrl"
:on-preview="handlePreview"
:on-remove="handleRemove"
:on-change="handleFileUpload"
:file-list="fileList"
:auto-upload="false"
:headers="headers"
>
<!--action 上传的地址
on-preview 点击文件列表中已上传的文件时
on-remove 文件列表移除文件时
on-change 文件状态改变时
file-list 上传的文件列表【array】
auto-upload 是否在选取文件后立即进行上传
headers 设置上传的请求头部【Object】 -->
<div slot="tip" class="el-upload__tip">只能上传xlsx文件格式</div>
<el-button slot="trigger" size="small" type="primary" class="btnBorder"
>选取文件</el-button
>
</el-upload>
</div>
<div slot="footer">
<el-button @click="onClose" class="btnBorder">取消</el-button>
<el-button type="primary" @click="submitUpload" class="btnBorder"
>确定</el-button
>
</div>
script部分
import {
importLawDocument,
downloadTemplate,
} from "@/api/lawDatabase.js";
import { debounce } from "
方法一
//点击方法 async downloadTemplateBtn() { // 调用下载模板的API,获取到文件的数据和状态码 const { data, code } = await downloadTemplate(this.code); if (code !== 200) return; // 获取到文件的URL this.templateUrl = data.fileIdDesc[0].url; // 创建XMLHttpRequest对象 const xhr = new XMLHttpRequest(); xhr.open("GET", this.templateUrl, true); xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xhr.responseType = "blob"; // 在下载完成后的回调函数中执行文件下载 xhr.onload = function () { if (this.status === 200) { // 创建一个URL对象 const url = window.URL.createObjectURL(this.response); // 创建一个隐藏的<a>元素,设置其href和download属性 const link = document.createElement("a"); link.href = url; link.download = data.
为了用户隐私安全,Android的数据访问权限限制越来越严,使用应用自己的私有目录的机会越来越多,有必要了解下获取私有目录的方法及与路径的对应关系:
方法路径getExternalCacheDir();/storage/emulated/0/Android/data/<应用包名>/cachegetExternalFilesDir(null);/storage/emulated/0/Android/data/<应用包名>/filesgetExternalFilesDir(“”);/storage/emulated/0/Android/data/<应用包名>/filesgetExternalFilesDir(“logs”);/storage/emulated/0/Android/data/<应用包名>/files/logsgetExternalFilesDir(“logs/zip”);/storage/emulated/0/Android/data/<应用包名>/files/logs/zipgetExternalFilesDir(Environment.DIRECTORY_MUSIC);/storage/emulated/0/Android/data/<应用包名>/files/MusicgetExternalFilesDir(Environment.DIRECTORY_PODCASTS);/storage/emulated/0/Android/data/<应用包名>/files/PodcastsgetExternalFilesDir(Environment.DIRECTORY_RINGTONES);/storage/emulated/0/Android/data/<应用包名>/files/RingtonesgetExternalFilesDir(Environment.DIRECTORY_ALARMS);/storage/emulated/0/Android/data/<应用包名>/files/AlarmsgetExternalFilesDir(Environment.DIRECTORY_NOTIFICATIONS);/storage/emulated/0/Android/data/<应用包名>/files/NotificationsgetExternalFilesDir(Environment.DIRECTORY_PICTURES);/storage/emulated/0/Android/data/<应用包名>/files/PicturesgetExternalFilesDir(Environment.DIRECTORY_MOVIES);/storage/emulated/0/Android/data/<应用包名>/files/MoviesgetDataDir;/data/user/0/<应用包名>getFilesDir;/data/user/0/<应用包名>/filesgetCacheDir;/data/user/0/<应用包名>/cache
1、先判断物理内存free是否大于swap使用空间。 此时发现free Mem是8g,Swap是9g,所以需要先释放buff/cache
free -g total used free shared buff/cache available Mem: 125 73 8 3 43 34 Swap: 9 9 0 2、如果物理剩余内存不足,可以先清一下buff/cache。 #清理页面缓存和slab分配中的内存
echo 3 > /proc/sys/vm/drop_caches 3、检查free Mem free -g total used free shared buff/cache available
Mem: 125 73 48 3 3 40
Swap: 9 9 0
4、释放完再打开自动分配 我这个操作没有生效,有人说0和>之间不要留空格就可以,我试过了,没卵用。不过也无所谓,下次服务器重启会自动置为0,不用刻意修改。
echo 0> /proc/sys/vm/drop_caches 5、关闭所有的交换分区 swapoff -a 6、再次检查free Mem 此时检查再次检查swap是否全部为0
该文章记录学习stm32串口遇到的一些问题,完整代码地址。
一、项目描述 通过串口或蓝牙发送指令来控制led灯。
open ------> led 亮close ------> led 灭其它 -------> 反馈给串口或蓝牙错误指令 二、项目用到的模块 stm32 串口1,PA9(TX), PA10(RX)HC01 蓝牙模块,PA9(TX), PA10(RX)led灯, PB8 三、USART1关键配置说明 四、代码说明 main.c中主要代码如下:
#define UART1_REC_LEN 200 uint16_t UART1_RX_STA=0; uint8_t buf=0; // 接收缓冲, 串口接收到的数据放在这个数组里,最大UART1_REC_LEN个字节 uint8_t UART1_RX_Buffer[UART1_REC_LEN]; void SystemClock_Config(void); // 接收中断 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance != USART1) { return; } // 数据接收完成 if((UART1_RX_STA & 0x8000) != 0) { HAL_UART_Receive_IT(&huart1, &buf, 1); return; } // 接收到回车之后判断后续的是不是换行,如果是换行,数据接收完成,但是还要开启一下中断 if(UART1_RX_STA&0x4000) { UART1_RX_STA= (buf == 0x0a) ?
目录
一、开发环境
二、编写按键input设备的注册与事件上报
2.1 修改设备树文件
1 添加 pinctrl 节点
2、添加 KEY 设备节点
3、检查 PIN 是否被其他外设使用
2.2 驱动程序编写
2.3 测试APP编写
2.4 运行测试
三、Linux内核自带按键input设备驱动
3.1 自带按键驱动程序源码简析
3.2 自带按键驱动程序的使用
3.3 运行测试
上一章已经了解了input子系统的大体框架和input设备的注册以及对应事件的上报流程,现在就写一个简单的input设备驱动实验来更加深入的理解input子系统。
本章将分别采用以下两种方法来进行按键input设备驱动的实验:
1、编写按键input设备的注册与事件上报
2、Linux内核自带按键input设备驱动
一、开发环境 CPU:IMX6ULL
内核版本:Linux-5.19
二、编写按键input设备的注册与事件上报 2.1 修改设备树文件
1 添加 pinctrl 节点
I.MX6U-ALPHA开发板上的 KEY 使用了 UART1_CTS_B这个 PIN,打开 imx6ul-14x14-evk.dtsi ,在 iomuxc 节点的 imx6ul-evk 子节点下创建一个名为“pinctrl_key”的子节点,节点内容如下所示:
pinctrl_key: keygrp { fsl,pins = < MX6UL_PAD_UART1_CTS_B__GPIO1_IO18 0xF080 /* key0 */ >; }; 第 3 行,将 GPIO_IO18 这个 PIN 复用为 GPIO1_IO18。
目录
一、input 子系统简介
二、input 驱动编写流程
1、注册 input_dev
2、上报输入事件
三、input_event 结构体
按键、鼠标、键盘、触摸屏等都属于输入(input)设备, Linux 内核为此专门做了一个叫做 input子系统的框架来处理输入事件。输入设备本质上还是字符设备,只是在此基础上套上了 input 框架,用户只需要负责上报输入事件,比如按键值、坐标等信息, input 核心层负责处理这些事件。本章就来学习一下 Linux 内核中的 input 子系统框架。
一、input 子系统简介 input 就是输入的意思,因此 input 子系统就是管理输入的子系统,和 pinctrl、 gpio 子系统一样,都是 Linux 内核针对某一类设备而创建的框架。比如按键输入、键盘、鼠标、触摸屏等等这些都属于输入设备,不同的输入设备所代表的含义不同,按键和键盘就是代表按键信息,鼠标和触摸屏代表坐标信息,因此在应用层的处理就不同,对于驱动编写者而言不需要去关心应用层的事情,只需要按照要求上报这些输入事件即可。
为此 input 子系统分为 input 驱动层、 input 核心层、 input 事件处理层,最终给用户空间提供可访问的设备节点, input 子系统框架如下图所示:
上图中左边就是最底层的具体设备,比如按键、 USB 键盘/鼠标等,中间部分属于Linux 内核空间,分为驱动层、核心层和事件层,最右边的就是用户空间,所有的输入设备以文件的形式供用户应用程序使用。可以看出 input 子系统用到了前面讲解的驱动分层模型,编写驱动程序的时候只需要关注中间的驱动层、核心层和事件层,这三个层的分工如下:
驱动层:输入设备的具体驱动程序,比如按键驱动程序,向内核层报告输入内容。
核心层:承上启下,为驱动层提供输入设备注册和操作接口。通知事件层对输入事件进行处理。
事件层:主要和用户空间进行交互。
二、input 驱动编写流程 input 核心层会向 Linux 内核注册一个字符设备,大家找到 drivers/input/input.c 这个文件,input.c 就是 input 输入子系统的核心层,此文件里面有如下所示代码:
struct class input_class = { .
目录
一、MISC 设备驱动简介
二、修改设备树文件
1、添加 pinctrl 节点
2、添加 BEEP 设备节点
三、驱动编写
四、编写测试 APP
五、运行测试
misc 的意思是混合、杂项的,因此 MISC 驱动也叫做杂项驱动,也就是当我们板子上的某些外设无法进行分类的时候就可以使用 MISC 驱动。 MISC 驱动其实就是最简单的字符设备驱动,通常嵌套在 platform 总线驱动中,实现复杂的驱动,本章我们就来学习一下 MISC 驱动的编写。
一、MISC 设备驱动简介 所有的 MISC 设备驱动的主设备号都为 10,不同的设备使用不同的从设备号。随着 Linux字符设备驱动的不断增加,设备号变得越来越紧张,尤其是主设备号, MISC 设备驱动就用于解决此问题。 MISC 设备会自动创建 cdev,不需要像我们以前那样手动创建,因此采用 MISC 设备驱动可以简化字符设备驱动的编写。我们需要向 Linux 注册一个 miscdevice 设备, miscdevice是一个结构体,定义在文件 include/linux/miscdevice.h 中,内容如下:
struct miscdevice { int minor; const char *name; const struct file_operations *fops; struct list_head list; struct device *parent; struct device *this_device; const struct attribute_group **groups; const char *nodename; umode_t mode; }; 定义一个 MISC 设备(miscdevice 类型)以后我们需要设置 minor、 name 和 fops 这三个成员变量。 minor 表示子设备号, MISC 设备的主设备号为 10,这个是固定的,需要用户指定子设备号, Linux 系统已经预定义了一些 MISC 设备的子设备号,这些预定义的子设备号定义在include/linux/miscdevice.
1. Spark 内核概述 1.1核心组件 1.1.1 Driver master(唯一的一个) Spark驱动节点,用于 Spark 任务中的 main 方法,fuze实际代码的执行工作. Driver 在 Spark 作业执行时主要负责:
1. 将用户程序转化为作业( job );
2. 在 Executor 之间调度任务( task );
3. 跟踪 Executor 的执行情况;
4.通过 UI 展示查询运行情况;
1.1.2 Executor worker(多个) Spark Executor节点是一个JVM进程,负责在 Spark 作业中运行具体任务,任务彼此之间相互独立。Spark 应用启动时,Executor节点被同时启动,并且始终伴随着整个 Spark 应用的生命周期而存在。如果有Executor节点发生了故障或崩溃,Spark 应用也可以继续执行,会将出错节点上的任务调度到其他Executor节点上继续运行。(spark的容错机制)
Executor有两个核心功能:
1. 负责运行组成Spark应用的任务,并将结果返回给驱动器进程;
2. 它们通过自身的块管理器(Block Manager)为用户程序中要求缓存的 RDD 提供内存式存储。RDD 是直接缓存在Executor进程内的,因此任务可以在运行时充分利用缓存数据加速运算。
1.2运行流程 如图 Spark 的运行流程不论Spark以何种模式进行部署,任务提交后,都会先启动Driver.进程.随后Driver进程向集群管理器注册应用程序,之后集群管理器根据此任务的配置文件分配Executor并启动,当Driver所需的资源全部满足后,Driver开始执行main函数,Spark查询为懒执行,当执行到action算子时开始反向推算,根据宽依赖进行stage的划分,随后每一个stage对应一个taskset,taskset中有多个task,根据本地化原则,task会被分发到指定的Executor去执行,在任务执行的过程中,Executor也会不断与Driver进行通信,报告任务运行情况。
2.部署模式 Spark支持3种集群管理器(Cluster Manager),分别为:
1. Standalone:(测试中)独立模式,Spark原生的简单集群管理器,自带完整的服务,可单独部署到一个集群中,无需依赖任何其他资源管理系统,使用Standalone可以很方便地搭建一个集群;
2. Apache Mesos:一个强大的分布式资源管理框架,它允许多种不同的框架部署在其上,包括yarn;
3.Hadoop YARN:统一的资源管理机制,在上面可以运行多套计算框架,如map reduce、storm等,根据driver在集群中的位置不同,分为yarn client(测试中)和yarn cluster。(实际工作中,只能用这种模式)部署在hadoop集群中,由yarn来管理资源分配。
大家好,小编来为大家解答以下问题,python中swith-case,python的case写法,今天让我们一起来看看吧!
方式一 Python 3.10版本 更新了类似其他语言的switch case结构,所以最好的方法是直接更新到python3.10,直接使用match case 语句:
C语言: switch (expression) { case constant-expression : statement(s); break; /* 可选的 */ case constant-expression : statement(s); break; /* 可选的 */ /* 您可以有任意数量的 case 语句 */ default : /* 可选的 */ statement(s); } Python: flag = False match (100, 200): case (100, 300): # Mismatch: 200 != 300 print('Case 1') case (100, 200) if flag: # Successful match, but guard fails print('Case 2') case (100, y): # Matches and binds y to 200 print(f'Case 3, y: {y}') case _: # Pattern not attempted print('Case 4, I match anything!
有些想进互联网大厂的人在无法成为正式员工的时候,会通过成为外包员工的方式来曲线救国。但在互联网大厂中,外包员工和正式员工的差别待遇一直是比较热门的话题。
最近,一个网友总结了华为外包和正式员工的区别,干货满满,先来看看:
看完以后,许多人表示赞同,有人说这是看到最全也最正确的一版了,总结得又全面又客观。
有人感叹,外包太惨了,没有机会求偶。
也有人觉得按照楼主的说法,外包员工好像比正式员工待遇还要好,就是名声上不大好听。
有人问,外包员工转正很难是真的吗?
楼主回答:当然很难,条件那么多。
有人问:有华为外包经历,想跳槽去大厂,好跳吗?
楼主回答:自己手下几个人有的去了ovm(oppo、vivo和小米),有的去了腾讯,有的去了京东和阿里。
还有人觉得楼主说的大部分正确,但慧通也不能算是华为的正式员工。
网友表示惊讶,外包转正竟然是转成慧通员工?以为慧通是华为自己内部的外包公司。
有人说,外包分为两个派系,慧通派和其他派系,接触到的内容不一样。
有人说楼主总结的是WX和84开头的传统外包,这种是外包但不是OD。OD工号开头的数字是3,工卡带子也是红色,转正的话是华技。建议楼主说清楚对象,不要以偏概全。
OD和外包的区别:OD算是华为的预备人员,考试过了基本上都能转成华为自研,不是慧通员工。
有人说,OD绩效是半年一评。外包出差机会也有很多,主要看岗位,如果转正肯定是正式的。
也有人说,正式员工也不是都有股票,中软分布式部门要在华为工作满五年才有。
还有人质疑楼主说的“没有有色眼镜”这一点,认为两者干着同样的活,却拿着不一样的工资。在工作中,是否和外包拉群共享资料也是有讲究的。就算正式员工嘴上不歧视外包员工,心里也会歧视,这就是人性的弱点和丑陋之处,外包制度放大了人内心的丑恶。
在公司的制度差异下,外包员工和正式员工在待遇、晋升和心态等方面都不一样,想要实现完全的公平公正是不可能的。
外包员工想转成正式员工也并不容易,在一个知乎话题“华为外包员工想转成正式员工有多难”下面,一位网友回答,要分两步走,先转成OD,再转成华为正式员工,至少需要两年时间,而且考评需要一枝独秀,深得领导赏识才可以。有些部门要求更高,可能三五年都不能转正,而且转正渠道不是一直有,说不定哪天就关闭了。建议:如果真的想进华为就坚决不要当外包员工,否则就要升级打怪,如果年龄大一点就基本不可能了。
能够顺利曲线救国的例子确实存在,但概率并不高。虽然许多人认为“是金子总会发光”,可在现实生活里并不一定都有如此好运。一块金子能否发光,也要看是否有足够的运气和机遇。如果年龄拖得太大还没成功转正,就像金子蒙尘太久,前途难测。希望有心进大厂的人能够在最开始就进入正确的赛道,给自己的未来减少不必要的风险。
由于墙内网络干扰屏蔽国外网络的原因,在国内下载nodejs依赖是非常缓慢的。
所以为了解决这个问题,必须设置代理,具体方法如下:
NPM设置代理:
npm config set proxy=<http_proxy>
NPM删除代理:
npm config delete proxy
YARN设置代理:
yarn config set proxy <http_proxy>
YARN删除代理:
yarn config delete proxy 由于我使用的是yarn包管理工具,所以这里以yarn为例来设置代理:
然后通过yarn config list命令查看代理是否已经设置生效
最近使用HCL5.5版本的模拟器,使用安装包提供的VirtualBox6.0.14版本,安装后能够正常启动设备,但再重启计算机后会出现无法启动设备警告。卸载重装后可以正常启动,但只要重启计算机HCL就会无法启动设备。
在VirtualBox里直接启动设备,会提示Error relaunching VirtualBox VM process:5,要我尝试重新安装VirtualBox。但按提示操作后问题依然存在。
查找了很多方法,高低版本的VirtualBox、清理注册表后重装都试过了,无一例外都无法解决。经过大量尝试,发现了解决办法。
首先,打开VirtualBox安装根目录/drivers/vboxDrv,右键VBoxDrv.inf安装。
然后,打开注册表,找到计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VBoxDrv目录下,编辑start项,将1改为2,并重启计算机。
完成以上操作后,HCL成功启动设备,重启计算机后依然能正常运行。
原理是将VirtualBox程序设定的“启动时加载服务”更改为“由服务控制管理器自动加载”。
在 Python列表中删除元素主要分为以下 3 种场景:
根据目标元素所在位置的索引进行删除,可以使用 del 关键字或者 pop() 方法;根据元素本身的值进行删除,可使用列表(list类型)提供的 remove() 方法;将列表中所有元素全部删除,可使用列表(list类型)提供的 clear() 方法。 del:根据索引值删除元素 del 是 Python 中的关键字,专门用来执行删除操作,它不仅可以删除整个列表,还可以删除列表中的某些元素。本节只讲解如何删除列表元素。
del 可以删除列表中的单个元素,格式为:
del listname[index]
其中,listname 表示列表名称,index 表示元素的索引值。
del 也可以删除中间一段连续的元素,格式为:
del listname[start : end]
其中,start 表示起始索引,end 表示结束索引。del 会删除从索引 start 到 end 之间的元素,不包括 end 位置的元素。
【示例】使用 del 删除单个列表元素:
lang = ["Python", "C++", "Java", "PHP", "Ruby", "MATLAB"] #使用正数索引del lang[2]print(lang)#使用负数索引del lang[-2]print(lang) 运行结果:
['Python', 'C++', 'PHP', 'Ruby', 'MATLAB']
['Python', 'C++', 'PHP', 'MATLAB']
【示例】使用 del 删除一段连续的元素:
lang = ["
因为之前不怎么使用pycharm,所以我不是很熟悉,经常敲着敲着就在代码下面出现一长条红色的线,大多数情况都是因为少了或多了个空格,让人很不习惯。
今天学习爬虫的时候反复检查好几遍代码,愣是没发现错误,但是程序一直有问题。
又检查了几遍,才恍然大悟,标红的这两行前面有空格,要把空格删掉。
果然,把空格删掉后,程序正常运行。
所以,如果大家以后用pycharm敲代码时,如果发现程序出问题,除了代码,是不是多了或少了空格也是需要注意的。与大家共勉。
今天的介绍会围绕下面四点展开:
Flink CDC 技术
海量数据集成的痛点
Flink CDC 如何加速海量数据集成
开源社区发展
01
Flink CDC 技术
广义的概念上, 能够捕获数据变更的技术, 我们都可以称为 CDC(Change Data Capture)。通常我们说的 CDC 技术主要面向数据库的变更, 是一种用于捕获数据库中数据变更的技术。
CDC 技术主要有三类应用场景:
①数据同步: 用于数据备份、系统容灾
②数据分发: 一个数据源分发给多个下游
③数据采集: 面向数据仓库/数据湖的 ETL 数据集成
业界 CDC 的技术方案非常多,从原理上可以分为两大类:一类是基于查询的 CDC,一类是基于日志的 CDC。
基于查询的 CDC 优点是实现简单,是通过批处理实现的,需要依赖离线调度,不能保证数据强一致性和实时性。基于日志的 CDC 实现比较复杂,但是可以实时消费日志,流式处理,可保证数据一致性和实时性。
与开源 CDC 方案 Debezium、DataX、Canal、Sqoop、Kettle 和闭源 OGG 等方案对比,Flink CDC 在功能和架构方面优势明显。Flink CDC 支持全量和增量一体化同步、断点续传,支持分布式架构、支持事务,生态友好。
Flink CDC 支持全量和增量数据一体化同步,首先读取数据库中表的历史全量数据,再无缝衔接到读取表的增量数据,为用户提供实时的、一致性的快照。 整个过程中,全量同步与增量读取无缝衔接,不需要用户进行手动干预或切换。
比如一张表中有全量的历史数据,同时增量数据也在不断写入。增量的 update 数据会在实时一致性快照内进行更新,insert 的数据则会追加到实时一致性快照中。
Flink CDC 核心技术就是提供实时的的全增量一体化同步。
02
海量数据集成的痛点
传统数据入仓架构1.0仍然有不少公司在使用,该方案通过 DataX、Sqoop 将数据以全量同步的方式写入到 HDFS 再导入到 Hive 构建离线数仓。
通过前面大数据开发相关知识的学习,准备做一个项目进行练习---我给他起了一个响亮的名字:基于HadoopHA的智慧社区服务平台
设计规范: 做一个项目之前肯定要先规定一些开发过程中的设计规范
(一)数据埋点规范: 数据埋点:是一种在软件、应用程序或网站中插入代码的技术,用于收集和跟踪用户行为和事件的数据。通过在关键位置插入代码片段(埋点),可以记录用户在应用程序中的操作和交互,以及其他有关系统和用户行为的信息。
(1)确保灵活、高可扩展
(2)兼顾后续的处理、分析的方便性
(3)确保可跟踪、数据正确性
(4)业务数据打通
(5)考虑不同C端产品特性与用户体验
(6)确保性能、敏感数据安全性
(二)数仓层次设计规范: ODS层:是原始数据层,是最接近数据源的一层,将数据源中的数据经过ETL之后装入ODS层,ODS的数据结构一般与数据来源保持一致,便于减少ETL工作的复杂性。
DWD层:是明细数据层,进行维度建模,该层的表结构和粒度与原始表保持一致,不过对ODS层数据进行清洗、维度退化、脱敏等,最终得到的数据是干净的,完整的,一致的数据。一般采用星型模型,呈现的状态一般为星座模型。 维度建模一般分为四步: 选择业务过程(先选择容易实现的)、 声明粒度(以最低的原子粒度处理数据)、 确认维度(考虑其他维度是否可以被属性化)、 确认事实(确认将那些事实---(指的是度量值,一些具体数据)放入事实表中)。
DWS层:服务数据层,基于DWD层的明细数据,按天轻度汇总成某一个主题域的服务数据,一般是宽表。DWS层统计各个主题对象的当天行为,以及一些业务明细数据,服务于DM(数据集市)层的某个主题。
(三)表命名规范: 英文在不是原意的情况下采用缩写,避免数字开头
能够合理的区分出表所描述的数据域、数据周期等。 命名规范设定:
层次_数据域_修饰/描述_范围/周期
订单相关数据表
dwd层: d_ord_info_d
dws层: s_ord_st_d
维度表(dimension)
用户维度: dim_user_d
商品缓慢渐变维表: dim_product_l
ods层
对于ods层表,最好能够区分数据来源,包括在来自什么系统、源数据名称。
eg 从业务系统全量采集订单(loan_order)数据到ods层 业务系统编码: buss 业务系统订单表: loan_order ods层表命名: o_buss_loan_order_d
(四)脚本命名规范: •ETL脚本名称尽可能和所产出的表同名 •数据采集、 数据推送脚本尽可能标识数据去向
•ETL脚本若产生多个表, 采用对应的数据域和语义描述命名
•Jar包命名以实际的业务处理逻辑语义描述为主,调度任务命名同样尽量以产出表名命名。
eg:
订单ETL过程 从表o_buss_loan_order_d整理数据并且装载到dwd层表d_ord_info_d中。
ETL脚本命名: d_ord_info_d.sh
ETL任务命名: d_ord_info_d 一个ETL脚本产出多个表,比如从商品表中分离出商品维度、厂家维度。
ETL脚本命名: dim_product_mfrs_d.sh
ETL任务名称: dim_product_mfrs_d 采集数据到ods层的表o_buss_loan_order_d imp_o_buss_loan_order_d.sh
数据表dm_ord_trsfm_d推送到BI系统 exp_bi_dm_ord_trsm_d.sh
(五)开发规范: 数仓中MR程序尽可能统一输入参数、输出参数,单个jar程序的功能模块清晰,避免多种处理逻辑写入一个jar包。
解决方法如下:
如果 ifcfg-ens33 这个文件已经提前编辑过并且已经将 ONBOOT 改为yes,之前还好好的但是现在ip突然就没了
1.先尝试重启网络服务
1. sudo service network restart
如果失败 (大概率会失败)就执行下边命令
解决方式:禁用 NetworkManager
2.执行下边这两条命令
1. systemctl stop NetworkManager
2. systemctl disable NetworkManager
3.执行完成之后重新启动网络服务。
1. sudo service network restart
重新启动网络服务后就OK了
4.输入ip addr查看ip地址。
目录
♈️一、三子棋的简介
♉️二、C语言实现思路
大体框架的构建
接口的定义
♊️ 三、根据所写接口实现函数主体
菜单的构建
game()主体的构建
💟重点在判断输赢!(肥肠重要!!!)
♋️四、总体代码
实现效果 ♈️一、三子棋的简介 三子棋是一种简单的棋类游戏。游戏的目标是在一个3x3或者更大的4x4等等的棋盘上,先将自己的棋子在一条直线上连成三个即可获胜。棋子可以横、竖、斜着连线。游戏通常由两个人轮流下棋进行,一方执X棋子,另一方执O棋子。如果棋盘被填满了且没有一方达成获胜条件,则平局。
♉️二、C语言实现思路 大体框架的构建 1. 定义棋盘:使用二维数组来表示棋盘,其中0表示空格,1表示*,2表示#。
2. 初始化棋盘:将每个元素初始化为0(空格)。
3. 画出棋盘:使用printf()函数在屏幕上绘制出棋盘,包括行和列的标记。
4. 玩家输入:使用scanf()函数让玩家在控制台上输入他想要下棋的位置。
5. 检查合法性:检查玩家输入的位置是否在棋盘范围内,并且是否为空格(即是否已经下过棋了)。
6. 下棋:如果玩家输入的位置合法,那么在该位置上下一颗棋子(*或#)。
7. 检查胜负:每下一颗棋子都需要检查是否有玩家已经获胜了,如果有,游戏结束。
8. 切换玩家:玩家vs玩家:每次玩家下完一步棋,需要切换到另一个玩家继续游戏。玩家vs电脑:电脑自动下,然后玩家下。
9. 循环游戏:按照上述步骤重复进行游戏,直到有一方获胜或者平局。
10. 打印结果:游戏结束后,使用printf()函数输出结果,说明谁获胜了或者是平局。
接口的定义 定义了棋盘的大小,ROW和COL来控制,以及两个主题函数,一个是作为菜单的函数,另外一个是作为游戏的主体函数,较为简单。(●'◡'●)
#define ROW 5 #define COL 5 #include<stdio.h> #include<stdlib.h> #include<time.h> void menu(); void game(); ♊️ 三、根据所写接口实现函数主体 菜单的构建 void menu()//菜单 { printf("---------------------------\n"); printf("|*************************|\n"); printf("|******* 1.play ********|\n"); printf("|******* 0.exit ********|\n"); printf("|*************************|\n"); printf("---------------------------\n"); } 大道至简,无需多言 !
引言 随着数字化和互联网的普及,越来越多的企业和组织需要高质量的用户界面和用户体验,以及可靠、高效的前端架构。UI/UX设计师和前端架构师可以为这些企业和组织提供所需的技术和创意支持。本文将介绍UI/UX+前端架构这个方向,包括设计原则、最佳实践和完整代码。
UI/UX设计原则 UI/UX设计师需要遵循一些设计原则,以确保用户界面和用户体验的质量。以下是一些常见的设计原则:
易用性:用户界面应该易于使用和理解,用户可以轻松地完成任务。可访问性:用户界面应该能够被所有用户访问,包括残障人士。一致性:用户界面应该保持一致,以便用户可以轻松地学习和使用。反馈:用户界面应该提供及时和准确的反馈,以便用户可以了解他们的行为的结果。可控制性:用户界面应该允许用户控制他们的行为和环境。 UI/UX最佳实践 UI/UX设计师还需要遵循一些最佳实践,以确保用户界面和用户体验的质量。以下是一些常见的最佳实践:
用户研究:在设计用户界面之前,应该进行用户研究,以了解用户的需求和期望。原型设计:应该使用原型设计工具来创建用户界面的原型,以便进行测试和评估。响应式设计:应该使用响应式设计,以确保用户界面在不同设备和屏幕尺寸上的可用性。A/B测试:应该使用A/B测试来评估不同设计的效果,以确定最佳设计。可访问性测试:应该进行可访问性测试,以确保用户界面能够被所有用户访问。 前端架构设计 前端架构师需要设计和开发可靠、高效的前端架构,以支持大规模的网站和应用程序。以下是一些常见的前端架构设计原则:
分层架构:应该使用分层架构,将前端应用程序分为不同的层,以便进行分离和重用。
模块化:应该使用模块化架构,将前端应用程序分为不同的模块,以便进行分离和重用。
依赖管理:应该使用依赖管理工具,以管理前端应用程序的依赖关系,以便进行可靠的部署和更新。
缓存:应该使用缓存技术,以提高前端应用程序的性能和响应速度。
测试:应该进行单元测试和集成测试,以确保前端应用程序的质量和稳定性。
完整代码 以下是一个简单的UI/UX+前端架构示例,包括设计原则、最佳实践和完整代码。
// UI/UX设计原则 function isUsable() { return true; } function isAccessible() { return true; } function isConsistent() { return true; } function isResponsive() { return true; } function isControllable() { return true; } // UI/UX最佳实践 function conductUserResearch() { // 进行用户研究 } function createPrototype() { // 创建用户界面原型 } function performA/BTesting() { // 进行A/B测试 } function performAccessibilityTesting() { // 进行可访问性测试 } // 前端架构设计 function createLayeredArchitecture() { // 创建分层架构 } function createModularArchitecture() { // 创建模块化架构 } function manageDependencies() { // 管理依赖关系 } function implementCaching() { // 实现缓存 } function writeUnitTests() { // 编写单元测试 } function writeIntegrationTests() { // 编写集成测试 } // 完整代码 function designAndDevelopUIUX() { // 进行UI/UX设计和开发 conductUserResearch(); createPrototype(); performA/BTesting(); performAccessibilityTesting(); // 进行前端架构设计和开发 createLayeredArchitecture(); createModularArchitecture(); manageDependencies(); implementCaching(); writeUnitTests(); writeIntegrationTests(); } // 示例用法 designAndDevelopUIUX(); 总结 UI/UX+前端架构是一个非常有前景的方向,可以为企业和组织提供高质量的用户界面和用户体验,以及可靠、高效的前端架构。UI/UX设计师和前端架构师需要具备多方面的技能和知识,包括设计、技术、用户体验、性能优化和软件工程等。他们需要不断学习和更新自己的知识和技能,以适应不断变化的技术和市场需求。
阅读须知: 本文主要内容为 Redis 哨兵机制搭建的详细步骤(以三哨兵为例)。
想要了解如何安装 Redis 的同学可以前往:【Redis】基于Docker安装Redis(详细步骤)
想要了解如何搭建 Redis 主从的同学可以前往:【Redis】基于Docker搭建Redis主从(详细步骤)
本文在前两文的基础上,进一步搭建起 Redis 的哨兵机制。
操作步骤 1. 创建配置文件 在 /usr/local/software/redis/6379/sentinel 目录下创建配置文件 sentinel.conf由于是三哨兵机制,因此在 /usr/local/software/redis/6380/sentinel 、 /usr/local/software/redis/6380/sentinel 目录下,均要建立对应的配置文件 sentinel.conf 演示图例如下:
2. 编辑配置文件 通过 vim 编辑器编辑配置文件内容,同样三个配置文件均需要分别编辑按下 i ,进入输入模式,粘贴如下内容按下:,输入wq,保存并退出 哨兵1:跟踪 Redis(主)
# 所以无需担心端口重复使用 # 如果需要在单机 port 26379 # 设定密码认证 # requirepass 123456 # 配置哨兵的监控参数 # 格式:sentinel monitor <master-name> <ip> <redis-port> <quorum> # master-name是为这个被监控的master起的名字 # ip是被监控的master的IP或主机名。因为Docker容器之间可以使用容器名访问,所以这里写master节点的容器名 # redis-port是被监控节点所监听的端口号 # quorom设定了当几个哨兵判定这个节点失效后,才认为这个节点真的失效了 sentinel monitor redis_6379 172.18.12.10 6379 2 # 连接主节点的密码 # 格式:sentinel auth-pass <master-name> <password> # sentinel auth-pass local-master 123456 # master在连续多长时间无法响应PING指令后,就会主观判定节点下线,默认是30秒 # 格式:sentinel down-after-milliseconds <master-name> <milliseconds> sentinel down-after-milliseconds redis_6379 30000 哨兵2:跟踪 Redis(从1)
当你创建一个 FastAPI 路径操作 时,你可以正常返回以下任意一种数据:dict,list,Pydantic 模型,数据库模型等等。
FastAPI 默认会使用 jsonable_encoder 将这些类型的返回值转换成 JSON 格式,
默认情况下会以content-type: application/json 格式返回
在有些情况下,我们需要在路径操作中直接返回Response对象,这样我们能有更多的操作灵活性,比如自定义头headers 信息、自定义Cookie信息等
默认返回 json 格式 返回一个基本数据类型 dict,list,str 会以 json 格式返回
# 上海悠悠 wx:283340479 # blog:https://www.cnblogs.com/yoyoketang/ from fastapi import FastAPI import uvicorn app = FastAPI() @app.get('/demo') def demo(): item = { "name": "yoyo", "email": "123@qq.com" } return item get 请求访问 http://127.0.0.1:8000/demo
HTTP/1.1 200 OK date: Tue, 18 Jul 2023 10:50:41 GMT server: uvicorn content-length: 36 content-type: application/json {"
一、概述
在实际应用系统开发中会设计多个数据表,每个表的信息不是独立存在的,而是若干个表之间的信息存在一定的关系,当用户查询某一个表的信息时,很可能需要查询关联数据表的信息,这就是多表关联查询。SELECT语句自身是支持多表关联查询的,多表关联查询要比单表查询复杂的多。在进行多表关联查询时,可能会涉及表别名、内连接、外连接、自然连接和交叉连接等概念,下面将对这些内容进行讲解。
二、表的别名
在多表关联查询时,如果多个表之间存在同名的列,则必须使用表名来限定列的引用。例如,在SCOTT模式中,DEPT表和EMP表都有DEPTNO列,当用户使用该列关联查询两个表时,就需要通过指定表名来区分这两个列的归属。但是,随着查询变得越来越复杂,语句就会因为每次限定列必须输入表名而变得冗长。对于这种情况,SQL提供了设定表别名的机制,使用简短的表别名可以代替原有较长的表名称,这样就大大缩减语句的长度。
【例2.1】在SCOTT模式下,通过DEPTNO(部门号)列来关联EMP表和DEPT表,并检索这两个表中相关字段的信息,代码及运行结果如下:
select e.empno 员工编号,e.ename 员工姓名,d.dname 部门 from dept d,emp e where d.deptno = e.deptno and e.job = 'MANAGER'; 在上面的SELECT语句中,FROM子句最先执行,然后才是WHERE子句和SELECT子句,这样在FROM子句中指定表的别名后,当需要限定引用列时,其他所有子句都可以使用表的别名。
另外,还需要注意一点,一旦在FROM子句中为表指定了别名,则必须在剩余的子句中都是用表的别名,而不允许再使用原来的表名称,否则,将出现【例2.2】错误提示。
【例2.2】 select e.empno 员工编号,e.ename 员工姓名,d.dname 部门 from dept d,emp e where d.deptno = e.deptno and emp.job = 'MANAGER'; 总结:
1、表的别名在FROM子句中定义,别名放在表名之后,之间用空格隔开。
2、别名一经定义,在整个查询语句中就只能使用表的别名而不能在使用表名。
3、表的别名只在所定义的查询语句中有效。
4、应该选择有意义的别名,表的别名最长为30个字符,但越短越好。
三、内连接
内连接是一种常用的多表关联查询方式,一般使用关键字INNER JOIN来实现。其中INNER关键字可以省略,当只使用JOIN关键字时,语句默认表示内连接操作。在使用内连接查询多个表时,必须在FROM子句之后定义一个ON子句,ON子句指定内连接操作列与连接条件匹配的数据行,使用比较运算符比较被连接列的值。简单来说,内连接就是使用JOIN指定用于连接的两个表,使用ON指定表的连接条件。若进一步限制查询范围,则可以直接在后面添加WHERE子句。内连接的语法格式如下:
SELECT columns_list FROM table_name1 [INNER] JOIN table_name2 ON join_condition [WHERE] 其中:columns_list:字段列表
table_name1 和 table_name2 :两个要实现内连接的表。
join_condition:实现内连接的条件表达式
WHERE :使用where子句进一步限制查询范围。
【例3.1】在scott模式下,通过deptno字段来内连接emp表和dept表,查询dept表中部门名称为 SALES,并检索这两个表中相关的字段信息。
在Unity中,我们可以通过修改Render Queue值来控制物体的渲染顺序。
Render Queue值默认为0,值越大的物体越靠后渲染。
修改渲染顺序的方法:
获取需要调整的Material或Shader
可以通过获取物体的renderer.material来获取Material。
设置Render Queue值
给Material或Shader添加一个名为"RenderQueue"的属性,设置不同的整数值控制顺序。
例如:
material.renderQueue = 2500;
Unity内置的Render Queue值
Background: -1000
Geometry: 2500
AlphaTest: 2450
Transparent: 2000
Overlay: 4000
调整半透明对象顺序
可以将半透明对象设置为2000,背景设置为2500,这样背景会先渲染。
特殊值控制
3000以下为不透明几何体
3000-3999为半透明效果
4000以上为界面元素
所以一般来说:
将背景设置高Render Queue值(2500+)
将半透明对象设置低值(2000-2400)
半透明对象内部相对顺序不变
这样可以有效控制渲染顺序,解决半透明问题。
目录
🍒docker的概念
🍒Docker 的优点
🫐1、快速,一致地交付您的应用程序
🫐2、响应式部署和扩展
🫐3、在同一硬件上运行更多工作负载
🍒云耀云服务器L实例
🫐产品优势
🥝智能不卡顿
🥝价优随心用
🥝上手更简单
🥝管理更省心
🫐购买方式
🍒docker安装
🫐阿里云镜像加速器
🦐博客主页:大虾好吃吗的博客
🦐专栏地址:闲谈专栏地址
docker的概念 Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版)。
Docker 的优点 Docker 是一个用于开发,交付和运行应用程序的开放平台。 Docker 能够将应用程序与基础架构分开,从而可以快速交付软件。借助 Docker,可以与管理应用程序相同的方式来管理基础架构。 通过利用 Docker 的方法来快速交付,测试和部署代码,大大减少编写代码和在生产环境中运行代码之间的延迟。
1、快速,一致地交付您的应用程序 Docker 允许开发人员使用您提供的应用程序或服务的本地容器在标准化环境中工作,从而简化了开发的生命周期。
容器非常适合持续集成和持续交付(CI / CD)工作流程,请考虑以下示例方案:
您的开发人员在本地编写代码,并使用 Docker 容器与同事共享他们的工作。 他们使用 Docker 将其应用程序推送到测试环境中,并执行自动或手动测试。 当开发人员发现错误时,他们可以在开发环境中对其进行修复,然后将其重新部署到测试环境中,以进行测试和验证。 测试完成后,将修补程序推送给生产环境,就像将更新的镜像推送到生产环境一样简单。
Vue - 将页面内容下载为 pdf 格式文件(html2canvas + jspdf) 一. 安装所需依赖二. htmlToPdfNew.js 核心文件三. 组件使用方法四. 组件使用实例 一. 安装所需依赖 npm install html2canvas --save
npm install jspdf --save
二. htmlToPdfNew.js 核心文件 /* eslint-disable */ import jsPDF from "jspdf"; import html2canvas from "html2canvas"; /* * 使用说明 * ele:需要导出pdf的容器元素(dom节点 不是id) * pdfFileName: 导出文件的名字 通过调用outPutPdfFn方法也可传参数改变 * splitClassName: 避免分段截断的类名 当pdf有多页时需要传入此参数 , 避免pdf分页时截断元素 如表格<tr class="itemClass"></tr> * 调用方式 先 let pdf = new PdfLoader(ele, 'pdf' ,'itemClass');再 pdf.outPutPdfFn() * 若想改变pdf名称 pdf.outPutPdfFn(fileName); outPutPdfFn方法返回一个promise 可以使用then方法处理pdf生成后的逻辑 * */ class PdfLoader { constructor(ele, pdfFileName, splitClassName) { this.
一、需求 1.双色球: 投注号码由6个红色球号码和1个蓝色球号码组成。
2.红色球号码从01--33中选择,红色球不能重复。
3.蓝色球号码从01--16中选择。
4.最终结果7个号码:6+1;即33选6(红)+ 16选1(蓝)
5.产品: 能用;用户放心使用;
原则:靠运气,不能有暗箱操作,号码开奖的随机性。
6.做法思路:
(1)从左往右---有序变化
(2)从右往左---有序变化
(3)同一时刻,球号码都变化~~
(4)可以做到让所有的球都变化,且都是相互独立的变化,随机性(推荐)
二、程序 1、界面:6个红球label显示LblRedNum1-LblRedNum6,一个蓝球LblBlue。
两个Button,BtnStart与BtnStop。一个listBox1.
2、代码:
private string[] redNums = Enumerable.Range(1, 33).Select(i => i.ToString("00")).ToArray(); private string[] blueNums = Enumerable.Range(1, 16).Select(i => i.ToString("00")).ToArray(); private object lockObj = new object(); private List<Task> tasks = new List<Task>(); private CancellationTokenSource cts; private async void BtnStart_Click(object sender, EventArgs e) { BtnStart.Enabled = false; BtnStop.Enabled = true; cts = new CancellationTokenSource(); CancellationToken ct = cts.