展开全部
是饱和蒸来汽的压力越高,沸点源越高,温度越高,反之2113压力5261越低沸点越低,温度越低。4102
在密闭条件中,1653在一定温度下,与固体或液体处于相平衡的蒸气所具有的压强称为饱和蒸气压。同一物质在不同温度下有不同的饱和蒸气压,并随着温度的升高而增大。纯溶剂的饱和蒸气压大于溶液的饱和蒸气压;对于同一物质,固态的饱和蒸气压小于液态的饱和蒸气压。
拓展资料:
(1)Clausius-Claperon方程:d lnp/d(1/T)=-H(v)/(R*Z(v))
式中p为蒸气压;H(v)为蒸发潜热;Z(v)为饱和蒸汽压缩因子与饱和液体压缩因子之差 。
该方程是一个十分重要的方程,大部分蒸汽压方程是从此式积分得出的 。
(2)Clapeyron 方程:
若上式中H(v)/(R*Z(v))为与温度无关的常数,积分式,并令积分常数为A,则得Clapeyron方程:ln p=A-B/T
式中B=H(v)/(R*Z(v))。
(3)Antoine方程:lg p=A-B/(T+C)
式中,A,B,C为Antoine常数,可查数据表。Antoine方程是对Clausius-Clapeyron方程最简单的改进,在1.333~199.98kPa范围内误差小。
.gitlab-ci.yml参数 .gitlab-ci.yml
.gitlab-ci.yml 用来配置 CI 用你的项目中做哪些操作,这个文件位于仓库的根目录。
当有新内容 push 到仓库,或者有代码合并后, GitLab 会查找是否有 .gitlab-ci.yml 文件,如果文件存在, Runners 将会根据该文件的内容开始 build 本次 commit 。
.gitlab-ci.yml 使用 YAML 语法, 需要格外注意缩进格式,要用空格来缩进,不能用 tabs 来缩进。
.gitlab-ci.yml 配置参数
关键字描述variables定义环境变量script必须参数,运行器需要执行的脚本image使用Docker image镜像services使用Docker services(服务)镜像stages定义流水线所有的阶段stage定义作业所处流水线的阶段(默认test阶段)only定义哪些分支运行,限制作业在什么上创建except限制作业在什么时候不创建tags作业使用的Runner运行器的标签when什么时候运行作业environment作用部署的环境名称cache指定需要在job之间缓存的文件或目录artifacts归档文件列表,指定成功后应附加到job的文件和目录的列表dependencies当前作业依赖的其他作业,你可以使用依赖作业的归档文件coverage作业的代码覆盖率retry作业失败时,可以自动执行多少次parallel指定并行运行的作业实例trigger定义下游流水线的触发器include作业加载其他YAML文件pages上传GitLab Pages的结果before_script作业执行前需要执行的命令after_script作业执行后需要执行的命令allow_failure允许作业失败,失败的作业不影响提交的状态 参数详情
variables 变量
variables 变量的优先级
变量的优先顺序是(从最高到最低):
触发变量或预定的流水线变量。 项目级别变量或受保护变量。 组级别变量或受保护变量。 YAML定义的作业级变量。 YAML定义的全局变量。 部署环境变量。 预定义的环境变量。 script
script 是作业中唯一必须的关键字参数,是运行器需要执行的脚本。
script: - mvn package docker:build -q -Dmaven.test.skip=false ....... image
image 指定使用Docker镜像。如 iamge:name
services
services 指定使用Docker镜像服务。如 services:name
Stages
stages 定义流水线全局可使用的阶段,阶段允许有灵活的多级管道,阶段元素的排序定义了作业执行的顺序。
相同 stage 阶段的作业并行运行。默认情况下,上一阶段的作业全部运行成功后才执行下一阶段的作业。默认有三个阶段, build 、test 、deploy 三个阶段,即 构建 、测试 、部署 。如果一个作业未定义 stage 阶段,则作业使用 test 测试阶段。默认情况下,任何一个前置的作业失败了,commit提交会标记为failed并且下一个stages的作业都不会执行。 stage
"
随着智能手机的出现,手机逐渐占据了我们生活当中的一部分,现在每个人的手机当中都搭载了大量的个人隐私,所以现在手机的安全性也就变得十分重要了。 IOS系统在安全性方面一直做的都是十分出色,主要也是得益于两方面,第一就是软件方面。iOS是一个封闭的系统下软件,仅限制于自身的Appstore下载,一款软件想要在iPhone的Appstore上架,就必须要经过苹果严格的审核。所以使用软件安全性非常的高,大量减少了感染病毒的几率。 并且在应用商店下载完软件之后苹果也会严格限制软件在手机上的权限,我们在每打开一个刚安装完的软件之后都会弹出各种权限提示,用户需要一一确认之后才可以使用。一般病毒主要的传播路径就是病毒软件,下载病毒链接等,这些路径大部分都被苹果严格的看管,提前预防了,自然就不需要去下载专门的病毒软件去看管手机了。 其次在iOS系统内部,所使用的源代码都是封闭性的,病毒很难去开发。相对安卓方面,因为系统与源代码都是开放的状态,现在安卓手机基本都会自带一个安全管家,去监管这个病毒的主要路径,而iOS用户就无需有这方面的担忧。那么大家会为iPhone手机安装一个杀毒软件吗? 如果有什么说的不对的,欢迎大家留言,小编一定积极改正。
"
啥年代了..你用苹果只从appstore下吗?
骚扰电话和垃圾短信呢
苹果用户少,鱼塘太小,封闭式系统 开发病毒麻烦,安卓用户多开放式系统,随便编个病毒,撒出去捞上来的鱼比苹果多多了。
小孩太多了,最基本的原因安卓是个开放平台,任何人都可以来,编写软件。用户不懂安装的话就中招了。苹果任何上架的软件都要通过审核。任何系统允许之外的调用都不会允许
苹果是在沙箱里运行程序,卡巴斯基之父都说iOS用不着杀毒软件。PS:除了App Store,越狱,还能通过链接下载临时版的APP
真正的病毒软件就是这些杀毒软件
因为没权限,怎么开发杀毒?
想想当年360被苹果下架就知道360有多流氓了!
说的安卓手机很多中毒了一样
throws throw的区别? 1.作用不同: throw 用于程序员自行产生并抛出异常, throws 用于声明该方法内抛出了异常;
2.使用的位置不同: throw 位于方法体内部,可以作为单独语句使用; throws 必须跟在方法参数列表的后面,不能单独使用;
3.内容不同: throw 抛出一个异常对象,且只能是一个; throws 后面跟异常类,且可以跟多个异常类;
4.如果异常抛给了main()方法,主方法不处理任何异常,而交给Java中最大头JVM,所以如果在main方法使用了throws关键字,则表示一切异常交给JVM进行处理。默认处理方式也是JVM完成。
throws throw必须是成对出现的吗?请举例说明 个人理解:不一定,当方法中的代码块出现了异常,而且不立刻处理,可以显式抛出给调用者,这时候只需要使用throws声明方法就可以了;当我们想自己抛出异常时使用throw,如果这个异常是运行时异常的话,就不需要throws进行声明,如果是检测异常,则此方法需要throws进行声明,此时才会成对出现。
请你写出你常见的10个异常类? 常见的RuntimeException异常:
1.NullPointerException: 空指针异常。当应用程序试图访问空对象时,则抛出该异常。
2.ClassCastException: 类型强制转换异常。它是JVM在检测到两个类型间转换不兼容时引发的运行时异常。
3.ArrayIndexOutOfBoundsException: 数组下标越界异常。跟数组打交道时,需要注意一下这个异常。
4.ArithmeticException:算术运算异常。当出现异常的运算条件时,抛出此异常。例如,一个整数“除以零”时,抛出此类的一个实例。
5.NumberFormatException: 数字格式异常。当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。如,”abc”转为int型
常见的 Checked Exception 异常:
1.SQLException:操作数据库异常 。提供关于数据库访问错误或其他错误信息的异常,它是Checked Exception(检查异常)。
2.IOException:IO异常。一般跟读写文件息息相关,它也是Checked Exception(检查异常)。平时读写文件,记得IO流关闭!
3.TimeoutException:阻塞操作超时异常。 指定超时的阻止操作需要一种表示超时发生的方法。 对于许多这样的操作,可以返回一个指示超时的值; 当不可能或不可取的时候,应该声明和抛出TimeoutException 。
4.FileNotFoundException:文件未找到异常。当试图打开指定路径名表示的文件失败时,抛出此异常。(IOException的子类)。
5.NoSuchMethodException:方法未找到异常。
前言 很多的工程用IDEA打开调试,如果用到 tomcat服务,都要配置一下,比如,几乎每一个java写的CMS内容管理系统都会用到tomcat,所以,很有必要单独拿出来详细说明一下。
参考: https://blog.csdn.net/wsjzzcbq/article/details/89463304
安装Tomcat服务器 上官网(https://tomcat.apache.org/download-90.cgi)下载一个免安装的版本:
下载完后放到 C:\tomcat\ 目录下即可。
标准安装步骤是要添加环境变量的,我就先不加环境变量,看行不行。
添加环境变量 1.右击,计算机——属性——高级系统设置——打开环境变量的配置窗口,在系统环境变量一栏点击新建。变量名为TOMCAT_HOME,变量值为Tomcat安装目录,此处为:C:\tomcat\apache-tomcat-9.0.41。点击确定即可。
2.同样,在系统变量里点新建:
变量名:CATALINA_BASE
变量值:C:\tomcat\apache-tomcat-9.0.41;
3.再次新建:
变量名:CATALINA_HOME
变量值:C:\tomcat\apache-tomcat-9.0.41;
4.在系统变量中找到Path变量,在变量值后面添加%CATALINA_HOME%\bin;
启动服务器 打开bin目录,可以看到里面的可执行文件是 jar格式的,也就是说,启动之前必须要先装好java环境。
也有很多的批处理文件,如下:
要启动服务器,点击运行 startup.bat 即可,关闭则使用 shutdown.bat。
测试: 在浏览器输入 http://localhost:8080/ ,果然可以顺利访问了。
新建一个java helloworld最简命令窗口工程 其实,这一步是不需要的。后面tomcat的相关内容跟helloworld最简命令窗口工程没有任何关系。
源码如下:
package helloworldPack; public class helloworld { public static void main(String[] args){ System.out.println("------ hello world -------"); } } 配置 tomcat 打开 Edit Configurations
点击 + 号,添加服务配置
找到 Tomcat Server,选择 Local
具体配置如下:
1.配置 Server:
2.配置 Deployment:
我正在尝试创建一个脚本,以通过adb shell从Android模拟器中查找和删除我的应用.
这就是我得到的:
adb shell "
cd data/app
for app in com.mycompany.*.apk;
do
echo $app
bundle=$(echo $app | sed 's/-[0-9]//g')
echo 'bundle name is $bundle'
if [ '$bundle' != '' ];then
adb uninstall $bundle
else
echo 'No apps found'
fi
done
exit
"
但是它似乎没有按预期工作.
>我的for循环不会遍历任何内容.如果我在外壳中完全按照上面的命令手动运行命令,则它可以工作,但是当我从shellscript运行命令时,for循环将看不到文件或任何内容.尽管如果添加“ ls”,它会正确打印文件夹的内容.
> echo $app不输出任何内容(空字符串),并且;
> echo’bundle name is $bundle’打印捆绑包名称为.
因此,它显然永远不会进入我的if块,而落入我的else子句中.
我究竟做错了什么?我对shell脚本不是很有经验,我会很感激任何想法.
我的目标是拥有一个shell函数,可以调用它来自动执行从模拟器中删除应用程序的过程,而无需手动拖动和卸载它.其他想法也非常受欢迎.
谢谢!
今天在自己的一台笔记本电脑上使用jupyternotebook,打开jupyternotebook之后启动IE浏览器,可是浏览器中啥也没有显示,空白的。
先是试了卸载jupyter notebook,再重新安装的方法,没有用,后来按下面的方法得到解决:
1.打开cmd,输入jupyter notebook --generate-config
然后会显示jupyter_notebook_config.py这个文件所在的位置。
2.根据上面提示的位置,打开C:\Users\Kevin\.jupyter\jupyter_notebook_config.py
3.在文件的末尾添加以下代码:
import webbrowser
webbrowser.register('2345Explorer', None, webbrowser.GenericBrowser(u'C:\\Program Files\\Mozilla Firefox\\firefox.exe'))
c.NotebookApp.browser = '2345Explorer'
然后你再打开jupyter notebook,就会发现它启动的是你设定的其他浏览器了。
参考:https://blog.csdn.net/weixin_42102444/article/details/88849905
进入我们刚才创建的项目目录cd vue_ant安装多个组件 cnpm i --save ant-design-vue moment // 安装最新版的ant-design-vue,支持vue3 cnpm i --save ant-design-vue@next 这里我们使用的是淘宝的景象cnpm,因为npm在国内使用很慢,这里安装了两个组件分别是ant-design-vue和时间库moment,多个组件同时安装,只需要在中间以空格隔开即可!
启动项目 npm run serve 全局引入组件 在main.js文件中全局引入组件ant-design-vue
import { createApp } from "vue"; import Antd from 'ant-design-vue' import App from "./App.vue"; // 引入css样式 // import 'ant-design-vue/dist/antd.css' // 引入less样式,这里会报错 import 'ant-design-vue/dist/antd.less' const app = createApp(App) // 关闭生产模式下的提示 app.config.productionTip = false; app.use(store) .use(router) .use(Antd) .mount("#app"); 引入less样式后,项目会保存,解决方案是,在项目根目录创建一个vue.config.js的文件,插入如下配置:
官方文档:
https://cli.vuejs.org/zh/config/#css-loaderoptions
module.exports = { css: { loaderOptions: { less: { javascriptEnabled: true }, } } } 必须开启webpack中javascript配置,重启项目即可解决!
一、list可以声明一个队列,里面的元素可以是不同类型的元素,元素类型灵活,缺点:因为元素类型可能不一样,所以效率比较低,处理大型数据或者复杂数据时,处理比较慢:
二、array 的数组中要求每个元素的类型必须是一致,所以处理效率较高,缺点:如果是多维矩阵时,array就没那么灵活
三、numpy的array方法要求元素类型必须也要一致,比如数字类型的数组如果设置某个元素为字符,则会报错,但是每个数组里的元素可以是整数、浮点数共存,且这样的数组类型认为是浮点型数组
而且在处理多维数组运算时,numpy.arange处理效率高很多:
使用numpy的arrange生成随机数:
生成初始值为指定值的:多维数组:
np.full中,不可使用shape
使用numpy生成初始值为随机数的多维矩阵 :
reshape:
文章目录 ViewModel 简介ViewModel 的生命周期ViewModel 的使用1、添加依赖2、创建 ViewModel3、获取 ViewModel 实例4、向 ViewModel 传递参数 ViewModel 简介 ViewModel 即是 MVVM 架构中的 VM 部分。ViewModel 专门用于存放应用程序页面所需的数据,它是连接 View 和 Model 的桥梁,使得数据和视图既能够互相分离又能互相通信。
ViewModel 的生命周期 ViewModel 的生命周期如下图所示:
在旋转屏幕的时候,Activity 会经历一次销毁与重新创建的过程,此时原本保存在 Activity 中的数据就会丢失,我们需要考虑此种场景下的数据的储存于恢复问题。但是通过 ViewModel 可以很好的解决这个问题,从上面的 ViewModel 生命周期图可以看到由屏幕旋转导致的 Activity 重建并不会影响 ViewModel 的生命周期。
ViewModel 的使用 1、添加依赖 首先在 app/build.gradle 文件中添加下面的依赖
dependencies{ ... implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" } 2、创建 ViewModel 为 Activity 和 Fragment 创建对应的 ViewModel,需要继承 ViewModel 类,示例如下:
class MyViewModel: ViewModel() { } 3、获取 ViewModel 实例 在 Activity 和 Fragment 中通过 ViewModelProvider 获取 ViewModel 的实例,示例如下:
项目代码 项目代码
体验一下 空格开始,左右箭头控制移动
体验一下
Phaser简介 Phaser是一个HTML5游戏框架。它使用了许多HTML5 API,例如Canvas,WebGL,Audio,Gamepad等,并添加了一些有用的逻辑,例如管理游戏循环并为我们提供了物理引擎。
使用Phaser,我们可以只用HTML,CSS和JavaScript来构建2D游戏。
项目需求 在使用Phaser构建Breakout克隆之前,让我们首先定义游戏的范围:
这款单人游戏具有30个积木,一个球拍和一个球的一个关卡
目标是让球摧毁所有积木,同时确保其不离开游戏画面的底部。
玩家将控制一个可左右移动的桨
该游戏是为桌面版网络用户打造的,因此将使用键盘进行输入
设置Phaser Phaser是一个JavaScript库,要开发和玩我们的游戏,我们需要一些基本的HTML来加载JS。在一个工作区中创建一个名为breakout的目录。
在目录中创建以下文件和文件夹:
一个index.html文件
一个breakout.js文件
名为的文件夹 assets
在您的assets文件夹中,创建一个images文件夹
游戏资产是游戏使用的艺术品,声音,视频和其他数据。对于这个简单的Breakout克隆,没有多少资产需要使用文件夹进行组织。但是,优良作法是将资产与代码分开,并按类型将资产分开。
将以下代码添加到您的index.html文件中:
<!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"> <title>Breakout</title> <style> html, body { margin: 0 auto; padding: 0; width: 100%; height: 100%; } #game { margin: 10px auto; padding: 0; width: 800px; height: 640px; } </style> </head> <body> <noscript>You need to enable JavaScript to run this app.
前端和后端开发哪个工资高?一般来说前端开发平均薪资17k左右,后端开发平均工资16k左右,能拿到这个薪资水平的一般是有1-2年工作经验的开发人员,由于公司要求几个人能力不同薪资差距还是比较大的。
前端和后端开发工作内容对比:
Web前端开发做什么?
Web前端开发主要是通过html、css、js、ajax、DOM等前端技术,实现网站在客服端的正确显示及交互功能。我们能看到的界面都可以理解为前端,比如Web端的界面,App端,小程序端,H5端等。设计页面的显示框架,包括网页的色彩、字体大小、一些上一页下一页等交互按钮等。
初级Web前端开发工程师职位的月平均收入为15K左右,随着工作经验的增长,有3年工作经验的Web前端工程师月平均收入水平能达到30K,一般有一年工作经验的Web前端开发工程师年薪可以达到15万,一些工作5年以上的工程师能成为互联网公司的技术总监或者是产品经理,年薪肯定也在随之增长。
在前端领域混了这几年,总结了一套前端学习的精讲视频和学习路线,如果有对前端开发感兴趣的伙伴,不管你是想转行,或是大学生,还有工作中想提升自己能力的web前端党,欢迎大家的加入我的前端开发交流群:603985993 希望大家诚心交流!,与企业需求同步。好友都在里面学习交流,每天都会有大牛定时讲解前端技术!也可以关注我的微信公众号:【前端留学生】 每天更新最新技术文章干货。
后端开发做什么?
通常人们把用户看到的称为前端,而把用户看不到的部分称为后端。开发网站项目会分为前端和后端两块业务,前端就是我们浏览的网页,利用css、js、html标签语言组合成的html文件通过浏览器渲染出来的前端编程;
通过前端发送请求给到服务器,服务器会根据不同的请求作出相应的处理响应,这处理响应也是通过代码逻辑来实现,也就是后端编程。后端主要是处理业务逻辑并且和数据库交互,把数据按预定的逻辑处理完以后返回给前端,并且接收前端的请求对前端的请求作出响应。
后端平均工资16.0K,其中 10K-15K 工资的占比最多,达 25.9%。不同地区也存在较大的差异。
Web前端工程师是目前互联网行业当中招聘需求非常大的一类,近日随着Web前端行业的高速发展,国外的前端开发和后端开发人员占比为1:1,但占比仍然是1:3以下。
很多程序员不知道自己值多少钱,有的人不敢要工资有的人狮子大开口。想知道自己值多少,到市场上试水是做好的办法。
1 先安装tensorflow, 配置如下:
CUDA :10.0, CUDNN : 7.5.0 , tensorflow1.14 ,GTX1070, python 2.7 , gcc 4.8 , 安装很顺利
2 下载deeplab_v3+
deeplab_v3+版本影响很大,我下载的版本是:
https://github.com/tensorflow/models
2. 安装deeplab_v3, 先在/deeplab_v3/research 目录下打开终端,输入:
export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim 3. 运行测试程序:
python deeplab/model_test.py 一次性完美通过,无任何问题。
场景:最近做tree异步加载的功能,但是发现只有我第一次点击的时候,会调用方法加载,后面再点击都不会再加载。
需求:每次点击都会加载
解决方法:
用onExpand,onLoad,loadedKeys,expandedKeys
<Tree showIcon blockNode loadData={this.onLoadData} onLoad={this.onLoad} // 节点加载完毕时触发 onSelect={this.onSelectTree} selectedKeys={selectedKeys} onExpand={this.onExpand} // 展开/收起节点时触发 expandedKeys={expandedKeys} // 已经展开的节点 loadedKeys={loadedKeys} // 已经加载的节点 > {this.renderTreeNodes(dataSource)} </Tree> // 展开/收起节点时触发 private onExpand = (keys) => { const { loadedKeys, expandedKeys } = this.state let newLoadKeys = loadedKeys // 判断当前是展开还是收起节点,当前展开的长度比之前的少,说明是收起。 if (expandedKeys.length > keys.length) { // 当是收起的时候,把这个收起的节点从loadedKeys中移除 newLoadKeys = loadedKeys.filter((i) => keys.includes(i)) } this.setState({ expandedKeys: keys, loadedKeys: newLoadKeys }) } // 节点加载完毕时触发 private onLoad = (loadedKeys) => { this.
概述 Azure DevOps Server (原名为Team Foundation Server)是微软研发管理平台产品。作为企业重要的研发数据管理平台,系统中存储着软件研发项目的需求、代码、文档等重要信息,我们应定期备份 Azure DevOps 服务器的数据库,以减少因设备故障或其他意外事件而丢失数据的风险。
通过DevOps Server自带的"计划备份向导"功能,可以方便地备份所有数据;在DevOps Server中,数据库是系统数据层的一部分,存储在SQL Server中。还原 Azure DevOps 服务器部署所需的所有信息都存储在这些数据库中,实现系统还原无需备份DevOps Server客户端计算机或应用程序层服务器。
本文主要介绍如何在DevOps Server中使用计划或手动的方式,实现数据备份。
创建备份 我们可以使用DevOps Server管理控制台中的"计划备份"工具为 Azure DevOps 服务器部署备份数据。如果我们定期备份这些数据库,则可降低因设备故障或其他意外事件而丢失研发过程中的数据的风险。
注意:如果我们使用的 SQL Server 的版本为企业版或数据中心版,并且希望将集合和配置数据库还原到 SQL Server 的标准版本,则在进行备份之前,必须关闭 SQL Server 的压缩功能压缩,具体可以参考这个链接(https://docs.microsoft.com/zh-cn/troubleshoot/azure/devops/disable-sql-data-compression?WT.mc_id=DT-MVP-5001330)
必要权限 在创建备份之前,确保你使用的账户是DevOps Server的系统管理员的成员、SQL Server的系统管理员角色(SysAdmin)。
另外,Azure DevOps 的服务帐户 (我们一般创建一个专用的服务账户,例如DevService) 必须具有 SQL Server 执行备份和创建维护计划的权限;服务器账户还应该具备备份路径的读写权限。
例如我们的备份路径为\DevBackupServer\DevBackupFiles,那么服务账户必须可以读写这个网络路径。
创建备份计划 打开 Azure DevOps 服务器管理控制台,选择"计划备份"页,然后启动向导以创建备份计划。
备份必须存储在网络可访问的位置,配置计划备份的帐户和 Azure DevOps 服务器都必须对该位置具有完全控制。您还可以选择备份集的保留时间以及用于备份类型的文件扩展名。 如果您的服务器配置了 SMTP 邮件功能,您可以选择针对特定事件的电子邮件警报。如果没有,则所有选择都将变暗。在我们的实际部署中,一般都会配置邮件功能,毕竟数据备份是系统维护中最重要的事情。 在三种默认计划之间进行选择,或创建自己的自定义计划。我们一般选择自定义备份。 完成向导。如果您的部署使用报告,系统将提示您输入密码,以便备份用于报告加密密钥。 配置计划备份后,系统会自动按照按计划运行备份。我们还可以立即进行备份;立即备份会立即运行备份程序。如果我们长时间没有做过数据备份,建议你马上执行一次完整备份。 如果需要,你还可以从微软Azure DevOps Server 的在线文档,查询更多的权威资料
------------------------------------------------------------
眼看又要年底了,趁着这个双休,给即将过去的 2020 做个简单的总结。
今年发生了很多事情, 对我的影响很大。
年初,2020年1月7日,我入职了上一家公司,在一个 Unity 项目组里做游戏开发。工资虽然不高,但是业务轻车熟路。也在组里涨了不少见识。因为是一个很新的项目组,并且之间我要接手的工作的负责人在我去了不久很快就离职了,我在项目里很快就接手了战斗开发的任务。
战斗开发在卡牌游戏里算是比较核心的业务了。最开始的工作不是很难,并且还发现之前一些同事的代码质量非常差。起初一段时间的工作算得上是平稳过度,工作压力和精神压力并不大。
在那段时间里,我抽出了比较多的时间能自学一些技术相关的东西。零零散散看过很多,印象里追着看了很久的 OpenGL 纯英文教程,了解了一些 C++ 和 Unity 互相调用的机制,对 Lua 做了更多的了解,在 Unity 里做一些 2D 动作游戏的 Demo , 玩了玩 行为树, 了解一些 Unity 的特性等等。
这种状态一直持续到了 五六月份。
再之后工作里战斗要重新写,有机会接触和实践了 ECS. 在这个过程里收获很大。 一方面来自于 ecs 本身,也体会到了 战斗逻辑和表现分离的 细节。
搞定了纯 Lua 的 ECS 结构之后,我在此基础上写了一个类似版的 C# ECS 框架,并且搭建了一个小的 类似炸弹人的 gameplay 的游戏。
借助 ECS 灵活的 增删 System 的机制, 我后来又给这个 demo 增加了联网通信机制。并且实现了基础的 服务器转发消息的 Lock Step 多人同步的机制。
在实现的过程中,搞定了很多细节,包括手撕 TCP 二进制流搞定半包粘包,转发服务器 socket 采用 poll 的方式处理各个客户端的消息,多线程处理消息分发等等细节。
立体几何一类题的两个秒杀公式
大家好,我又回来了.
欢迎关注:[1点数学]
本文摘要: 1. 双半径单交线公式及其证明
2. 公共边两对角公式
3. 两个公式的应用
今天给大家介绍立体几何中两个公式,
这两个公式的使用条件是:
存在两个平面互相垂直.
具体内容请看下面的图片.
如果你想获得本文的文档,请{关注}+{点赞}+{转发},然后私信我,或者在文章后面留言.
正文开始:
双半径单交线公式 若相互垂直的两凸多边形的外接圆半径分别为R_1,R_2,两外接圆公共弦长为L,则由两凸多边形顶点连接而成的几何体的外接球半径: R=√[R_1^2+R_2^2- (L^2)/4].
公共边两对角公式 若相互垂直的两凸多边形(存在外接圆)公共边的长度为a,公共边(弦)在两凸多边形内所对的圆周角分别为α,β,则由两凸多边形顶点连接而成的几何体的外接球半径: R=a√(1+1/tan^2α+1/tan^2β).
感谢大家的观看,如有疑问请留言.
感谢大家的支持,如果喜欢的话就点个赞吧~
这里写自定义目录标题 如何使用FPGA驱动PHY芯片前言必要的硬件知识如何确定PHY芯片的物理地址?如何确定PHY芯片的工作模式? 如何驱动PHY芯片?MDIO的通讯协议是什么?PHY芯片怎么收发数据? 如何使用FPGA驱动PHY芯片 前言 笔者因为工作的原因接触到使用FPGA驱动PHY芯片进行通信,期间接触到了德州仪器的dp83849,博通公司的B50610,裕太车通等芯片。下面以博通公司的B506102为例来讲解如何使用和驱动PHY芯片。
必要的硬件知识 对于嵌入式软件开发来说,不讲硬件就讲软件构架的行为都是耍流氓。
如何确定PHY芯片的物理地址? 首先读者要明确一点,PHY芯片的物理地址是什么?这个东西有什么意义? 假如在你使用的电路板子上存在多个PHY芯片,为了区分每个不同的PHY芯片,给定PHY芯片一个独有的地址,从而确定我发送的的控制信号是给哪个PHY芯片的,而这个地址就是PHY芯片的物理地址。根据MDIO的协议,PHY的物理地址是5Bit数据,则理论上来说一根总线最多可以驱动2的5次方,即32个PHY芯片。但是实际上一般不会这么使用,首先在一般的工程中用不到这么多芯片,其次就是FPGA的引脚往往有很多,也不会如此的节省引脚。
那么如何给定PHY芯片的物理地址呢?一般来说,PHY芯片的物理地址都是通过PHY芯片管脚连接的电阻的上拉下拉决定的。即当你板子焊接好后,PHY的物理地址就确定了,除了改变硬件连接之外,没有其它办法改变PHY芯片的物理地址。
PHY芯片有一个POS(英语原文叫PowerOnStrapping ,笔者也不知道对应的中文名词是什么)的过程,即PHY芯片在上电的过程中,通过硬件的连接确定PHY芯片的物理地址,工作模式等等。
如何确定PHY芯片的工作模式? 以博通芯片为例,此芯片支持两种接口:MII和RGMII。在上文提到的POS过程中,根据控制引脚的电阻上拉下拉决定。
如何驱动PHY芯片? 以MII为例
读者可以把PHY芯片的接口简单的理解为两部分,其一为控制接口,包括MDC, MDIO两个管脚;其二为通讯管脚,包括TXCLK, TXD, TXEN, RXCLK, RXD, RXDV等信号。
控制管脚用于了解和控制PHY芯片的工作状态,通过读取和写入寄存器数据的方式了解当前PHY芯片的工作状态。MDIO是一种串行通讯方式,每次读取或者写入16位数据,至于每一位数据代表什么,就请各位读者去看对应芯片的器件手册了。其中MDC起到的是同步时钟的作用,其每个周期应该发送和接收MDIO一个bit数据。以笔者使用的,裕太车通的YT8512的MII规定为例:根据工作模式的不同,如果工作在100M工作模式下,MDC应该为25MHz的时钟,如果工作在10M工作模式下,MDC应该是2。5MHz的时钟。
通讯管脚就更好理解了,就是发送和接收数据的管脚。当发送信号的时候TXEN作为发送信号的使能位,将其置为高电平后只需按照TXCLK时钟把要发送的数据赋给TXD端口就行了;同理,当接收信号的时候当RXDV置为高电平意味着发送的信息已经开始到达PHY芯片,只需按照RXCLK时钟把RXD信号存储起来就好。
MDIO的通讯协议是什么? 所谓MDIO总线通信即FPGA和PHY芯片之间控制接口的通讯方式,根据FPGA读和写操作的不同,又分为两种不同帧格式,这个帧都是FPGA发送给PHY芯片的,分为以下几个部分:
前导码(PRE):
器件手册上为Preameble,一般是32个或者32个以上bit的高电平,用来提醒PHY芯片数据将要来临。
起始码(ST):
器件手册上为Start Of Frame。以0,1作为发送帧的起始位。即先发送一个低电平,和前面32个高电平分隔开,再发送一个高电平。
操作码(OP):
Opration Code。用来使PHY芯片区分这帧数据是读操作还是写操作。如果是读指令,发送1,0;如果是写指令,发送0,1;
PHY的物理地址(PHYAD):
PHY Address。PHY芯片的物理地址,用于区分特定的PHY芯片,在原则上讲,一条MDIO总线可以驱动32个PHY芯片,但是实际上往往不会这么做。如果读者朋友们使用的是FPGA开发板的话,往往只有几个PHY芯片,因为FPGA的并行操作特点,还有很可能是每个PHY芯片单独有一根MDIO总线连接,但是值得说明的是,这个5Bit数据是不可或缺的。请读者朋友们仔细读器件手册,弄清楚相应的PHY芯片对应的物理地址。
寄存器地址(REGAD):
Register Address。 PHY芯片往往有很多寄存器用于配置相应的工作模式,或者监视芯片的工作状态,期存器中的数据便是下文中的Data数据,往往是16Bit的。
转换码(TA):
Turn Around。根据读写操作的不同,TA也会有不同的输入,这很好理解,在写操作状态下,FPGA只需不停地输入便可;但是在读操作状态下,PHY会向FPGA返回数据,所以需要两个时钟的时间作为缓冲。读操作下TA为Z,0;写操作下为1,0。
数据(DATA):
读出或者写入的数据,至于这16bit数据每一位代表什么意思,就需要各位读者去看相应器件的器件手册了。
图为博通芯片的MII接口
PHY芯片怎么收发数据? //TODO
题目 As a world-famous traveler, Prof. Pang’s research interest is to travel as many places as possible in his life.
We have a segment {[0, n]}[0,n]. There are two travelers on it. The first one is on position p 1 p_1 p1withvelocity v 1 v_1 v1(which means s/he can walk v 1 v_1 v1unit on the segment per second). The second one is on position p 2 p_2 p2with velocity v 2 v_2 v2
题目 In mathematics, the Fibonacci numbers, commonly denoted as f_nf
n
, is a sequence such that each number is the sum of the two preceding numbers, starting with 1 {1} 1 and 1 {1} 1. That is, f 1 = 1 , f 2 = 1 f_1=1,f_2 =1 f1=1,f2=1 and f n = f n − 2 + f n − 1 ( n ≥ 3 ) f_n = f_{n-2} + f_{n-1}~(n \ge 3) fn=fn−2+fn−1 (n≥3)Thus, the beginning of the sequence is 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 , … 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 , … .