学习vue的时候遇到了一个路由的问题.首先自己刚开始学,确实太菜了… 这个问题就是使用this.$router.push添加了跳转的路由地址,router那边也添加了跳转的vue组件,结果点击这个按钮没有发生跳转,但是地址栏的地址已经发生了变化,再次点击按钮的时候会报错:
这个错误是因为不能跳转当前地址.
然后是我在网上看到很多人用了一个改写路由的push方法:
const routerPush = VueRouter.prototype.push VueRouter.prototype.push = function push (location) { return routerPush.call(this, location).catch(error => error) } 这个方法在我这里没有发生作用…
然后我又在网上寻求帮助,遇到一位大佬,他告诉我说:
1.首先,你要记得在父容器里使用 router-view
2.其次,链接应该用 router-link
3.链接应尽量用名称,不要用实际路径,方便维护
4.所以这里你应该写成 router-link(:to="{name: ‘member.new’}")
5.报错本身是正常的
然后我才意识到我没有使用router-view,我又问了一下,确实这个是必须要有的.
最后我加上router-view之后还是没有成功,于是我又按照之前在网上看到的一个方式:
1.给router-view 添加一个name属性
2.再路由中把component属性改为components,多了一个s
3.components属性是一个对象里面需要有一个属性,属性名就是上面router-view 中添加的name的值,然后属性值就指向要跳转的vue组件
到这里就把问题解决了,至于为什么要把component改成components,其实我也不知道…
接下来就是我寻求帮助的全过程
实验室自1月初发布“渗透新鸟WEB安全零基础入门到进阶培训”以来,已经2个月了,2个月内我们按计划每周录制2节课,并针对这2节课内容,每周6进行直播答疑讲解,最后布置家庭作业,讲师进行批改。 授课内容汇总如下:
疫情期间为让加入知识星球的同学更快的掌握WEB攻防技术,还设计了知识星球教学内容配套靶场,并购买了3年靶场服务器:4核/8G/50G/5M
靶场采用iis+asp+aspx+php+mysql+access环境,使用护卫神主机大师搭建而成。附带cms80余个,并安装了awvs12,appscan最新版,nessus破解最新版8.9.0,插件为12月份更新。靶场包含SQL注入,xss,文件包含,csrf等常见漏洞。除常见渗透测试靶场源码之外,另有0组资料库中的漏洞cms进行即时更新,以便知识星球成员进行更加贴近实战的练习,充分培养知识星球成员的动手能力。
这样书籍(可签名)+配套视频+配套靶场,可以边看书边学习视频边在靶场中练习,在练习中学习,在学习中练习,理论联系实际,更加贴近实战!
书籍:https://item.jd.com/12401707.html
靶场:study.ms08067.com
最后再重申下我们的宗旨:
1.只做我们出版图书的配套视频及衍生讲解,写出一本书绝不是网上一些培训随便编个大纲或者PDF所能比拟的,我们以此来保证我们的课程质量。
2.只在知识星球开展,一来采用第三方平台,保质保量保时效;二来以确保读者不满意可以在3天内无理由退款。
3.课程都是我们团队录制视频,并至少100课以上,如果你想通过参加某个二三十节课的一周班,就想在某个安全领域有质的的飞跃的话,我劝你不要太天真,人生没有捷径,该走的路,一步都不能少,莫欺自己。
4.保持低价,很多朋友看我录制这么多课,劝我多收点费用,但是他们不知我读者60%都是25岁以下,也就是说是学生这个群体,所以我现在,包括以后推出所有蜜圈都会定价365元!
最后再介绍下课程目录:
期待更多志同道合的同学一起交流讨论学习,乱七八糟的人就不用来了!
Ms08067安全实验室
专注于普及网络安全知识。团队已出版《Web安全攻防:渗透测试实战指南》,《内网安全攻防:渗透测试实战指南》,目前在编Python渗透测试,JAVA代码审计和二进制逆向方面的书籍。
团队公众号定期分享关于CTF靶场、内网渗透、APT方面技术干货,从零开始、以实战落地为主,致力于做一个实用的干货分享型公众号。
一、前言 方便要开发微信小程序的朋友们,可以快速将服务搭建起来,不要把时间浪费在服务的搭建上,专心写我们的业务代码。
你需要了解的知识:
1.微信小程序大概的开发流程
2.注册小程序(个人测试账号)
3.服务器的配置
4.内网穿透(我用的是花生壳)
5.小程序开发文档先大概看一遍
废话不多说了,你懂得,直接讲重点…
源码下载地址(服务端):下载 源码下载地址(小程序demo):下载 二、脚手架预览 2.1 项目结构 2.2 小程序demo 整体小程序上就实现上面这些功能。
三、怎么快速把项目跑起来(服务端) 3.1 修改配置 application.xml logging: level: org.springframework.web: info com.lxh.miniapp: debug cn.binarywang.wx.miniapp: debug server: port: 80 servlet: context-path: / wx: miniapp: configs: - appid: wx2d88824e64axxxxxx secret: f1e1d8785bfbe9d36d538xxxxxxxxx token: miniapp aesKey: K1ewVmypZKPTl2BIB8ySTY9C5rpteZxxxxxxxxx msgDataFormat: JSON 3.2 启动服务 WxMiniAppDemoApplication.java
四、核心代码 本项目依赖WxJava - 微信开发 Java SDK。https://github.com/Wechat-Group/WxJava
由于本项目支持多个小程序,在调用接口时,要先调用下面接口切换一下小程序。
public static WxMaService switchover(String appid){ if (StringUtils.isBlank(appid)){ throw new IllegalArgumentException("appId为空"); } WxMaService wxMaService = WxMiniAppConfiguration.
在使用指针时如果出现了错误,第一步我们首先检查指针是否正确的进行了初始化。指针总是指向一个地址的,因此在检查初始化是否正确的时候, 可以关注一下,“=”号的右边是不是一个地址。 指针的初始化主要有两大类方法: 一是给指针变量初始化一个在内存中已经存在的地址;二是通过指针变量申请一块新的内存并赋初值。 接下来从几个方面来详细列出:
一是给指针变量初始化一个在内存中已经存在的地址,常用的有以下几种方法:
1.变量的地址:
int a = 10;
int * p = NULL;
p = &a;
这两句等价于 int * p = &a;
2.地址常量
将指针常量赋给一个指针
如:long p = (long)(unsigned long)0xfffffff0;
3.数组的地址
char ary[100];
char *cp = ary;
4.字符串常量
char *cp = “abcdefg”;
对于一个不确定要指向何种类型的指针,在定义它之后最好把它初始化为NULL,并在解引用这个指针时对它进行检验,防止解引用空指针。另外,为程序中任何新创建的变量提供一个合法的初始值是一个好习惯,它可以帮你避免一些不必要的麻烦。
二是通过指针变量申请一块新的内存即动态内存分配
1.采用malloc函数与free函数,这时需要包含<stdlib.h>
int *a =(int )malloc(nsizeof(int));
…
free (a);此处释放指针
2.采用new与delete:
(1)变量
int * p = new int(10);表示指针指向的内存中存放的数据是10
…
delete p;
(2)数组
int *arr = new int[10];表示数组中可以存放10个元素
初学c语言中的一些常见代码 一、输出乘法口诀表二、判断1000年---2000年之间的闰年方法1:方法2: 三、输出1~100之间的奇数方法1:方法2:四、计算n的阶乘 五、计算1!+2!+3!+...+10!方法1:方法2: 六、在一个有序数组中查找具体的某个数字n七、编写代码,演示多个字符从两端移动,向中间汇聚八、编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则提示登陆成功,如果三次均输入错误,则退出程序)九、猜数字游戏十、关机小程序方法1:方法2: 十一、打印100~200之间的素数(递归)试除法见第三篇博客十二、给定两个整形变量的值,将两个值的内容进行交换十三、不允许创建临时变量,交换两个数的内容方法1:方法2: 十四、求10 个整数中最大值十五、将三个数按从大到小输出十六、求两个数的最大公约数十七、将数组A中的内容和数组B中的内容进行交换。(数组一样大)十八、计算1/1-1/2+1/3-1/4+1/5 …… + 1/99 - 1/100 的值十九、编写程序数一下 1到 100 的所有整数中出现多少次数字9二十、在屏幕上输出菱形二十一、求出0~999之间的所有“水仙花数”并输出二十二、求Sn=a+aa+aaa+aaaa+aaaaa的前5项之和,其中a是一个数字, 例如:2+22+222+2222+22222二十三、编写一个程序,可以一直接收键盘字符, 如果是小写字符就输出对应的大写字符, 如果接收的是大写字符,就输出对应的小写字符, 如果是数字不输出方法1:方法2: 二十四、实现一个函数,打印乘法口诀表,口诀表的行数和列数自己指定,二十五、创建一个数组, 实现函数init()初始化数组、 实现empty()清空数组、 实现reverse()函数完成数组元素的逆置。 要求:自己设计函数的参数,返回值。二十六、编写一个函数实现n^k,使用递归实现二十七、strlen的常规写法和递归写法常规写法:递归写法: 一、输出乘法口诀表 #include<stdio.h> int main() { int i = 0; for (i = 1; i < 10; i++) { //打印一行 int j = 0; for (j = 1; j <=i; j++) { printf("%d*%d = %-4d", j,i , i*j); } printf("\n"); } return 0; } 二、判断1000年—2000年之间的闰年 方法1: #include<stdio.
本文参考:
https://scikit-learn.org/stable/modules/cross_validation.html#stratified-k-fold
与《python机器学习基础教程》
好,开始今天的cv学习!
本文需要有一些CV的基础概念之后看会更有收获。
在开始之前,我们要先明确一点:
交叉验证不是一种构建可应用于新数据的模型的方法。交叉验证不会返回一个模型。在调用cv时,内部虽然会构建多个模型,但交叉验证的目的只是评估在给定算法在特定数据集上训练后的泛化性能好坏。
补充:上面的话没有问题,但是在一些ML比赛中会用CV的内部模型来预测,也就是说内部模型有被用到的可能。
我认为CV的学习路线应该是这样的:
要知道k-folds(k层交叉验证)与stratified k-folds cv(分层k折cv)两种重要的方式,然后至于shufflesplit只是一种采用方式,即随机采样的方式,或者叫上面那两种基本方式的点缀。当然,还有留一法,分组cv的方式,但在这里我只讨论上面的k-folds(k层交叉验证)与stratified k-folds cv(分层k折cv)。
最最基本的k折交叉验证:
可以看到。对于训练集,它做了5等分,注意是按顺序分的。强调这个,就是因为这样分有不妥的时候,后面会提及。之后对于每一次,都会有4份做训练集,剩下一分做验证集或者叫训练集。
所以5个模型就会有5个结果:
>>> from sklearn.model_selection import cross_val_score >>> clf = svm.SVC(kernel='linear', C=1) >>> scores = cross_val_score(clf, iris.data, iris.target, cv=5) >>> scores array([0.96..., 1. ..., 0.96..., 0.96..., 1. ]) 12345 看起来这样做CV挺好的,问题是什么呢?
问题就在于它是按顺序划分的。或者看这张图:
这是sklearn官网的一张图,从图中可以看到,很可能一折中的每等分都是同样的种类,也就是说没有意义了。所以有了shufflesplit与分层stratified交叉验证两种方式。先看shuffle:
from sklearn.model_selection import ShuffleSplit X = np.arange(10) ss = ShuffleSplit(n_splits=5, test_size=0.25, random_state=0) for train_index, test_index in ss.split(X): print("%s %s" % (train_index, test_index)) 1234567 输出:
在visual studio中,若不提供绝对路径,如,只有文件名,则文件需要和项目目录放在一起。
以项目testing为例
点进去后,下一层文件夹是
点开testing
即,将要打开的文件和源文件cpp放在一起。
打开的代码如下:
ifstream infile; infile.open(filename); //filename="persons.txt" in this case 另附用绝对路劲打开的方法
https://blog.csdn.net/weixin_43889700/article/details/89919704
一、前言 方便要开发微信公众号的朋友们,可以快速将服务搭建起来,不要把时间浪费在服务的搭建上,专心写我们的业务代码。
你需要了解的知识:
1.微信公众号大概的开发流程
2.注册公众号(本脚手架是用公共的测试账号)
3.服务器的配置
4.内网穿透(我用的是花生壳)
5.公众号开发文档先大概看一遍
废话不多说了,你懂得,直接讲重点…
脚手架代码下载地址:下载
二、几个关键的地方 本项目依赖SDK开发工具包(WxJava)https://gitee.com/binary/weixin-java-tools
2.1 验证服务器地址有效性 开发者ID(AppID)
开发者密码(AppSecret)
服务器地址(URL)
令牌(Token)
2.2 AccessToken的处理 access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时(7200秒),需定时刷新,重复获取将导致上次获取的access_token失效。
2.3 公众号消息的处理 2.4 网页授权,拆分链接 2.5 Js-Sdk配置,测试 将以上问题先注意一下。
三、怎么快速把项目跑起来 3.1 项目结构 3.2 修改配置 1.application.xml (公众号对应配置修改,支持多个公众号)
2.JedisConfiguration.java (修改Redis配置,如果不配置,就内存缓存)
3.3 启动服务 WxMpDemoApplication.java
3.4 常用配置 我的内网穿透域名:http://chenxingxing.51vip.biz
1.接口配置信息URL:${内网穿透域名}/wx/portal/${appId} 例如:http://chenxingxing.51vip.biz/wx/portal/wx62458041039e62ee 2.JS接口安全域名 例如:chenxingxing.51vip.biz 3.消息模板 例如:{{first.DATA}} 4.创建菜单 例如:http://chenxingxing.51vip.biz/wx/menu/wx62458041039e62ee/create 5.发送模板 例如:http://chenxingxing.51vip.biz/wx/other/wx62458041039e62ee/sendTemplate 6.授权回调地址 例如:http://chenxingxing.51vip.biz/wx/redirect/wx62458041039e62ee/oauth/callback 7.拆分链接 例如:http://chenxingxing.51vip.biz/wx/redirect/wx62458041039e62ee/split/jump?url=http://chenxingxing.51vip.biz 基本上到这,你的公众号就可以用了。然后你配置一下菜单,发消息,发模板,测试测试。
四、怎么玩 公众号开发文档:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html
4.1 创建菜单 访问url:http://chenxingxing.51vip.biz/wx/menu/wx62458041039e62ee/create
4.2 发送模板消息 访问url:http://chenxingxing.51vip.biz/wx/other/wx62458041039e62ee/sendTemplate
4.3 Js-Sdk测试 访问url:http://chenxingxing.51vip.biz/jssdk
前言: 闲来无事,想起把zookeeper的相关知识再补充一下。作为中间件部门的成员,与zookeeper打交道的机会还是很多的。目前市面上的很多产品,尤其是分布式相关的,基本都会用上zookeeper。
本文不是一篇介绍zookeeper是什么和怎么使用的文章,而是介绍zookeeper的使用框架Curator的。本来笔者还想着把Curator的使用再好好熟悉下,因为一段时间不用就觉得生疏了,突然发现之前竟然对Curator的使用封装过,好吧,那就发出来吧,以供大家参考、指正。
写这篇博客的另一个动机就是为了下一篇博客,下一篇会写一下真正的大牛他们是怎么封装使用Curator,也算是抛砖引玉了。
准备工作: 老规矩,首先介绍下笔者的使用环境和相关依赖。
1.zookeeper服务,单机版,本地使用,版本为3.4.11
2.maven依赖如下:
<!-- zookeeper --> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.11</version> <exclusions> <exclusion> <artifactId>log4j</artifactId> <groupId>log4j</groupId> </exclusion> </exclusions> </dependency> <!-- curator --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.0.0</version> <exclusions> <exclusion> <artifactId>zookeeper</artifactId> <groupId>org.apache.zookeeper</groupId> </exclusion> </exclusions> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>4.0.0</version> </dependency> 1.Curator封装使用
笔者就写了一个单类,里面封装CRUD的操作方法,具体如下:
package com.example.demo.curator; import org.apache.curator.RetryPolicy; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.api.ACLBackgroundPathAndBytesable; import org.apache.curator.framework.api.BackgroundCallback; import org.apache.curator.framework.recipes.cache.*; import org.apache.curator.retry.ExponentialBackoffRetry; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.data.Stat; import java.util.concurrent.Executor; /** * Curator的简单封装 * @author lucky */ public class CuratorManager { /** 默认值 */ private static final String DEFAULT_CONNECT_STRING = "
按照blog-demo 进行分析:
<p>标题:<input type="text" v-model="title" placeholder="标题" ></p>
<p>内容:<textarea name="content" id="" cols="30" rows="10" v-model="content"></textarea></p>
<p><input type="submit" value="添加" v-on:click="add" ></p>
显示基本对框框:
绑定事件监听: data:{
// 标题
title:'',
// 内容
content:'',
// 所有的内容
datas:[]
},
if(this.title =="" || this.content==""){ alert("标题或内容不能为空") return } // 把标题和内容添加到数组中 this.datas.push({"title":this.title,"content":this.content}) // 添加完数据以后把标题和内容置空 this.title="" this.content="" 二。有无表格的数据显示:
依次遍历的表格数据并显示出来
<table border="1"> <tr> <th>序号</th> <th>标题</th> <th>内容</th> <th>操作</th> </tr> <!-- 遍历把内容显示出来 --> <tr v-for="(data,index) in datas"> <td>{{index+1}}</td> <td>{{data.title}}</td> <td>{{data.content}}</td> <td> <a href="#" v-on:click="deleteRow(index)">删除</a> <a href="
来源:AINLPer微信公众号(点击了解一下吧)
编辑: ShuYini
校稿: ShuYini
时间: 2020-02-21
2020年的ICLR会议将于今年的4月26日-4月30日在Millennium Hall, Addis Ababa ETHIOPIA(埃塞俄比亚首都亚的斯亚贝巴 千禧大厅)举行。
2020年ICLR会议(Eighth International Conference on Learning Representations)论文接受结果刚刚出来,今年的论文接受情况如下:poster-paper共523篇,Spotlight-paper共107篇,演讲Talk共48篇,共计接受678篇文章,被拒论文(reject-paper)共计1907篇,接受率为:26.48%。
下面是ICLR2020接受的论文(poster-paper)列表,欢迎大家Ctrl+F进行搜索查看。
关注 AINLPer ,回复:ICLR2020 获取会议全部列表PDF,其中一共有四个文件(2020-ICLR-accept-poster.pdf、2020-ICLR-accept-spotlight.pdf、2020-ICLR-accept-talk.pdf、2020-ICLR-reject.pdf)
Kernel of CycleGAN as a principal homogeneous space
Author: Nikita Moriakov, Jonas Adler, Jonas Teuwen
link: https://openreview.net/pdf?id=B1eWOJHKvB
Code: None
Abstract: Unpaired image-to-image translation has attracted significant interest due to the invention of CycleGAN, a method which utilizes a combination of adversarial and cycle consistency losses to avoid the need for paired data.
1、先删除pod
2、再删除对应的deployment
否则只是删除pod是不管用的,还会看到pod,因为deployment.yaml文件中定义了副本数量
实例如下: 删除pod [root@test2 ~]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
jenkins2-8698b5449c-grbdm 1/1 Running 0 8s
[root@test2 ~]# kubectl delete pod jenkins2-8698b5449c-grbdm -n jenkins
pod "jenkins2-8698b5449c-grbdm" deleted
查看pod仍然存储 [root@test2 ~]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
jenkins2-8698b5449c-dbqqb 1/1 Running 0 8s
[root@test2 ~]# 删除deployment [root@test2 ~]# kubectl get deployment -n kube-system
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
jenkins2 1 1 1 1 17h
相比于YOLOv2,YOLOv3主要做了如下改进:1、提出了新的特征提取器模型Darknet53,该模型相比于Darknet19采用了残差单元(类似ResNet),因此网络模型可以更深;2、采用FPN(feature pyramid networks)结构来实现多尺度预测;3、分类器的改变,使用多个多个 logistic 分类器替代原始的Softmax分类器。
1、Darknet53
Darknet53 与 ResNet-101 或 ResNet-152 准确率接近,但速度更快,对比如下:
检测模型网络结构如下所示:
2、多尺度预测
YOLOv3使用了3个尺度的feature map(当输入图像的分辨率为416×416时3个尺度的feature map为:13×13、26×26、52×52)来预测检测结果。每种尺度预设3个Anchor box(使用k-means聚类的方式得到9个Anchor box,并将其分配到3个不同尺度的feature map上,尺度越大的feature map使用更小的Anchor box,这一做法是为了使模型对小目标物体更友好),检测模型如上图所示:
scale 1:在基础网络的后面添加了一系列的卷积层,经过一系列的卷积操作后输出预测的bounding box信息。
scale 2:将scale1中的倒数第三个卷积层的输出进行1×1的卷积后进行上采样(x2),再与backbone中最后一个26×26的feature map进行concat拼接,之后经过一系列的卷积操作后输出预测的bounding box信息。
scale 3:将scale2中的倒数第三个卷积层的输出进行1×1的卷积后进行上采样(x2),再与backbone中最后一个52×52的feature map进行concat拼接,之后经过一系列的卷积操作后输出预测的bounding box信息。
3、分类器
YOLOv2中预测bounding box中目标所属类别时是用的Softmax分类器,Softmax分类器不适用于多标签分类。因此,在YOLOv3中使用多个独立的logistic 分类器来替代Softmax分类器。
YOLOv3的性能对比如下所示:
可以看出YOLOv3模型的AP值虽然不是最好的,但是在速度方面YOLOv3完胜其它模型方法。YOLOv3 在 mAP-0.5 及小目标 APs 上的优势更加明显,但是随着 IOU的增大,性能开始下降,这说明 YOLOv3 不能很好地与 ground truth 贴合。
以上是自己学习YOLOv3时一些看法以及查阅相关资料的一些总结,如有理解错误之处请指正。
我们知道,在android camera里,可以给一个request添加多个target.比如以google的camera2Basic为例:
private void createCameraPreviewSession() { try { SurfaceTexture texture = mTextureView.getSurfaceTexture(); assert texture != null; // We configure the size of default buffer to be the size of camera preview we want. texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); // This is the output Surface we need to start preview. Surface surface = new Surface(texture); // We set up a CaptureRequest.Builder with the output Surface. mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); mPreviewRequestBuilder.addTarget(surface); mPreviewRequestBuilder.addTarget(mImageReader.getSurface()); // Here, we create a CameraCaptureSession for camera preview.
快 30 了,还是一名程序员,干着一些 CURD 的工作,以后该怎么办呢?
昨天晚上,在公众号后台看到上面这条留言,我感到很震惊,忍不住晃了两下脑袋,生怕自己会错了意。原因有两个,一个是:“30 了,还是一名程序员,不应该感到很幸运吗?仍然和自己心爱的程序打着交道,何乐而不为呢?”另外一个是:“30 岁了,还没学会靠着脖子上的那颗脑袋去思考,确实有点过分。”
类似这样的问题你应该不会感到陌生,反正我在其他地方就见过很多次。30 岁以后该干什么,我也问过自己很多次,但答案总绕不开一句话:
管特么以后干什么,先把手里的事情干好再说。
提这类问题的人,我想他现在做的事情就很烂,做的不用心,又不肯花心思去学习新的东西,所以才会担心前途。
还记得这篇文章吗?强烈推荐10本程序员在家读的书,我公众号上的读者都说好,并且夸我是良心推荐,已经下载好了准备读,有的甚至已经读了好几本——你们都是最胖的,不,最棒的。
第二天同步到 CSDN 上后,同样颇受欢迎,阅读量非常高。但有一条留言让我愤愤不平:
你自己全看过吗?
透露着赤裸裸的轻蔑,奇怪的是,点赞的人数非常多(排在留言榜的第一名)。我一向推崇“兼容并包”,但这次没忍住,“同道中人”还不少嘛,就回复了一句话:
悲哀啊,这个世界上总有那么一小撮人,觉得自己菜别人就也要菜;自己的天空就井口那么大,所以别人的天空也就那么大。自己没读过的书,就以为别人一定也没读过。
这类人就可以和 30 岁还在担心自己前途的人归并到一处,并且给他们立一块碑,上面只写四个字:一群懒蛋。
感觉没前途就不能趁着业余时间学点你感觉有前途的,然后跳槽?也就 10 本书,没读过就不能趁着宅在家的这段时间读一读,然后长进一下?
听到业余时间四个字,他们可能又要抱怨:没时间学啊,上班忙死了,下班后吃个饭收拾收拾,扣扣手机,打打游戏,时间就没了啊!
靠,这样的人感觉自己有前途才怪。
前途在哪里?前途就在你手头做的事情上,提高效率,把这件事情做好,做到极致,做到无可挑剔;然后再去做另外一件事,再把它做好,一点一点的进步。我敢保证,如果你能够把一件事情做好,就有能力去做下一件事情,做着做着,你的前(钱)途就找上门了。
再说,大道至简,我就不觉得 CURD 有什么可耻的。归根到底,所有的程序不都是在这个基础上延伸的吗?伟大的哲学家罗素曾说过:
人活在世上,主要是在做两件事:一、改变物体的位置和形状,二、指使别人这么干。
这句话就很简单,但仍然充满智慧。想一想,假如你真的对 CURD 驾轻就熟,恐怕就要升职指挥别人这么干了吧?你没升职,说明你就只配干这件事,领导真的是比你傻,公司真的是比你傻,放任你的才华在那消磨时光吗?
假如真的有这样的领导和公司,我想比你更没前途吧?
我认识一个人,年纪和我相仿,自称以前是做管理和运营的。然后就在微信上给我聊:“王师兄,我想学 Python 语言。”我心想这是好事啊,就回复说:“学呗。”然后他就说:“有什么建议?”
“what?哪方面的建议?需求很不明确啊!”
然后他就巴拉巴拉给我说了很多,我就静静地等他说完,终于说完了,结尾是这样一句话:“讲的比较啰嗦,自己也是干着急。”一个做管理和运营的人,应该做事很有条理才对啊?如果自己都嫌啰嗦的话,那一定是没把问题搞清楚。
这和那些快 30 岁但不知道前途的人遇到的问题是一样的:对过去糊糊涂涂,对将来迷迷茫茫。
我也 30 岁的人了,还在做一名程序员,只不过在前面加了一个前缀:有趣的。我不能说自己没有糊涂过,迷茫过,那是自欺欺人,但最近两年我逐渐摸清楚了自己。虽然处在三线城市洛阳,IT 环境很糟糕,跳槽升职加薪这事几乎不太可能,但是我找到了自己的出路啊。
至于出路是什么,都写在了我的文章里,你多看几篇就一清二楚了,没必要怀疑——我又不骗你钱花。你也别来直接问我,如果我告诉你了,你恐怕要说这不适合你,又要反驳我:“你说的是真的吗?”难不成我天天靠说假话活着,那估计要饿死。
我总感觉,干程序员这件事挺好的,我愿意一直干下去:编程就和解几何题一样,对了马上能知道对,错了也马上知道错,干干脆脆。比去做管理和人打交道要容易得多,并且只要技术功底到位,挣得也不会少。
30 岁,年轻着呢,时间有的是。但要肯动脑筋,要勤奋,如果你听不进去我的建议,我也没办法,你有没前途的权力。
最近,有不少读者问我是怎么学习的,那我干脆就把我看过的一些优质书籍贡献出来: 计算机基础入门推荐:《程序是怎样跑起来的》、《网络是怎样连接的》、《计算机是怎样跑起来的的》
进一步认识计算机网络:《计算机网络:自顶向下》、《图解http》
数据结构+算法入门:《大话数据结构》、《阿哈算法》
算法进阶:《算法第四版》、《编程珠玑》
由于我是 Java 技术栈的,顺便推荐几本 Java 的书籍,从左到由的顺序看到
Java:《Java核心技术卷1》、《编程思想》、《深入理解Java虚拟机》、《effective Java》、《Java并发编程的艺术》
数据库:《mysql必知必会》、《MySQL技术内幕:InnoDB存储引擎》
就先介绍这么多,这些都是最基础最核心的,希望对那些不知道看什么书的同学有所帮助。
对了,我介绍的这些书籍,已经顺便帮你整理好了,你可以在我的原创微信公众号『沉默王二』回复『书籍』获取哦
有收获?希望老铁们来个三连击,给更多的同学看到这篇文章 1、老铁们,关注我的原创微信公众号「沉默王二」,专注于有趣有益的程序人生,保证你看完有所收获,不信你打我。
步骤:
Windows设置——更新和安全——激活——更改产品密钥——输入密钥
在这里密钥我是到某宝上买的,为了方便和保险起见,网络上也有一些免费的方法,但是鱼龙混杂,上一台电脑就是用的网上的免费的方法,虽然也升级成功了,但是升级完后摄像头就不能用了(我也不知道是不是因为升级的原因,但感觉是因为这个)
之后会重启
我升级的时候还遇到了无法升级的问题
解决方法:
在进行升级之前,先把系统下安装的所有三方安全程序全部卸载掉,之后进行干净启动,重启之后再尝试进行更新升级,看下效果。
1. win+R后,输入msconfig,回车
2. 点击服务选项卡,勾选隐藏Microsoft服务,点击全部禁用
3. 重启Win10系统;
4.重新开始升级。
vue版本 vue打包后的版本有很多,其中可以归结为三大类,运行时和带编译以及完整版。
具体版本信息及版本差异请移步官网,本文主要是从源码分析两种版本之间的主要差异。
源码分析 查看源码文件src/platforms/web/entry-runtime-with-compiler.js 可以看到当前文件夹下的vue模块来自于'./runtime/index'运行时版本中的vue
// src/platforms/web/entry-runtime-with-compiler.js const mount = Vue.prototype.$mount //缓存运行时定义的$mount方法 Vue.prototype.$mount = function ( // 重新定义$mount方法 el?: string | Element, hydrating?: boolean ): Component { el = el && query(el) /* istanbul ignore if */ if (el === document.body || el === document.documentElement) { process.env.NODE_ENV !== 'production' && warn( `Do not mount Vue to <html> or <body> - mount to normal elements instead.` ) return this } const options = this.
#include <iostream> using namespace std; int row_col[8]; int count=0; bool isOk(int row,int col) { int leftUp=col-1; int rightUp=col+1; for(int i=0;i<row;i++) { if(row_col[i]==col) { return false; } if(leftUp>=0) { if(leftUp==row_col[row-i-1]) { return false; } } if(rightUp<=7) { if(rightUp==row_col[row-i-1]) { return false; } } leftUp--; rightUp++; } return true; } void printOut() { for(int i=0;i<8;i++) { for(int j=0;j<8;j++) { if(row_col[i]==j) { cout<<" Q "; } else { cout<<" * "; } } cout<<endl; } cout<<"
解决error while loading shared libraries: libXXX.so.X: cannot open shared object file: No such file
分析原因:ld提示找不到库文件,而库文件就在当前目录中。
链接器ld默认的目录是/lib和/usr/lib,如果放在其他路径也可以,需要让ld知道库文件在哪里。
方法1:
编辑/etc/ld.so.conf文件,在新的一行中加入库文件所在目录;
运行ldconfig,以更新/etc/ld.so.cache文件;
方法2:
在/etc/ld.so.conf.d/目录下新建任何以.conf为后缀的文件,在该文件中加入库文件所在的目录;
运行ldconfig,以更新/etc/ld.so.cache文件;
本人觉得第二种办法更为方便,对于原系统的改动最小。因为/etc/ld.so.conf文件的内容是include /etc/ld.so.conf.d/*.conf
所以,在/etc/ld.so.conf.d/目录下加入的任何以.conf为后缀的文件都能被识别到。
本人的作法:
1. 将所有的用户需要用到的库放到/usr/loca/lib;
2. 在/etc/ld.so.conf.d/目录下新建文件usr-libs.conf,内容是:/usr/local/lib
3. #sudo ldconfig
老电脑或者游戏本一般都是有光驱的,也就是放光盘的地方,现在光盘已经淘汰,光驱基本没意义。可以想想自己的电脑最近使用过光盘吗。之前也写过一篇换硬盘的文章(https://blog.csdn.net/weixin_42715688/article/details/81607149),咱们衔接那个替换下来的硬盘转到光驱位置。
拆下光驱 1.拆下来自己的光驱,一般在光驱位置有一个螺丝,不用打开后盖就能拿下来光驱。具体怎么操作百度就行了,每台电脑的拆卸方法都不一样的。
2.拿到光驱之后,测量厚度,直尺就能测,有9mm和12.7mm两个尺寸。
准备硬件 1.光驱硬盘托架一个,按着你量好的尺寸买,这个随便哪里买都行,十几块钱一个,记得接口一定要买大于等于3.0,不要买成2.0的就OK了,3.0得传输速度快就这个意思。
2. 2.5寸硬盘一个,因为你是用来当储存盘用,所以机械硬盘足矣,资金富裕的当然可以买固态硬盘啦!之前主硬盘地方把机械换下来的,现在就可以直接拿来用了。对于机械硬盘你买个二手的也是可以的,网购自行选择吧。
安装 硬盘放进光驱托架里面,光驱托架都带着说明书呢。看一下就明白,跟上手机壳似的。接下来最重要的一步,如果你买的是一个新硬盘,都装好之后,光驱托架位置灯也亮了(一般是蓝色灯),但你在电脑里面看不到这个硬盘。
这时候右击此电脑,点击管理,进入界面如下,再点击磁盘管理,会弹出一个窗口,选择GPT点确定
磁盘1是光驱位置硬盘,右击黑色区域新建简单卷,就可以了。
今天光驱转硬盘到这里就结束了,小伙伴有什么不懂的留言即可,小编最近申请了一个微信公众号,准备写一些电脑知识和其他提升自身的小技能,感兴趣的小伙伴搜索 拾光日子 。 咱们下篇再见! 往期文章: https://blog.csdn.net/weixin_42715688
1 .Failed to mount /sysroot terminal :
xfs_repair -v -L /dev/dm-0 2 . Linux rescue: give root password for maintenance (or type control-d to continue:) OR
系统文件都变成只读了
这两种情况,统一的解决方法:
terminal :
mount -o remount,rw / 让 / 路径文件系统为可读模式,这样就可以实现自由修改
知识点 github的文件在 https://(项目url)/archive/master.zip实验参考教程[https://chyyuu.gitbooks.io/ucore_os_docs/content/](https://chyyuu.gitbooks.io/ucore_os_docs/content/)搭建执行ucoreos的学习环境随时复习一些linux命令控制流程 (1) 输入/输出(2) 重定向(3) linux管道(4) 后台进程环境变量获得软件包配置vimctags命令使用离线安装chrom插件gcc编译简单的 C 程序AT&T汇编基本语法 和 intel汇编的区别安装硬件模拟器QEMU制作lab1镜像文件并用qemu加载 github的文件在 https://(项目url)/archive/master.zip 知道一个github项目,可以直接在项目后边加上 /archive/master.zip 来,wget下载
下载操作系统源代码 wget https://github.com/chyyuu/ucore_lab/archive/master.zip 实验参考教程https://chyyuu.gitbooks.io/ucore_os_docs/content/ 搭建执行ucoreos的学习环境 #创建一个 centos 开发环境,来体验开发ucoreos的过程 docker run -tdi -p 21022:22 -p 21088:8888 --name ucoreos --privileged=true registry.cn-hangzhou.aliyuncs.com/mkmk/conda:qemu init | docker exec -d ucoreos /bin/bash -c "cd /home && source /etc/profile && nohup jlab &" #关机后重启实验环境 docker start ucoreos | docker exec -d ucoreos /bin/bash -c "cd /home && source /etc/profile && nohup jlab &"
作者:Walker
在机器学习的世界中,通常我们会发现有很多问题并没有最优的解,或是要计算出最优的解要花费很大的计算量,面对这类问题一般的做法是利用迭代的思想尽可能的逼近问题的最优解。我们把解决此类优化问题的方法叫做优化算法,优化算法本质上是一种数学方法,常见的优化算法包括梯度下降法、牛顿法、Momentum、Nesterov Momentum、Adagrad、Adam等。其实大部分机器学习算法的本质都是建立优化模型,通过优化算法对损失函数(优化的目标函数)进行优化,从而训练出最好的模型。
(1)梯度下降法: 梯度下降法是最常用的一种优化算法。其核心思想是:在当前位置寻找梯度下降最快的方向,来逐渐逼近优化的目标函数。且离目标函数越近,逼近的“步伐”也就越小。梯度下降法本质是一种迭代方法,常用于机器学习算法的模型参数求解。其示意图如下图1所示:
图1梯度下降法
梯度下降法的更新公式为:
其中α为梯度上每次逼近的步长,前边的“-”表示搜索方向为负梯度的方向,L我损失函数。算法更新终止的条件是梯度向量接近于0即可。此外需要特别注意的是,梯度下降法不一定能够找到全局的最优解,很有可能找到的是一个局部最优解。
(2)梯度下降法的变式
通常基于梯度的下降方法又有很多变式,我们主要为大家介绍:随机梯度下降法(SDG)、Momentum、Nesterov Momentum、Adagrad、Adam。
随机梯度下降法是每次使用一批数据进行梯度的计算,而非计算全部数据的梯度,因为如果每次计算全部数据的梯度,会导致运算量加大,运算时间变长,容易陷入局部最优解,而随机梯度下降可能每次不是朝着真正最小的方向,这样反而可以跳出局部的最优解。
Momentum是在随机梯度下降法的基础上,增加了动量(Momentum)的技术。其核心是通过优化相关方向的训练和弱化无关方向的振荡,来加速SGD训练。Momentum的方法能够在一定程度上缓解随机梯度下降法收敛不稳定的问题,并且有一定的摆脱陷入局部最优解的能力。
Nesterov Momentum是基于Momentum的加速算法,相比于传统的动量算法,最大的优化是计算经过动量更新之后的位置梯度。
Adagrad即adaptive gradient,是一种自适应学习率的梯度法。它通过记录并调整每次迭代过程中的前进方向和距离,使得针对不同问题都有一套自适应学习率的方法。Adagrad最大的优势是不需要手动来调整学习率,但与此同时会降低学习率。
Adam即Adaptive Moment Estimation,是能够自适应时刻的估计方法,能够针对每个参数,计算自适应学习率。这是一种综合性的优化方法,在机器学习实际训练中,往往能够取得不错的效果。
(3)牛顿法和拟牛顿法
与上述梯度类型的优化算法最大的不同是,牛顿法是一种二阶收敛算法,所以它的收敛速度相较于一阶算法会更快。牛顿法二阶的意义在于它不仅会沿着梯度最大的方向下降,还会考虑走的下一步坡度是不是也很大,它能够以较远的目光全局的逼近目标函数。其算法的具体步骤为:
1.首先选择接近于函数f(x)的零点x0,并计算f(x0)处的斜率f’(x0)。然后我们求解以下方程,得到比刚刚的x0更加准确的解x1。
2.接下来我们利用x1进行下一轮的迭代,迭代公式如下所示。这样经过反复的迭代过程,我们便能取得函数f(x)的最优解。
牛顿法的迭代示意图如下所示:
图2 牛顿法
虽然牛顿法相较于梯度下降法等优化算法收敛速度更快,但每一步都需要求解复杂的Hessian矩阵,计算非常不易。所以后来美国Argonne国家实验室的物理学家W.C.Davidon又针对牛顿法计算复杂的缺陷提出了拟牛顿法。它的核心思想是使用正定矩阵来近似Hessian矩阵的逆,从而简化了运算的复杂。另外,因为拟牛顿法不需要二阶导数的信息,所以现在拟牛顿法在机器学习实际问题中应用更加的广泛。
【总结】:除了以上几类较为常见的优化算法以外,还有共轭梯度法、启发式优化算法等。在实际的机器学习问题中,往往需要具体问题具体分析,根据每类优化问题的特征,选择合适的优化算法。
————————————————
版权声明:本文为CSDN博主「磐创 AI」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/fendouaini/article/details/80991216
文章目录 Linux内存管理 -- 白话页框回收什么是Page Cache?什么是Swap Cache?什么是buffer Cache?图解页框回收 Linux内存管理 – 白话页框回收 经过前面几篇博客翻译和阅读Understaning Linux Virtutal Memory Manger,对于Linux页框回收有了一些基本的理解。现在自己再来对照Linux kernel2.6.9源码来做一些总结。
什么是Page Cache? 在Linux中所谓的page cache就是指struct address_space。磁盘中一个文件或者其他虚拟文件(shmem)所对应的page每次都是经过同一个struct address_space来进行管理,便于此类型的page在多进程见进行共享,以及阻止一些不必要的磁盘IO。
如下图中,两个进程打开同一个文件file A,以及读取文件内容:
从上图中可以看出,page cache的作用主要是将磁盘中文件缓存到内存,并集中管理,便于回收利用。
什么是Swap Cache? 系统中常常会有一些进程在初始化时要了很多memory(主要是通过malloc获取的匿名page),初始化完成之后,这部分memory该进程不会经常用到,也没有释放。这就造成了内存的浪费。Linux就想了个办法要把这些memory中的数据置换到磁盘中,然后将这个memory标记为可回收,然后Linux中页框回收机制就会将这些page回收然后将这些page让给有需要的进程来用。
swap cache主要是要解决两个层面的问题:
<1>哪些page可以加入到swap cache中?swap cache中page如何管理?
<2>swap cache中被交换到磁盘中page,如何知道放在磁盘哪个位置,再次被找回来 ?
第一个问题有一个特殊的address_space,swapper_space来管理,具体如何回收由下一小节说明。
第二个问题通过struct swap_info_struct来管理,其中最终要的是将原来这个page的对应的PTE替换成type + offset的形式。
什么是buffer Cache? 在page cache出现之前,文件的缓存或者块设备的数据缓存叫做buffer cache。现在都叫page cache。
图解页框回收 在Linux的每个Zone中有两个list:active_list和inactive_list,这两个list包含了该Zone中所有已经分配的page。其中active_list中表示正在使用的page,而inactive_list中是很少使用待回收的page。在下列两种case下会触发内存回收机制:从active_list的底部循环将active_list中符合条件的page添加待inactive_list,然后再从inactive_list中选择合适的page释放内存。 每当alloc page时,如果发现memory不够了,调用try_to_free_pages()来释放内存。通过守护进程kswapd来check zone的memory water mark,发现内存到达低水位,触发内存回收机制释放内存。
一、Camera框架介绍: Camera的框架分为Kernel 部分和hal部分,其中kernel部分主要有两块:
(1)image sensordriver,负责具体型号的 sensor 的 id 检测,上电,以及在preview、capture、
初始化、3A等等功能设定时的寄存器配置;
(2)isp driver,通过DMA将sensor数据流上传;
HAL层部分主要有三部分组成:
(1)imageio,主要负责数据buffer上传的pipe;
(2)drv,包含imgsensor和isp的hal层控制;
(3)feature io,包含各种3A等性能配置;
这篇内容主要介绍开机过程中search sensor已经上电流程等内容。
二、Camera启动流程: 1、CameraService是在开机时启动的,启动后进行searchSensor的操作,会search系统多少camera,
开机时的search操作,只进行camera支持数量的遍历,以及sensorID的读取操作,如下是hal部分
的ASTAH绘制调用流程图,对应的接口的文件路径:
HalSensorList: vendor/mediatek/proprietary/hardware/mtkcam/drv/src/sensor/common/v1/HalSensorList.enumList.cpp
vendor/mediatek/proprietary/hardware/mtkcam/drv/src/sensor/common/v1/HalSensorList.cpp
SeninfDrv: vendor/mediatek/proprietary/hardware/mtkcam/drv/src/sensor/mt6765/seninf_drv.cpp
SensorDrv: vendor/mediatek/proprietary/hardware/mtkcam/drv/src/sensor/common/v1/imgsensor_drv.cpp
(1)这里先看enumerateSensor_Locked完成的工作,直接看代码:
MUINT HalSensorList::searchSensors() { Mutex::Autolock _l(mEnumSensorMutex); MY_LOGD("searchSensors"); return enumerateSensor_Locked(); } MUINT HalSensorList::enumerateSensor_Locked() { SensorDrv *const pSensorDrv = SensorDrv::get(); SeninfDrv *const pSeninfDrv = SeninfDrv::createInstance(); //初始化seninf,配置ISP相关内容 pSeninfDrv->init(); //将所有的clk全部打开 pSeninfDrv->setAllMclkOnOff(ISP_DRIVING_8MA, TRUE); pSensorDrv->init(); for (MUINT i = IMGSENSOR_SENSOR_IDX_MIN_NUM; i <= max_index_of_camera; i++) { if((ret = pSensorDrv->searchSensor((IMGSENSOR_SENSOR_IDX)i)) == SENSOR_NO_ERROR){ //query sensorinfo querySensorDrvInfo((IMGSENSOR_SENSOR_IDX)i); //fill in metadata buildSensorMetadata((IMGSENSOR_SENSOR_IDX)i); pSensorInfo = pSensorDrv->getSensorInfo((IMGSENSOR_SENSOR_IDX)i); addAndInitSensorEnumInfo_Locked( (IMGSENSOR_SENSOR_IDX)i, mapToSensorType(pSensorInfo->GetType()), pSensorInfo->getDrvMacroName()); } } } (2)下面主要看下searchSensor的流程,这里有去获取sensorList的内容:
oracle 获取某字段有最大值的那一行的整行记录 select * from ( select r.*,row_number() over (order by r.age desc) rnum from user r where r.sex = '男' ) temp where rnum = 1;
💜 💜 💜
被题目要求的等差数列吓到了,其实由这个要求可以发现子串长度大于3是没有贡献的,因为只要出现长度为3的串就一定存在长为2的串。
所以我们对长为2和长为1的串分别计算一下贡献即可,计算长为2的串的时候枚举当前字符作为第二个字母的贡献,最后加和
#define int ll string s; int dp[26][26],num[26]; void solve() { cin>>s; int n=sz(s); for(int i=0;i<n;++i) { rep(j,26) { dp[j][s[i]-'a']+=num[j]; } ++num[s[i]-'a']; } int ans=0; rep(i,26) ans=max(ans,num[i]); rep(i,26) rep(j,26) ans=max(ans,dp[i][j]); cout<<ans<<endl; } signed main() { solve(); return 0; }
(1)替换指定的所有字符:string.replace(‘a’,‘b’) 表示将字符串string中所有字符为a的替换为b。
例子 string = "abcabcabc" string = string.replace('a','b') print(string) 输出 bbcbbcbbc
(2)替换指定位置i的字符为字符s:列表化字符串再以字符串形式输出 例子 i,s = 0,'b' string = "abcabcabc" string = list(string) string[i] = s print(''.join(string)) 输出 bbcabcabc
在看这篇前需要了解以下几点
HashMap里的键值数一旦大于阈值,就会进行扩容HashMap的底层数据结构是数组+链表+红黑树(JDK1.8)HashMap相同hash值,但是equals结果不相等的键值对会在同一条单向链表或红黑树中 所以问题来了,这里所说的键值数大于阈值,这个键值数只是单纯的指在数组中(链表头的键值对)的键值数,还是指包含所有链表下键值对的所有键值数。
以下跟进源码做个测试:
测试代码:
public class TestMain { public static void main(String[] args) throws Exception { HashMap<String, String> map = new HashMap<>(3); map.put("1", "1"); map.put("Aa", "11"); map.put("BB", "66"); int beforeSize = map.size(); System.out.println(beforeSize); map.put("2", "6"); int afterSize = map.size(); System.out.println(afterSize); } } 以上代码我初始容量设置为3,然后先向map里添加3条数据,其中key为Aa和BB的数据,他们的hash值是相同的,都是2112,所以这两条数据会在一个链表里,而之后再添加第4条数据,这时如果键值对数目为3,则需要扩容,如果键值对数目为2,则不会触发扩容操作。
直接找到判断扩容的代码,打上断点,这里的size就是我们要讨论的,而threshold就是阈值:
map.put(“1”, “1”)时,size原始值为0,++size,所以size变为1:
map.put(“Aa”, “11”)时,size原始值为1,++size,所以size变为2:
map.put(“BB”, “66”)时,发现"BB"的hashcode值和"Aa"一样,所以"BB"成为了"Aa"的下一个节点,二者组成了一个小型链表,但是"BB"的加入一样还是导致了++size,所以size变为3:
map.put(“2”, “6”)时,可以发现代码已经运行到了resize()方法,也就是扩容方法了,同时size也变成了4:
最后运行结果如下:
总结
通过如上代码运行和debug的参考,可以得出HashMap里的size属性指的就是键值总数,因为哪怕新加的元素和旧元素hash值相等而equals结果不同,会处于同一链表中,size一样会加一,而size大小最终决定了是否要进行扩容。
修改build.gradle中compileSdkVersion版本号,我的是原来是28修改为25
修改compile 'com.android.support:appcompat-v7:27.1.1'改为compile 'com.android.support:appcompat-v7:25.3.1'
Flowable 快速入门教程:通过 Comment 保存审核记录 前言表结构接口整理查询新增更新删除 审核示例新增信息审核信息查询附赠 CommentVo 目前我在 Comment 上的使用效果图 前言 先说下本人为什么使用 Comment 来保存审核信息
自然因为简单,不需要自己额外建表保存(本人懒汉)由于本人项目这使用的是微服务架构,流程引擎单独一个数据库,其他数据其他库。但不管在哪建表,查询后也需要自己对数据整合,比较麻烦(本人懒汉)就目前而言,个人觉得 flowable 提供的 Comment 足够支持这方面的需求 表结构 ACT_HI_COMMENT
PS:只有 TYPE_,TIME_,ACTION_ 这三个参数会自动生成,也就是说 TASK_ID_,PROC_INST_ID_ 这两个参数,如果调用接口时候不设置,就不会有
接口整理 PS:都在 TaskService 接口中
查询 Comment getComment(String commentId)
List<Comment> getTaskComments(String taskId)
PS:默认只会获取类型为 comment 的建议
List<Comment> getTaskComments(String taskId, String type)
List<Comment> getCommentsByType(String type)
List<Comment> getProcessInstanceComments(String processInstanceId)
List<Comment> getProcessInstanceComments(String processInstanceId, String type)
新增 Comment addComment(String taskId, String processInstance, String message)
PS:默认 TYPE_ 为 comment
Comment addComment(String taskId, String processInstance, String type, String message)
由于新型冠状病毒的缘故,只好在家里办公。我们需要连接到公司的vpn,由于我用的是Mac,公司vpn为L2TP/IPSec,但是在连接的时候一直报这个错误
L2TP-VPN服务器没有响应。请尝试重新连接。如果仍然有问题,请验证您的设置并与管理员联系。
真的是非常的头痛,查找了N种方法,甚至采用第三方,比如shimo,但是并没有什么作用。
大部分的教程都让你创建一个文件
sudo vim /etc/ppp/options
然后在文件种输入
plugin L2TP.ppp l2tpnoipsec 然后结果还是不行,最后的办法呢,我把第二行删掉,这个看翻译过来像 “没有ipsec的l2tp”,我们实际上要的是“在ipsec上的l2tp”,所以我试着删除,最后竟然可以了,可以愉快的办公了。
什么是加密套件? 加密套件是用于在SSL / TLS握手期间协商安全设置的算法的组合。在ClientHello和ServerHello消息交换之后,客户端发送优先级列表的密码支持套件。然后,服务器使用从列表中选择的密码套件进行响应。
TLS算法组合:
在TLS中,5类算法组合在一起,称为一个CipherSuite:
认证算法
加密算法
消息认证码算法 简称MAC
密钥交换算法
密钥衍生算法
比较常见的算法组合是 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 和 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 都是ECDHE 做密钥交换,使用RSA做认证,SHA256做PRF算法。
一个使用AES128-CBC做加密算法,用HMAC做MAC。
一个使用AES128-GCM做加密算法,MAC由于GCM作为一种AEAD模式并不需要。
这里是一个加密套件的例子:
TLS _ECDHE_ RSA _ WITH_AES_128_GCM _ SHA256 TLS是协议。从ECDHE开始,在握手期间,密钥将通过临时ECDHE进行交换。RSA是认证算法。AES_128_GCM是批量加密算法。SHA-256是散列算法。
大多数浏览器和服务器都有各自支持的密码套件列表,两者将在握手过程中进行优先顺序比较,以确定使用的安全设置。
最后作为TLS 1.3最终版本,这一切都会改变。虽然以前SSL / TLS通过TLS 1.2版本是使用上诉描述的加密套件模板,但1.3版本的加密套件将会有所改变,因为它们仅用于协商加密和HMAC算法。
因为1.3加密套件的结构与之前的版本不同,所以它们与旧的TLS版本不能进行互换。
密码是算法,用于加密和解密。它们可以是对称的或不对称的,这取决于它们支持的加密类型。
加密套件是用于在SSL / TLS握手期间协商安全设置的密码的命名组合。在握手期间,客户端和服务器交换密码套件的优先级列表,并决定两者最佳支持的套件。
在TLS 1.3中,加密套件的结构将改变。
SSL协议的握手过程 第一步,爱丽丝给出协议版本号、一个客户端生成的随机数(Client random),以及客户端支持的加密方法。
第二步,鲍勃确认双方使用的加密方法,并给出数字证书、以及一个服务器生成的随机数(Server random)。
第三步,爱丽丝确认数字证书(对证书信息进行md5或者hash后的编号==用证书机构的公钥对加密的证书编号解密后的证书编号)有效,然后生成一个新的随机数(Premaster secret),并使用数字证书中的公钥(鲍勃的公钥),加密这个随机数,发给鲍勃。
第四步,鲍勃使用自己的私钥,获取爱丽丝发来的随机数(即Premaster secret)。
第五步,爱丽丝和鲍勃根据约定的加密方法,使用前面的三个随机数,生成"对话密钥"(session key),用来加密接下来的整个对话过程。
https要使客户端与服务器端的通信过程得到安全保证,必须使用对称加密算法并且每个客户端的算法都不一样,需要一个协商过程,但是协商对称加密算法的过程,需要使用非对称加密算法来保证安全,直接使用非对称加密的过程本身也不安全,会有中间人篡改公钥的可能性,所以客户端与服务器不直接使用公钥,而是使用数字证书签发机构颁发的证书来保证非对称加密过程本身的安全。这样通过这些机制协商出一个对称加密算法,就此双方使用该算法进行加密解密。从而解决了客户端与服务器端之间的通信安全问题。
Java 对SSL的支持 JDK7的client端只支持TLS1.0,服务端则支持TLS1.2。 JDK8完全支持TLS1.2。
JDK7不支持GCM算法。
JDK8支持GCM算法,但性能极差极差极差,按Netty的说法: Java 8u60以前多版本,只能处理1 MB/s。
Java 8u60 开始,10倍的性能提升,10-20 MB/s。
但比起 OpenSSL的 ~200 MB/s,还差着一个量级。
一、算法思想 孤立森林是属于无监督学习范畴中检测异常值的一种模型,他不同于其他通过计算距离和密度来识别样本点是否是孤立点,而是通过样本的疏密程度来判断样本的是否孤立。仅适用于连续数据。
孤立森林采用多重二分法将样本点进行分区,该算法将样本中所有样本进行切分,直到每个样本点或极少样本点被划分在同一区域呢,这样样本越密集的区域,区域中的点被孤立时所需要的切分次数就越多,同理样本是孤立点,则该点被孤立时切分的次数就越低。
二、模型推理 在已经理解孤立森林算法思想后,如何通过数学公式实现孤立森林模型是我们需要解决的问题,接下来从模型步骤和计算公式、算法伪代码、模型python代码三个方面进一步深入了解掌握模型。
2.1 模型步骤及公式 孤立森林是和随机森林的概念类似,孤立森林是由多颗孤立树构成,先使用测试集训练每颗孤立树,然后再计算验证集每个样本的异常分数值(0,1]判断该样本是否异常,分值越接近1样本越孤立,即样本异常可能性越大。
在创建孤立森林之前,先创建一颗孤立树,孤立树的创建步骤如下:
1.从总体中,随机选择样本容量为n的样本,作为训练孤立树的训练集,也可以用总体;
2.在训练集中随机选择变量Q作为根节点,并随机在Q的取值范围内选择分割点p;
3.将≥p的样本放在左节点,将<p的样本放在右节点;
4.对左右节点的数据重复2、3步骤直到结束,结束的条件是以下三种情况之一:①达到最大限度树的高度;②节点上的样本对应特征的值全相等;③节点只有一个样本;
计算公式:
路径长度:从根节点到叶子节点所经过的边的个数
样本的期望路径长度:E(h(x)),样本在每个孤立树的路径长度的期望
树的平均路径长度:c(x,n),包含n个样本的数据集树的平均路径长度,其中H(i)为调和函数,可以被估值
为
样本的异常得分为,下图给出s和E(h(x))的关系:
由上图可以得到一些结论:
当E(h(x))→c(n)E(h(x))→c(n)时,s→0.5s→0.5,即样本xx的路径平均长度与树的平均路径长度相近时,则不能区分是不是异常。
当E(h(x))→0E(h(x))→0时,s→1s→1,即xx的异常分数接近1时,被判定为异常。
当E(h(x))→n−1E(h(x))→n−1时,s→0s→0,被判定为正常。
2.2 算法伪代码 孤立树的建立是通过对样本的递归分割 实现的,直到孤立树达到最大高度或者独立样本,树的最大高度与样本数量的关系是
他近似等于树的平均高度,我们只关心路径长度较小的那些点,他们更有可能是疑似异常点。
训练过程如下:
评估阶段:
2.3 模型python代码 在python中实现孤立森林的包是sklearn中ensemble中的 IsolationForest
import numpy as np import matplotlib.pyplot as plt from sklearn.ensemble import IsolationForest rng = np.random.RandomState(42) # 生成训练数据 X = 0.3 * rng.randn(100, 2) X_train = np.r_[X + 2, X - 2] # 产生一些常规的新观察 X = 0.
箭头函数是必须要掌握的,今天我们一起来学习一下,它给开发者带来方便的同时,也要留意它的「无能」。先看一个例子:
const names = [ 'wsy', 'suyan', '前端小课' ]; let lengths = names.map(name => name.length); console.log('lengths = ', lengths); 结过如图:
先看下它的语法:
1、无参数
function call(callback) { callback(); } call(() => { console.log('arrow void'); }); // 箭头函数类似于下面这个函数 call(function () { console.log('void'); }); 2、只有一个参数,无返回值
function call(callback) { callback('前端小课'); } call(name => { console.log('arrow', name); }); // 箭头函数类似于下面这个函数 call(function (name) { console.log(name); }); 3、只有一个参数,有返回值
function call(callback) { // 返回值为 4 let len = callback('前端小课'); console.
参考链接:
python爬取网易云音乐评论及相关信息
https://blog.csdn.net/qiang12qiang12/article/details/80821834
urllib了解
参考链接:
https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432688314740a0aed473a39f47b09c8c7274c9ab6aee000/
requests了解
参考链接:
http://docs.python-requests.org/zh_CN/latest/user/quickstart.html
正则表达式
参考链接:
http://www.runoob.com/python/python-reg-expressions.html
爬取网易云音乐评论及相关信息
1、分析网易云页面
2、获取加密的参数 params 和 encSecKey
3、爬取网易云音乐评论及相关信息
参考链接https://blog.csdn.net/fengxinlinux/article/details/77950209
【START】
爬取网易云音乐的评论,首先在浏览器打开一首需要爬取评论的歌曲页面,比如:https://music.163.com/#/song?id=862102137
然后,在Chrome浏览器(其他类似)按F12键,按F5刷新,根据下图箭头顺序,按顺序操作
如下图所示,即为页面信息。
如下图所示,即为热评内容,获取页面内容,然后解析content即可,解析步骤继续向下看。
2、获取加密的参数 params 和 encSecKey
参考链接:https://www.zhihu.com/question/36081767
3、爬取网易云音乐评论及相关信息(代码有冗余)
(1)使用User Agent和代理IP隐藏身份之为何要设置User Agent
参考链接:https://blog.csdn.net/c406495762/article/details/60137956
agents = [ "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1", "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.
线阵相机行频和物体运动速度。
已知相机参数(分辨率、像元尺寸)和镜头参数(焦距)。根据相机横向扫描精度(每个像素表示的实际宽度)等于纵向扫描精度原则,得出式(1)
其中 表示视野尺寸, 表示分辨率, 表示物体运动速度, 表示相机线扫描速率(单位:线/s),对上式变形得到式(2)
根据相似三角形原理,视野计算公式可以表示为:视野=物距×靶面尺寸/焦距,代入式(2),线扫描速率 =( ×焦距)/(像元尺寸×物距)。当 过小则导致纵向扫描精度小于横向扫描精度,拍摄出的图像被“压扁”。
Ps:粗计算确定物距的方法为,根据预估视野尺寸,计算物距(粗计算物距=预估视野×焦距/靶面尺寸),对物距取整可以稍大或稍小于粗计算值,将取得的物距代入(视野=物距×靶面尺寸/焦距)计算最终视野尺寸,继而计算所需的相机行频。照明方式
拟解决的问题:针对轮毂阴影和反光问题,选择合适的光源。
解决方案:选择配合线阵相机使用的线性光源(利用棱镜使光线汇聚得到高亮度的光);为了消除阴影选择扁平环状光源(扩散光能有效消除阴影),扩散光源也能有效避免物体上的反光。
文章目录 shell数组的练习题练习1:使用循环批量输出数组的元素练习2:通过竖向列举方法定义数组元素并批量打印练习3:将命令结果作为数组元素定义并打印练习4:利用bash for 循环打印下面这句话中字母数不大于6的单词 shell数组的练习题 练习1:使用循环批量输出数组的元素 #!/bin/bash #使用循环批量输出数组的元素 array=(a b c d e) for ((i=0;i<${#array[@]};i++)) #从数组的第一个下标0开始,循环数组的所有下标 do echo ${array[i]} #打印数组元素 done 练习2:通过竖向列举方法定义数组元素并批量打印 #!/bin/bash #通过竖向列举方法定义数组元素并批量打印 array=( shell python java c# c++ ) for ((i=0;i<${#array[@]};i++)) do echo "This is NO.$i,then content is ${array[i]}" done echo ==================================== echo "array len:${#array[@]}" 练习3:将命令结果作为数组元素定义并打印 #!/bin/bash #将命令结果作为数组元素定义并打印 dir=($(ls /array)) for ((i=0;i<${#dir[*]};i++)) do echo "This is NO.$i,filename is ${dir[$i]}" done 练习4:利用bash for 循环打印下面这句话中字母数不大于6的单词 #!/bin/bash #利用bash for 循环打印下面这句话中字母数不大于6的单词 # I am westos teacher welcome to westos training class array=(I am westos teacher welcome to westos training class) for ((i=0;i<${#array[@]};i++)) do if [ ${#array[$i]} -le 6 ] then echo ${array[$i]} fi done
首先内部网关协议包括:RIP,OSPF。外部网关协议包括BGP。RIP使用UDP传送,OSPF使用IP数据报传送,BGP使用TCP传送,所以RIP是应用层协议,同理BGP也是应用层协议。OSPF是传输层协议。但是一些教材上说是网络层,这是不严谨的!一个协议的实现需要依赖协议所在层次的下一层功能。简单的说就是,如果TCP需要依赖网际层协议IP,那么它就是传输层的协议,但是笔者不认为它能算是应用层协议。举个例子,ICMP是网络层协议,但它需要依赖IP承载,那么ICMP是传输层协议吗?说明TCP/IP是相当不严谨的。严格意义上说,根本就没有明确定义这些协议的位置。学习这些协议关键是掌握它们在网络中的功能和如何应用它们,至于它们到底是哪一层的协议,并不重要。
文章目录 1. 工具收集阶段1.1 Prometheus+Grafana环境部署1.2 阿里云RDS(mysqld)相关监控1.3 资源监控1.3.1 重新打包Dockerfile1.3.2 修改bug配置1.3.3 启动docker1.3.4 Grafana配置图 2. 工具组合2.1 架构图2.2 supervisor+mysqld_exporter2.3 prometheus服务发现2.4 最后一哆嗦 3. 简单效果展示4. 遗憾 云厂商可以帮助我们解决8-90%的“脏乱臭”的活,方便的不要不要的,当然也是有得有失吧。但个人觉得 RDS监控用起来确实有点不是太方便,自然要想办法改善使用。 Prometheus+Grafana,这套万金流自然首当其冲(有的人喜欢zabbix,都可以,仁者见仁)
1. 工具收集阶段 1.1 Prometheus+Grafana环境部署 此处不做过多赘述,网上文章很多。推荐电子书链接:prometheus-book
1.2 阿里云RDS(mysqld)相关监控 MySQL数据采集工具:mysqld_exporter,此工具也是prometheus官方工具下载地址。
部署也相当简单,创建好采集MySQL数据需要的用户,以及选择需要采集的指标,直接启动即可,如:
export DATA_SOURCE_NAME='user:password@(hostname:3306)/' ./mysqld_exporter <flags> 1.3 资源监控 除了RDS(MySQL)本身的一些监控,还需要关注资源的一些信息。如果是自建IDC,肯定是使用node_exporter。
谁让我们使用的是云产品呢,哎~
幸运的是PingCAP的工程师Aylei写了一套aliyun-exporter,原理是调用阿里云API收集监控数据(可以监控ECS、SLB、Redis、Mongodb、RDS等),以prometheus格式存储,同时非常nice的做了非常漂亮的Grafana图。
但是,由于“年久失修”,在使用的时候遇到不少问题,再加上个人代码能力青铜三段,重写有点难,那就硬修吧。以下是在使用时遇到的问题。
1.3.1 重新打包Dockerfile 原因是,pip3 install aliyun-exporter拉的镜像没有SLB的模块(其实这个根RDS监控没什么关系,另一位同事在搞SLB的监控,顺道都修了),人肉了很久,发现github中最新的代码有这个功能。尴尬~想用也只能自己动手了,替换最新的代码文件info_provider.py,重新打包。脚本如下:
$ cat docker.file FROM aylei/aliyun-exporter:0.3.0 RUN pip3 install -U aliyun-exporter==0.3.1 PyYAML==5.1.2 RUN pip3 install aliyun-python-sdk-slb aliyun-python-sdk-dds COPY info_provider.py /usr/local/lib/python3.7/site-packages/aliyun_exporter/info_provider.py # 注意:作者没有把最新的代码打包进docker中,没办法只能我们先去下载代码,然后替换 $ docker build -f docker.
1.先去微信开发平台注册
然后开通网站应用
成功后是这样的
注意这里写的是顶级域名,其他的不行
现在去写前端 前端写个js就可以请求微信了
// 微信授权登录 $('.login-tip-btn').click(function(){ var obj = new WxLogin({ self_redirect: false, id: "login_container", appid: "wxda88e44dfcab312d", scope: "snsapi_login", //redirect_uri 这里可以写回调到哪个页面的地址。 但是在配置页面必须写顶级域名地址 redirect_uri: encodeURIComponent("https://www.yun-live.com/chat_callback"), // redirect_uri: encodeURIComponent("http://" + window.location.host + "/login.php"), state: Math.ceil(Math.random() * 1000), style: "black", href: "https://www.yun-live.com/web_pc/css/code_img.css?v=4" //根据自己的css修改二维码样式 }); $('.kkcolos_a').show(); $('.code_img_a').show(); }) //关闭微信授权登录 $('.kkcolos_a').click(function(){ $('.kkcolos_a').hide(); $('.code_img_a').hide(); }) 在写给按钮去促发这个js方式请求
这个的login_container是div的di名称
<!-- 放置二维码的div --> <div class="kkcolos_a" style="display: none;"><i class="iconfont colos_a"></i></div> <div class="code_img_a" style="display: none;" id="login_container"></div> 前端基本这样就可以方式请求了
先指定做好的封装路径,使封装与下一步导入的网表映射上👇
然后指定导入原理图路径👇
file👉import👉logic
再导入就不会报错了。
##.dra封装文件产生.psm .pad步骤👇
用PCB Editor打开一个.dra文件,file👉Export👉libraries
如图勾选,路径选择存放产生.psm .pad的文件,统一存放即可。
导出完成点击Close,再保存,这样在指定路径下就产生好.psm和.pad文件了
##第三方网表需要的device产生方法👇
file👉Create device 点击OK就好了,会在打开的.dra文件路径下产生一个.txt文件,这个就是setup里用户参数devpath所需要指定的.device文件。
题意: 有t组数据,每组数据有三个数n,a,b;n表示要修的路的长度,a表示修好的路的天数,b表示修不好的路的天数,要求将所有的路修完并且好的路占至少一半,问所需要的天数。
思路: 题意很好理解,实现起来也不是很难,但是不知道为什么就是一直wa,就很气。然饿一个小时改来改去,终于改对了。我分了三种情况,
第一种情况是a*2>n,那么肯定修的超过一半都是好路并且一次就修完了。
第二种情况是a>=b,就是修a天再修b天算作一次轮回的话,那好的路肯定是超过一半的,所以res也是n的值。
第三种情况就是我们容易考虑不全的情况。因为我们要保证好的路要至少占一半,那么我们先求出好路修一半需要多少个a天,以为b是大于a的,所以在同等天数下不好的路一定是大于好的路的,所以不必考虑总数会小于n,由于是除法,可能会存在有余数,那么我们当前刚好是(k2-1)个轮回,所以我们在从a天开始,知道好的路到了一半,那么这天就是最后一天,到这天为止的总天数就是我们所要求的答案。
代码: #include<iostream> #include<bits/stdc++.h> #include<algorithm> using namespace std; int main() { int t; scanf("%d",&t); while(t--) { long long int n , g , b; long long int res = 0; scanf("%lld %lld %lld",&n,&g,&b); if(g*2 >= n) { res = n; } else if(g >= b) { res=n; } else { long long int k1 = 0; long long int k2 = 0; long long int z = 0; z = n / 2; if(z*2<n) z++; k2=z/g; if(k2*g<z) k2++; res=res+(k2-1)*(g+b); if((k2-1)*g<z) { res=res+z-(k2-1)*g; } if(res < n) res = n; } printf("
新型冠状病毒的确诊人数依旧在持续上升。在对传染病模型的研究上有很多模型比如:SI、SIS、SERS、SIR等,本文将利用SIR模型对这次新型冠状病毒的发展情况进行研究。
数据 数据本次数据比较简单可以看我之前文章爬取疫情数据,也可以直接直接手动输入。当然本次数据选取从一月份开始到2月12日,因为自从13日公布的确诊数据包含了临床数据,与之前的数据统计方式不一样因此步加进去。那么先看下数据,在左边的图里,可以看到截止2月12日的确诊人数变化,右图是取完对数的变化并用线性模型拟合了一下,可以发现呈现出一种类似对数线性的关系。这表明该流行病处于指数阶段,尽管发病率略低于开始时。顺便说一句:一开始,很多人都没有惊慌。为什么?因为指数函数在开始时看起来是线性的。 相关python代码(python做个线性回归都要写个函数,所以接下来用R去建模)
import pandas as pd import matplotlib.pyplot as plt import math import numpy as np def linear_regression(x, y):
N = len(x)
sumx = sum(x)
sumy = sum(y)
sumx2 = sum(x ** 2)
sumxy = sum(x * y)
A = np.mat([[N, sumx], [sumx, sumx2]])
b = np.array([sumy, sumxy])
return np.linalg.solve(A, b)
data = pd.read_csv(‘data.csv’,encoding=‘gb2312’)
I = list(data[‘感染’])
N =1400000000
Day = []
logI = []
for i in range(len(I)):
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include<stdlib.h> #define SL 50 typedef enum SEX { //类型定义,用于方便输入同时区分男女 Man = 0, Woman=1 }SEX; struct STU { //定义学生结构体 char name[SL]; SEX sex; char birth[SL]; char id[SL]; int phoneNum; struct STU* next; //实现链表功能,指向下一个学生 }; /* struct STU* findLast(struct STU* head) { if (head == NULL) { return NULL; } struct STU* current = head; while (current->next != NULL) { current = current->next; } return current; } */ void menu(int n) { //菜单函数,用来实现主界面 system("
运算符声明成类成员还是声明独立友元函数建议准则: C++规定: 赋值运算符=、数组下标运算符[]、函数调用运算符()、成员访问运算符->在重载时必须声明为类的成员函数流运算符<<、>>、类型转换运算符不能定义为类的成员函数,只能是 友元函数一元运算符和复合赋值运算符重载时,一般声明类的 成员函数二元运算符在运算符重载时,一般声明为 友元函数 注意: 对于很多运算特来说,可以选择使用成员函数或非成员函数来实现运算符重载,一般来说,非成员函数应该是友元函数,这样才能直接访问类的私有数据。在定义运算特时,必须选择其中的一种格式,而不能同时选择这两种格式,同时定义这两种格式将被被为二义性错误,导致编译错误那么哪种格式最好呢?对于某些运算特来说,成员函数是唯一合法的解释,在其他情况下,这两种格式没有太大的区别,有时,根据类的设计,使用非成员函数版本可能更好(尤其是为类定义类型转换时). 友元函数在定义时不需要使用域运算符 :: 重载流运算符后可以很容易控制某个对象的打印格式 类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员。尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数。 友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类,在这种情况下,整个类及其所有成员都是友元。 如果要声明函数为一个类的友元,需要在类定义中该函数原型前使用关键字 friend,如下所示: class Box { double width; public: double length; friend void printWidth( Box box ); void setWidth( double wid ); }; #include <iostream> using namespace std; class Box { double width; public: friend void printWidth( Box box ); void setWidth( double wid ); }; // 成员函数定义 void Box::setWidth( double wid ) { width = wid; } // 请注意:printWidth() 不是任何类的成员函数 void printWidth( Box box ) { /* 因为 printWidth() 是 Box 的友元,它可以直接访问该类的任何成员 */ cout << "
解决方法:
按照提示在IDEA的Terminal中输入git branch --set-upstream-to origin即可。
HTML编写一个抽奖转盘 以下是所有代码:HTML、css
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="description" content=""> <meta name="author" content="菜鸟训练"> <title>转盘抽奖效果</title> <!-- 这里是css部分 --> <style> #bg { width: 650px; height: 600px; margin: 0 auto; background: url( turntable-bg.jpg.jpg) no-repeat; position: relative; } img[src^="pointer"] { position: absolute; z-index: 10; top: 155px; left: 247px; } img[src^="turntable"] { position: absolute; z-index: 5; top: 60px; left: 116px; transition: all 4s; } </style> </head> <body> <!-- 这里是HTML结构部分 --> <div id="bg"><img src="
本文始发于个人公众号:TechFlow,原创不易,求个关注
上一篇文章我们复习了函数求导的定义和一些常见函数的导数,今天这篇文章我们回顾一下复杂函数的求导方法。先强调一下,今天的文章很重要,想要看懂机器学习各种公式推导,想要能够自己推一推各种公式,函数求导是基础中的基础,在算法这个领域,它比积分要重要得多。
我们先来看第一种情况:多个函数进行四则运算的导数。
函数四则运算求导法则 我们假设 u = u ( x ) u=u(x) u=u(x)和 v = v ( x ) v=v(x) v=v(x)都在x点有导数,那么它们进行加减乘除四则运算之后的结果的导数有如下性质:
[ u ( x ) ± v ( x ) ] ′ = u ′ ( x ) ± v ′ ( x ) [ u ( x ) v ( x ) ] ′ = u ′ ( x ) v ( x ) + u ( x ) v ′ ( x ) [ u ( x ) v ( x ) ] = u ′ ( x ) v ( x ) − u ( x ) v ′ ( x ) v 2 ( x ) ( v ( x ) ≠ 0 ) \begin{aligned} \left[u(x) \pm v(x)\right]'&= u'(x) \pm v'(x) \\ \left[u(x)v(x)\right]' &= u'(x)v(x) + u(x)v'(x) \\ \left[\frac{u(x)}{v(x)}\right] &= \frac{u'(x)v(x)-u(x)v'(x)}{v^2(x)} (v(x) \neq 0) \end{aligned} [u(x)±v(x)]′[u(x)v(x)]′[v(x)u(x)]=u′(x)±v′(x)=u′(x)v(x)+u(x)v′(x)=v2(x)u′(x)v(x)−u(x)v′(x)(v(x)=0)