部分背包问题-贪心算法 问题描述 有一个调制饮品比赛
参赛者拥有容量为 c ml的杯子,可任选不超过体积上限的饮料进行混合调制饮品价格为各所使用饮料的价格之和,所得饮品价格之和最高者获胜 每种饮品有对应的价值和体积,应该如何使调制的饮品价格最高?
输入数据 第一行输入物品数量n和背包容量c。
接下来是n行数据,表示每个饮料的价值的体积。
输入输出样例 输入:
5 800
60 600
10 250
36 200
16 100
45 300
输出:
117
思路分析 这是一个典型的贪心问题,要求调制的饮品价格最高。
我们采用最高性价比优先的方法
性价比 = 价格/体积优先选择高性价比饮料全部装入,尽可能装满杯子 首先对n种饮品按照性价比降序排序,这里对于饮品我使用了结构体类型,结合sort函数即可实现。
定义一个ans表示当前饮品的价值,并赋初值为0,接下来对排好序的饮品进行遍历循环,循环条件为c>0(杯子还有剩余体积)且i<n.
while循环体内,若当前饮品体积小于剩余体积c,则将其全部放入,c=c-当前饮品体积;
否则,放入剩余体积c的该饮品,也就是将剩下的体积全部放入当前饮品,c=0。
代码样例 // // main.cpp // 部分背包问题 // // Created by MacBook Pro on 2021/4/19. // #include <iostream> #include<algorithm> using namespace std; struct goods//表示商品 { float weight;//重量 float value;//价值 float ratio;//性价比 }; bool cmp(goods x,goods y) { return x.
测试环境 centos7
安装 slither
sudo yum -y install python3 pip3 sudo pip3 install slither-analyzer 安装 solc-select
sudo pip3 install solc-select 使用 solc-select 安装 solc,装不了的话挂下代理
solc-select install 0.4.15 # 使用的 solc 0.4.15 版本 solc-select use 0.4.15 # 查看当前使用的 solc 版本 solc --version slither 扫描目录
一、前言 通过在通道画面上拾取鼠标按下的坐标,然后鼠标移动,直到松开,根据松开的坐标和按下的坐标,绘制一个矩形区域,作为热点或者需要电子放大的区域,拿到这个坐标区域,用途非常多,可以直接将区域中的画面放大,也可以将该圈起来的区域位置发给设备,由设备设定对应的热点区域作为集中观察点,可以用来人工智能分析,比如出现在该区域的人脸,可以判定为入侵,该区域内的画面被改动过,判定为物体非法挪动等。各种各样的分析算法应用上来,就可以做出非常多的检测效果,这些都有个前提,那就是用户能够在视频画面中自由的选择自己需要的区域,这就是要实现的功能。
采集到的视频数据,在UI界面上,可能是拉伸填充显示的,也可能是等比例缩放显示的,最重要的是,显示的窗体,几乎不大可能刚好是和分辨率大小一样,所以这就涉及到一个转换关系,就是根据窗体的尺寸和视频的尺寸,当前鼠标按下的坐标,需要换算成视频对应的坐标,换算公式是:视频X=坐标X / 窗体宽度 * 视频宽度,视频Y=坐标Y / 窗体高度 * 视频高度。所以在视频窗体控件上识别鼠标按下/鼠标移动/鼠标松开事件进行处理即可,最后发送信号出去,带上类型(鼠标按下/鼠标移动/鼠标松开)和QPoint坐标。为什么要带上类型呢?方便用户处理,比如识别到用户按下就记住坐标,移动的时候绘制方框,结束的时候发送滤镜执行裁剪也就是电子放大操作。
二、效果图 三、体验地址 国内站点:https://gitee.com/feiyangqingyun国际站点:https://github.com/feiyangqingyun个人作品:https://blog.csdn.net/feiyangqingyun/article/details/97565652体验地址:https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g 提取码:01jf 文件名:bin_video_demo。视频主页:https://space.bilibili.com/687803542 四、功能特点 4.1. 基础功能 支持各种音频视频文件格式,比如mp3、wav、mp4、asf、rm、rmvb、mkv等。支持本地摄像头设备和本地桌面采集,支持多设备和多屏幕。支持各种视频流格式,比如rtp、rtsp、rtmp、http、udp等。本地音视频文件和网络音视频文件,自动识别文件长度、播放进度、音量大小、静音状态等。文件可以指定播放位置、调节音量大小、设置静音状态等。支持倍速播放文件,可选0.5倍、1.0倍、2.5倍、5.0倍等速度,相当于慢放和快放。支持开始播放、停止播放、暂停播放、继续播放。支持抓拍截图,可指定文件路径,可选抓拍完成是否自动显示预览。支持录像存储,手动开始录像、停止录像,部分内核支持暂停录像后继续录像,跳过不需要录像的部分。支持无感知切换循环播放、自动重连等机制。提供播放成功、播放完成、收到解码图片、收到抓拍图片、视频尺寸变化、录像状态变化等信号。多线程处理,一个解码一个线程,不卡主界面。 4.2. 特色功能 同时支持多种解码内核,包括qmedia内核(Qt4/Qt5/Qt6)、ffmpeg内核(ffmpeg2/ffmpeg3/ffmpeg4/ffmpeg5/ffmpeg6)、vlc内核(vlc2/vlc3)、mpv内核(mpv1/mp2)、mdk内核、海康sdk、easyplayer内核等。非常完善的多重基类设计,新增一种解码内核只需要实现极少的代码量,就可以应用整套机制,极易拓展。同时支持多种画面显示策略,自动调整(原始分辨率小于显示控件尺寸则按照原始分辨率大小显示,否则等比缩放)、等比缩放(永远等比缩放)、拉伸填充(永远拉伸填充)。所有内核和所有视频显示模式下都支持三种画面显示策略。同时支持多种视频显示模式,句柄模式(传入控件句柄交给对方绘制控制)、绘制模式(回调拿到数据后转成QImage用QPainter绘制)、GPU模式(回调拿到数据后转成yuv用QOpenglWidget绘制)。支持多种硬件加速类型,ffmpeg可选dxva2、d3d11va等,vlc可选any、dxva2、d3d11va,mpv可选auto、dxva2、d3d11va,mdk可选dxva2、d3d11va、cuda、mft等。不同的系统环境有不同的类型选择,比如linux系统有vaapi、vdpau,macos系统有videotoolbox。解码线程和显示窗体分离,可指定任意解码内核挂载到任意显示窗体,动态切换。支持共享解码线程,默认开启并且自动处理,当识别到相同的视频地址,共享一个解码线程,在网络视频环境中可以大大节约网络流量以及对方设备的推流压力。国内顶尖视频厂商均采用此策略。这样只要拉一路视频流就可以共享到几十个几百个通道展示。自动识别视频旋转角度并绘制,比如手机上拍摄的视频一般是旋转了90度的,播放的时候要自动旋转处理,不然默认是倒着的。自动识别视频流播放过程中分辨率的变化,在视频控件上自动调整尺寸。比如摄像机可以在使用过程中动态配置分辨率,当分辨率改动后对应视频控件也要做出同步反应。音视频文件无感知自动切换循环播放,不会出现切换期间黑屏等肉眼可见的切换痕迹。视频控件同时支持任意解码内核、任意画面显示策略、任意视频显示模式。视频控件悬浮条同时支持句柄、绘制、GPU三种模式,非绝对坐标移来移去。本地摄像头设备支持指定设备名称、分辨率、帧率进行播放。本地桌面采集支持设定采集区域、偏移值、指定桌面索引、帧率、多个桌面同时采集等。还支持指定窗口标题采集固定窗口。录像文件同时支持打开的视频文件、本地摄像头、本地桌面、网络视频流等。瞬间响应打开和关闭,无论是打开不存在的视频或者网络流,探测设备是否存在,读取中的超时等待,收到关闭指令立即中断之前的操作并响应。支持打开各种图片文件,支持本地音视频文件拖曳播放。视频流通信方式可选tcp/udp,有些设备可能只提供了某一种协议通信比如tcp,需要指定该种协议方式打开。可设置连接超时时间(视频流探测用的超时时间)、读取超时时间(采集过程中的超时时间)。支持逐帧播放,提供上一帧/下一帧函数接口,可以逐帧查阅采集到的图像。音频文件自动提取专辑信息比如标题、艺术家、专辑、专辑封面,自动显示专辑封面。视频响应极低延迟0.2s左右,极速响应打开视频流0.5s左右,专门做了优化处理。支持H264/H265编码(现在越来越多的监控摄像头是H265视频流格式)生成视频文件,内部自动识别切换编码格式。支持用户信息中包含特殊字符(比如用户信息中包含+#@等字符)的视频流播放,内置解析转义处理。支持滤镜,各种水印及图形效果,支持多个水印和图像,可以将OSD标签信息和各种图形信息写入到MP4文件。支持视频流中的各种音频格式,AAC、PCM、G.726、G.711A、G.711Mu、G.711ulaw、G.711alaw、MP2L2等都支持,推荐选择AAC兼容性跨平台性最好。内核ffmpeg采用纯qt+ffmpeg解码,非sdl等第三方绘制播放依赖,gpu绘制采用qopenglwidget,音频播放采用qaudiooutput。内核ffmpeg和内核mdk支持安卓,其中mdk支持安卓硬解码,性能非常凶残。可以切换音视频轨道,也就是节目通道,可能ts文件带了多个音视频节目流,可以分别设置要播放哪一个,可以播放前设置好和播放过程中动态设置。可以设置视频旋转角度,可以播放前设置好和播放过程中动态改变。视频控件悬浮条自带开始和停止录像切换、声音静音切换、抓拍截图、关闭视频等功能。音频组件支持声音波形值数据解析,可以根据该值绘制波形曲线和柱状声音条,默认提供了声音振幅信号。标签和图形信息支持三种绘制方式,绘制到遮罩层、绘制到图片、源头绘制(对应信息可以存储到文件)。通过传入一个url地址,该地址可以带上通信协议、分辨率、帧率等信息,无需其他设置。保存视频到文件支持三种策略,自动处理、仅限文件、全部转码,转码策略支持自动识别、转264、转265,编码保存支持指定分辨率缩放或者等比例缩放。比如对保存文件体积有要求可以指定缩放后再存储。支持加密保存文件和解密播放文件,可以指定秘钥文本。提供的监控布局类支持64通道同时显示,还支持各种异型布局,比如13通道,手机上6行2列布局。各种布局可以自由定义。支持电子放大,在悬浮条切换到电子放大模式,在画面上选择需要放大的区域,选取完毕后自动放大,再次切换放大模式可以复位。各组件中极其详细的打印信息提示,尤其是报错信息提示,封装的统一打印格式。针对现场复杂的设备环境测试极其方便有用,相当于精确定位到具体哪个通道哪个步骤出错。同时提供了简单示例、视频播放器、多画面视频监控、监控回放、逐帧播放、多屏渲染等单独窗体示例,专门演示对应功能如何使用。监控回放可选不同厂家类型、回放时间段、用户信息、指定通道。支持切换回放进度。可以从声卡设备下拉框选择声卡播放声音,提供对应的切换声卡函数接口。支持编译到手机app使用,提供了专门的手机app布局界面,可以作为手机上的视频监控使用。代码框架和结构优化到最优,性能强悍,注释详细,持续迭代更新升级。源码支持windows、linux、mac、android等,支持各种国产linux系统,包括但不限于统信UOS/中标麒麟/银河麒麟等。还支持嵌入式linux。源码支持Qt4、Qt5、Qt6,兼容所有版本。 4.3. 视频控件 可动态添加任意多个osd标签信息,标签信息包括名字、是否可见、字号大小、文本文字、文本颜色、背景颜色、标签图片、标签坐标、标签格式(文本、日期、时间、日期时间、图片)、标签位置(左上角、左下角、右上角、右下角、居中、自定义坐标)。可动态添加任意多个图形信息,比如人工智能算法解析后的图形区域信息直接发给视频控件即可。图形信息支持任意形状,直接绘制在原始图片上,采用绝对坐标。图形信息包括名字、边框大小、边框颜色、背景颜色、矩形区域、路径集合、点坐标集合等。每个图形信息都可指定三种区域中的一种或者多种,指定了的都会绘制。内置悬浮条控件,悬浮条位置支持顶部、底部、左侧、右侧。悬浮条控件参数包括边距、间距、背景透明度、背景颜色、文本颜色、按下颜色、位置、按钮图标代码集合、按钮名称标识集合、按钮提示信息集合。悬浮条控件一排工具按钮可自定义,通过结构体参数设置,图标可选图形字体还是自定义图片。悬浮条按钮内部实现了录像切换、抓拍截图、静音切换、关闭视频等功能,也可以自行在源码中增加自己对应的功能。悬浮条按钮对应实现了功能的按钮,有对应图标切换处理,比如录像按钮按下后会切换到正在录像中的图标,声音按钮切换后变成静音图标,再次切换还原。悬浮条按钮单击后都用名称唯一标识作为信号发出,可以自行关联响应处理。悬浮条空白区域可以显示提示信息,默认显示当前视频分辨率大小,可以增加帧率、码流大小等信息。视频控件参数包括边框大小、边框颜色、焦点颜色、背景颜色(默认透明)、文字颜色(默认全局文字颜色)、填充颜色(视频外的空白处填充黑色)、背景文字、背景图片(如果设置了图片优先取图片)、是否拷贝图片、缩放显示模式(自动调整、等比缩放、拉伸填充)、视频显示模式(句柄、绘制、GPU)、启用悬浮条、悬浮条尺寸(横向为高度、纵向为宽度)、悬浮条位置(顶部、底部、左侧、右侧)。 五、相关代码 void VideoWidget::btnClicked(const QString &btnName) { QString flag = widgetPara.videoFlag; QString name = STRDATETIMEMS; if (!flag.isEmpty()) { name = QString("%1_%2").arg(flag).arg(name); } if (btnName.endsWith("btnRecord")) { QString fileName = QString("%1/%2.mp4").arg(recordPath).arg(name); this->recordStart(fileName); } else if (btnName.endsWith("btnStop")) { this->recordStop(); } else if (btnName.endsWith("btnSound")) { this->setMuted(true); } else if (btnName.
0. 前言 图像分类的大部分经典神经网络已经全部介绍完,并且已经作了测试
代码已经全部上传到资源,根据文章名或者关键词搜索即可
LeNet :pytorch 搭建 LeNet 网络对 CIFAR-10 图片分类
AlexNet : pytorch 搭建AlexNet 对花进行分类
Vgg : pytorch 搭建 VGG 网络
GoogLeNet : pytorch 搭建GoogLeNet
ResNet : ResNet 训练CIFAR10数据集,并做图片分类
关于轻量级网络
MobileNet 系列:
V1 :MobileNet V1 图像分类V2 :MobileNet V2 图像分类V3 :MobileNet V3 图像分类 ShuffleNet 系列:
V1 : ShuffleNet V1 对花数据集训练V2 : ShuffleNet V2 迁移学习对花数据集训练 EfficientNet 系列:
V1 :EfficientNet 分类花数据集V2 :EfficientNet V2 Swin-Transformer :Swin-Transformer 在图像识别中的应用
本章将根据 Swin-Transformer 网络对图像分类ending,包括如何获取数据集,训练网络、预测图像等等。
本文从头实现对Marvel superhero 进行分类记录,项目下载在后面
1、GPT+AI医学数据集MIMIC-Diff-VQA:16万张图片、70万问答对的临床问答数据 主页:https://holipori.github.io/KDD2023-MIMIC-Diff-VQA/
论文地址:https://arxiv.org/abs/2307.11986
数据集:https://physionet.org/content/medical-diff-vqa/1.0.0/
其它相关内容可见:个人主页 本文的主要参考是METATRUST的捕鲸船分享,链接如下:
MetaTrust价格操纵攻击分享
价格操纵的来源: 区块链世界中,为保持所有节点的共识一致,区块链阉割了每个节点独立获取链外信息的能力
区块链想获取类似外界的价格信息,只有两种方式:
通过实体类似Chainlink主动喂价,不断地将价格数据发布到链上直接通过某个智能合约中存储的参数,如uniswap等 举例:这是想获得的WETH价格,即为外部数据
getReserves()请求ETH价格,金融模型计算返回对应的值
这里如果通过闪电贷,如果金融模型错误计算的话,计算出的WETH就很可能出现问题
什么是价格操纵攻击: 价格操纵攻击是指通过操控市场的买卖行为(操控流动性池或地址余额),人为地影响产品或资产价格,以谋取不正当利益
价格操纵的四要素:
市场力量的不对等:通过闪电贷行为拥有大量的资金买卖行为的操纵:大额的代币兑换,破坏市场机制(市场的流动性)恶意影响价格:资产价格计算错误(脆弱的询价机制)谋取不正当利益:出现异常数量的奖励或抵押品 真实价格操纵攻击案例: 正常流程: 用户质押BNB和USDT,获得LP流动性证明;随后调用getReward()函数兑换掉LP,获得收益移除流动性过程中,会根据池子中BNB代币,兑换成Bunny代币 攻击流程: 分析可见慢雾pancake攻击分析
第一笔自己交易获得一定的LP流动性证明
用户通过闪电贷兑换了大量的BNB和USDT
第二笔交易闪电贷,向池子中添加大量流动性,同时调用getReward()函数
首先将LP转到WBNB-USDT池子中移除流动性,池子中有大量BNB和USDT
随后大量的BNB和USDT转化为WBNB-BUNNY流动性,WBNB池子中WBNB数量激增
随后根据得到的WBNB-BUNNY的LP数量,valueOfAsset函数计算LP价值
问题就出在valueOfAsset进行LP价值计算的时候,通过WBNB-BUNNY池子中的WBNB实时数量计算,导致单个LP价值显著增加
漏洞函数 getReserve()函数计算得到池中BNB余额,后直接用以计算LP相对于BNB的价值
具体金融模型计算:
如何避免价格操纵攻击: 避免使用脆弱的询价机制,主要有三种方式:
通过EOA(Chainlink)这样的实体,不断地喂价收集多个来源的价格,对不同来源的价格进行加权平均对过去一段时间内的价格,进行加权平均(uniswap) 一个敏感操作的变量数据,一定不能依赖于用户易于操控的数据,不然容易产生危险。
污点分析的方式进行漏洞检测
GMP是Go语言运行时(runtime)层面的实现,是go语言自己实现的一套调度系统,区别于操作系统调度OS线程
Golang"调度器"的由来 单进程时代不需要调度器 我们知道,一切的软件都是跑在操作系统上,真正用来干活(计算)的是CPU,早期的操作系统每个程序就是一个进程,直到一个程序运行完,才能进行下一个进程,就是"单进程时代"
一切的程序只能串行发生.
早期的单进程操作系统,面临2个问题:
单一的执行流程,计算机只能一个任务一个任务处理进程阻塞所带来的CPU时间浪费 那么能不能有多个进程宏观一起来执行多个任务呢?
后来操作系统就具有了最早的并发能力:多进程并发,当一个进程阻塞的时候,切换到另外等待执行的进程,这样就能尽量把CPU利用起来,CPU就不浪费了.
多进程/线程有了调度器需求 在多进程/多线程的操作系统中,就解决了阻塞的问题,因为一个进程阻塞CPU可以立刻切换到其他进程中去执行,而且调度CPU的算法可以保证在运行的进程都可以被分配到CPU的运行时间片.这样从宏观来看,似乎多个进程是在同时被运行
但是新的问题就又出现了,进程拥有太多的资源,进程的创建,切换,销毁,都会占用很长时间,CPU虽然利用起来了,但如果进程太多,CPU有很大一部分都被用来进行进程调度了.
怎么才能提高CPU的利用率呢?
对于Linux操作系统来讲,CPU对进程的态度和线程的态度是一样的.
很明显,CPU调度切换的是进程和线程.尽管线程看起来很美好,但实际上多线程开发设计会变得更加复杂,要考虑很多同步竞争等问题,如锁,竞争冲突等.
协程来提高CPU利用率 多进程,多线程已经提高了系统的并发能力,但是在当今互联网高并发场景下,为每个任务都创建一个线程是不现实的,因为会消耗大量的内存(进程虚拟内存会占用4GB[32位操作系统],而线程也要大约4MB).
大量的进程/线程出现了新的问题:
高内存占用调度的高消耗CPU 好了,然后工程师们就发现,其实一个线程分为"内核态"线程和"用户态"线程.
一个"用户态线程"必须要绑定一个"内核态线程",但是CPU并不知道有"用户态线程的存在",它只知道它运行的是一个"内核态线程"(Linux的PCB进程控制块).
我们再去细化去分类一下,内核态线程依然叫"线程(thread)“,用户态线程叫"协程(co-routine)”
既然一个协程(co-routine)可以绑定一个线程(thread),那么能不能多个协程(co-routine)绑定一个或者多个线程(thread)上呢.
有三种协程和线程的映射关系:
N:1关系
N个协程绑定1个线程,优点是协程再用户态线程即完成切换,不会陷入到内核态,这种切换非常的轻量快速.但是也有很大的缺点,1个进程的所有协程都绑定再1个线程上
某个程序用不了硬件多核加速能力一旦某协程阻塞,造成线程阻塞,本进程的其他协程都无法执行了,根本就没有并发的能力了
1:1关系
1个协程绑定1个线程,这种最容易实现.协程的调度都有CPU完成了,不存在N:1的缺点,但是协程的创建,删除和切换的代价都有CPU完成,有点略显昂贵了
M:N关系
M个协程绑定N个线程(一般情况下M>N),是N:1和1:1类型的结合,克服了以上2种模式的缺点,但实现起来最为复杂.
协程跟线程是有区别的,线程由CPU调度是抢占式的,协程由用户态线程调度是协作式的,一个协程让出CPU后,才执行下一个协程.
Go语言的协程goroutine Go为了提供更容易使用并发方法,使用了goroutine和channel.goroutine来自协程的概念,让一组可复用的函数运行在一组协程之上,即使有协程阻塞,该线程的其他协程也可以被runtime调度,转移到其他可运行的线程上.最关键的是,程序员看不到这些底层的细节,这就降低了编程的难度,提供了更容易的并发.
Go中,协程被称为goroutine,它非常轻量,一个goroutine只占几KB,并且这几KB就足够goroutine运行完,这就能在有限的内存空间内支持大量的goroutine,支持了更多的并发.虽然一个goroutine的栈只占几KB,但实际是可伸缩的,如果需要更多内容,runtime会自动为goroutine分配.
Goroutine特点
占用内存更小(几KB)调度更灵活(runtime调度) 2012年前的调度器(弃用) Go目前使用的调度器是2012年重新设计的,因为之前的调度器性能存在问题,所以使用4年就被废弃了,那么我们先来分析一下被废弃的调度器是如果运作的.
来看看被废弃的golang调度器是如何实现的?
M要想执行,放回G都必须访问全局G队列,并且M有多个,即多线程访问同一资源都需要加锁进行保证互斥/同步,所以全局G队列是有互斥锁进行保护的.
老调度器有几个缺点:
创建,销毁,调度G都需要每个M获取锁,这就形成了激烈的锁竞争.M转移G会造成延迟和额外的系统负载.比如当G中包含创建新协程的时候,M创建了G1,为了继续执行G,需要把G1交给M1执行,也造成了很差的局部性,因为G1和G是相关的,最好放在M上执行,而不是其他的M系统调用(CPU在M之间的切换)导致频繁的线程阻塞和取消阻塞操作增加了系统开销 Goroutine调度器的GMP模型的设计思想 新的调度器中,除了M(thread)和G(goroutine),又引进了P(Processor)
Processor,它包含了运行goroutine的资源,如果线程想运行goroutine,必须先获取P,P中还包含了可运行的G队列
GMP模型 在Go中,线程是运行goroutine的实体,调度器的功能是把可运行的goroutine分配到工作线程上.
全局队列(Global Queue):存放等待运行的GP的本地队列:同全局队列类似,存放的也是等待运行的G,存的数量有限,不超过256个.新建G1时,G1优先加入到P的本地队列,如果队列满了,则会把本地队列中一半的G移动到全局队列P列表:所有的P都在程序启动时创建,并保存在数组中,最多有GOMAXPROCS(可配置)个M:线程想运行任务就得获取P,从P的本地队列获取G,P队列为空时,M也会尝试从全局队列拿一批G放到P的本地队列,或从其他P的本地队列偷一半放到自己P的本地队列.M运行G,G执行之后,M会从P获取下一个G,不断重复下去 Goroutine调度器和OS调度器是通过M结合起来的,每个M都代表了1个内核线程,OS调度器负责把内核线程分配到CPU的核上执行,
有关P和M的个数问题 P的数量 由启动时环境变量$GOMAXPROCS或者是由runtime的GOMAXPROCS函数决定.这意味着在程序执行时的任意时刻都只有$GOMAXPROCS个goroutine在同时运行 M的数量: go语言本身的限制:go程序启动时,会设置M的最大数量,默认10000.但是内核很难支持这么多的线程数,所以这个限制可以忽略runtime/debug中的SetMaxThreads函数,设置M的最大数量一个M阻塞了,会创建新的M M与P的数量没有绝对关系,一个M阻塞,P就会去创建或者切换另一个M,所以,即使P的默认数量是1,也有可能会创建很多个M出来.
P和M何时会被创建 P何时创建:再确定了P的最大数量n后,运行时系统会根据这个数量创建n个PM合适创建:没有足够的M来关联P并运行其中的可运行的G.比如所有的M此时都阻塞住了,而P中还有很多就绪任务,就会去寻找空闲的M,而没有空闲的,就会去创建新的M 调度器的设计策略 复用线程:避免频繁的创建,销毁线程,而是对线程的复用
work stealing机制:当本地线程无可运行的G时,尝试从其他线程绑定的P偷取G,而不是销毁线程hand off机制:当本线程因为G进行系统调用阻塞时,线程释放绑定的P,把P转移给其他空闲的线程执行 利用并行:GOMAXPROCS设置P的数量,最多由GOMAXPROCS个线程分布再多个CPU上同时运行.GOMAXPROCS也限制了并发的程度,比如:GOMAXPROCS=核数/2,则最多利用一半的CPU进行并行
抢占:再coroutine中要等待一个协程主动让出CPU才执行下一个协程,在Go中,一个goroutine最多占用CPU10ms,防止其他的goroutine被饿死,这就是goroutine不同于coroutine的一个地方.
全局G队列:在新的调度器中依然有全局G队列,但功能已经被弱化了,当M执行work stealing从其他P偷不到G时,它可以从全局G队列获取G
go func()调度流程 从上图我们可以分析出几个结论:
1.PLLVR频率计算
高云的M3核要用到PLLVR核,其输出频率=FCLKIN*(FBDIV_SEL+1)/(IDIV_SEL+1),但同时要满足FCLKIN*(FBDIV_SEL+1)*ODIV_SEL)/(IDIV_SEL+1)的值在600MHz和1200MHz之间。例如官方示例,其输入频率FCLKIN=50MHz,要输出80MHz,则pllvr_inst.IDIV_SEL = 4,pllvr_inst.FBDIV_SEL = 7,pllvr_inst.ODIV_SEL = 8,计算可知50*(7+1)/(4+1)=80,同时50*(7+1)*8/(4+1)=640,满足要求。
2.官方代码在27M时钟下的适配
已知主频和波特率之间的误差如下:
取115200bps,选择72M主频,50M输入频率下,PLLVR配置,可以看出实际频率只能是71.875M:
相应参数如下:
defparam pllvr_inst.IDIV_SEL =15; defparam pllvr_inst.FBDIV_SEL = 22; defparam pllvr_inst.ODIV_SEL = 16; 已知高云GW1NSR-4C开发板板载时钟为27M,根据以上参数,可知其实际频率为27*(22+1)/(15+1)=38.8125,同时有27*(22+1)*16/(15+1)=621,满足大于600小于1200的要求。以上是FPGA工程的修改,MCU工程进行相应的修改,打开\EMPU(GW1NS-4C)_V1.2\ref_design\MCU_RefDesign\Keil_RefDesign\uart\SYSTEM\system_gw1ns4c.c文件第65行找到 #define __XTAL,把值改为77625000。编译EMPU(GW1NS-4C)_V1.2\ref_design\MCU_RefDesign\Keil_RefDesign\uart\PROJECT下的uart工程,上传,串口调试助手测试效果如下:
FPGA工程中gowin_pllvr.v文件的defparam pllvr_inst.FCLKIN参数为输入频率,但不宜直接更改,必须按照以上计算以符合规范。也就是说,虽然FPGA工程代码所写晶振频率50M,但实际用的是27M,PLL输出频率38.8125M,而MCU工程则按照38.8125M(晶振为77.625M)主频配置。另外要特别注意,PLL输出频率不要超过80M,否则有很大可能导致MCU无法运行。
3.PLLVR主频特别说明
高云M3内核应用时,需要PLLVR核,默认时钟输入为50M,若根据开发板实际改为27M,经广泛测试,有可能会出现不可预料的问题:(1)MCU无法启动;(2)MCU可以硬启动(即上电启动),但reset按键会导致死机;(3)串口无法通信。而且这些问题随机出现,甚至不同开发板出现的问题都不同。故而,代码中保持50M输入频率不变,MCU编程中根据实际对主频作出调整。
4.官方代码
Embedded M3 Hard Core in GW1NS-4C - 科技 - 广东高云半导体科技股份有限公司 (gowinsemi.com.cn)
5.pllvr另外一种设置方法
先用27M晶振进行设置pll输出(不大于43.5M。代码生成后将FCLKIN改为50。建议pllvr输出频率选择40.5M,),此时FBDIV_SEL=2,IDIV_SEL=1,ODIV_SEL=16,换成50后输出为75M,小于80M,代入FCLKIN*(FBDIV_SEL+1)*ODIV_SEL)/(IDIV_SEL+1)得1200,全都符合要求,经测试115200bps串口工作稳定可靠。
1.仅提供RT-Thread的Nano版本
MCU工程在\EMPU(GW1NS-4C)_V1.2\ref_design\MCU_RefDesign\Keil_RefDesign\rt_thread_nano\PROJECT目录下,FPGA工程参考:
高云GW1NSR-4C开发板M3硬核应用-CSDN博客
特别注意,MCU主频(即FPGA工程经PLL输出的频率)应该不大于80M,FPGA工程时钟输入建议选择50M,而MCU则需要根据实际加以修改,原因见:
高云GW1NSR-4C开发板M3核串口通信-CSDN博客
2.RT-Thread波特率为115200bps,要根据实际情况计算出MCU频率,并修改MCU工程的#define __XTAL参数,串口调试助手也据此设置波特率。对于27M晶振来说,建议选择pllvr输出40.5M,代码生成后将FCLKIN改为50,如下:
defparam pllvr_inst.FCLKIN = "50"; defparam pllvr_inst.IDIV_SEL = 1; defparam pllvr_inst.FBDIV_SEL = 2; defparam pllvr_inst.ODIV_SEL = 16; 同时,MCU工程修改\EMPU(GW1NS-4C)_V1.2\ref_design\MCU_RefDesign\Keil_RefDesign\rt_thread_nano\SYSTEM\system_gw1ns4c.c文件第65行:
#define __XTAL (81000000UL) /* Oscillator frequency */ 3.代码修改
为了实现交互行,需要修改官方main.c代码,增加msh入口,并把led作为命令加入。如下:
int main(void) { return 0; //msh入口 } int led(void) { while(1) { GPIO_ResetBit(GPIO0, GPIO_Pin_0); printf("LED on.\r\n"); rt_thread_mdelay(500); GPIO_SetBit(GPIO0, GPIO_Pin_0); printf("LED off.\r\n"); rt_thread_mdelay(500); } return 0; } MSH_CMD_EXPORT(led, RT-Thread led command); //作为命令添加 4.效果展示
上电后,串口调试助手(115200bps)应该显示如下界面:
发送help,效果如下:
可以看出,led已经作为命令加入了,此时发送led,即可运行之,板上led同步闪烁,效果如下:
总结: 1.DDL数据库操作
show database; //查看当前创建的数据库
create database 数据库名; //创建数据库
use 数据库; //切换数据库
select database(); //查看当前所处的数据库(当前进入的那个数据库)
drop database 数据库名; //删除数据库名
2.DDL表操作
show tables; //查看数据库内所有表名
create table 表名 (字段名 字段类型,字段名 字段类型 ) ; //创建表结构
desc 表名; //查看表结构
show create table 表名; //查看建表语句
alter table 表名 add/modify/change/drop/rename to //表的添加 修改 类型 删除 修改表名
drop table 表名 ; //删除表名
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录 一、HC(华为云、公有云)、HCSO、HCS的区别二、k8s相关三、容器网络1、Pod通信2、 一、HC(华为云、公有云)、HCSO、HCS的区别 1、HC:公有云,物料是华为的,客户买华为服务,数据在华为,华为在线安装,升级、运维,数据控制者;
2、HCSO(HCS Online):混合云,物料是客户的(也会买华为的硬件),客户买华为服务,数据在客户,华为在线安装,升级、运维(从客户机房拉线)
3、HCS:混合云,物料是客户的(也会买华为的硬件),客户买华为的服务,数据在客户,华为现场安装,升级、运维,设备供应者。
HCIP学习笔记-华为云运维方案-9:https://blog.csdn.net/GoNewWay/article/details/131528217?
HCIP:https://blog.csdn.net/gonewway/category_12320829.html
告警术语
故障:云服务的意外中断或华为云公有云服务质量的下降,面向用户提供的服务发生不可用及用户体验有损的场景定义为故障
隐患:现网云服务发生故障的潜在风险点,如不提前处理可能会引发现网故障
事件型告警:在某一时刻突然触发的错误性告警,例如:某一刻虚拟机蓝屏故障、某接口调用失败
指标型告警:在特定网站,多某个监控指标设置阈值,持续达到阈值时触发的动作,比如:CPU利用率过高,磁盘使用率过高
告警工单:通过告警规则生成的工单,由告警处理人按照规范进行处理,告警平台统一处理承载
告警氛围三个等级:Critical(紧急)、Major(重要)、Info(提示)
二、k8s相关 Deployment不是直接控制pod的,Deployment是通过一种名为ReplicaSet的控制器控制pod,通过kubectl get rs可以查看ReplicaSet
回滚也称回退,即发现升级出现问题时,让应用回到老的版本,Deployment可以非常方便的回滚到老版本,Deployment之所以能够如此容易的做到回滚,是因为Deployment通过ReplicaSet控制pod的,升级后之前ReplicaSet都一直存在,Deployment回滚做的就是使用之前的ReplicaSet再次把pod创建出来,Deployment中保存ReplicaSet的数量可以使用revisionHistoryLimit参数限制,默认值是10.
Job和CronJob
Job和CronJob是负责批量处理短暂的一次性任务(short lived one-off tasks),即仅执行一次任务,它保证批处理任务的一个或多个pod成功结束
Job:是Kubernetes用来控制批处理型任务的资源对象,批处理业务与长期伺服业务(Deployment、Statefulset)的主要区别是批处理业务的运行有头有尾,而长期伺服业务在用户不停止的情况下永远运行。Job管理的pod根据用户的设置把任务成功完成就自动退出(pod自动删除)
CronJob:是基于时间的Job,类似于Linux的crontab文件中的一行,在指定的时间周期运行指定的Job
任务负载的这种用完即停止的特性特别适合一次性任务,比如持续集成
docker和containerd调用链区别
docker(Kubernetes 1.23及以下版本)
kubelet–>docker shim (在kubelet进程中)–>docker–>containerd
docker(Kubernetes 1.24及以上版本社区方案)
kubelet–>cri-dockerd(在kubelet使用cri接口对接cri-dockerd)–>docker–>containerd
containerd
kubelet–>cri plugin(在containerd进程中)–>containerd
其中docker虽增加了swarm cluster、docker build、docker API等功能,但也会引入一些bug,并且与containerd相比,多了一层调用,因此containerd被认为更加节省资源且安全
devops持续交付场景
开发者–>提交代码–代码库–>源码到镜像–>SWR–>CCE(测试环境、预发环境、生产环境)
云容器引擎与其他服务的关系图:
对象存储服务是一个基于对象的海量存储服务,为客户提供海量、安全、高可靠、低成本的数据存储能力,包括:创建、修改、删除桶,上传、下载、删除对象等。云容器引擎支持创建OBS对象存储卷并挂载到容器的某一路径下。-云容器引擎对接了AOM,AOM会采集容器日志存储中的“.log”等格式日志文件,转储到AOM中,方便您查看和检索;并且云容器引擎基于AOM进行资源监控,为您提供弹性伸缩能力。
区域(region):从地理位置和网络时延维度划分,同一个region内共享弹性计算、块存储、对象存储、VPC网络、弹性公网IP、镜像等公共服务。region分为通用region和专属region,通用region指面向公共租户提供通用云服务的region,专属region指只承载同一类业务或只面向特定租户提供业务服务的专用region;可用区(AZ—Available Zone):一个AZ是一个或多个物理数据中心的集合,有独立的风火水电,AZ内逻辑上再将计算、网络、存储等资源划分成多个集群。一个region中的多个AZ见通过高速光纤相连,以满足用户跨AZ构建高可用性系统的需求。
一般情况,若客户的应用需要较高的容灾能力,建议将资源部署在同一区域的不同可用区;(一般国内区域间的差别并不大,可暂不考虑时延问题) 三、容器网络 Kubernetes本身并不负责网络通信,但提供了容器网络接口CNI(Container Network Interface),具体的网络通信交由CNI插件来实现。开源的CNI插件非常多,像Flannel、Calico等。针对Kubernetes网络,CCE也定制了相应的CNI插件(Canal和Yangtse),用于负责集群内网络通信。
Kubernetes虽然不负责搭建网络模型,但要求集群网络满足以下要求:
Pod能够互相通信,且Pod必须通过非NAT网络连接,即收到的数据包的源IP就是发送数据包Pod的IP。节点之间可以在非NAT网络地址转换的情况下通信。 1、Pod通信 同一个节点中的Pod通信
Pod通过虚拟Ethernet接口对(Veth Pair)与外部通信,Veth Pair像一根网线,一端在Pod内部,一端在Pod外部。同一个节点上的Pod通过网桥(Linux Bridge)通信,如下图所示。
在同一节点上的Pod会通过Veth设备将一端连接到网桥,且它们的IP地址是通过网桥动态获取的,和网桥IP属于同一网段。此外,同一节点上的所有Pod默认路由都指向网桥,网桥会负责将所有非本地地址的流量进行转发。因此,同一节点上的Pod可以直接通信。
不同节点上的Pod通信
Kubernetes要求集群Pod的地址唯一,因此集群中的每个节点都会分配一个子网,以保证Pod的IP地址在整个集群内部不会重复。在不同节点上运行的Pod通过IP地址互相访问,该过程需要通过集群网络插件实现,按照底层依赖大致可分为Overlay模式、路由模式、Underlay模式三类。
Overlay模式是在节点网络基础上通过隧道封装构建的独立网络,拥有自己独立的IP地址空间、交换或者路由的实现。VXLAN协议是目前最流行的Overlay网络隧道协议之一。
我在将Vue和Pinia结合使用时发现在Axios请求结束后forEach并没有执行,后来发现是由于Axios请求还未结束forEach却先执行了,此时Axios请求还没有获取到任何数据,那么forEach将对一个空数组进行操作,但是forEach对于空数组是不会执行回调函数的,所以forEach完全没有执行。
解决方法是使用Promise.all().then() 修改前的代码 <script setup lang="ts"> import ... // getWebInfoList方法继承自Store,是一个发起异步请求获取数据的方法 // 这里不用理解这个方法具体是干什么的,当作任意异步请求就行 webInfo.getWebInfoList(); webInfo.webInfoList.forEach((item: any) => { console.log("forEach执行了") }) <script> 修改后的代码 <script setup lang="ts"> import ... // getWebInfoList方法继承自Store,是一个发起异步请求获取数据的方法 // 这里不用理解这个方法具体是干什么的,当作任意异步请求就行 webInfo.getWebInfoList().then(() => { Promise.all(webInfo.webInfoList).then(() => { webInfo.webInfoList.forEach((item: any) => { console.log("forEach执行了") }) }) }) <script>
一、直播原理 直播是一对多的完整的视频解编码原理:
那么直播的原理无疑也是要基于视频的解编码原理的
参考视频 二、直播CDN 什么是CDN就不多说了,可参考亚马逊的文章
三、相关协议 RTMP及HTTP-FLV(都是在FLV封装格式基础上的) RTMP:(Real-Time Messaging Protocol,实时消息传输协议)是一种用于实时数据传输的协议,最初由Adobe Systems开发。RTMP广泛应用于音视频直播领域一般用于直播流推流(也可以拉流)可基于TCP或者UDP,基于 TCP 的 RTMP 通常用于对数据完整性要求较高的场景,而基于 UDP 的 RTMFP 可以用于对实时性要求更高的场景。HTTP-FLV:HTTP-FLV 是一种通过 HTTP 协议传输的流媒体协议,主要用于实现实时的音视频传输`。它的名称中的 “FLV” 表示 Flash Video,因为它最初是为 Adobe Flash Player 设计的。 HTTP-FLV适配多个播放场景,一般如果是web端,引入bilibili开源的flv.js即可以播放HTTP-FLV直播流。
HLS协议(一般用于拉流观看) HLS(HTTP Live Streaming)是一种基于HTTP的流媒体传输协议,主要用于实现在互联网上通过 HTTP 协议传输音视频内容。HLS 最初由苹果公司推出,现在已经成为流媒体领域中应用广泛的标准之一。
HLS 的主要特点和工作原理包括:
分段传输: HLS 将整个流媒体内容切分为小的、独立的分段。每个分段通常持续几秒钟,这样就可以实现更好的灵活性和容错性。
HTTP传输: HLS 使用标准的 HTTP 协议进行数据传输。这使得它能够通过大多数网络设备和防火墙,降低了部署的难度。
自适应码率: HLS 支持自适应码率(Adaptive Bitrate
Streaming,ABR),可以根据观众的网络条件和设备性能,动态调整传输的码率,以提供更好的观看体验。
播放器兼容性: 由于 HLS 基于 HTTP,因此可以在支持 HTML5 视频的大多数现代浏览器上播放。同时,许多流媒体播放器也支持 HLS。
多平台支持: HLS 不仅在苹果设备上得到广泛支持,而且也可以在 Android 设备和其他流行的平台上播放。
WebRTC(点对点的视频/语音通话协议) WebRTC(Web Real-Time Communication)是谷歌开源的一种基于UDP用于在Web浏览器之间实现实时通信的开放标准和协议。它提供了一组用于音频、视频和数据通信的API,使得开发者能够构建实时的、点对点的Web应用程序,无需插件或其他第三方软件的支持。
测试AES加密参数时报出的错,对比参数,发现接口收到的请求参数少了个+号。这是因为+号在URL中是一个特殊字符,所以传递时可能会丢失。
处理方案
使用param.replaceAll(" ", "+")统一替换空格为+号。前端传递参数时,将客户端带“+”的参数中的“+”全部替换为“2B%”。换请求方式为POST。加密为16进制,不要有字母和+号这些。 以上4种方案,就感觉用第4种最合适,因为使用post方式接收String参数,测试下来还是会丢失+号,第4个方案则因为参数是对接系统传的,也没办法让改,只能先采用1方案暂时满足需求了。
测试AES加解密的时候出的错,问题在于使用的秘钥有问题,找个工具如hutool生成正常的秘钥即可。
到了年底,今年不管经济如何,形势多么不好,这个月也要结束2023年了,在这个阶段最关键的是做好今年的总结以及明年的计划。
总结是为了更好地做明年的计划和形势的预判。
借用数据表作为工具,科学理性地对自身公司的经营范围、产品定向做一个完整的分析。
一、SPAN分析表
对自身产品做一个市场吸引力分析
然后再对产品竞争力做分析
最后会得出SPAN矩阵
这个矩阵就会非常有意思了,假如分布是这样的
说明在数据表分析面前
将公司的产品(业务)划分为四个种类,给它们各自的定位。
二、客户分类评价表
至于客户分类评价表就更加简单了,每个公司,每个人都要从中去挑选所关联的重点几个客户
根据销售额、利润率等来做评分,这些客户可以是一个行业的客户,也可以是明确的某个客户
最终会通过得分来判定哪些才是明年的重要客户,哪些是战略客户,也要狠心地放弃掉某些占用着时间又没法带来产出的客户,适当地做一些取舍。
三、销售目标分解与行动计划
相信大部分公司,都会做明年的销售预算表
这部分也会随着明年的每个月要做相应的增加和删减,不断去制定下一个月,下一个季度的销售目标。
四、SWOT分析及经营项目一览表
最后一个SWOT表就非常有意思了
从企业的内部和外部结合来做分析
从优势、劣势、机会、威胁四个维度来分析明年要做怎样的战略调整。
这些表格资料也整理起来希望能给到有需要的人:https://download.csdn.net/download/Highning0007/88636332
文章目录 1、ZooKeeper是什么2、应用场景(1)维护配置信息(2)集群管理&注册中心(3)分布式锁(4)生成分布式唯一ID 3、数据模型4、Zookeeper使用 1、ZooKeeper是什么 zooKeeper致力于为分布式应用提供一个高性能、高可用,且具有严格顺序访问控制能力的分布式协调服务。
1、高性能
zooKeeper将全量数据存储在内存中,并直接服务于客户端的所有非事务请求,尤其适用于以读为主的应用场景。
2、高可用
zooKeeper一般以集群的方式对外提供服务,一般3 ~ 5台机器就可以组成一个可用的zookeeper集群了,每台机器都会在内存中维护当前的服务器状态,并且每台机器之间都相互保持着通信。只要集群中超过一半的机器都能够正常工作,那么整个集群就能够正常对外服务。
3、严格顺序访问
对于来自客户端的每个更新请求,ZooKeeper都会分配一个全局唯一的递增编号,这个编号反映了所有事务操作的先后顺序。
2、应用场景 ZooKeeper是一个经典的分布式数据一致性解决方案,致力于为分布式应用提供一个高性能、高可用,且具有严格顺序访问控制能力的分布式协调存储服务。
注册中心、配置中心、集群管理、分布式锁、生成分布式唯一ID
(1)维护配置信息 zooKeeper、config、nacos都可以当做配置中心使用。分布式兴起,许多服务使用相同的配置文件,如果配置文件发送变化,运维上需要逐个修改服务的配置文件,非常繁琐。通常会将配置文件部署在一个集群上,提供服务,高效快速且可靠地完成配置项的更改等操作,并能够保证各配置项在每台服务器上的数据一致性。
zookeeper就可以提供这样一种服务,其使用Zab这种一致性协议来保证一致性。现在有很多开源项目使用zookeeper来维护配置,比如在hbase中,客户端就是连接 一个zookeeper,获得必要的hbase集群的配置信息,然后才可以进一步操作。还有在开源的消息队列kafka中,也使用zookeeper来维护broker的信息。在alibaba开源的soa框架dubbo中也广泛的使用zookeeper管理一些配置来实现服务治理。
(2)集群管理&注册中心 一个集群有时会因为各种软硬件故障或者网络故障,出现某些服务器挂掉而被移除集群,而某些服务器加入到集群中的情况,zookeeper会将这些服务器加入/移出的情况 通知给集群中的其他正常工作的服务器,以及及时调整存储和计算等任务的分配和执行等。此外zookeeper还会对故障的服务器做出诊断并尝试修复。
(3)分布式锁 多台服务器上运行着同一种服务,要协调各服务的进度,有时候需要保证当某个服务在进行某个操作时,其他的服务都不能进行该操作,即对该操作进行加锁,如果当前机器挂掉后,释放锁并fail over 到其他的机器继续执行该服务。
(4)生成分布式唯一ID 单库单表型系统中,通常可以使用数据库字段自带的auto_increment属性来自动为每条记录生成一个唯一的ID。但是分库分表后,就无法在依靠数据库的 auto_increment属性来唯一标识一条记录了。此时我们就可以用zookeeper在分布式环境下生成全局唯一ID。做法如下:每次要生成一个新Id时,创建一个持久顺序节点,创建操作返回的节点序号,即为新Id,然后把比自己节点小的删除即可。
3、数据模型 zookeeper的数据节点可以视为树状结构(或者目录),树中的各节点被称为znode(即zookeeper node),类似Linux的文件系统,一个znode可以有多个子节点。zookeeper节点在结构上表现为树状;使用路径path来定位某个znode,比如/ns-1/itcast/mysql/schema1/table1,此处ns-1、itcast、mysql、schema1、table1分别是根节点、2级节点、3级节点以及4级节点;其中ns-1是itcast的父节点,itcast是ns-1的子节点,itcast是mysql的父节点,mysql是itcast的子节点,以此类推。
znode,兼具文件和目录两种特点。既像文件一样维护着数据、元信息、ACL、时间戳等数据结构,又像目录一样可以作为路径标识的一部分。
节点类型:
zookeeper中的节点有两种,分别为临时节点和永久节点。节点的类型在创建时即被确定,并且不能改变。
临时节点:该节点的生命周期依赖于创建它们的会话。一旦会话(Session)结束,临时节点将被自动删除,当然也可以手动删除。虽然每个临时的Znode都会绑定到一个客户端会话,但他们对所有的客户端还是可见的。另外,ZooKeeper的临时节点不允许拥有子节点。
持久化节点:该节点的生命周期不依赖于会话,并且只有在客户端显示执行删除操作的时候,他们才能被删除。
4、Zookeeper使用 参考链接:https://blog.csdn.net/java_66666/article/details/81015302?
Docker 是一种以容器为基础的虚拟化技术,它可以将应用程序和其依赖的运行环境打包在一个容器中,使其能够在任何地方以相同的方式运行。以下是 Docker 的基本概念和优势,以及在应用程序开发中的实际应用。
基本概念:
1. 镜像(Image):Docker 镜像是一个只读的模板,包含了运行应用程序所需的所有文件、代码和依赖。镜像可以通过 Dockerfile 定义和构建。
2. 容器(Container):Docker 容器是由镜像创建的可运行的实例。容器包含了应用程序、其依赖和运行时环境。容器可以被启动、停止、删除和移动。
3. 仓库(Repository):Docker 仓库是用来存放和分享镜像的地方。可以从仓库中获取镜像,并将自己的镜像上传到仓库中。
优势:
1. 简化配置和部署:Docker 可以将应用程序及其依赖的环境封装在一个容器中,消除了在不同环境中配置和部署的痛点。
2. 轻量级和快速:Docker 容器与传统虚拟机相比,启动和停止速度更快,并且占用更少的系统资源。
3. 可移植性和一致性:Docker 容器在任何地方都可以以相同的方式运行,无论是在开发环境、测试环境还是生产环境。
4. 可伸缩性:可以通过创建多个容器来水平扩展应用程序,以满足不同的负载需求。
实际应用:
1. 开发环境一致性:开发人员可以使用 Docker 来创建包含应用程序和其依赖的容器,确保在不同开发环境中应用程序的一致性。
2. 持续集成和持续部署:Docker 可以与持续集成和持续部署工具集成,实现自动化的构建、测试和部署过程。
3. 云原生应用开发:Docker 是云原生应用开发的重要组成部分,可以使用 Docker 容器来构建和运行云原生应用。
总结而言,Docker 通过提供简化的配置和部署方式、轻量级和快速的容器、可移植性和一致性以及可伸缩性等优势,成为了应用程序开发中的重要工具。
1. 元字符 * 匹配任意多个字符 ls in* rm -rf *.pdf find / -name "*-eth0" ? 匹配任意一个字符 touch love loove live l?ve [] 匹配括号中任意一个字符 [abc] [0-9] [a-zA-Z0-9] [^a-zA-Z0-9] () 在子shell 中执行 (cd /boot;ls) {} 集合 touch file{1.9} # 表示 1-9 \ 转义字符 echo \* # 让元字符 回归本意 2. 颜色输出 #!/bin/bash YELLOW='\e[33m' BLUE='\e[44m' NC='\e[0m' # 重置样式 echo -e "${YELLOW}${BLUE}这段文字将显示为黄色文字和蓝色背景${NC}"
1.重定向 1.1 输出重定向 > :标准输出重定向到指定文件,如果文件不存在则创建,文件创建则覆盖 >>: 标准输出追加到指定到文件末尾,文件不存在则创建 示例: ls >file.txt # 将ls 命令输出保存到 file.txt文件中 1.2 输入重定向 <: 命令的标准输入重定向自指定的文件 示例:sort <file.txt # 从file.txt 文件中读取内容,并进行排序 1.3 错误重定向 2>: 将命令的错误输出重定向到指定的文件 2>>: 将命令的错误输出追加到指定的文件末尾 示例: command 2> error.txt # 将命令的错误输出保存到 error.txt 文件中 1.4 合并输出和错误 &>: 标准输出 和错误 都重定向到指定的文件 &>>: 将命令的标准输出和错误都追加到指定的文件末尾 示例:command &> output.txt # 将 command 命令的输出(包括标准输出和错误输出) 保存到 output.txt 文件中 2. tee 用于同时将命令输出到显示屏幕上并写入文件。 # 将command 命令传递给 tee 显示在屏幕上 并写入文件 command | tee file.txt # 并且追加到 文件 并不是覆盖 command | tee -a file.
目录 1.初识MQ1.1.同步调用1.2.异步调用1.3.技术选型 2.RabbitMQ2.1.安装2.2.收发消息2.2.1.交换机2.2.2.队列2.2.3.绑定关系2.2.4.发送消息 2.3.数据隔离2.3.1.用户管理2.3.2.virtual host 1.初识MQ 1.1.同步调用 之前说过,我们现在基于OpenFeign的调用都属于是同步调用,那么这种方式存在哪些问题呢?
举个例子,我们以昨天留给大家作为作业的余额支付功能为例来分析,首先看下整个流程:
目前我们采用的是基于OpenFeign的同步调用,也就是说业务执行流程是这样的:
支付服务需要先调用用户服务完成余额扣减然后支付服务自己要更新支付流水单的状态然后支付服务调用交易服务,更新业务订单状态为已支付 三个步骤依次执行。
这其中就存在3个问题:
第一,拓展性差
我们目前的业务相对简单,但是随着业务规模扩大,产品的功能也在不断完善。
在大多数电商业务中,用户支付成功后都会以短信或者其它方式通知用户,告知支付成功。假如后期产品经理提出这样新的需求,你怎么办?是不是要在上述业务中再加入通知用户的业务?
某些电商项目中,还会有积分或金币的概念。假如产品经理提出需求,用户支付成功后,给用户以积分奖励或者返还金币,你怎么办?是不是要在上述业务中再加入积分业务、返还金币业务?
。。。
最终你的支付业务会越来越臃肿:
也就是说每次有新的需求,现有支付逻辑都要跟着变化,代码经常变动,不符合开闭原则,拓展性不好。
第二,性能下降
由于我们采用了同步调用,调用者需要等待服务提供者执行完返回结果后,才能继续向下执行,也就是说每次远程调用,调用者都是阻塞等待状态。最终整个业务的响应时长就是每次远程调用的执行时长之和:
假如每个微服务的执行时长都是50ms,则最终整个业务的耗时可能高达300ms,性能太差了。
第三,级联失败
由于我们是基于OpenFeign调用交易服务、通知服务。当交易服务、通知服务出现故障时,整个事务都会回滚,交易失败。
这其实就是同步调用的级联失败问题。
但是大家思考一下,我们假设用户余额充足,扣款已经成功,此时我们应该确保支付流水单更新为已支付,确保交易成功。毕竟收到手里的钱没道理再退回去吧。
因此,这里不能因为短信通知、更新订单状态失败而回滚整个事务。
综上,同步调用的方式存在下列问题:
拓展性差性能下降级联失败 而要解决这些问题,我们就必须用异步调用的方式来代替同步调用。
1.2.异步调用 异步调用方式其实就是基于消息通知的方式,一般包含三个角色:
消息发送者:投递消息的人,就是原来的调用方消息Broker:管理、暂存、转发消息,你可以把它理解成微信服务器消息接收者:接收和处理消息的人,就是原来的服务提供方 在异步调用中,发送者不再直接同步调用接收者的业务接口,而是发送一条消息投递给消息Broker。然后接收者根据自己的需求从消息Broker那里订阅消息。每当发送方发送消息后,接受者都能获取消息并处理。
这样,发送消息的人和接收消息的人就完全解耦了。
还是以余额支付业务为例:
除了扣减余额、更新支付流水单状态以外,其它调用逻辑全部取消。而是改为发送一条消息到Broker。而相关的微服务都可以订阅消息通知,一旦消息到达Broker,则会分发给每一个订阅了的微服务,处理各自的业务。
假如产品经理提出了新的需求,比如要在支付成功后更新用户积分。支付代码完全不用变更,而仅仅是让积分服务也订阅消息即可:
不管后期增加了多少消息订阅者,作为支付服务来讲,执行问扣减余额、更新支付流水状态后,发送消息即可。业务耗时仅仅是这三部分业务耗时,仅仅100ms,大大提高了业务性能。
另外,不管是交易服务、通知服务,还是积分服务,他们的业务与支付关联度低。现在采用了异步调用,解除了耦合,他们即便执行过程中出现了故障,也不会影响到支付服务。
综上,异步调用的优势包括:
耦合度更低性能更好业务拓展性强故障隔离,避免级联失败 当然,异步通信也并非完美无缺,它存在下列缺点:
完全依赖于Broker的可靠性、安全性和性能架构复杂,后期维护和调试麻烦 1.3.技术选型 消息Broker,目前常见的实现方案就是消息队列(MessageQueue),简称为MQ.
目比较常见的MQ实现:
ActiveMQRabbitMQRocketMQKafka 几种常见MQ的对比:
RabbitMQActiveMQRocketMQKafka公司/社区RabbitApache阿里Apache开发语言ErlangJavaJavaScala&Java协议支持AMQP,XMPP,SMTP,STOMPOpenWire,STOMP,REST,XMPP,AMQP自定义协议自定义协议可用性高一般高高单机吞吐量一般差高非常高消息延迟微秒级毫秒级毫秒级毫秒以内消息可靠性高一般高一般 追求可用性:Kafka、 RocketMQ 、RabbitMQ
追求可靠性:RabbitMQ、RocketMQ
追求吞吐能力:RocketMQ、Kafka
追求消息低延迟:RabbitMQ、Kafka
据统计,目前国内消息队列使用最多的还是RabbitMQ,再加上其各方面都比较均衡,稳定性也好,因此我们课堂上选择RabbitMQ来学习。
2.RabbitMQ RabbitMQ是基于Erlang语言开发的开源消息通信中间件,官网地址:
Messaging that just works — RabbitMQ
接下来,我们就学习它的基本概念和基础用法。
2.1.安装 我们同样基于Docker来安装RabbitMQ,使用下面的命令即可:
Android WindowManagerService架构分析 WindowManagerService(以下简称WMS) 是Android的核心服务。WMS管理所有应用程序窗口(Window)的Create、Display、Update、Destory。
因为Android系统中只有一个WMS(运行在SystemServer进程),可以称其为全局的WMS。其主要的任务有两个:
全局的窗口管理
应用程序的显示(在屏幕上看到应用)在WMS的协助下有序、有层次的输出给底层服务,最终显示到物理屏幕上。
全局的事件管理派发
WMS为Android输入系统(InputManagerService)提供窗口相关信息,让输入事件(比如touch、homekey等等)可派发给适合的应用(窗口)。
触摸屏:主流Android设备都使用了出触控屏,支持手势触控、多指触控。
鼠标:android系统加入鼠标,通过光标触发相应动作。
硬按键:Home、back、menu等等功能按键。
WMS的客户端WindowManager WindowManager是WMS提供给使用者的API。Manager的命名方式遵循了Android通过的Service/Client框架的命名方法,即
Service端:XXXService
客户端API:XXXManager
WindowManager封装了WMS提供的AIDL对象,主要包括:
IWindowManager.aidl:官方注释为**“System private interface to the window manager.”**,定义了WMS服务提供的能力接口。 //frameworks/base/core/java/android/view/IWindowManager.aidl /* ** Copyright 2006, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.
一.bin
先从bin文件夹开始:
vue.js
#!/usr/bin/env node // 主入口 const program = require('commander') // 对应指令 & 具体文件 program .version(require('../package').version) .usage('<command> [options]') .command('init', 'generate a new project from a template') .command('list', 'list available official templates') .command('build', 'prototype a new project') .command('create', '(for v3 warning only)') program.parse(process.argv) vue-build
#!/usr/bin/env node // 高亮工具 const chalk = require('chalk') console.log(chalk.yellow( '\n' + ' We are slimming down vue-cli to optimize the initial installation by ' + 'removing the `vue build` command.
1、信号机制 1.1 信号机制介绍 大白话来说,类似于两方属于敌对关系时,某人在敌对方阵营进行交谈,一旦遇到特殊情况,某人便会发送信号,他的同伙接收(监听)到他发的信号后,同伙便会做出一系列的应对策略(进攻|撤
退)。
1.2 第三方库安装 flask中的信号使用的是一个第三方插件,叫做blinker。通过pip list看一下,如果没有安装,通过以下命令即可安装blinker。
pip install blinker 1.3 自定义信号步骤 自定义信号可分为3步来完成。
第一是创建一个信号,第二是监听一个信号,第三是发送一个信号。
以下将对这三步进行讲解:
创建信号:定义信号需要使用到blinker这个包的Namespace类来创建一个命名空间。比如定义一个在访问了某个视图函数的时候的信号。
# Namespace的作用:为了防止多人开发的时候,信号名字冲突的问题 from blinker import Namespace mysignal = Namespace() signal1 = mysignal.signal('信号名称') 监听信号:监听信号使用signal1对象的connect方法,在这个方法中需要传递一个函数,用来监听到这个信号后做该做的事情。
def func1(sender,uname): print(sender) print(uname) signal1.connect(func1) 发送信号:发送信号使用signal1对象的send方法,这个方法可以传递一些其他参数过去。
signal1.send(uname='momo') 示例代码:
from flask import Flask from blinker import Namespace app = Flask(__name__) # 信号机制 3步走 # 1.定义信号 signal_space = Namespace() signal_name = signal_space.signal('访问首页') # 2.监听信号 def main_func(sender): print(sender) print('start main_func') signal_name.connect(main_func) # # 3.
其它相关内容可见:个人主页 2. Forge: Forge是Foundry附带的命令行工具,用来测试、构建和部署智能合约
forge test 运行测试用例,所有测试都是Solidity编写
Forge将从源目录的任何位置查找测试,任何具有以test开头的函数的合约都被认为是一个测试。
通常测试放在src/test中
通过传递过滤器运行特定测试:
forge test --match-contract ComplicatedContractTest --match-test testDeposit 这将在名称中带有 testDeposit 的 ComplicatedContractTest 测试合约中运行测试。
2.1 编写测试: 测试代码是用Solidity编写的,最常见的测试编写是通过Forge ****标准库的Test合约实现。
使用Forge标准库,会利用到DSTest合约,其提供基本的日志记录和断言功能
导入forge-std/Test.sol 并继承自测试合约Test
import "forge-std/Test.sol"; 一个测试案例:
pragma solidity 0.8.10; import "forge-std/Test.sol"; contract ContractBTest is Test { uint256 testNumber; function setUp() public { testNumber = 42; } function testNumberIs42() public { assertEq(testNumber, 42); } function testFailSubtract43() public { testNumber -= 43; } } setUp() :在每个测试用例运行之前调用的可选函数test() :以test 为前缀的函数作为测试用例执行testFail() :test 的相反情况,如果函数没有报错revert,那么测试失败 测试函数必须具有external 或public ,否则测试函数将无效
基于胡寿松主编的《自动控制原理》(第七版)附录的 M A T L A B {\rm MATLAB} MATLAB控制系统简单教程,快速了解 M A T L A B {\rm MATLAB} MATLAB在控制理论的应用,下载链接: MATLAB辅助分析与设计方法基础.
5.控制系统的校正 【实例分析 1 1 1:串联校正】
E x a m p l e B − 5 {\rm ExampleB-5} ExampleB−5: 设单位负反馈系统的开环传递函数为:
G ( s ) = K s ( s + 1 ) G(s)=\frac{K}{s(s+1)} G(s)=s(s+1)K
若要求系统在单位斜坡输入信号作用时,位置输出稳态误差 e s s ( ∞ ) ≤ 0.1 r a d e_{ss}(\infty)≤0.1{\rm rad} ess(∞)≤0.1rad,开环系统截止频率 ω c ′ ′ ≥ 4.
大模型:常见的文字表情包(可以直接加到微调数据里) 返回论文目录
返回资料目录
表情符号含义😊愉快、微笑😂大笑😍爱心眼😎酷、自信🤔思考、疑惑😜调皮、顽皮🙌鼓掌、庆祝🎉庆祝、喜庆🥳欢呼、狂欢😇天使、善良😏傲慢、得意🤗拥抱、亲切🤩令人赞叹、兴奋🥺哀怨、可爱😕困惑、犹豫😬尴尬、不安😭哭泣、伤心😴睡着、困倦🤢恶心、不适🤯惊讶、震惊😌安心、满足😅尴尬的笑😃开心、快乐😳尴尬、羞涩😖不悦、生气🤓书呆子、聪明🙄眼珠翻白、无奈😒不满、不耐烦😣烦躁、苦恼😶沉默、无言🤑财迷、眼睛发财😷口罩、生病😕困惑、疑惑😟担忧、焦虑😈恶魔、调皮👻幽灵、鬼魂🤠牛仔、放荡不羁🤖机器人、冷漠🤕生病、受伤😸猫咪、调皮🙈眼睛蒙住、害羞🤔思考、疑虑😻爱猫人士、喜悦🤠牛仔、放荡不羁🤗拥抱、亲切🥶冷、冷漠🤤流口水、馋🥴醉、头晕🥳庆祝、狂欢🧐专注、好奇🤓书呆子、聪明🥱打哈欠、困倦😵头晕目眩、震惊🤪疯狂、开心😨害怕、恐惧😧担忧、不安😮吃惊、惊讶🤫保密、安静🤭笑而不语、害羞🎉庆祝、喜庆🥳欢呼、狂欢😇天使、善良🚀着火、飞行🔍搜索、发现🎓学业、学术📈增长、上升🔗链接、关联🌈彩虹、多彩🎨艺术、创意🍀幸运、好运🌟辉煌、闪耀🤗拥抱、亲密🎶音乐、欢乐🌍地球、全球📚书籍、知识💡灵感、启示🌺花朵、美好
Visual Studio 下载:https://visualstudio.microsoft.com/zh-hans/downloads/
鸡啄米 ----- VS2010/MFC编程入门教程之目录和总结:VS2010/MFC编程入门教程之目录和总结-软件开发-鸡啄米
一、VS2010/MFC编程入门教程之目录
第一部分:VS2010/MFC开发环境
VS2010/MFC编程入门之前言
VS2010/MFC编程入门之一(VS2010与MSDN安装过程图解)
第二部分:VS2010/MFC应用程序框架
VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)
VS2010/MFC编程入门之三(VS2010应用程序工程中文件的组成结构)
VS2010/MFC编程入门之四(MFC应用程序框架分析)
VS2010/MFC编程入门之五(MFC消息映射机制概述)
第三部分:对话框
VS2010/MFC编程入门之六(对话框:创建对话框模板和修改对话框属性)
VS2010/MFC编程入门之七(对话框:为对话框添加控件)
VS2010/MFC编程入门之八(对话框:创建对话框类和添加控件变量)
VS2010/MFC编程入门之九(对话框:为控件添加消息处理函数)
VS2010/MFC编程入门之十(对话框:设置对话框控件的Tab顺序)
VS2010/MFC编程入门之十一(对话框:模态对话框及其弹出过程)
VS2010/MFC编程入门之十二(对话框:非模态对话框的创建及显示)
VS2010/MFC编程入门之十三(对话框:属性页对话框及相关类的介绍)
VS2010/MFC编程入门之十四(对话框:向导对话框的创建及显示)
VS2010/MFC编程入门之十五(对话框:一般属性页对话框的创建及显示)
VS2010/MFC编程入门之十六(对话框:消息对话框)
VS2010/MFC编程入门之十七(对话框:文件对话框)
VS2010/MFC编程入门之十八(对话框:字体对话框)
VS2010/MFC编程入门之十九(对话框:颜色对话框)
第四部分:常用控件
VS2010/MFC编程入门之二十(常用控件:静态文本框)
VS2010/MFC编程入门之二十一(常用控件:编辑框Edit Control)
VS2010/MFC编程入门之二十二(常用控件:按钮控件Button、Radio Button和Check Box)
VS2010/MFC编程入门之二十三(常用控件:按钮控件的编程实例)
VS2010/MFC编程入门之二十四(常用控件:列表框控件ListBox)
VS2010/MFC编程入门之二十五(常用控件:组合框控件Combo Box)
VS2010/MFC编程入门之二十六(常用控件:滚动条控件Scroll Bar)
VS2010/MFC编程入门之二十七(常用控件:图片控件Picture Control)
VS2010/MFC编程入门之二十八(常用控件:列表视图控件List Control 上)
VS2010/MFC编程入门之二十九(常用控件:列表视图控件List Control 下)
VS2010/MFC编程入门之三十(常用控件:树形控件Tree Control 上)
VS2010/MFC编程入门之三十一(常用控件:树形控件Tree Control 下)
VS2010/MFC编程入门之三十二(常用控件:标签控件Tab Control 上)
VS2010/MFC编程入门之三十三(常用控件:标签控件Tab Control 下)
第五部分:菜单、工具栏与状态栏
VS2010/MFC编程入门之三十四(菜单:VS2010菜单资源详解)
VS2010/MFC编程入门之三十五(菜单:菜单及CMenu类的使用)
VS2010/MFC编程入门之三十六(工具栏:工具栏资源及CToolBar类)
VS2010/MFC编程入门之三十七(工具栏:工具栏的创建、停靠与使用)
VS2010/MFC编程入门之三十八(状态栏的使用详解)
傅里叶变换 系数表示法与点值表示法 f ( x ) = a 0 ∗ x 0 + a 1 ∗ x 1 + a 2 ∗ x 2 + a 3 ∗ x 3 + . . . + a n ∗ x n f(x) = a_0 * x ^ 0 + a_1 * x^1 + a_2 * x^2 + a_3 * x^3+...+a_n * x ^ n f(x)=a0∗x0+a1∗x1+a2∗x2+a3∗x3+...+an∗xn
系数表示法:
( a 0 , a 1 , a 2 , a 3 , a 4 , .
k8s简介 编排工具分类 系统层面 ansible、saltstack
docker容器 docker compose + docker swarm + docker machine docker compose:实现单机容器编排
docker swarm:实现多主机整合成为一个
docker machine:初始化新主机
mesos + marathon mesos IDC的操作系统,Apache研发的资源分配工具 kubernetes 开发模式和架构 开发模式 瀑布式开发→迭代开发→敏捷开发→DevOps
应用程序的架构 单体架构→分层架构→微服务 DevOps 过程:
需求→开发→测试→交付→部署
应用模式的开发把开发与运维整合起来,打破了两者直接的壁垒。
CI(持续集成):
开发完合并代码到代码仓库然后自动构建部署测试,有问题打回给开发,无问题自动交付给运维方
CD(持续交付):
测试完之后自动打包好最终产品,并存放到可以被运维或客户拿到的地方
CD(持续部署):
交付完后自动拖出开发包并自动部署,运行时出现的bug自动反馈给开发
常见部署方案
容器化部署优势:
早期交付与部署环节因为各种不同系统不同版本的环境因素使其极其的困难,而容器的实现可以使其得以非常容易实现,可以真正的一次编写多次部署
微服务:
把每一个应用都拆解成一个微小的服务,只做一个功能,例如把一个单体应用程序拆解为数百个微服务,让其彼此间进行协作
缺点:
分发部署以及微服务互相之间的调用关系变得极其复杂,并且数以百计微服务难免其中的某些微服务会出现很问题,而单靠人工梳理和解决并不现实,容器与编排工具可以完美解决这些问题
解决方案:
正是容器和编排工具的出现使得微服务和DevOps得以容易落地
kubernetes的特性 自动装箱
自我修复
水平扩展
服务发现和负载均衡
自动发布和回滚
密钥和配置管理
批量处理执行
K8S组成与架构 K8S组成架构 整个kubernetes由master、node、组件、附件组成
kubernetes是一个有中心节点架构的集群系统master/node,一般会有一个或一组(三个master)节点作为主节点来做高可用,各node节点是用来贡献计算能力、存储能等相关资源(运行容器)的节点
master四个核心组件(运行为三个守护进程): API Server: 负责对外提供服务解析请求,并且需要存储整个集群中的个对象的状态信息,向客户端提供服务时使用https协议需要CA与证书
scheduler(调度器): 负责观测每个node之上的资源,并根据用户请求要创建容器所需要的资源量找到符合条件的node,然后根据调度算法中的最优算法选择最优node 控制器管理器: 负责监控并确保每一个控制器的健康,并且在多个master之上做控制器管理器的冗余
PowerBI自带的数据钻取功能,在实际应用中是用户使用度较高的功能之一,特别是需要实际操作的业务用户,往往需要根据汇总的结果定位到相关的明细数据,以便进行下一步的流程操作,这种场景下钻取功能显得尤为便利。
关于钻取功能,白茶之前也介绍过,包括云端的跨页钻取,本期是结合特定的场景进行实际应用的介绍,偏向于业务会多一些。
先来看看本期的案例数据:
数据较为简单,一张事实表。将其导入到PowerBI里面。
案例数据与以往的不同,偏向于商机类型的数据,一般数据来源于SalesForce结构会与此类似,SAP系统中关于销售订单类型的数据,也符合本期的应用场景。
商机数据的划分,前几个阶段都属于未关单数据,最后的Loseing和Win都属于已关单数据。业务用户往往会关注未关单的数据进展如何,是否需要提供额外的支持,已关单的数据其中丢单的原因是什么等等。
而销售订单数据,会划分为已发货/未发货,部分发货/全部发货,已发货确收/已发货未确收等,业务形态与商机数据区别很大,但是在BI上需要的功能点,基本雷同。
编写如下基础度量值:
001.OppAmt = SUM ( Fact_Opportunity[Amount] ) 根据上面的业务形态,不难发现,其实用户想要的,就是动态度量值的切换,我们实现的办法有两种。
①新建维度表,通过逻辑关系关联度量值。
新建如下度量值:
未关单数据:
002.NoEndOppCount = CALCULATE ( [001.OppAmt], FILTER ( 'Fact_Opportunity', 'Fact_Opportunity'[Status] IN { "1", "2", "3", "4" } ) ) 已关单数据:
003.EndOppCount = CALCULATE ( [001.OppAmt], FILTER ( 'Fact_Opportunity', NOT 'Fact_Opportunity'[Status] IN { "1", "2", "3", "4" } ) ) 动态度量值:
004.SelectValue = VAR SelectValue = SELECTEDVALUE ( 'Dim_Select'[Index] ) VAR Result = SWITCH ( TRUE (), SelectValue = 1, [002.
微信小程序 - 龙骨图集拆分 注意目录结构演示动画废话一下业务逻辑注意点龙骨JSON图集结构 源码分享dragonbones-split.jsdragonbones-split.jsondragonbones-split.wxmldragonbones-split.wxssimgUtil.js 参考资料 注意 只支持了JSON版本
目录结构 演示动画 Spine播放器1.5.0_PC端
Spine播放器1.5.1_移动端
废话一下 这是 SpinePlayer 2D骨骼动画播放器 - 微信小程序版 工具箱中的一个功能。
功能很简单,80% 的代码都在处理交互逻辑,以及移动端PC端兼容方面的问题。
业务逻辑 读取JSON文件和PNG图片。解析JSON得到所有小图在图集(PNG图片)中的 x,y 坐标和高宽。将PNG图集绘制到2d画布,然后使用 canvasToTempFilePath 逐个截取区域,保存为小图。最后将所有小图打包为 zip 供用户保存即可。 注意点 为了保证截取图片的清晰度,画布尺寸需要用图片大小乘以设备像素比。图片填充完整,再截图。否则会空白。所以会成两步操作比较稳妥。当然也可以自己控制延时自动调用,一气呵成。因为 2d 画布不便于直接显示,所以使用一个 image 组件来实现预览。
3.1. 方法是将 PNG 读取为 base64 赋给 image 组件 <image src="{{textureBase64}}" />
3.2. 读取 PNG 为 base64 就这句 fs.readFileSync(‘临时图片路径’, 'base64') 当然用的时候还要拼接一下头,详情看源码吧。 龙骨JSON图集结构 可以看出结构非常简单,直接读 SubTexture 数组,遍历它进行截取就可以了。
{ "imagePath": "body_tex.png", "width": 1024, "SubTexture": [ { "height": 472, "
参考文档:https://mysql.net.cn/doc/refman/8.0/en/mysql-upgrade.html
mysql5.7包: mysql-5.7.25-linux-glibc2.12-x86_64 <<<glibc2.12
mysql8包: mysql-8.0.35-linux-glibc2.28-x86_64.tar.xz <<< glibc2.28 ,这个包,需要升级gcc,最终没有使用这个包
mysql8包:mysql-8.0.35-linux-glibc2.12-x86_64.tar.xz <<< 最终使用这个包 -- 创建mysql5.7的文件夹
[mysql@19ctest mysql]$ mkdir -p mysql_upgrade_test/mysql7000 [mysql@19ctest mysql]$ cd mysql_upgrade_test/mysql7000 [mysql@19ctest mysql_upgrade_test]$ pwd /mysql/mysql_upgrade_test/mysql7000 [mysql@19ctest mysql_upgrade_test]$ --安装mysql5.7,copy安装文件到指定的目录
[mysql@19ctest mysql-5.7.25-linux-glibc2.12-x86_64]$ cp -r * /mysql/mysql_upgrade_test/mysql7000/ [mysql@19ctest mysql-5.7.25-linux-glibc2.12-x86_64]$ -- 编辑my7000.cnf文件
vi /mysql/mysql_upgrade_test/mysql7000/my7000.cnf [mysqld] datadir=/mysql/mysql_upgrade_test/mysql7000/data socket=/mysql/mysql_upgrade_test/mysql7000/mysql7000.sock port=7000 basedir=/mysql/mysql_upgrade_test/mysql7000 server-id=7000 lc-messages-dir=/mysql/mysql_upgrade_test/mysql7000/share/english [client] port=7000 socket=/mysql/mysql_upgrade_test/mysql7000/mysql7000.sock [mysql] prompt="\u@db \R:\m:\s [\d]> " -- 进行初始化mysql5.7 .会生成初始化的密码 cd /mysql/mysql_upgrade_test/mysql7000/bin ./mysqld --defaults-file=/mysql/mysql_upgrade_test/mysql7000/my7000.cnf --initialize --user=mysql [mysql@19ctest bin]$ ./mysqld --defaults-file=/mysql/mysql_upgrade_test/mysql7000/my7000.
项目运行
环境配置:
Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。
项目技术:
JSP + mybatis + Maven +mysql5.7或8.0等等组成,B/S模式 + Maven管理等等。
环境需要
1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。
2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;
3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可
4.硬件环境:windows 7/8/10 4G内存以上;或者 Mac OS;
5.是否Maven项目: 否;查看源码目录中是否包含pom.xml;若包含,则为maven项目,否则为非maven项目
6.数据库:MySql 5.7/8.0等版本均可;
毕设帮助,指导,本源码分享,调试部署(见文末) 3.2 系统需求分析 需求的分析中用户需求就是比较的重要,而且可以通过各种的路径,以及各每个用户对于系统的功能需求,你需要对这些内容做出整理以及分类,然后分析这些需求的现实情况下的可能原因,还需要有认真的分析过程,结合现实的情况下最终做出一系列的需求资料。在有关用户的期望分析中能够明确一些可能实现的情况,公交管理系统功能是许多个可以测试的功能相结合的,正是由于这些功可以使得用户能够更加积极的提供出需求,让系统功能可以变得更加的完善。这样就可以保证所有设计的功能模块都是可以用到的,而且也是可测试的,对于后续系统的开发能够有比较关键的作用,也能快速完成用户所提供的需求[9]。
本课题要求实现一套公交管理系统,系统主要包括管理员和用户两大功能模块。
(1)管理员用例图如下所示:
图3-1管理员用例图
(2)用户用例图如下所示:
图3-2用户用例图
3.3 系统流程分析 3.3.1后台管理流程图设计 图3-3后台管理流程图
3.3.2管理员修改信息流程图设计 图3-4 管理员修改信息流程图
3.3.3管理员查询信息流程图设计 图3-5 查询信息流程图
4功能结构 为了更好的去理清本系统整体思路,对该系统以结构图的形式表达出来,设计实现该公交管理系统的功能结构图如下所示:
图4-1 系统总体结构图
4.1 数据库设计 4.1.1 基于MySQL数据库的存储设计 在MySQL数据库管理平台上进行了系统的开发。在进行了系统架构的基础上,结合MySQL应用的特性,开发了相应的数据库,并对其进行了存贮和总体的体系架构。数据技术要求数据删除,修改,添加,查询等功能,并对数据进行维护与管理。并针对特定组织优化程序级应用服务。习惯统一管理和维护删除、修改、添加、查询功能[10]。
MySQL数据库主要包括两个部分:指令行和操作接口。该方法利用SQL语句和数据库操作指令来建立数据库,并设计并存储数据库表。但是,命令行的运行模式对操作员的技术要求很高,而且在整个系统中也很难被发现。
4.1.2 数据库E/R图 ER图是由实体及其关系构成的图,通过E/R图可以清楚地描述系统涉及到的实体之间的相互关系。在系统中对一些主要的几个关键实体如下图:
1、公告信息实体图如图4-2所示:
项目运行
环境配置:
Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。
项目技术:
JSP + mybatis + Maven +mysql5.7或8.0等等组成,B/S模式 + Maven管理等等。
环境需要
1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。
2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;
3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可
4.硬件环境:windows 7/8/10 4G内存以上;或者 Mac OS;
5.是否Maven项目: 否;查看源码目录中是否包含pom.xml;若包含,则为maven项目,否则为非maven项目
6.数据库:MySql 5.7/8.0等版本均可;
毕设帮助,指导,本源码分享,调试部署(见文末) 3.1 可行性分析 校园失物招领小程序主要目标是实现网上的相关信息管理服务。在确定了目标后,我们从以下四方面对能否实现本系统目标进行可行性分析。
3.1.1 技术可行性 技术上的可操作性是项目建设顺利进行的一个关键因素,技术措施必须达到要求,方能使项目顺利进行。该方案使用了开放源码的代码,并使用 Java、微信小程序等技术,对软件的设计具有适度的困难和对电脑的硬件需求。所有的语言都很容易使用。该项目具有技术上的可行性。
3.1.2 操作可行性 当今社会,电脑和手机已经是耳熟能详的存在了,绝大部分用户都可以通过电脑轻松操作本系统。由此可知,我们的管理系统对于绝大部分用户来说,操作是完全可行的,并不存在操作上的盲区。
3.1.3 经济可行性 本系统所需要用到的所以的工具都是开源,不收费的,并且本系统因为不具有太过于复杂的结构,用户维护系统的费用也不高。所以,本系统的经济可行性是可行的。
3.1.4 法律可行性 此校园失物招领小程序是自己设计的管理系统,具有很大的实际意义。因为无论是软件还是数据库,采用的都是开源代码,因此这个系统的开发和设计,并不存在侵权等问题,在法律上完全具有可行性。
综上所述,校园失物招领小程序在技术、经济、操作和法律上都具有很高的可行性,开发此程序是可行的。
3.2 系统性能分析 3.2.1 系统安全性 校园失物招领管理制度必须由领导机构严格执行。具体要求如下:
(1)如果要使用校园失物招领管理系统,必须先注册才能进行登录。未获许可的使用者,只有浏览的功能,不能进行其他的操作,因而本系统将会得到保护。
(2)在不同司法管辖区的具体实施。使用其他权限登录时,无法跳过此操作。
(3)如果专门应用,该系统将包含许多必须保密的数据和信息。该系统存在系统漏洞,发布此信息将给客户造成重大损失。因此,我们充分保证了该规则和系统的发展趋势。
3.2.2 数据完整性 (1)必须对所有的数据进行详尽的记载,而该信息的内容不得为空白。
(2)各种资料的关联一定要恰当。
(3)在不同的档案中,同一资料资讯应该互相相符。
3.3 系统功能分析 校园失物招领管理系统主要有管理员和用户两个两个功能模块:管理员模块、用户模块。以下将对这两个功能的作用进行详细的剖析。
一、使用背景 相信很多前端开发者都有这么一个需求:拿到后端返回的某个字段值,但是这个值并不能直接展示在前端给用户看,我们需要转换格式,比如后端返回 “1”,我们要展示“男”,拿到 “2”,我们要展示“女”。这时就可以使用 filter 方法,注意本文讲的这个 filter 是数组的一个方法,而不是组件中的filters:{},开发者可自行在组件 filters:{} 中加入筛选函数去转换格式。
二、filter使用方法与注意事项 直接上代码会更直观:
如图所示,countryOptions 是要进行筛选的一个数组,它有一个 filter 方法,item 则是countryOptions 里的每一个子项,filter 会遍历这个数组,将满足 item.value === "C" 的子项拿出来放在 filters1 数组中,直到筛选出所有满足条件的子项才结束,因此它返回的一定是个数组,哪怕只有一个子项满足条件。
注意点:
1、如果参数只有一个,括号可加可不加,但是参数超过 1 个时必须使用括号;
2、如果执行体加了 {},那么必须要有 return 关键字,否则筛选出的数组永远为空;
3、除了箭头函数,也可以用常规的普通函数去筛选条件,结果是一样的;
4、不论哪种方式去进行筛选,被筛选的原数组是不会被改变的;
5、如果未筛选出指定条件的数组,则返回空数组 [ ],所以其结果永远不会为 undefined 或者 null(该条注意点为最近新增,未体现在上面的代码中,开发者们可自行去验证);
6、如果 countryOptions 是作为下拉框的选项,那么它里面每个对象的 value 必须唯一,图中只是为了举例,不用于实际项目。
三、filter与find的区别 还是直接上代码:
从上图可以总结出 filter 与 find 的区别与共同点:
1、filter 遍历数组后会把所有符合条件的子项筛选出来,而 find 按顺序遍历数组后只会把符合条件的第一个子项筛选出来,然后就停止遍历;
2、因为 filter 是筛选出所有满足条件的子项,所以返回的结果一定是个数组对象,哪怕只筛选出了一项(见 filters3);而 find 因为只返回一项,故返回的结果是一个非数组的对象(见 filters4);
3、当未筛选出满足指定条件的对象时,filter 会返回空数组 [ ],其结果永远不为 undefined 或者null,但是 find 则一定是返回 undefined,这一点在做对象的判断时尤其要注意;
docker部署minio对象存储并用rclone同步
本文首发于 ❄️慕雪的寒舍
1.什么是minio? minio是一个开源的对象存储服务器,兼容S3协议。
官网:https://min.io/
官方在开源的基础上也提供云端S3服务,分为个人和企业,有不同的收费标准。
1.1 自建对象存储的好处? 当然,本文写下来肯定不是让你去买它的对象存储服务的,而是在我们自己的服务器/Nas上部署一个minio的docker,来拥有一个我们自己的对象存储服务器!
对象存储服务器可以用来做图床、静态资源缓存,亦或者是直接当作一个网盘来使用。
自建的对象存储的好处是所有源文件我们都能亲手管理,且无需为付费的对象存储的奇怪的计价文档感到手足无措,也不需要担心有人恶意刷流把你一套房子给套走。
缺点就是,自建的稳定性肯定不如已有厂家提供的服务,且自购的服务器/Nas上传带宽一般都很低,文件一多,访问速度就很慢了。
对于我个人而言,自建minio的唯一作用,就是备份七牛云/阿里云对象存储中的文件。考虑到2023下半年,各大厂接连boom云服务,国外的谷歌还出现了云盘里面用户的数据回滚到几月前的恶性问题,这可是可能导致用户数据丢失的大问题啊!
谷歌公布方案,修复 Drive 云盘文件丢失问题谷歌承认云端硬盘Google Drive存在BUG,3月内用户文件可能丢失 所以,将数据在自己本地留一份总是安心一些。数据安全靠的是备份,不是云服务厂家给你提供的99.99999%可用性的一面之词。
如果你对数据备份这个话题感兴趣,可以看看我的另外一篇博客:谈谈如何进行有效数据备份,3+2+1
温馨提醒:如果你想在云服务器上安装minio来备份已有S3中的文件的话,最好是使用一个和已有S3不在同一个地域、非同一个服务商的云服务器,避免某些服务商云服务器和对象存储一起boom的情况……
2.docker安装minio 2.1 安装docker docker安装的教程详见我的另外一篇博客
【Docker】deepin/centos安装docker | 慕雪的寒舍
2.2 安装minio 这里推荐使用由VMware维护的minio docker版本bitnami/minio,更新很频繁。
hub.docker.com/r/bitnami/minio
创建容器的命令如下,非常简单
docker run -it -d --name minio \ -p 9000:9000 \ -p 9001:9001 \ --restart=always \ -v /minio/data:/bitnami/minio/data \ -e MINIO_ROOT_USER="minio_root" \ -e MINIO_ROOT_PASSWORD="minio_123456" \ -e TZ='Asia/Shanghai' \ bitnami/minio:latest 该创建容器操作基于如下hash的docker镜像(更新于2023-12-12),创建容器的命令后续可能会有变动,请参考docker-hub中的官方文档
bitnami/minio latest 552af9bd3d6d 2 days ago 212MB 对这个docker命令进行解释
1、先在网上购买合适的电池,现在买电池一般都是附带工具的。
2、后盖用撬刀轻易即可打开,打开后盖的图如上,之后小心取出上图红色箭头标注处的白色结构圈, 戴上买电池所送的手套,小心取出电池,接着换上新的电池(注意正反,分不清正负的话按原电池的方向放入即可),观察指针是否正常行走,若正常,即可放回白色结构圈。
3、 涂上防水膏,合上后盖(按原位放置)。如果用手合不上,可以借助工具辅助,如擀面杖,木质的锅铲把柄等,用力按压即可。
strace
ld_preload
在「X」Embedding in NLP 进阶系列中,我们介绍了自然语言处理的基础知识——自然语言中的 Token、N-gram 和词袋语言模型。今天,我们将继续和大家一起“修炼”,深入探讨神经网络语言模型,特别是循环神经网络,并简要了解如何生成 Embedding 向量。
01.深入了解神经网络 首先,简要回顾一下神经网络的构成,即神经元、多层网络和反向传播算法。如果还想更详细深入了解这些基本概念可以参考其他资源,如 CS231n 课程笔记。
在机器学习中,神经元是构成所有神经网络的基本单元。本质上,神经元是神经网络中的一个单元,它对其所有输入进行加权求和,并加上一个可选的偏置项。方程式表示如下所示:
在这里, x 0 , x 1 , . . . , x n − 1 代表上一层神经元的输出, w 0 , w 1 , . . . , w n − 1 代表这个神经元用来综合输出值的权重。
如果一个多层神经网络仅由上述方程中的加权和组成,我们可以将所有项合并为一个单一的线性层——这对于建模 Token 之间的关系或编码复杂文本并不是很理想。这就是为什么所有神经元在加权和之后都包含一个非线性激活函数,其中我们最熟知的例子就是修正线性单元(ReLU)函数:
对于大多数现代神经网络语言模型来说,高斯误差线性单元(GELU)激活函数更常见:
在这里, Φ q 代表高斯累积分布函数,可以用 G E L U ( q ) ≈ q 1 + e − 1.702 q 来表示。这个激活函数在上述的加权求和之后被应用。总而言之,一个单一的神经元看起来像这样:
为了学习更复杂的函数,我们可以将神经元堆叠起来——一个接一个地形成一个层。同一层中的所有神经元接收相同的输入;它们之间唯一的区别是权重 w 和偏置 b 。我们可以用矩阵符号将上述方程表示一个单层:
一、封装 封装:将类的某些信息隐藏在类的内部(用private修饰),不允许外部程序直接访问,需要访问也是访问该类为其提供的公共属性。
装属性的作用:防止类中的数据被恶意修改。
封装属性的好处:1.可以隐藏类的实现细节
2.外部只能通过访问规定的属性来访问数据,保护数据
3.方便加入控制语句,即对数据做约束
代码例子:
public class Person { // 私有字段 private string name; private int age; // 公共构造函数 public Person(string name, int age) { this.name = name; this.age = age; } // 特性可以保护数据安全 public int Age { get { return age; } set { age =value; } } // 公共方法,用于获取姓名 public string GetName() { return name; } // 公共方法,用于设置姓名 public void SetName(string newName) { name = newName; } // 公共方法,用于获取年龄 public int GetAge() { return age; } // 公共方法,用于设置年龄 public void SetAge(int newAge) { if (newAge > 0 && newAge < 150) // 简单的年龄验证逻辑 { age = newAge; } else { throw new ArgumentOutOfRangeException("
vs code使用教程 链接远程服务器免密登陆服务器1生成客户机(个人PC)密令2复制到服务器中3测试 远程debug和选环境unable to watch for file changes in this large workspace问题 链接远程服务器 https://blog.csdn.net/zhaxun/article/details/120568402
免密登陆服务器 1生成客户机(个人PC)密令 ssh-keygen -t rsa 生成的文件在主目录的.ssh文件当中。
查看密令并复制到linux系统当中
cat id_rsa.pub 2复制到服务器中 echo "xxxx" >> ~/.ssh/authorized_keys "XXX"代表的是客户机中生成的密令。
然后重启服务器的ssh服务。
sudo service sshd restart 3测试 commond(ctrl)+shit+P -> Reload Window -> Enter
不需要密码,流畅进入。
远程debug和选环境 运行时报错找不到文件,可能是相对路径错误:
只要你在每次使用 Code Runner 调试时, cd 一下进入对应的文件夹就可以正常运行的。如果需要更高级的修改,可以参考下面这篇文章。
No such file or directory. 解决VSCode相对路径出错问题
unable to watch for file changes in this large workspace问题 官方解决方案如下:
官方方案
一、类的定义
C#中类是一种引用类型,用于表示具有状态和行为的对象。类可以包含字段、属性、方法、事件等成员。
public class MyClass { // 类的成员定义 }
常用的关键字如下:
1、public 是一个访问修饰符,用于指定类成员的访问级别。当将类成员声明为 public 时,表示该成员可以从程序的任何地方都可以访问。(所有都能访问) 2、private 是一个访问修饰符,用于指定类成员的访问级别。当将类成员声明为 private 时,表示该成员只能在当前类中访问,其他类无法访问。(只有本类内可以访问)
3、protected 是一个访问修饰符,用于指定类成员的访问级别。当将类成员声明为 protected 时,表示该成员只能在当前类及其子类中访问,其他类无法访问。(只有在子类和父类中才能访问)
4、internal 是一个访问修饰符,用于指定类成员的访问级别。当将类成员声明为 internal 时,表示该成员只能在当前程序集中访问,其他程序集无法访问。(只有在本项目中能访问,引用该dll的项目无法访问)
二、类内的成员
1、字段(Fields):字段是类的私有或公共成员,用于存储类的数据。
public class MyClass { private int myField; // 私有字段 public int MyPublicField; // 公共字段 } 2、属性(Properties):属性是类的封装手段,提供了访问类的字段的方法,也可以作为数据成员来访问。
public class MyClass { private int myField; public int MyProperty { get; set; } // 自动属性 public int MyCustomProperty { get { return myField; } set { myField = value; } // 也可以有更复杂的逻辑 } } //其中value是get set 中默认使用的关键字 //快速定义属性的方法: MyCustomProperty =>myField //简单方便省略的get set 3、方法(Methods):方法是类的行为或功能的具体实现。
29. 两数相除 问题 给你两个整数,被除数 dividend 和除数 divisor。将两数相除,要求 不使用 乘法、除法和取余运算。
整数除法应该向零截断,也就是截去(truncate)其小数部分。例如,8.345 将被截断为 8 ,-2.7335 将被截断至 -2 。
返回被除数 dividend 除以除数 divisor 得到的 商 。
注意:假设我们的环境只能存储 32 位 有符号整数,其数值范围是 [−231, 231 − 1] 。本题中,如果商 严格大于 231 − 1 ,则返回 231 − 1 ;如果商 严格小于 -231 ,则返回 -231 。
示例 1:
输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = 3.33333… ,向零截断后得到 3 。
示例 2:
输入: dividend = 7, divisor = -3
binarycreator.exe -c config/config.xml -p packages install.exe -v
前言 我相信大多 Java 开发的程序员或多或少经历过 BAT 一些大厂的面试,也清楚一线互联网大厂 Java 面试是有一定难度的,小编经历过多次面试,有满意的也有备受打击的。因此呢小编想把自己这么多次面试经历以及近期的面试真题来个汇总分析,阐述下如何去准备,去回答面试官的提问,可以和面试官有个愉快的交谈。
小编分享的这份 BAT 必考 Java 真题合集包含了性能调优、并发编程、框架源码、分布式框架、微服务架构、项目实战、互联网工具等七个大专题技术点真题模块分享,都是小编在各个大厂面试总结出来的面试真题,已经有很多粉丝靠这份真题合集拿下金九银十的面试,今天小编在这里总结分享给到大家!
小编这篇分享篇幅可能有点长,观看的朋友可以先了解一下目录
JVM 面试题MySQL 面试题Tomcat 调优面试题Nginx 调优面试题并发同步(乐观锁、悲观锁、重入锁、公平锁、非公平锁及锁的粒度详解)Executor 线程池面试题Spring aop 面试题Spring mvc 面试题Spring 面试题Mybatis 面试题RabbitMQ 面试题RocketMQ 面试题Kafka 面试题Redis 面试题Zookeeper 面试题Dubbo 面试题Netty 面试题Spring Boot 面试题Spring cloud 面试题Linux 面试题 JVM 面试题 1、什么情况下会发生栈内存溢出。
java 中的栈一般存储的是栈帧。
所以栈内存溢出就是栈帧的数量太多超过了系统预先设定的值,所以导致内存溢出。
可能的原因就是方法循环调用,栈帧充满了整个栈后溢出。
2、说一下 JVM 的主要组成部分及其作用?
类加载器:加载类文件到内存。Class loader 只管加载,只要符合文件结构就加载,至于能否运行,它不负责,那是有 Exectution Engine 负责的。执行引擎:也叫解释器,负责解释命令,交由操作系统执行。本地库接口:本地接口的作用是融合不同的语言为 java 所用运行时数据区: 3、详解 JVM 内存模型
java 定义内存模型的目的是:为了屏蔽各种硬件和操作系统的内存访问之间的差异。 java 内存模型规定了所有的变量都存储在主内存中,每条线程拥有自己的工作内存,工作内存保存了主内存中变量的副本。
4、说一下 JVM 运行时数据区
5、JVM 内存为什么要分成新生代,老年代,持久代。新生代中为什么要分为 Eden 和 Survivor。
Scoop项目点击跳转
本文参考
1.添加环境变量 添加后, 可以直接安装scoop到指定的路径
可以在gui下设置环境变量:
也可以用命令行设置环境变量:
User为设置用户变量, 可以替换成Machine设置系统变量(需要管理权权限)
$env:SCOOP='D:\Scoop' [Environment]::SetEnvironmentVariable('SCOOP',$env:SCOOP,'User') 2.安装命令 PowerShell 执行策略必须为以下之一:Unrestricted、RemoteSigned 或 ByPass 才能执行安装程序. 例如, 可以通过命令行设置:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser 安装命令如下(需要挂梯子, 不然会报连接错误)
irm get.scoop.sh | iex 上述命令需要在非管理员身份下执行, 否则报以下错误:
官方解释:
对于管理员, 出于安全考虑, 默认情况下禁用管理员控制台下的安装. 除非您知道自己在做什么并且想以管理员身份安装 Scoop.
安装完成:
查看版本:
在最初设置的环境变量路径下有了scoop文件:
管理员身份可以用以下安装命令:
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser irm get.scoop.sh -outfile 'install.ps1' .\install.ps1 -RunAsAdmin 3.应用安装 一个库里面包含很多app, 需要先导入库, 然后才能安装app
常用的库: extras和main
其中main在安装scoop的时候就默认导入了, 所以部分app可以直接安装了
比如安装aria2, 貌似是个加速下载的app:
scoop install aria2 安装结果如下:
然后导入extras库, 用以下命令:
scoop bucket add extras 结果如下:
文章目录 linux 查看服务启动时间参数解析 linux 查看服务启动时间 [root@104 ~]# ps -o lstart -p `ps -ef |grep -v grep |grep "zookeeper"|awk '{print$2}'` STARTED Fri Dec 15 16:54:10 2023 参数解析 linux 命令中 ps -ef 详解
ps -ef表示查看全格式的进程。 ps 是 linux 下最常用的也是非常强大的进程查看命令,常配合 管道命令 | 和查找命令 grep 同时执行来查看特定进程。
参数含义:
-e: 显示所有进程。
-p:(pid)查找具有指定进程 ID 的进程
-f :全格式。
-h :不显示标题。
-l :长格式。
-w :宽输出。
a :显示终端上的所有进程,包括其他用户的进程。
r :只显示正在运行的进程。
x :显示没有控制终端的进程。
-o :选就是用户自定义格式,输出用户想要的格式。如下:
-o pid 进程号 -o cmd 启动进程命令 -o lstart 进程启动精确时间 -o etime 启动后所流逝的时间 # 示例 ps -eo pid,etimes,cmd | grep <进程名> 扩展资料: 进程状态:
由于到新公司解决老旧系统定时任务基于bat脚本curl定时请求无法统一管理和扩展性太差问题,以及在搭建的过程中遇到的坑,故针对这情况写了一个定时任务的管理模块,支持Get,Post请求方式。
源代码地址:源代码地址
无缝嵌入项目,支持Swagger测试
什么是定时任务? 定时发邮件,定时统计信息等内容,那么如何实现才能使得我们的项目整齐划一呢?本文通过一些简单的小例子,简述在.Net 7+Quartz实现定时任务的一些基本操作,及相关知识介绍,仅供学习分享使用,如有不足之处,还请指正。
什么是Quartz?
Quartz 是一个开源的作业调度框架,它完全由 Java 写成,并设计用于 J2SE 和 J2EE 应用中。它提供了巨大的灵 活性而不牺牲简单性。你能够用它来为执行一个作业而创建简单的或复杂的调度。它有很多特征,如:数据库支持,集群,插件,EJB 作业预构 建,JavaMail 及其它,支持 cron-like 表达式等等。虽然Quartz最初是为Java编写的,但是目前已经有.Net版本的Quartz,所以在.Net中应用Quartz已经不再是奢望,而是轻而易举的事情了。
Github上开源网址为:https://github.com/quartznet
关于Quartz的快速入门和API文档,可以参考:
https://www.quartz-scheduler.net/documentation/quartz-3.x/quick-start.html
Quartz安装 为了方便,本项目采用仓储模式,由Api,BizManagement,DataBase,Entity 4个模块组成,本次基于Rider开发,通过Nuget包管理器进行安装,如下所示:
项目模块组成: 依赖组件: 1. redis (StackExchange.Redis: 2.6.122)查询全量数据的持久化
2. Nlog(5.3.5) 日志记录到文件
3. SkyApm(0.9.0) 接口追踪
4. Mysql(Pomelo.EntityFrameworkCore.MySql: 7.0.0) 持久化Scheduler到数据库
5. AutoMapper(12.0.1) 实体映射
6. EFCore(7.0.13) ORM管理
remark:数据库,Redis地址在api模块 appsetting.json修改
主要功能组件: QuartzManage: 对Job的管理,支持暂停,启动,更新频率,批量删除等操作
using System.Collections.Specialized; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using org.huage.BizManagement.Job; using org.huage.BizManagement.Listener; using org.huage.BizManagement.Proxy; using org.huage.Entity.common; using org.