当前WebStorm版本:2023.1
更改 查看 右下角右键,勾选内存指示器
背景: 在项目中,我们难免遇到同一时刻需要不同的方法对同一个数据库的数据进行修改。因此就可能会出现脏写的情况。对于mqsql而言,明明有排他锁来管理update操作,为什么会出现数据脏写情况呢?终于在我测试下发现,@Transactional很是无辜的背到了这个黑锅。
问题复现: 场景一: /** * 测试方法一 * @param condition * @return */ @PostMapping(value = "/testOnee") @Transactional(rollbackFor = Exception.class) @ApiOperation(value = "测试方法一") public IResponse testOne(@ModelAttribute ChannelWitnessCondition condition) throws InterruptedException { CaseContractInfo caseContractInfo = caseContractInfoService.getContractByContractNo("BYD3000028-001"); //线程等待100秒,我先看看风景去【执行update前等待】 Thread.currentThread().sleep(100000); caseContractInfo.setApplyStatus(ApplyStatusEnum.LOAN_WAIT_APPROVE.getState()); caseContractInfoService.updateById(caseContractInfo); return IResponse.success(true); } /** * 测试方法二 * @param condition * @return */ @PostMapping(value = "/testTwo") @Transactional(rollbackFor = Exception.class) @ApiOperation(value = "测试方法二") public IResponse testTwo(@ModelAttribute ChannelWitnessCondition condition) { CaseContractInfo caseContractInfo = caseContractInfoService.getContractByContractNo("BYD3000028-001"); caseContractInfo.
下面所有博客是个人对EEG脑电的探索,项目代码是早期版本不完整,需要完整项目代码和资料请私聊。
数据集
1、脑电项目探索和实现(EEG) (上):研究数据集选取和介绍SEED
相关论文阅读分析:
1、EEG-SEED数据集作者的—基线论文阅读和分析
2、图神经网络EEG论文阅读和分析:《EEG-Based Emotion Recognition Using Regularized Graph Neural Networks》
3、EEG-GNN论文阅读和分析:《EEG Emotion Recognition Using Dynamical Graph Convolutional Neural Networks》
4、论文阅读和分析:Masked Label Prediction: Unified Message Passing Model for Semi-Supervised Classification
5、论文阅读和分析:《DeepGCNs: Can GCNs Go as Deep as CNNs?》
6、论文阅读和分析: “How Attentive are Graph Attention Networks?”
7、论文阅读和分析:Simplifying Graph Convolutional Networks
8、论文阅读和分析:LightGCN: Simplifying and Powering Graph Convolution Network for Recommendation
9、图神经网络汇总和总结
相关实验和代码实现:
1、用于图神经网络的脑电数据处理实现_图神经网络 脑电
2、使用GCN训练和测试EEG的公开SEED数据集
3、使用GAT训练和测试EEG公开的SEED数据集
4、使用SGC训练和测试SEED数据集
5、使用Transformer训练和测试EEG的公开SEED数据集_eeg transformer
下面所有博客是个人对EEG脑电的探索,项目代码是早期版本不完整,需要完整项目代码和资料请私聊。
数据集
1、脑电项目探索和实现(EEG) (上):研究数据集选取和介绍SEED
相关论文阅读分析:
1、EEG-SEED数据集作者的—基线论文阅读和分析
2、图神经网络EEG论文阅读和分析:《EEG-Based Emotion Recognition Using Regularized Graph Neural Networks》
3、EEG-GNN论文阅读和分析:《EEG Emotion Recognition Using Dynamical Graph Convolutional Neural Networks》
4、论文阅读和分析:Masked Label Prediction: Unified Message Passing Model for Semi-Supervised Classification
5、论文阅读和分析:《DeepGCNs: Can GCNs Go as Deep as CNNs?》
6、论文阅读和分析: “How Attentive are Graph Attention Networks?”
7、论文阅读和分析:Simplifying Graph Convolutional Networks
8、论文阅读和分析:LightGCN: Simplifying and Powering Graph Convolution Network for Recommendation
9、图神经网络汇总和总结
相关实验和代码实现:
1、用于图神经网络的脑电数据处理实现_图神经网络 脑电
2、使用GCN训练和测试EEG的公开SEED数据集
3、使用GAT训练和测试EEG公开的SEED数据集
4、使用SGC训练和测试SEED数据集
5、使用Transformer训练和测试EEG的公开SEED数据集_eeg transformer
下面所有博客是个人对EEG脑电的探索,项目代码是早期版本不完整,需要完整项目代码和资料请私聊。
数据集
1、脑电项目探索和实现(EEG) (上):研究数据集选取和介绍SEED
相关论文阅读分析:
1、EEG-SEED数据集作者的—基线论文阅读和分析
2、图神经网络EEG论文阅读和分析:《EEG-Based Emotion Recognition Using Regularized Graph Neural Networks》
3、EEG-GNN论文阅读和分析:《EEG Emotion Recognition Using Dynamical Graph Convolutional Neural Networks》
4、论文阅读和分析:Masked Label Prediction: Unified Message Passing Model for Semi-Supervised Classification
5、论文阅读和分析:《DeepGCNs: Can GCNs Go as Deep as CNNs?》
6、论文阅读和分析: “How Attentive are Graph Attention Networks?”
7、论文阅读和分析:Simplifying Graph Convolutional Networks
8、论文阅读和分析:LightGCN: Simplifying and Powering Graph Convolution Network for Recommendation
9、图神经网络汇总和总结
相关实验和代码实现:
1、用于图神经网络的脑电数据处理实现_图神经网络 脑电
2、使用GCN训练和测试EEG的公开SEED数据集
3、使用GAT训练和测试EEG公开的SEED数据集
4、使用SGC训练和测试SEED数据集
5、使用Transformer训练和测试EEG的公开SEED数据集_eeg transformer
下面所有博客是个人对EEG脑电的探索,项目代码是早期版本不完整,需要完整项目代码和资料请私聊。
主要内容:
1、在EEG(脑电)项目中,使用图神经网络对脑电进行处理,具体包括baseline的GCN图架构、复现baseline论文的RGNN架构、注意力机制图架构、Transformer图架构、注重效率的simple图架构等,进行实验和对比。
2、学习图神经网络相关的资料。是学习图神经网络的一个完整项目;
数据集
1、脑电项目探索和实现(EEG) (上):研究数据集选取和介绍SEED
相关论文阅读分析:
1、EEG-SEED数据集作者的—基线论文阅读和分析
2、图神经网络EEG论文阅读和分析:《EEG-Based Emotion Recognition Using Regularized Graph Neural Networks》
3、EEG-GNN论文阅读和分析:《EEG Emotion Recognition Using Dynamical Graph Convolutional Neural Networks》
4、论文阅读和分析:Masked Label Prediction: Unified Message Passing Model for Semi-Supervised Classification
5、论文阅读和分析:《DeepGCNs: Can GCNs Go as Deep as CNNs?》
6、论文阅读和分析: “How Attentive are Graph Attention Networks?”
7、论文阅读和分析:Simplifying Graph Convolutional Networks
8、论文阅读和分析:LightGCN: Simplifying and Powering Graph Convolution Network for Recommendation
9、图神经网络汇总和总结
相关实验和代码实现:
1、用于图神经网络的脑电数据处理实现_图神经网络 脑电
2、使用GCN训练和测试EEG的公开SEED数据集
下面所有博客是个人对EEG脑电的探索,项目代码是早期版本不完整,需要完整项目代码和资料请私聊。
数据集
1、脑电项目探索和实现(EEG) (上):研究数据集选取和介绍SEED
相关论文阅读分析:
1、EEG-SEED数据集作者的—基线论文阅读和分析
2、图神经网络EEG论文阅读和分析:《EEG-Based Emotion Recognition Using Regularized Graph Neural Networks》
3、EEG-GNN论文阅读和分析:《EEG Emotion Recognition Using Dynamical Graph Convolutional Neural Networks》
4、论文阅读和分析:Masked Label Prediction: Unified Message Passing Model for Semi-Supervised Classification
5、论文阅读和分析:《DeepGCNs: Can GCNs Go as Deep as CNNs?》
6、论文阅读和分析: “How Attentive are Graph Attention Networks?”
7、论文阅读和分析:Simplifying Graph Convolutional Networks
8、论文阅读和分析:LightGCN: Simplifying and Powering Graph Convolution Network for Recommendation
9、图神经网络汇总和总结
相关实验和代码实现:
1、用于图神经网络的脑电数据处理实现_图神经网络 脑电
2、使用GCN训练和测试EEG的公开SEED数据集
3、使用GAT训练和测试EEG公开的SEED数据集
4、使用SGC训练和测试SEED数据集
5、使用Transformer训练和测试EEG的公开SEED数据集_eeg transformer
文章目录 QNAP+Transmission目标硬件及系统安装 Transmission安装 Transmission Web Control启动 Transmission登录 Transmission配置 Transmission自定义限速时间修改Transmission Web 端口号使transmission 端口测试显示开启问题描述错误原因解决办法: 利用反向代理配置HTTPS访问ssl 证书验证问题 QNAP+Transmission 目标 在QNAP的TS-453Dmini上安装Transmission并进行设置。
硬件及系统 QNAP的TS-453Dmini8G内存QTS 5.1.0.1986(2022/03/24)
安装 Transmission 下载:从QNAP商店下载架构为TS-NASX86_64的安装包QTransmission3_3.0.0.2_x86_64.qpkg;1安装:QTS的APPCenter,点击右上角的手动安装,通过浏览选定刚刚下载的qpkg文件后点击安装,等待安装完成。2 安装 Transmission Web Control 下载:从QNAP商店下载架构为TS-NASX86_64的安装包TransmissionWC_1.6.1_x86_64.qpk;1安装:QTS的APPCenter,点击右上角的手动安装,通过浏览选定刚刚下载的qpkg文件后点击安装,等待安装完成。2 启动 Transmission 在QTS中启动Transmission 和 Transmission web control。
登录 Transmission 在QTS中点击左上角的主菜单(三条横线)图标,找到Transmission,单击打开,或者也可以直接通过网址nas ip:49092 打开,用户名和密码均为qnap。
配置 Transmission 启用QTS的ssh连接:主菜单>>控制台>>网络文件服务>>Telnet/SSH,勾选允许SSH连接(只有管理员群组可远程登陆)后点击应用;建立 SSH 连接:通过CMD或专门的ssh连接管理软件,例如 finalshell,远程连接 QTS;停止运行transmission;使用vim 打开配置文件: sudo vim /share/CACHEDEV1_DATA/.qpkg/QTransmission3/etc/settings.json 其中各参数含义如下,注意:json 并不支持注释,下文代码块中的 #注释只是为了方便说明3
{ "alt-speed-down": 50, # 限速时段下载限速值 "alt-speed-enabled": false, "alt-speed-time-begin": 540, "alt-speed-time-day": 127, # 时段限速日期(星期几),127 表示每天, # 更复杂配置参考官网。用 7 位二进制数表示,然后转换成十进制数, # 0000001 表示周日,1000000 表示周六,0000010 表示周一, # 0000100 表示周二。如果你只要在周末限速,该数应该 1000001, # 转换为十进制就是 65 "
文章目录 目标A. 下载qBittorrentB. 安装qBittorrentC. 配置qBittorrenta. 修改用户名和密码b. 修改下载文件的默认保存地址c. 修改文件夹权限 D. 远程访问E. 添加SSLF. 修改打开文件数量限制[^2]常见问题 目标 为威联通NAS配置qBittorrent,使其可远程访问,可直接从NAS中删除通过其下载的文件,而不是必须从qBittorrent中删除。
A. 下载qBittorrent 从qnapclub下载qBittorrent,由于NAS为TS-453Dmini,故选择版本TS-NASX86_64。
B. 安装qBittorrent 进入威联通NAS网页端的AppCenter,右上角选择从手动安装,然后浏览选中下载的qpkg文件后点击安装,等待安装完成。1
C. 配置qBittorrent a. 修改用户名和密码 打开qBittorrent,初始用户名admin,密码adminadmin,然后登录。
tool菜单下的options...子菜单中的Web UI页中可修改用户名和密码。
b. 修改下载文件的默认保存地址 在options>>Downloads>>Saving Management>>Default Save Path中可修改默认保存地址,可设置为/share/Public/qbittorrent/Downloads/。
c. 修改文件夹权限 经测试上面操作完成后无法在NAS中直接删掉qBittorrent下载的文件,为实现可从NAS中直接删除其下载的文件,可在威联通NAS网页端中控制台>>权限>>共享文件夹>>高级权限中勾选启动高级文件夹权限并应用。尚未确定该方法是否有弊端。
D. 远程访问 上面安装的是套装,直接附带Web UI,可配置端口转发或启动UPnP即可远程访问。
E. 添加SSL 从阿里云网站上下载证书,类型选择其他。解压后得到两个后缀分别为pem和key的文件,上传到NAS。
Options>>Web UI>>勾选Use HTTPS instead of HTTP,Certificate填写后缀为pem的证书文件云端地址,Key填写后缀为key的证书文件的云端地址,然后保存。
F. 修改打开文件数量限制2 ssh登录qnap nas并进入/share/CACHEDEV1_DATA/.qpkg/qBittorrent/文件夹;执行命令创建limit.c文件 touch lilmit.c 使用 prlimit 函数来调整虽然网上有许多关于修改系统文件的教程,但是在这里我都不管用…… 后面是看到了 CARLO 的博文,采用他的方案。大致就是使用如下的代码来对运行中的进程进行动态调整,三个输入参数分别为待调整的进程 pid、文件打开数的 soft limit、文件打开数的 hard limit。因此基本操作就是在 qbittorrent-nox 进程运行后,再在威联通系统上运行一下此程序即可。要实现这一目的,首先要在威联通系统上对此 C 程序进行编译。
Android中将APK放入系统APK目录中,启动失败. 背景:有时候我们需要将apk放进系统里面去,拷贝到system/app/或者打包进system.image中。
问题:有时候apk需要相应的so库,这时候直接拷贝进system/app,apk程序无法正常运行,会报错.
AndroidRuntime: FATAL EXCEPTION: main AndroidRuntime: Process: com.cmccpoc, PID: 2708 AndroidRuntime: java.lang.UnsatisfiedLinkError: Couldn't load airtalkee from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/system/app/POCM3A.apk", zip file "/data/data/com.cmccpoc/code_cache/secondary-dexes/POCM3A.apk.classes2.zip"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]]: findLibrary returned null AndroidRuntime: at java.lang.Runtime.loadLibrary(Runtime.java:358) AndroidRuntime: at java.lang.System.loadLibrary(System.java:526) AndroidRuntime: at com.airtalkee.sdk.engine.AirNative.<clinit>(Unknown Source) AndroidRuntime: at com.airtalkee.sdk.engine.AirEngine.serviceTraceMode(Unknown Source) AndroidRuntime: at com.airtalkee.sdk.controller.AccountController.traceMode(Unknown Source) AndroidRuntime: at com.airtalkee.sdk.AirtalkeeAccount.AirTalkeeConfigTrace(Unknown Source) AndroidRuntime: at com.cmccpoc.application.MainApplication.onCreate(MainApplication.java:38) AndroidRuntime: at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1007) AndroidRuntime: at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4422) AndroidRuntime: at android.app.ActivityThread.access$1500(ActivityThread.java:138) AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1259) AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:102) AndroidRuntime: at android.
一、流程图效果 最近一段时间在研究go.js,它是一款前端开发画流程图的一个插件,也是一个难点,要说为什么是难点,首先,它是依赖画布canvas知识开发。其次,要依赖于内部API开发需求,开发项目实战需求的时候就要花费大量的时间去熟悉go.js的API,然后才能进行开发。话不多说,我就先把我最近做的项目案例效果图展示一下:
看到效果图大家可能会想这个挺简单的,会想没什么难点,其实真正开发的时候才会知道的、才会领悟到。
二、为什么选go.js流程图插件去开发项目? 在项目开发一期的时候我用的不是go.js,而用的是一款轻便的流程插件jsplumb.js,它也集成了各种功能性API,但是在开发二期的时候它的内部功能已经满足不了需求了,所以我就开始在网上查找流程插件来学习,看了很多插件,比如:G6,D3 等这些可视化流程插件都是不能满足需求。要说为什么不能满足需求,原因如下:
一、首先,看到效果图里的内置多点和其他模块单点连线问题,其他插件是无法这个满足需求的,可能我没有深入去了解其他的流程插件吧,但是go.js里内置点连线可以让开发者很快的理解代码逻辑,不用耗费大量的时间去想点与点的连线。
二、代码上的数据结构问题,其他插件里的API数据字段繁琐量多,不够清晰明了,而go.js里的数据结构就两个重要字段,一是所有模块的字段集合二是连线字段集合,根据需求可以随意加字段。
三、项目开发 (一)、首先直接使用go.js,画布中是有水印的
其实这个问题不大,替换一行代码就可以去除水印
引入go.js后,直接在编辑器中全局搜索7eba17a4ca3b1a8346,找到类似这样结构的代码
a.ir=b.W[Ra("7eba17a4ca3b1a8346")][Ra("78a118b7")](b.W,ok,4,4); 注:不同的版本代码不是完全相同的,可能是a.jv(属性名是会变的) =‘xxxxx’,将这行代码替换成
a.ir=function(){return true;}; //a.属性名 要保持一致 去除水印的效果
(二)、HTML
<--第一种-->
<template> <div id="wrap"> <div id="chart-wrap"> <div id="chart-palette"></div><-- 画布一 --> <div id="chart-diagram"></div><-- 画布二 --> </div> </div> </template> 如图:
第二种
结合vue的拖拽组件vuedraggable 实现业务需求。
<template> <div id="chart-wrap"> <div v-for="tab in tabLIst" :key="tab.id" class="tab"> //拖动 <vuedraggable @end.stop="end" @start.stop="move"> <i :class="tab.icon" /> {{ tab.text }} <el-tooltip effect="dark" :content="tab.tooltip" placement="top"> <i class="el-icon-question" /> </el-tooltip> </vuedraggable> </div> <div id="
1.在vscode中点击扩展-->安装插件koroFileHeader
2.进行配置
点击设置按钮 进入配置页面-->搜索fileheader-->settings.json
可以在settings.json文件中设置一些头部注释和函数注释
以下列举一些配置代码,也可根据实际情况进行变化
// 此为头部注释 "fileheader.customMade": { "Description": "", "Version": "2.0", "Autor": "ABing", "Date": "Do not edit", "LastEditors": "lhl", "LastEditTime": "Do not edit" }, // 此为函数注释 "fileheader.cursorMode": { "description":"", "param": "", "return": "", "author":"lhl" }, "fileheader.configObj": { // 默认开启自动添加头部注释,当文件没有设置头部注释时保存会自动添加 "autoAdd": true, // 默认开启 "autoAlready": true, // 禁止.json .md文件,自动添加头部注释 "prohibitAutoAdd": [ "json", "md" ], // 设置为true开启 "wideSame": false, // 字段长度 默认为13 "wideNum": 13 } 3.根据快捷键进行注释
(1)当我们想在对应php文件头部设置注释信息时使用快捷键:
ctrl+alt+i 备注头部
这篇文章主要介绍了linux挂载点目录在哪个目录下的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇linux挂载点目录在哪个目录下文章都会有所收获,下面我们一起来看看吧。
linux挂载点目录在一般在“/mnt”目录下;用户手动挂载点,即用户自己使用mount命令挂载的设备;在linux中,挂载是一个非常重要的功能,它将一个设备挂接到一个已存在的目录上;当我们要访问存储中的文件,必须将文件所在的分区挂载到一个已存在的目录,然后通过访问这个目录来访问存储设备。
linux 挂载点目录在哪?
1、用户手动挂载点,即用户自己使用mount命令挂载的设备,一般目录在/mnt目录下。
2、系统分区的挂载点及介绍如下图所示
挂载是什么?
挂载是一个非常重要的功能,它将一个设备(通常是存储设备,可以挂载光盘、硬盘、磁带、光盘镜像文件等)挂接到一个已存在的目录上(这个目录可以不为空,但挂载后这个目录下以前的内容将不可用)。
linux操作系统将所有的设备都看作文件,它将整个计算机的资源都整合成一个大的文件目录,我们要访问存储中的文件,必须将文件所在的分区挂载到一个已存在的目录,然后通过访问这个目录来访问存储设备。挂载需要有挂载源和挂载点。
挂载源:要挂载的对象
挂载点:一个特定的目录
linux 查看目录挂载点
df 选项 文件目录或文件名
参数:
-a. --all ,显示所有的文件系统,包括虚拟文件系统
-B。--block-size 指定单位大小,比如1K,1M等
-h,--human-readable 以人们易读的GB,MB,KB等格式显示
-H。--si和-h参数一样,但不是一1024,而是1000,即1K=1000,而不是1K=1024
-i,--inodes,不用硬盘容量,而是以inode的数量来显示
-k,以KB的容量显示各文件系统,相当于--block-size=1k
-m,以MB的容量显示各文件系统,相当于--block-size=1m
-l,--local,只显示本地文件系统
--no-sync; 在统计使用信息之前不调用sync命令
-sync,在统计使用信息之前调用snyc命令
-P,portability,使用POSIX格式显示
-t,--type=TYPE,只显示指定类型的文件系统
-T,--print-type,显示文件系统类型
-x,--exclude-type=TYPE ,不显示指定类型的文件系统
--help,显示帮助信息
--version。显示版本信息
举例
$ df /home Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda1 39088576 21481232 15598720 58% / $ df -kh Filesystem Size Used Avail Use% Mounted on udev 971M 0 971M 0% /dev tmpfs 200M 6.
1、用下列命令查看WSL2 有没有运行 wsl.exe --list --verbose 如果是下边这种,状态为Running,就需要执行第二步,终止运行。否则,直接从第三步开始
2、终止正在运行的 wsl.exe --terminate docker-desktop wsl.exe --terminate docker-desktop-data 3、利用diskpart收缩硬盘 diskpart 4、选择对应的数据盘位置 select vdisk file="C:\Users\Administrator\AppData\Local\Docker\wsl\data\ext4.vhdx" 如果上边的不能运行,就需要换成自己的用户名: select vdisk file="C:\Users\自己的用户名\AppData\Local\Docker\wsl\data\ext4.vhdx" 5、压缩 compact vdisk 6、完成
爬取地铁站数据,计算两点距离 爬取地铁站数据代码计算两点距离 效果图:
爬取地铁站数据代码 import json import requests from bs4 import BeautifulSoup headers = {'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'} def get_message(ID, cityname, name): """ 地铁线路信息获取 """ url = 'http://map.amap.com/service/subway?_1555502190153&srhdata=' + ID + '_drw_' + cityname + '.json' response = requests.get(url=url, headers=headers) html = response.text result = json.loads(html) with open('subway.csv', 'a+', encoding='gbk') as f: f.write('city' + ',' + 'line_name' + ',' + 'site_name' + ',' + 'gd_lon' + ',' + 'gd_lat' + '\n') for i in result['l']: for j in i['st']: # 判断是否含有地铁分线 if len(i['la']) > 0: print(name, i['ln'] + '(' + i['la'] + ')', j['n']) # 经度lon 纬度lat gd_lon = j['sl'].
vmware是大家经常使用的虚拟机软件,在其上面可以安装多种操作系统不管是windows系统、linux系统还是mac系统。那么win11系统也能安装吗?当然是可以的。
vmware安装Win11教程
1、首先我们需要在电脑上下载安装vmware虚拟机(选择经典即可)以及win11系统镜像文件。
2、接下来选择安装程序光盘映像文件,选择我们下好的win11的iso文件。
3、接下来选择客户机操作系统,我们选择win10 x64就可以,没问题。
4、接下来选择将要安装的位置,这里可以把虚拟机名称改为windows11。
5、选择给这个虚拟机分配的磁盘大小,这里选择将虚拟磁盘存储为单个文件,方便到时候删除。
6、最后一步,自定义一下我们这个虚拟机的硬件。
7、小编这里使用了8g内存,但是可以根据自己的实际情况减少,因为害怕运行出现卡顿,所以小编直接使用的8g的,没有试过其他的内存。然后点击完成就可以准备启动我们的虚拟机了。
8、打开虚拟机,如果出现EFI network time out字样,不必担心,先关闭虚拟机,然后在打开虚拟机的页面,点击编辑虚拟机,点击选项-高级,使用BIOS,确定。
9、重新启动虚拟机,此时应该可以正常看到windows的加载图标了。
10、进到安装页面,几乎不需要做什么选择,大部分选择next即可。
11、由于我们肯定没有密钥,所以点击红框中的i don’t have a product key。
12、这里我们选择安装你想要的版本。
13、这里我们选择第二个。
14、然后耐心等待即可。
15、系统安装完成后我们就来到了windows 11系统,然后进行一些基础设置即可。
16、设置完成后等待电脑开启进入win11系统桌面就代表我们已经安装完成了。更多内容欢迎咨询xitongbuluo.com小编。
import java.util.HashMap; import java.util.Map; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; public class WeChatUtils { // 应用ID和应用秘钥,需要在微信公众平台中申请 private static final String APP_ID = "YOUR_APP_ID"; private static final String APP_SECRET = "YOUR_APP_SECRET"; // 获取微信用户access_token的接口地址 private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token"; // 获取微信用户信息的接口地址 private static final String USER_INFO_URL = "https://api.weixin.qq.com/sns/userinfo"; /** * 获取微信用户的access_token * * @param code 微信小程序登录时获取的code * @return 包含access_token和openid的Map * @throws Exception */ public static Map<String, String> getAccessToken(String code) throws Exception { OkHttpClient client = new OkHttpClient(); String url = ACCESS_TOKEN_URL + "
前端 在ruoyi-ui中的vue.config.js中
下图为前端启动端口
下图为连接的后端接口
原理:为解决跨域问题 若依使用前端的反向代理。
url请求前端进行代理,映射到后端。
此处为dev模式,统一用proxy代理,因此只需修改内部的target
后端 ruoyi-admin中application.yml
Windows Server 2019负载均衡部署 ## 一、环境搭建 准备三台Windows Server 2019服务器并关闭防火墙
二、实验拓扑图 说明:
Web1-Windows Server 2019 -1
主机名为:WSS34-WEB1
外网IP(NAT):10.0.34.111
外网DNS1:10.0.34.170
外网DNS2:114.114.114.114
管理IP(仅主机):192.168.34.111
管理DNS:192.168.34.170
Web2-Windows Server 2019 -2
主机名为:WSS34-WEB2
外网IP(NAT):10.0.34.112
外网DNS1:10.0.34.170
外网DNS2:114.114.114.114
管理IP(仅主机):192.168.34.112
管理DNS:192.168.34.170
DC-Windows Server 2019 -3
主机名为:WSS34-DC
外网IP(NAT):10.0.34.170
外网DNS1:10.0.34.170
外网DNS2:114.114.114.114
管理IP(仅主机):192.168.34.170
三、域控制器安装 其他步骤有小报错警告什么的,忽略,直接点击下一步
⭕注意: 如果你使用的是Windows Server 2019就在以上步骤一路顺风
如果你使用的是Windows Server 2016的话,就会看到如下步骤报错无法进行安装
解决方案:(因为我没有使用Windows Server 2016来进行试验,无法提供详细操作过程,就大概描述一下)
使用cmd运行以下命令
net user administrator /passwordreq:yes 最后重新点击上一步→下一步解决
安装完成后系统将会重启,最后再关闭域防火墙,域控制器DC部署完毕
四、部署Web服务器加入域 1、重置SID(严谨一点,两台web服务器都要重置) 先在cmd中输入以下命令查看当前的SID
whoami /user Win+R键中调出运行窗口,输入以下命令即可调出重置SID的应用程序
sysprep 选择sysprep.exe右击选择管理员身份运行
2、给刚重置过SID的服务器分别重新配置IP地址还有进行计算机名的修改 3、加入域 这里用户名输入:administrator ,密码是自己设置的。然后看到下图就加入成功了!重启一下就好。
校准目标是:使用户行为的预估值尽可能逼近真实概率值,众所周知,在推荐系统中,很多情况下,我们的点击率通常会被错误的估计(通常会被高估),所以需要进行校准。
一、保序回归 保序:只影响CTR的绝对值,但不影响多条数据CTR之间的相对大小,即不影响商品最终的排序结果
分桶:将所有数据按模型输出的预估值(pCTR)进行分桶,对桶内数据的label(0/1值)求平均,作为近似的真实CTR
回归:通过分段线性回归将pCTR映射到CTR上
二、校准评价指标 1、predict click over click(PCOC) PCOC指标是校准之后的点击率与后验点击率(近似真实概率)的比值,越接近于1,意味着在绝对值上越准确,大于1为高估,小于1为低估,是一种常用的高低估评价指标。
2、calibration-N(cal-N) cal-N将样本集合按照自定义规则划分出多个簇分别计算PCOC,并计算与1的偏差作为标准误差。举个例子,将pctr根据值大小划分为多个桶,每个桶为一个簇,计算每个簇的PCOC及其与1的偏差 数学公式:
参考:https://zhuanlan.zhihu.com/p/460061332
背景:调整学习率可能会对模型提升1~2%,当前我们采用的学习率比较简单粗暴,使用指定学习率,为了优化模型,现对学习率进行探索,希望对我们模型的指标结果有所提升
一、工业界学习率现存形式 1、指定学习率 固定学习率,只在模型训练的全过程中,学习率只采用某个固定值,如0.15,进行模型训练
2、指定学习率+衰减 指定学习率+衰减,顾名思义是,满足一定条件内,使用固定学习率,如0.15,达到条件后,采用衰减的形式
代码如下:
指定学习率+衰减
initial_learning_rate = 0.15 lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay( initial_learning_rate, decay_steps=100000, decay_rate=0.8, staircase=True) 3、warm up 谈到warm之前,总结一下,学习率几种常见的衰减形式
3.1 衰减函数 指数衰减 tf.train.exponential_decay()
lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay
指数衰减 代码
lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay( initial_learning_rate, decay_steps=100000, # 衰减周期,当staircase=True时,学习率在decay_steps内保持不变,即得到离散型学习率; decay_rate=0.8,#衰减率系数 staircase=True) # 是否定义为离散型学习率,默认False def decayed_learning_rate(step): return initial_learning_rate * decay_rate ^ (step / decay_steps) # 当为False时,需要加一个判断语句 倒数衰减 tf.train.inverse_time_decay() tf.keras.optimizers.schedules.InverseTimeDecay 倒数衰减代码
tf.keras.optimizers.schedules.InverseTimeDecay( initial_learning_rate, decay_steps, decay_rate, staircase=False, name=None ) # staircase=False def decayed_learning_rate(step): return initial_learning_rate / (1 + decay_rate * step / decay_step) 分段常数衰减: tf.
目录 1.字节流字符流2.Reader和InputStream3.writer和OutputStream4.基本步骤 1.字节流字符流 针对文本文件,提供了一组类,称为“字符流”(典型代表 Reader ,Writer)
针对二进制文件,提供一组类,称为“字节流”(典藏代表 InputStream,OutputStream)
字符流=》读写的基本单位是字符
字节流=》读写的基本单位是字节
流:Stream,是一个类别,对于字节流而言,如果想从文件中读取100个字节,那我们可以一次直接读取100个或一个读取50个,分2次读取或一个读取20个,分5次读取有很多方法。
每一种流对象,又分为两种(咋们讨论的输入输出,都是以cpu为基准的)
输入:Reader ,InputStream
输出:Writer,OutputStream
2.Reader和InputStream 查看InputStream源代码可以知道,这是一个抽象类,要是用的话需要一个实现类,我们最常用到的输入输出都是在文件上进行操作的,因此我们常用FileInputStream
因此我们在使用的时候,我们需要先找一个实现类
InputStream inputStream=new FileInputStream("d:/test.txt"); //大家注意,我们是new FileInputStream() //里面指定一个文件路径,inputStream要打开这个文件的意思 //让当前的变量和这个文件关联起来 作为文件而言,我们有打开那么就一定会有关闭
inputStream.close();这个文件关闭十分重要,千万不要忘记
文件这里的资源吗,主要是以“文件描述符”,进程是使用PCB这样的结构来表示的(1.pid 2.内存指针,3.文件描述符),文件描述符就记载了进程打开了那些资源,没打开一个资源,就会在表中申请一个位置,,但是这个表是有程度限制的,一旦满了继续打开就会失败,导致咋们的代码/进程出现问题,这个问题是十分严重的。
所以大家一定要记得关闭文件。
那我们每一次都要手动关闭文件吗?其实不用,我们知道InputStream实现了一个特定的接口,那我们使用try语句来关闭
try(InputStream inputStream=new FileInputStream("d:/test.txt")) { //这样我们就不用手动关闭了,代码在出try语句的时候,会自动关闭文件 //执行语句 } 我们的读入有三个类型
read()无参数的read,相当于每一次读取一个字节
read(byte[] buffer)将读到的内容放到参数buffer数组中,此时的返回值是读到的字节数
read(byte[] buffer,int offset,int length)将读到的内容放到参数buffer数组中,但不是从头放,是从offest位置开始放,最多放length这么多内容,此时的返回值是实际读到的字节数
byte的范围是-128=》+127,或者是0-255,当文件读取完毕的时候,再次read就会返回-1,
大家看下面这个代码
当我们的文件写入abc,然后读取的会出现61,62,63,也就是abc的ASCII
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; public class Deno5 { public static void main(String[] args) throws IOException { try(InputStream inputStream=new FileInputStream("
我们先看一个星号三角形的例图:
星号三角形的特点如下
以打印输出和例图一模一样的图案为例进行代码编写。
思路分析
1)先打印输出星星前没有空格的星号三角形 。
代码如下:
#include <stdio.h> # define N 4 void main(){ int i,j,k; for(i=1;i<=N;i++){//控制打印输出4行星星 for(j=1;j<=2*i-1;j++){//控制打印输出每行的星星个数 printf("*"); } printf("\n");//打印完一行后都需要换行 } } 代码运行结果如下:
2)在原来代码的前提下,加上控制打印输出每一行第一个星星前空格个数的for循环语句。
案例全部代码如下
#include <stdio.h> # define N 4 void main(){ int i,j,k; for(i=1;i<=N;i++){//控制打印输出4行星星 for(k=1;k<=N-i;k++){ printf(" ");//控制打印输出每一行第一个星星前的空格个数 } for(j=1;j<=2*i-1;j++){//控制打印输出每行的星星个数 printf("*"); } printf("\n");//打印完一行后都需要换行 } } 代码运行结果如下
说明:代码已经写完,图案也打印输出完全正确。可是有一点,要是在考场上紧张找不到规律怎么办呢?巧办法来了:他要什么图案我们就打印输出什么图案啊,暴力做题法,一行一行的按图案打印输出星星啊!假如行数在10行以内这个办法完全可以,要是控制打印输出100行我的这个巧办法失效还是老老实实找规律用循环打印输出吧。
我的这种巧办法老师看了都直呼内行,双击666!
代码如下:
#include <stdio.h> void main(){ printf(" *\n"); printf(" ***\n"); printf(" *****\n"); printf("*******\n"); } 代码运行结果如下:
是不是特别简单,我自己都要佩服我自己了。
一些说明:
老师看了我用printf输出星星图案的答案,也就是我的巧办法,给了我2分,估计还是辛苦分。我的这个巧办法就图一乐吧,慎用。
一篇教你快速了解使用dom选择器
话不多说,直接上代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div class="wrapper" name="wrapper"> <p class="active">web</p> <p class="active">java</p> <p id="third"> <span>你好</span> <input type="text" name="username" value="张三"> <input type="text" name="pwd" value="123"> </p> </div> <script> //通过id获取,不是数组 let _third=document.getElementById("third"); console.log(third); //通过类名获取,伪数组 let _active=document.getElementsByClassName("active") console.log(_active[0].innerHTML,_active[1]); //通过标签名获取,伪数组 let _p=document.getElementsByTagName("p"); console.log(_p); //通过name属性名获取,伪数组 let _wrapper=document.getElementsByName("wrapper"); console.log(_wrapper); //H5新的获取方式 let _third1=document.querySelector("#third"); console.log(_third1); //获取的是第一个元素,不是数组 let _active2=document.querySelector(".active"); console.log(_active2); //获取的是所有元素,伪数组 let _active3=document.querySelectorAll(".active"); console.log(_active3); //可以使用css大部分选择器 let _span=document.
先看效果
代码如下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .wrapper{ width: 400px; } .contents{ border:2px solid black } .contents .content{ /* 默认全部隐藏 */ display: none; } .tabs{ display: flex; justify-content: space-between; } </style> </head> <body> <div class="wrapper"> <div class="tabs"> <div class="tab">商品介绍</div> <div class="tab">规格包装</div> <div class="tab">售后保障</div> <div class="tab">预约说明</div> </div> <div class="contents"> <div class="content">内容1</div> <div class="content">内容2</div> <div class="content">内容3</div> <div class="content">内容4</div> </div> </div> <script> let _tabs=document.
一、根据id名获取元素:getElementById 语法:document.getElementById(“id属性的值”);
返回值:是一个元素对象,即当前id的对象(获取到元素则返回该元素,如果页面上没有你所获取的id,则返回null)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <div id="d1"></div> </body> <script type="text/javascript"> console.log(document.getElementById("d1")); console.log(document.getElementById("d2")); </script> </html> 二、根据标签名获取元素:getElementsByTagName 语法:document.getElementsByTagName(“标签的名字”);
返回值:是一个伪数组,所以页面上没有对应标签的时候返回空数组
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <div name="d1"></div> <div name="d2"></div> </body> <script type="text/javascript"> console.log(document.getElementsByTagName("div")); console.log(document.getElementsByTagName("p")); </script> </html> 三、根据类名获取元素:getElementsByClassName 语法:document.getElementsByClassName(“类样式的名字”);
返回值:是一个伪数组,所以页面上没有对应标签的时候返回空数组
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <div class="c1"></div> <div class="c1"></div> <div class="c2"></div> </body> <script type="text/javascript"> console.log(document.getElementsByClassName("c1")); console.log(document.getElementsByClassName("c2")); </script> </html> 四、根据选择器获取元素
点击蓝字
关注我们
因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享 来源于网络,侵删
1.关于c语言的结构体:
首先我们为什么要用到结构体,我们都已经学了很多int char …等类型还学到了同类型元素构成的数组,以及取上述类型的指针,在一些小应用可以灵活使用,然而,在我们实际应用中,每一种变量进行一次声明,再结合起来显然是不太实际的,类如一位学生的信息管理,他可能有,姓名(char),学号(int)成绩(float)等多种数据。如果把这些数据分别单独定义,就会特别松散、复杂,难以规划,因此我们需要把一些相关的变量组合起来,以一个整体形式对对象进行描述,这就是结构体的好处。
2、首先我们要了解一些小知识
2.1**只有结构体变量才分配地址,而结构体的定义是不分配空间的。**
2.2结构体中各成员的定义和之前的变量定义一样,但在定义时也不分配空间。
2.3结构体变量的声明需要在主函数之上或者主函数中声明,如果在主函数之下则会报错
2.4c语言中的结构体不能直接进行强制转换,只有结构体指针才能进行强制转换
2.5相同类型的成员是可以定义在同一类型下的
列如
struct Student
{ int number,age;//int型学号和年龄
char name[20],sex;//char类型姓名和性别
float score;
};
最后的分号不要忘了 有的编译器会自动加上,因此有的同学就会不注意。
3、关于结构体变量的定义和引用
在编译时,结构体的定义并不分配存储空间,对结构体变量才按其数据结构分配相应的存储空间
struct Book
{ char title[20];//一个字符串表
示的titile 题目
char author[20];//一个字符串表示的author作者
float value;//价格表示 };//这里只是声明 结构体的定义 struct Book book1,book2;//结构体变量的定义 分配空间
book1.value;//引用结构体变量
定义结构体变量以后,系统就会为其分配内存单元,比如book1和book2在内存中占44个字节(20+20+4)具体的长度你可以在你的编译器中使用sizeof关键字分别求出来。
列如
当然,要注意一点:用sizeof关键字求结构体长度时,返回的最大基本类型所占字节的整数倍 比方说我们上面求得的为44 为 float(4个字节)的整数倍,
但是我们把title修改为title[22]; 这时正常长度为46 ,但是你会发现实际求得的为48,(4的整数倍)
这就涉及到结构体的存储:
1结构体整体空间是占用空间最大的成员(的类型)所占字节数的整数倍。
2.结构体的每个成员相对结构体首地址的偏移量(offset)都是最大基本类型成员字节大小的整数倍,如果不是编译器会自动补齐,
关于这个我们简单介绍下:
1.偏移量----偏移量指的是结构体变量中成员的地址和结构体变量首地址的差。即偏移字节数,结构体大小等于最后一个成员的偏移量加上他的大小,第一个成员的偏移量为0,
struct S1
{
char a;
int b;
double c;
一、作用 call、apply、bind作用是改变函数执行时的上下文,简而言之就是改变函数运行时的this指向call、apply、bind是Function.prototype下的方法,都是用于改变函数运行时上下文,最终的返回值是你调用的方法的返回值,若该方法没有返回值,则返回undefined。 二、区别 最主要的区别是call()、apply()方法是立即调用当前函数,而bind()是返回一个改变了this指向的新函数,并不立即调用。
call(),bind()的参数是依次传参,一一对应传递的。 apply() 需要把多个参数放在一个数组中,作为第二个参数传递 三、说明 (一)、call()
用法: call(newThis,arg1,arg2。。。)
call 的第一个参数就是 this 所要指向的那个对象,后面的参数则是函数调用时所需的参数。
1、 newThis包括以下类型:
(1) 传null,undefined或不传, 函数中的this指向window对象。
(2) 传递另一个函数的函数名,函数中的this指向这个函数的引用,则就指向函数体。
(3) 传递字符串、数值或布尔类型等基础类型,函数中的this指向其对应的包装对象,如 String、Number、Boolean等。
(4) 传递一个对象,函数中的this指向这个对象。
2、args是将会传入被绑定函数的参数,被绑定函数的执行时参数顺序为:newThis,args,原参数
列子:
var fan = { user:"dragon", fun:function(age,sex){ console.log(this.user); //dragon console.log(this.user,age,sex) //dragon 男 学习 } } var b = fan.fun; b.call(fan,'男','学习'); b.call(fan); //传递函数名. this指向这个函数的引用 function fan1(){ console.log(this); //输出函数a中的this对象 } function fan2(){} var fan3={name:"dragon"};//定义对象fan3 fan1.call(); //window 不传, 函数中的this指向window对象。 fan1.call(null); //window 传null, 函数中的this指向window对象。 fan1.call(undefined); //window 传undefined, 函数中的this指向window对象。 fan1.
<template> <view class="code"> <u-navbar title="找回" :autoBack="true" :fixed='true' :placeholder="true"></u-navbar> <view class="wrodtext"> 输入验证码 </view> <view class="code-tip-one"> <view class="code-tip">已发送至<text>+86 {{phone.substring(0, 3)}}****{{phone.substr(phone.length-4)}}</text> </view> <view class="code-errow" v-if="codeclolor == '#ff0000'">验证码输入错误</view> </view> <input class="cinput" adjust-position="false" auto-blur="true" @blur="blur" @input="codenum" :focus="focus" value="code" v-model="code" type="number" maxlength="6" /> <view class="code-input"> <view v-for="(item,index) in 4" :key="index" @click="codefocus(index)" :style='(index == code.length? "border: 5rpx solid #242832;width: 122rpx;height: 122rpx;line-height: 122rpx;":"color: " + codeclolor + ";" +"border: 2rpx solid" + codeclolor)'> {{code[index] && code[index] || ''}} </view> </view> <view class="
关于https 导致资源问题被不同岗位的同事问过很多次。 一、图片链接加载失败或下载资源失败。
报错信息:Mixed Content: The page at '<URL>' was loaded over HTTPS, but requested an insecure image '<URL>'. This request has been blocked; the content must be served over HTTPS.
意思是:- “Mixed Content”问题,在 https 网站中发起的 http 请求被禁止,这是因为 chrome 提高了用户安全策略,保护用户免受不安全下载的侵害(点击这里查看 chrome 文档 Protecting users from insecure downloads)
注意:https 协议的网站中不允许存在 http 协议的请求 http 协议的网站中允许访问 https 协议的资源 二、一般情况都是Nginx里解决
在nginx可通过在server或location后添加配置
#解决https请求http资源不可用的情况 add_header Content-Security-Policy "upgrade-insecure-requests;connect-src *";
欢迎大神批评指正~~
在互联时代,协同型SRM管理体系的广泛应用将成为必然趋势。我们团队调研了数百家企业对于协同型SRM管理系统的需求,形成了这份43页的报告以及协同型SRM的应用模板,希望帮助实现采供双方数据实时透明、消息及时互通、流程高效协作,建立高度互信,实现从供应商到供应伙伴的转变。
全文包括:SRM解决方案介绍、企业供应商管理案例等内容,干货满满!
点此直接领取>>供应商管理信息化方案报告
第一部分 企业供应商管理现状 组织内部找寻有效的生产力提高的来源是越来越难实现了。
——《财富》杂志
过去企业通过引入精益生产、TQC、OA、 ERP等管理方法和系统,实现了降本增效, 但想进一步增长则愈加困难。
供应商作为企业的核心组织要素,成为企业利润高增长的新方向。然而,大部分企业却仍采用传统方式管理,管理不规范、效率低、数据不透明等问题成为阻碍企业进一步发展的顽石,降本增效潜力巨大。
具体来看,传统供应商管理的痛点问题有以下几方面——
供应商档案管理:缺少供应商全生命周期管理体系、供应商准入不规范、缺乏客观、自动化的绩效考核、供应商资质证书管理混乱、供应商缺乏入口共享优质产品库招投标管理:招投标过程不透明,管理不规范、人工1对1电话邀标,效率低、线下招投标大会,耗时耗力询报价管理:人工编制报价单效率低、报价单通过邮件等渠道手工分发太繁琐、报价单手工从各渠道汇总进行比价,效率低、报价过程不透明,管理不规范合同管理:手工编制合同太繁琐,易出错、线下合同审批效率低财务管理:采供双方信息不透明,对账效率低,易扯皮、手工汇总数据易出错,实时性差、发票管理不规范,发票已开未开不透明订单管理:手工编制订单效率低、订单通过邮件/微信等低效方式传递、供应商订单确认状态不透明外部协作生产管理:供应商领料管理不规范,造成领料浪费;供应商生产进度缺乏管控,延迟交货成常态;设计需求缺乏流程管控,成品和需求不匹配...... 总结起来,就是:数据不透明! 消息不互通! 数据链不完整! 人工重复录入、汇总数据!这些问题无疑成为企业效益提高道路上的绊脚石。
我们再来看看供应商管理发展历程——
目前,大多数企业都处于2.0阶段的传统型SRM,正在向3.0阶段的协同型SRM发展。如果你的企业还处于1.0手工阶段,那么一定要加速供应商管理建设了。
那么协作型SRM究竟有什么价值?为什么能成为企业信息化的新风向?
提高供应商质量:通过供应商全生命周期管理, 实现供应商分级管理。增强采供合作关系:采供双方互联互通,数据实时透明,建立高度互信。降低采购低成本:在线实时高效采购寻源,供应商直接参与寻源,避免暗箱操作。提高产品质量:到货扫码质检提高质检效率, 到货合格率实时同步供应商, 8D改善提高供应商管理水平。提高到货及时率:实时掌握供应商生产进度、发货进度,提前识别延期问题。快速响应市场需求:提高供应链整体效率,打柔性供应链,实现快速响应市场需求。 我们可以利用简道云零代码平台,使企业的协同型SRM快速落地。
第二部分 简道云SRM解决方案介绍 为什么用简道云实现企业供应商管理,是好的选择?
因为,简道云为企业提供了一个完美的SRM解决方案——
基于简道云强大的跨组织协作能力,使企业仅通过一套系统,就能实现与供应商从【需求-寻源-合同-订单-收发货-质检-库存-财务】全流程之间的互联互通,数据实时透明,建立高效互信的新型采供关系。
我们一起来看看,简道云SRM解决方案能实现哪些效果?
1、实现供应商全生命周期管理 通过简道云SRM解决方案,企业可以对供应商的全过程进行管理和跟踪,包括供应商的工商认证、准入、考核、评级和改进优化等。这样一来,企业可以规范管理流程,提高管理效率,降低风险。
2、供应商注册-自动获取企业工商信息 供应商信息通过前端事件对接天眼查、阿里云等工商信息查询平台,通过接口自动填入供应商的多维度工商信息,比如纳税人识别号、企业状态、成立时间、法定代表人、注册资本、经营范围等。
3、强大的门户管理功能 供应商外部门户:潜在、合格供应商可登陆门户进行协作,支持微信、移动端、钉钉、企业微信、飞书等多个平台; 采购、财务等内部门户:为供应商管理提供统一入口。 4、高效协同、互联互通 利用简道云可实现采购企业与供应商实时在线协作,主要包括寻源协同、订单协同、收发货协同、质量协同、财务协同五个方面,实现从供应商到供应伙伴的转变,构建高效互信的采供关系。
⭐寻源协同
一键发起询价:采购可批量群发询价并自动通知到供应商,供应商输入价格即可便捷报价;自动比价:对供应商报价自动汇总生成比价单;全流程线上招投标:采购和供应商在线上即可完成从邀标、报名、答疑、投标到中标的全流程协同。 ⭐订单协同
快捷线上下单:数据自动关联,采购点击即可线上下订单到供应商;订单提交提醒:供应商可实时接收订单通知并查看、打印订单;订单进度把控:采供双方可实时查询最新订单进度情况。 ⭐收发货协同
便捷发货:发货时系统自动调取未发货明细,供应商可直接点击本次发货明细并打印发货单;同步发货进度:发货后自动提醒采购发货进度;扫码一键收货:到货后仓库扫码自动录入本次收货数据,确认无误即可完成收货。 ⭐质量协同
扫码一键质检:来料后,扫码自动录入本次质检明细,采购录入质检结果数量即可;
便捷退货发:现不合格数据,采购可直接申请退货;
8D质量改善:识别到问题后,采购可在线发起8D整改,供应商按标准进行改善;
信息实时透明:质检结果、退货明细、历史数据等,采供双方均可一键查看。
⭐财务协同
线上对账:供应商选择对账周期即可自动生成对账数据并打印对账单,采购审核无误完成对账;
发票管理:供应商上传发票后自动识别发票信息,财务审核完成后自动同步信息;
付款管理:供应商在线发起付款申请,采购、财务线上即可完成审批付款。
我们一起来看一看企业应用实例——
高创建工股份有限公司是建筑工程施工总承包特级和建筑行业(建筑工程、人防工程)设计甲级企业,面临着外部市场竞争激烈,国家调控政策收紧,内部信息化缺乏合理规划的背景下,公司存在许多痛点:外部竞争激烈,资金压力大融资难、政策收紧资质新政变革;项目风险管控不到位;管理创新意识薄弱,项目管理水平低......
于是,高创智慧云依托简道云为基础,集成在钉钉中,目前分为十二个子模块,后续将计划升级为十三至十五个模块。
我们简单选取两个板块,给大家介绍一下他们具体是怎么做的:
场景一:企业投标管理
痛点:
原先公司的投标管理是以线下的方式进行管控,无法掌控投标进度、投标项目成本,投标项目证章合规管控不到位,项目投标经验无法复用。
解决过程:
将整个投标流程分为投标管理、对手分析、客户管理、资质证件管理等模块进行搭建和串联。做到投标前查勘,投标时审批,投标后分析,自动汇总客户信息、员工证件信息,快速查找可用证件等功能。在每次投标之后,还能对本次投标进行复盘,指导下次投标。
价值:
实现了对投标项目的全生命周期管理,线上提醒,可以加速投标文件审批;证照、印章规范统一管理,支撑多场景投标规范使用。对投标结果进行统一整理,为项目复盘提供数据依据,让历史投标模板得以复用,灵活投标。
场景二:供应链管理
痛点:
项目库存成本和采购总成本居高不下,究其原因,线上线下不互通和仓库管理不规范是关键问题。
目录
前言
课题背景和意义
实现技术思路
一、图像预处理(Image preprocessing)
二、U-net网络模型(U-net network model)
三、实验结果与分析(Experimental results and analysis)
四、总结(Conclusion)
实现效果图样例
最后
前言 📅大四是整个大学期间最忙碌的时光,一边要忙着备考或实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科同学来说是充满挑战。为帮助大家顺利通过和节省时间与精力投入到更重要的就业和考试中去,学长分享优质的选题经验和毕设项目与技术思路。
🚀对毕设有任何疑问都可以问学长哦!
选题指导: https://blog.csdn.net/qq_37340229/article/details/128243277
大家好,这里是海浪学长毕设专题,本次分享的课题是
🎯毕业设计-基于机器视觉的眼底视网膜血管语义分割-U-net
课题背景和意义 眼底血管与人体健康息息相关,同时也作为医生诊断各 类眼科疾病以及心脑血管疾病的重要依据。眼底视网膜血管 结构特征变化与高血压、动脉硬化等心脑血管疾病有着密切 的联系,医生借助计算机图像处理技术,可以自动获取到眼 底图像中的血管形态。眼底图像血管提取的传统方法有匹配 滤波方法、阈值分割方法、形态学处理方法等。这些方法不 需要训练模型,但是血管分割的精度不够高。基于机器学习 的方法利用人工标记的血管图像来训练模型,以实现血管的 提取,Staal利用KNN(K-Nearest Neighbor)分类器来区分血 管的半径、亮度和边缘强度等特征信息。潘林等[2]为了克服光 照不均、对比度低以及病灶干扰等问题,提出了Gabor小波和 SVM(Support Vector Machines)分类器相结合的方法,利用多 种尺度的Gabor滤波特征和绿色通道灰度信息组成特征向量进 行降维,然后用SVM分类来区分血管。 近年来,卷积神经网络在图像处理领域取得了突破性。
实现技术思路 一、图像预处理(Image preprocessing) 为了下游分割任务更顺利地进行,我们先对图像进行 预处理。文献[3]单通道能够更加清晰地体现眼背景差异。 因此,在实验中将3通道图像按比例转换为灰度图像。原始 图像中血管与背景的对比度较弱,血管边界模糊,眼底图像 对比度较低,不易于人眼分辨。
使用OpenCv库中cv2.createCLAHE(clipLimit, titleGridSize)来实现这一功能。clipLimit是限制对比度阈值, 默认为40,直方图中像素值出现次数大于该阈值,多余的次 数会被重新分配;titleGridSize表示图像进行像素均衡化的网 格大小。经过上述操作后,可弱化眼底图像中的背景,提升 图像中血管区域的灰度,可以更清楚地显示血管结构。效果图如图所示。
二、U-net网络模型(U-net network model) 网络结构
U-net网络结构呈U字形,由卷积和池化单元构成。左 半边为编码器即如传统的分类网络是下采样阶段,右半边为 解码器是上采样阶段,中间的箭头为跳跃连接,将浅层的特 征与深层的特征进行拼接。因为浅层提取到图像的一些简单特征,比如边界、颜色等。
深层经过的卷积操作多抓取到图 像的一些高级抽象特征。跳跃连接将编码器中获得特征信息 引入到对应的解码器中,为上采样提供了更多低层次的空间 与信息。这些低级的信息通常为轮廓和位置等,为后期图像 分割提供多尺度多层次的信息,由此可以得到更精细的分割 效果。U-net的网络结构如图所示。
1.增加尺度变换 去掉马赛克之后,就什么数据增强都没有了,需要增加尺度变换
YOLOX-main/yolox/data/data_augment.py 增加一个函数 #163行
def random_perspective_rotation_scale( #新加的尺度变换 img, targets=(), degrees=10, scale=0.1, perspective=0.0, border=(0, 0), ): # targets = [cls, xyxy] height = img.shape[0] + border[0] * 2 # shape(h,w,c) width = img.shape[1] + border[1] * 2 # Rotation and Scale 旋转和缩放 R = np.eye(3) a = random.uniform(-degrees, degrees) # a += random.choice([-180, -90, 0, 90]) # add 90deg rotations to small rotations s = random.uniform(scale[0], scale[1]) ##### s = random.
目录
一般参数:
调整模型生成答案的倾向性:
一般参数: temperature:控制生成文本的随机性。较高的温度会导致更加随机和多样化的生成文本,而较低的温度则会更加保守和精准。取值范围为0到1,一般默认为0.5。
top_p:指定生成文本的多样性。该参数与温度类似,可以控制生成文本的随机性,但是会更加保守和精准。如果设置了top_p,则在保证生成文本的概率总和超过top_p之前,会一直选择概率最高的单词进行生成。一般取值范围为0到1,一般默认为1.0。
frequency_penalty:控制重复单词的惩罚力度。较大的惩罚力度会导致生成文本中不太可能出现相同的单词,而较小的惩罚力度则会容忍一定程度的重复。取值范围为0到1,一般默认为0。
presence_penalty:控制模型生成与文本样本中不同的单词的惩罚力度。较大的惩罚力度会导致生成文本中更多地包含文本样本中未出现的单词,而较小的惩罚力度则会限制生成文本的多样性。取值范围为0到1,一般默认为0。
best_of:指定API返回多少个完整的响应中的最佳响应。如果指定了best_of,则API将生成多个响应并从中选择最佳响应。
timeout:指定等待API返回响应的最长时间(以毫秒为单位)。
echo:指定是否返回输入的请求。
prompt:指定API的输入文本。
engine:指定要使用的OpenAI语言模型。
max_tokens:指定API生成文本的最大长度。
n:指定API生成的文本数量。
stop:指定当API生成的文本中出现此字符串时停止生成文本
来个python举例:
import openai # 设置 OpenAI API 凭据 openai.api_key = 'YOUR_API_KEY_HERE' # 设置生成文本的提示 prompt = "在一个令人震惊的发现中,科学家们在安第斯山脉的一个偏远、以前未开发的山谷里发现了一群独角兽。更令研究人员惊讶的是,这些独角兽竟然说着流利的英语。" # 设置 OpenAI 模型 model = "text-davinci-002" # 设置最大生成 token 数量 max_tokens = 100 # 设置 "temperature" 参数,控制生成文本的创造力 temperature = 0.5 # 设置 "top_p" 参数,控制生成文本的多样性 top_p = 1 # 设置 "frequency_penalty" 参数,防止生成的文本重复 frequency_penalty = 0 # 设置 "
解决办法 方法一:关于@Resource和@Autowired为null的解决办法方法二:多线程下@Value注入失败的解决办法 方法一:关于@Resource和@Autowired为null的解决办法 新建一个 ApplicationContext(spring上下文对象) 的工具类SpringContextUtil
public class SpringContextUtil { private static ApplicationContext applicationContext; // 设置上下文 public static void setApplicationContext(ApplicationContext context) throws BeansException { applicationContext = context; } // 获取上下文 public static ApplicationContext getApplicationContext() { return applicationContext; } // 通过名字获取上下文中的bean public static Object getBean(String name) { if(name == null || name.length()==0) { return null; } try { String beanName = ""; if(name.length() >1){ beanName = name.substring(0, 1).toLowerCase() + name.substring(1); } else { beanName = name.
1. 使用 /proc/cpuinfo 文件查看
/proc/cpuinfo 是一个存储有关 Linux 系统中 CPU 详细信息的虚拟文件。可以使用以下命令来查看 CPU 核心数:
cat /proc/cpuinfo | grep "cpu cores" | uniq 该命令会输出每个 CPU 核心的数量。例如,输出结果可能是这样的:
cpu cores : 2 这表明每个 CPU 核心有两个处理器。
2.使用 lscpu 命令查看
lscpu 命令可以显示计算机处理器架构相关的信息,包括硬件架构、型号名称、CPU MHz、CPU 核心数等等。要查看 CPU 核心数,可以使用以下命令:
lscpu | grep "^CPU(s):" | head -n 1 该命令会输出系统中可用的 CPU 核心数。例如,输出结果可能是这样的:
CPU(s): 4 这表明系统中有 4 个 CPU 核心。
@element-ui 改变单选框,多选框的颜色
注意 是写在less文件中,并在vue.config.js中配置
@ztColor: #da222a; // 全局单选多选按钮,选中颜色改变 /deep/ .is-checked { .el-checkbox__inner { background-color: @ztColor; border: 1px solid @ztColor; } .el-checkbox__label { color: @ztColor; } } /deep/ .el-radio{ &.is-checked { &.is-bordered { border: 1px solid @ztColor; } .el-radio__label { color: @ztColor; } .el-radio__inner { background-color: @ztColor; border: 1px solid @ztColor; } } }
对任给的3个正整数,求它们的最小公倍数
分析:递归设计的思想就是先找小规模问题去解,然后再递推地解决大问题。还可以直接设计一个求两个数的最小公倍数的函数LeastCommonMultiple()。这样,在主函数中通过函数的嵌套调用,就可完成求解3个数的最小公倍数的过程。
import java.util.Scanner; public class TEST2 { //题目:对任给的3个正整数,求它们的最小公倍数 //递归设计的思想就是先找小规模问题去解,然后再递推地解决大问题 // 还可以直接设计一个求两个数的最小公倍数的函数LeastCommonMultiple() // 这样,在主函数中通过函数的嵌套调用,就可完成求解3个数的最小公倍数的过程。 public static void main(String[] args) { System.out.println("Input 3 number:"); Scanner scanner = new Scanner(System.in); int x1 = scanner.nextInt(); int x2 = scanner.nextInt(); int x3 = scanner.nextInt(); //利用函数嵌套调用实现3个数的最小公倍数 int x0 = LeastCommonMultiple(LeastCommonMultiple(x1, x2), x3); System.out.println("x1.x2.x3,LeastCommonMultiple is " + x0); } //求两个整数的最小公倍数 public static int LeastCommonMultiple(int m, int n) { int max = (m > n) ? m : n; int c = 1; for (int i = max; i <= m * n; i++) { //最大的数值开始,终点为2个数的乘积 if (i % n == 0 && i % m == 0) { //第一次出现的数值就是最小公倍数 c = i; break;//找到第一个数值满足条件,跳出循环 } } return c; } }
关于QT项目移植到开发板,工作总结
首先需要在buildroot/package/rockchip下创建工程文件夹,此处以hello为例,作为工程名。
然后在hello目录下创建Config.in、hello.mk文件
Config.in
config BR2_PACKAGE_HELLO bool "hello" help hya qt demo hello.mk
########################## ##hello ######################## HELLO_VERSION = 1.0 HELLO_SITE = $(TOPDIR)/../app/hello HELLO_SITE_METHOD = local HELLO_LICENSE = Apache V2.0 HELLO_LICENSE_FILES = NOTICE define HELLO_CONFIGURE_CMDS cd $(@D); $(TARGET_MAKE_ENV) ~/workspace/RV1126_RV1109_SDK_2.3.2/buildroot/output/rockchip_rv1126_owl_50emmc_ipc/host/bin/qmake endef define HELLO_BUILD_CMDS $(TARGET_MAKE_ENV) $(MAKE) -C $(@D) endef define HELLO_INSTALL_TARGET_CMDS $(INSTALL) -D -m 0755 $(@D)/hello $(TARGET_DIR)/usr/bin/hello endef $(eval $(generic-package)) 重点关注11行:qmake的选择,因为我们要使可执行程序在开发板上运行,因此编译器应选择rv1126的SDK中带有的qmake
"cd $(@D); $(TARGET_MAKE_ENV) ~/workspace/RV1126_RV1109_SDK_2.3.2/buildroot/output/rockchip_rv1126_owl_50emmc_ipc/host/bin/qmake" 这里要改成自己的路径
可执行文件的安装路径19行:
"$(INSTALL) -D -m 0755 $(@D)/hello $(TARGET_DIR)/usr/bin/hello"
Mybatis入门操作 Mybatis内容 ✨ MyBatis的简介
✨ MyBatis的快速入门
✨ MyBatis的映射文件概述
✨ MyBatis的增删改查操作
✨ MyBatis的核心配置文件概述
✨ MyBatis的相应API
1.Mybatis简介 1.1 原始Jdbc操作 1.2 原始Jdbc操作分析 原始jdbc开发存在的问题如下:
① 数据库连接创建、释放频繁造成系统资源浪费从而影响系统性能
② sql 语句在代码中硬编码,造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变java代码。
③ 查询操作时,需要手动将结果集中的数据手动封装到实体中。插入操作时,需要手动将实体的数据设置到sql语句的占位符位置
应对上述问题给出的解决方案:
① 使用数据库连接池初始化连接资源
② 将sql语句抽取到xml配置文件中
③ 使用反射、内省等底层技术,自动将实体与表进行属性与字段的自动映射
1.3 什么是Mybatis 2.Mybatis的快速入门 2.1 Mybatis的开发步骤 2.2 环境搭建步骤 导入Mybatis的坐标和其他相关的坐标创建好一个user的数据表,内容为(id,username,password)创建好对应的User实体类编写UserMapper的映射文件编写Mybatis的核心文件 2.3 导入相关的坐标 <!--mybatis坐标--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.5</version> </dependency> <!--mysql驱动坐标--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> <scope>runtime</scope> </dependency> <!--单元测试坐标--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!--日志坐标--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.
定义和用法:
replace()方法用于在字符串中用一些字符替换另一些字符,或者替换一个与正则表达式匹配的子串。
stringObject.replace(regexp/substr,replacement) regexp/substr: 必需。规定子字符串或者要替换的模式的RegExp对象。请注意,如果访值是字符串,则将它作为要检索的直接量文本模式,而不是首先被转换为RegExp对象。
replacement: 必需。一个字符串值。规定了替换文本或生成替换文本的函数。
1、普通的字符串
当replacement 为字符串时,如果是普通的字符串,那很简单,就是将匹配到的字符远的成该字符串。
var str = 'hello world'; str = str.replace(/world/, 'javascript'); console.log(str) // -> hello javascript; 2、特殊标记$
对于replace使用正则,约定了一个特殊标记$
字符替换文本1、1、1、2、... $99与 regexp 中的第 1 到第 99 个子表达式相匹配的文本。$&与regexp相匹配的子串$`位于匹配子串左侧的文本$'位于匹配子串右侧的文本$$插入一个“$” 1)$i(i: 1 - 99):表示从左到右,正则子表达式(组)匹配到的文本。
var name = 'Peppa Pig'; name = name.replace(/(\w+)\s* \s*(\w+)/, '$2 $1'); console.log(name); // -> Pig Peppa var str = '"a", "bc"'; str = str.replace(/"([^"]*)"/g, "'$1'"); console.log(str); // -> 'a','bc' $`(tab键上方的字符):表示匹配字符串文本左边的文本 var str = 'hello world'; str = str.
html css实现九宫格布局,自适应屏幕,子元素之间、子元素与父元素之间的上下左右间距
html:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> html,body,ui,li{ padding: 0; margin: 0; } </style> </head> <body> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> <li>9</li> </ul> </body> </html> 方法一:grid布局 通过 display: grid;然后结合
grid-template-columns 属性设置列宽
grid-template-rows 属性设置行高
grid-gap行与列之间的间隙
实现
ul { overflow: hidden; background: none; padding: 100px; display: grid; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: 200px 200px 200px; grid-gap: 10px; } li{ border: 1px solid red; list-style: none; } 如图: 方法二:flex布局 通过 flex-wrap: wrap;然后子元素计算宽度并换行实现。
1. 百步穿杨 Problem Description
时维九月,序属三秋,辽军大举进攻MCA山,战场上两军正交锋.辽军统帅是名噪一时的耶律-James,而MCA方则是派出了传统武将中草药123.双方经过协商,约定在十一月八日正午十分进行射箭对攻战.中草药123早早就开始准备,但是他是武将而不是铁匠,造弓箭的活就交给聪明能干的你了,现在告诉你每种弓箭规格,即箭身的长度,以及每种规格弓箭所需要的数目,要求你把需要的弓箭都输出.
弓箭的基本样子为 “>±–+>”,其中"±–+"为箭身,数据保证箭身长度 > 2
Input
首先输入一个t,表示有t组数据,跟着t行: 每行一个N (N < 50 ),接下去有N行,第i行两个整数Ai , Bi,分别代表需要箭身长度为Ai的弓箭Bi枝. (Ai < 30 , Bi < 10 ) 输入数据保证每一个Ai都是不同的.
Output
按照箭身的长度从小到大的顺序依次输出所有需要的弓箭,"每一种"弓箭后输出一个空行.
Sample Input
1 4 3 4 4 5 5 6 6 7 Sample Output
>+-+> >+-+> >+-+> >+-+> >+--+> >+--+> >+--+> >+--+> >+--+> >+---+> >+---+> >+---+> >+---+> >+---+> >+---+> >+----+> >+----+> >+----+> >+----+> >+----+> >+----+> >+----+> tips:
一定要认真读题目!!测试数据是从小到大输出,所以就忘了要排序了,本题需要用结构体排序 , 需要自己写一个关于判断结构体排序的算法,return a1.
自我介绍 大家好,我是一名仲恺农业工程学院的大一学生,专业是电子信息工程。我之所以喜欢编程还要从玩游戏说起,小时候因为手机配置不行,玩游戏总是很卡,我便在网上找了很多修改画质的方法,当时也是第一次接触了代码,感觉很神奇,后面慢慢的也就开始感兴趣了起来。
编程目标 先要深入学习一门语言,我选择的是c和c++,提升自己的编程思维能力,能自己完成一个项目。
学习方法 大学生的时间还是很充足的,要懂得利用好时间,每天至少花1-2个小时学习,周末可以多挤出一点时间学习,而且还要多多复习,多敲代码,多做题,充分利用好网上资源还有学校资源,不懂的问题要自己多思考,实在不行再找老师或大佬询问,千万不要丢下不管。
要养成良好的作息规律,学习要在自己状态好的时候学,不建议熬夜学习,一是状态差,二是对身体不好,很容易熬出病。学习时尽量找个独处环境或者有学习氛围的地方。
总结 编程学习是枯燥无味的,但你也会从中发现一些有趣的事情,今后我也会发表一些我自己有趣的编程故事,让我们一起努力学习,早日找到好工作!
Pytorch从零开始实现Transformer 前言一、Transformer架构介绍1. Embedding2. Multi-Head AttentionQuery,Key,Value 3. Transformer BlockLayerNormFeed Forward 4. Decoder Block 二、Transformer代码实现0. 导入库1. Word Embedding2. Positional Encoding3. Multi-Head Attention4. Transformer Encoder5. Transformer DecoderDecoder attentionEncoder decoder attention 6. Overrall Transformer7. Test Code 总结日志参考文献 前言 2023年可以说是AI备受关注的一年,ChatGPT(GPT3.5)的问世引起了世界的轰动,近期GPT4的出现更是颠覆了各界对深度学习的认知,AI不止停留在特定任务的学习上,诸如此类的大模型已经初步符合人们最开始对AI的幻想——通用模型,通用模型可以处理多种场景下的难题。总所周知这些大模型背后的基础就是Transformer,于2017年提出后就席卷了整个学术界,各领域学者纷纷投入到Transformer的研究中,比如用Transformer取代ResNet作为Backbone取得更好的下游任务,或是单纯就Transformer的网络架构进行改进。“树要长多高,根就要扎多深”,在Transformer构建的金碧辉煌的大厦逐步建起时,不能忘记其最原初的根本。
正值论文写作稍微告一段落,有时间深入理解Transformer工作原理,复现Transformer和Transformer相关问题在工作面试中也是比较常见的,对于深度学习初学者,从零开始实现Transformer即Code the Transformer from scratch可能会是一个很艰巨的任务,甚至望而却步,不可否认在写这篇博客前我也是这样。Transformer的衍生比如BERT、Vision Transformer这种比较大的模型,下意识就会被这个“大”所吓到,觉得凭自己贫瘠的代码功底应该是难以实现。可实际做起来并没有想象那么难,“Just do it!”
希望每位读者看完这篇文章后能手撕Transformer或者对其有更深入的理解。
一、Transformer架构介绍 Transformer的模型流程图如上,取自原论文 Attention is all you need,目前引用量是69364。论文于2017年发表,由Google Brain和Google Research团队研发。据我所知,Transformer最初就是设计出来解决NLP领域问题的,比如机器翻译。
Tip:对于学习的建议是首先观看视频讲解,然后手打打一遍代码,最后看些博客对每个模块细致理解。(推荐视频和博客将放到文末参考文献部分)
接下来会简短介绍一下流程图中的各个部分,之后在下一节详细说明并实现代码。
1. Embedding 此处的Embedding包含上图中的Input Embedding和Output Embedding,实际上这部分代码的实现是一样的。按Input Embedding为例,其分为Word Embedding和Positional Embedding(即图中Positional Encoding)。Word Embedding作用是将一个个单词转化为向量,即词嵌入,位置编码Positional Encoding这是给单词句子对应词向量添加位置信息。
论文对位置编码这块并没有解释说明,就直接通过sin和cos对词向量的每个位置元素进行操作,偶数位(2i)使用sin,奇数位(2i+1)使用cos,然后将位置编码直接加(+)到词向量上。
2. Multi-Head Attention 多头注意力机制,也可称为Self-attention自注意力机制,叫法不一。仔细看可以看到图中在Embedding后引申出4路,有3路进入Multi-Head Attention模块,另1路在之后和多头注意力模块的结果Norm后汇合(其实就是相加)。Multi-Head Attention是Transformer的核心,而这3路信息则是Multi-Head Attention的核心。3路分别为Query,Key和Value。
ws=driver.window_handles[] driver.switch_to.window(ws) ws=driver.window_handles[] 获得指定索引窗口句柄 driver.switch_to.window(ws) 将视窗切换到指定窗口 然后,如果想关闭窗口, 使用 driver.close() 但有一个问题就是它会默认关闭新打开的窗口而且close函数无法传入其他参数
那么该如何关闭其他窗口呢?以某度网站为例
点击百度图标打开另一窗口
使用如下代码进行关闭
会发现新窗口被关闭,如图一所示
将代码改成这样,就能做到关闭指定窗口的操作,效果如下
此外,在获取指定窗口句柄之后,如果要对其他窗口进行操作,还需要用 driver.switch_to.window(driver.window_handles[]) 重新定位到你需要操作的窗口
最后附上源码
driver=webdriver.Chrome() driver.get('http://www.baidu.com/') driver.find_element_by_xpath('//*[@id="lg"]/map/area').click() ws=driver.window_handles[0] driver.switch_to.window(ws) time.sleep(1) driver.close()
使用map时,需包含头文件< map>
.
一、定义及初始化 // 直接定义 map<char,int> mymap; mymap['a'] = 10; mymap['b'] = 60; // 复制 map<char, int> second(mymap); // 通过迭代器 map<char, int> third(mymap.begin(),mymap.end()); 二、插入元素 map<string, string> mapStudent; // 用insert函数插入pair mapStudent.insert(pair<string, string>("r000", "student_zero")); // 用"array"方式插入 mapStudent["r123"] = "student_first"; mapStudent["r456"] = "student_second"; // 指定位置插入 map<string, string>::iterator it = mapStudent.begin(); mapStudent.insert(it, pair<string, string>("r324", "student_third" )); //效率更高 三、删除元素 map<int, int> mp; for (int i = 0; i < 20; i++){ mp.insert(make_pair(i, i)); } mp.
Java集群实战:单体架构升级到集群架构(一)使用NGINX建立集群
Java集群实战:单体架构升级到集群架构(二)实现session共享
Java集群实战:单体架构升级到集群架构(三)上传文件的共享
Java集群实战:单体架构升级到集群架构(五)定时任务
Java集群实战:单体架构升级到集群架构(六)分布式缓存REDIS
我们还是从这张图开始:
这张图是《Java集群实战:单体架构升级到集群架构(一)使用NGINX建立集群》里面使用的。如果你的代码中使用了synchronized和lock,它们在单体应用中跑得很好,但是在集群环境中就不好用了,因为它们只能锁住自己的tomcat,锁不了其他tomcat。这时候要把synchronized和lock改成分布式锁。常见的分布式锁有数据库的乐观锁悲观锁,zookeeper分布式锁,etcd分布式锁,redis分布式锁等等。我们前面已经使用redis来保存session了,所以今天我们就再使用redis分布式锁。
GitHub: GitHub - Dengxd/JavaCluster 所有源码都在这里,GitHub经常连不上,要多刷新几次
首先在pom.xml中引入redisson:
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.20.0</version> </dependency> 然后建立一个bean:
@Configuration public class Configure { @Bean public RedissonClient redissonClient() { Config config = new Config(); // use "rediss://" for SSL connection config.useSingleServer().setAddress("redis://127.0.0.1:6379"); RedissonClient redisson = Redisson.create(config); return redisson; } } 这样就可以使用redissonClient进行加锁操作
主要的加锁代码也很简单:
RLock lock = redissonClient.getLock("TicketLock");//建立锁 try { lock.lock();//锁住资源 //在这里写您要做的工作 } catch (Exception e) { e.printStackTrace(); return e.getMessage(); }finally { lock.
Java集群实战:单体架构升级到集群架构(二)实现session共享
Java集群实战:单体架构升级到集群架构(三)上传文件的共享
Java集群实战:单体架构升级到集群架构(四)使用REDIS分布式锁
Java集群实战:单体架构升级到集群架构(五)定时任务
Java集群实战:单体架构升级到集群架构(六)分布式缓存REDIS
对于大厂的IT技术人员来说,微服务架构是天天都在使用,滚瓜烂熟了。而对小厂的菜鸟程序员来说,我们天天做的都是CRUD,对我们来说集群、分布式、微服务也只是头脑中一个模糊的概念。我们写的大多是单体架构的系统,运行在一台服务器上,如果用户量增加了,服务器撑不住了,我们就加配置吧,反正阿里云腾讯云现在加配置也很容易。但是如果有一天(希望所有菜鸟都有这么一天),我们的用户数增加太快太多,使用最高配置的服务器还是撑不住,对我们来说这算不算是幸福的烦恼?――幸福的是老板,烦恼的却是我们。
这种情况下,我们想到了使用微服务,于我们开始学习spring cloud alibaba,就是不知道在我们学会之前,我们的服务器要崩溃多少次,就怕老板一生气把我们杀了祭天。所以说临时抱佛脚是不行的,学习要趁早!那么这时候,什么才是比较快的解决方法呢?我想可能就是使用集群架构。集群架构学起来相对容易,代码修改量也会少一些。
今天我们首先来建一个简单的集群,如下图所示:
总共三台电脑,一台安装NGINX,两台安装TOMCAT。这两个TOMCAT运行我们的单体应用程序,NGINX接受浏览器发来的请求,再把请求轮流转发给其中一台TOMCAT处理。如果您不理解这段话,也没关系,咱们开始动手操作,做完之后,你就明白了。没有三台电脑的同学,可以用虚拟机。要么就在一台电脑上操作也行,这时两个IP都要改成127.0.0.1
GitHub: GitHub - Dengxd/JavaCluster 所有源码都在这里,GitHub经常连不上,要多刷新几次
安装NGINX 因为所有程序员都会用WINDOWS,而有部分程序员不会用LINUX,所以我选择了WINDOWS7来安装。
NGINX下载地址:nginx: download
Stable version是稳定版,选择这个版本。下载下来是一个文件nginx-1.22.1.zip,解压之后,如下图所示:
打开文件夹conf里面的nginx.conf文件,找到这几行:
server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { root html; index index.html index.htm; } 改成这样:
upstream mytomcat { server 192.168.1.200:8000; server 192.168.1.201:8001; } server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { proxy_pass http://mytomcat; } 保存一下,NGINX就配置好了。
编程实现将任意的十进制整数N转换成R进制数(R在2-16之间)。N<0则直接退出。
一行中输入两个数分别是N与R,两者之间以空格隔开。
【输出格式】
将转换后的R进行数。
输入样例1:
在这里给出一组输入。例如:
23 2
输出样例1:
在这里给出相应的输出。例如:
10111
输入样例2:
在这里给出一组输入。例如:
23 8
输出样例2:
在这里给出相应的输出。例如:
27
输入样例3:
在这里给出一组输入。例如:
123 16
输出样例3:
在这里给出相应的输出。例如:
7B
设计思想:十进制转为二进制,对一个数不断的对二求余直到最后的商小于二,在将余数和最后的商逆序输出,转为R进制同理。不同的是从11进制开始要将其输出以字符形式+’55’。
#include<stdio.h> int main() {int N,R,i,j,h,t; char s[10000]; scanf("%d %d",&N,&R); i=0; h=N; while(t!=-1) {t=h%R; h=h/R; s[i]=t; i++; if(h<R) {t=-1; s[i]=h; }} for(j=i;j>-1;j--) if(s[j]>9) printf("%c",s[j]+55); else printf("%d",s[j]); printf("\n"); } 核心代码: i=0; h=N; while(t!=-1) {t=h%R; h=h/R; s[i]=t; i++; if(h<R) {t=-1; s[i]=h; }}