目录: 版本说明问题原因解决办法 一、版本说明 本机系统: Mac Android studio: 3.6.2 "react": "16.8.3", "react-native": "0.59.9" 二、问题原因 2.1、修改项目代码后,Android Studio 中运行、打包后未更新 三、解决办法,参考这里 3.1、原因是 8081 端口被占用,kill 所有 8081 端口的其他程序,再重新运行项目即可 项目根目录下运行此命令 react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res ⚠️ 如果项目不存在文件 index.android.bundle,解决办法参考这里 3.2、重新运行项目,即可成功 ✌️ react-native run-android 写给自己的随笔,有问题欢迎指出
目录: 版本说明报错内容解决办法 一、版本说明 本机系统: Mac Android studio: 3.6.2 "react": "16.8.3", "react-native": "0.59.9" 二、在Android 安卓环境,Android Studio 中运行启动项目时出现以下错误: Unable to load script.Make sure you're either running a metro server(run `react-native start`) or that your bundle 'index.android.bundle' is packaged correctly for release. ...... 如下图:
三、解决办法,参考这里 3.1、检查此文件是否存在 index.android.bundle,应该是没有此文件,所以按以下步骤生成 目录 ${项目名}/android/app/src/main/ 下创建文件夹 assets检查项目中是否有 index.android.js 文件,如果【有】执行第 3 步的命令,如果【没有】则执行第 4 步的命令(修改了第 3 步的命令 index.android.js 为 index.js )项目中执行以下命令(对应 index.android.js 文件): react-native bundle --platform android --dev false --entry-file index.
一.启动Hadoop后运行Hive时出现如下错误。
Exception in thread "main" java.lang.IllegalArgumentException: java.net.URISyntaxException: Relative path in absolute URI: ${system:java.io.tmpdir%7D/$%7Bsystem:user.name%7D
Exception in thread "main" java.lang.IllegalArgumentException: java.net.URISyntaxException:
Relative path in absolute URI: ${system:java.io.tmpdir%7D/$%7Bsystem:user.name%7D
at org.apache.hadoop.fs.Path.initialize(Path.java:205)
at org.apache.hadoop.fs.Path.(Path.java:171)
at org.apache.hadoop.hive.ql.session.SessionState.createSessionDirs(SessionState.java:644)
at org.apache.hadoop.hive.ql.session.SessionState.start(SessionState.java:563)
at org.apache.hadoop.hive.ql.session.SessionState.beginStart(SessionState.java:531)
at org.apache.hadoop.hive.cli.CliDriver.run(CliDriver.java:705)
at org.apache.hadoop.hive.cli.CliDriver.main(CliDriver.java:641)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.hadoop.util.RunJar.run(RunJar.java:221)
at org.apache.hadoop.util.RunJar.main(RunJar.java:136)
Caused by: java.net.URISyntaxException: Relative path in absolute URI: ${system:java.io.tmpdir%7D/$%7Bsystem:user.name%7D
at java.net.URI.checkPath(URI.java:1823)
at java.net.URI.(URI.java:745)
at org.apache.hadoop.fs.Path.initialize(Path.java:202)
... 12 more
SpringMVC 中,文件的上传,是通过 MultipartResolver 实现的。 所以,如果要实现文件的上传,只要在 spring-mvc.xml 中注册相应的 MultipartResolver 即可。
MultipartResolver 的实现类有两个:
CommonsMultipartResolver
StandardServletMultipartResolver
两个的区别:
第一个需要使用 Apache 的 commons-fileupload 等 jar 包支持,但它能在比较旧的 servlet 版本中使用。
第二个不需要第三方 jar 包支持,它使用 servlet 内置的上传功能,但是只能在 Servlet 3 以上的版本使用。
第一个使用步骤:
/CommonsMultipartResolver 上传用到的两个包/
"commons-fileupload:commons-fileupload:1.3.1",
"commons-io:commons-io:2.4"
如果是maven项目的话直接导入:
commons-fileupload
commons-fileupload
1.3.1
dispatcher-servlet.xml配置:
web.xml:
dispatcher
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:dispatcher-servlet.xml
dispatcher
/
后台java(上传、下载)处理代码:
package edu.nf.ch08.controller;
import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.multipart.MultipartFile;
packageSocket;importjava.io.DataInputStream;importjava.io.DataOutputStream;importjava.io.EOFException;importjava.io.IOException;importjava.net.BindException;importjava.ne...
package Socket;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class Chat_Server {
ServerSocket ss = null;
Socket s = null;
List clients = new ArrayList();
boolean started = false;
public void start() {
try {
ss = new ServerSocket(12345);
started = true;
while (started) {
s = ss.accept();
System.out.println("客户端_" + s.getPort() + "加入到这个聊天室。");
Client c = new Client(s);
一、IIS7的安装Windows 中IIS7、IIS7.5是默认不安装的,所以在安装完Windows Vista/windows 7/windows 2008之后如果需要安装IIS7/iis7.5的话,就要自己动手了。
安装的步骤为:开始》控制面板》程序》打开或关闭Windows功能》Internet信息服务。IIS7安装时需要注意的是,如果需要ASP、ASP.NET等的支持,是需要把功能模块给装上的,默认是不安装的。
IIS7安装完成之后可以在开始菜单的所有程序中看到“管理工具”,其中有一个“Internet信息服务管理器”,如果没有可以按以下步骤添加:开始》右击属性》“开始”菜单选项卡》自定义》把“系统管理工具”设置为“在所有程序菜单显示”或者“在所有程序菜单和开始菜单上显示”。
打开Internet信息服务管理器就可以看到IIS7的主页了
IIS7配置ASP+Access使用环境默认装完IIS7之后,使用ASP程序会发现提示数据库连接失败,因为MSJet引擎改变了临时目录的位置,但是又没有对临时的存取权限,导致数据库使用失败。
先要设置应用程序池(ApplicationPool)为Classic.NETAppPool,而不是默认的DefaultAppPool,可以在网站目录里对每个站点设置,也可以在站点进行单独设置。选择好要设置的站点之后,点右边的“基本设置”即可调出应用程序池设置对话框。
然后再给“系统盘:WindowsServiceProfilesNetworkServiceAppDataLocalTemp”目录添加一个“AuthenticatedUsers”的用户,其中AppData目录是隐藏的,在进入的时候可以直接在地址栏输入路径,或者在文件夹选项里显示隐藏文件。
设置权限步骤:右击Temp文件夹,选择“属性”》选择“安全”选项卡》单击“编辑”》出来“Temp的权限”对话框,单击“添加”,在下面的“输入对象名称来选择”中输入AuthenticatedUsers,确定》返回到“Temp的权限”,将Authenticated Users的权限中的完全控制给勾上,确定》确定。
启用父路径支持
在站点主页上选择“ASP”,然后在“行为”组中将“启用父路径”设置为True即可。
右击网站文件夹,选择“属性”》选择“安全”选项卡》单击“编辑”》出来“网站文件夹的权限”对话框,单击“添加”,在下面的“输入对象名称来选择”中输入everyone,确定》返回到“文件夹的权限”,将everyone的权限中的完全控制给勾上,确定》确定。【注:为了方便才这么设置,详细的安全配置请咨询相关专业人士】
在64bit Win2008上运行Asp + Access网站1, 安装ASP.
控制面板\程序\打开或关闭Windows功能\角色: Web 服务器(IIS)\添加角色服务
选中ASP,确定
2,创建网站
3,设置该网站所在的应用程序池
高级设置\启用32位应用程序 : True
现在网站应该可以正常运行了.
如果仍然不行,则可能需要修改数据库文件所在目录的权限(注意*.mdb文件需要给IUSR用户写权限),只读等设置.
至此,完成了IIS7的安装及使用ASP+Access的配置。
*****************InetAddress**********************
InetAddress:用于标识网络上的硬件资源(如,IP,主机名,域名等)。
对于InetAddress,三个方法:getLocalHost()、getByName()以及getAllByName()可以用来创建InetAddress的实例。
InetAddress类没有提供返回构造函数,所以不能用new()方法来创建它的对象,而只可以调用静态方法getLocalHost()、getByName()、getByAddress()等来生成InetAddress类的实质。
1、InetAddress常用方法:
1.InetAddress.getLocalHost()仅返回象征本地主机的InetAddress对象。(返回的是本地地址)
本机地址还为localhost,127.0.0.1,这三个地址都是一回事。
例,InetAddress.getLocalHost();//Lenovo-PC/169.254.193.131
2.getByName()方法返回一个传给它的主机名的InetAddress。
如果这些方法不能解析主机名,它们引发一个UnknownHostException异常。
在Internet上,用一个名称来代表多个机器是常有的事。
例,InetAddress.getByName("www.baidu.com");//www.baidu.com/61.135.169.121
3.getAllByName()方法返回代表由一个特殊名称分解的所有地址的InetAddresses类数组。
getAllByName()方法是根据主机名返回其可能的所有InetAddress对象,保存在一个数组中。
在不能把名称分解成至少一个地址时,它将引发一个UnknownHostException异常。
4.getLoopbackAddress()方法返回本地环回地址
例,InetAddress.getLoopbackAddress();//localhost/127.0.0.1
5.查看端口是否已使用
Socket socket = new Socket(Address,port);#address代表主机的IP地址,port代表端口号.
如果对该主机的特定端口号能建立一个socket,则说明该主机的该端口在使用。
例,import java.net.*;
for (int i = 500; i < 1024; i++) {
try {
System.out.println("查看 端口"+ i);
Socket skt = new Socket("localhost", i);
System.out.println("端口 " + i + " 已被使用");
}
catch (UnknownHostException e) {
System.out.println("Exception occured"+ e);
break;
}
catch (IOException e) {
System.out.println("端口"+i+"未被使用");
数组,其实就是一个给定了大小给定了类型的容器,在这容器中有你设定的元素,你可以对这些元素进行各种升降排列,或者找出其中特殊的元素并进行一系列的运算。数组,本身是有序的元素序列,本文我们就来看看Java数组排序的几个方法。
一、冒泡排序
举 个 栗 子:5 2 0 4 1 3 一个容量为七的数组排升序(降序同理,最大值变最小就ok)
①从这组数中找那个冒泡的(最大的),把它踢到最后 2 0 4 1 3 5
②重复上述行为 2 0 1 3 4 5
③重复~~ 2 0 1 3 4 5
④~~0 1 2 3 4 5
⑤~~0 1 2 3 4 5 完成
Java代码实例:
二、选择排序
还是刚才那个栗子:5 2 0 4 1 3 升序
①找到数组中最小的 放到第一个位置 0 5 2 4 1 3
②数组中剩下的找到最小的放在第二个位置 0 1 5 2 4 3
1.概览
Spring 的 @Vaule 注解提供了一种便捷的方法可以让属性值注入到组件中,当属性值不存在的时候提供一个默认值也是非常好用的
这就是我们这篇文章所专注的,如何给 @Vaule 注解指定一个默认值。对于更多的关于 @Vaule 的教程看这篇文章
2.String 默认值
让我们看看对于 String 类型的值,给定一个默认值得基础语法
@Value("${some.key:my default value}")
private String stringWithDefaultValue;
如果 some.key 无法解析,那么 stringWithDefaultValue 的值会被设置为默认值 "my default value".
相似的,我们也可以用如下方法,设置一个空字符串作为默认值
@Value("${some.key:})"
private String stringWithBlankDefaultValue;
3.原始类型
给像 int 或者 boolean 的原始类型赋一个默认值,我们使用文字值:
@Value("${some.key:true}")
private boolean booleanWithDefaultValue;
@Value("${some.key:42}")
private int intWithDefaultValue;
如果愿意,可以用原始类型的包装类型来代替,例如 Boolean 和 Integer
4.数组
我们可以使用逗号分隔的 list 来用于数组的注入,如下
@Value("${some.key:one,two,three}")
private String[] stringArrayWithDefaults;
@Value("${some.key:1,2,3}")
private int[] intArrayWithDefaults;
在上面第一个例子, 值为 "one", "two", 和 "
原标题:cadence原理图快捷键
Allegro Design Entry CIS 原理图
1.shift+鼠标滚轮 左右移动
2.Ctrl+鼠标滚轮 放大缩小
3.Alt+鼠标滚轮 上下移动
4.按下鼠标滚轮可任意方向拖动图纸(可以一直保持按下状态或者按一下松开)
5.CTRL+鼠标左键 : 元件叠选
6.CTRL+鼠标左键拖动 : 复制该元件,元件标号自动加一
7.ALT+F4 退出当前窗口
8.CTRL+E 编辑元件属性(要先选中)
9.CTRL+Z 撤消上步操作
10.i : 放大图纸
(zoom in 聚焦,镜头拉近放大物体)
11.o : 缩小图纸 (zoom out扩焦,镜头拉远缩小物体)
12.r : 元件旋转 rotate
13.p : 放置元件 place
14.n : 放置网络标号 number
15.b : 放置总线 bus
16.e : 放置总线管脚
17.g/f : 放置电源和地 g和f两个快捷键的效果是一样的,ground/frame
18.z : 查询本地元件与网上元件
19.w : 放置导线
20.h :水平镜像
21.z :上下镜像
aria2 是 Linux 下一个不错的高速下载工具 。由于它具有分段下载引擎,所以支持从多个地址或者从一个地址的多个连接来下载同一个文件。这样自然就大大加快了文件的下载速 度。aria2 也具有断点续传功能,这使你随时能够恢复已经中断的文件下载。除了支持一般的 http(s) 和 ftp 协议外,aria2 还支持 BitTorrent 协议。这意味着,你也可以使用 aria2 来下载 torrent 文件。
安装 aria2
aria2 目前已被包含到许多 Linux 发行版中,因此你可以通过所用的系统直接加以安装。例如,在 Debian/Ubuntu 中,你可以在终端执行如下指令来安装 aria2:
sudo apt-get install aria2 aria2 的使用方法
aria2 是命令行 程序,使用非常简单。
一般使用使用 aria2 下载文件,只需在命令后附加地址即可。比如我们下载ubuntu如:
aria2c http://www.mirror.tw/pub/ubuntu/releases/jaunty/ubuntu-9.04-desktop-i386.iso 分段下载利用 aria2 的分段下载功能可以加快文件的下载速度,对于下载大文件时特别有用。为了使用 aria2 的分段下载功能,你需要在命令中指定 s 选项。如:
aria2c -s 2 http://www.mirror.tw/pub/ubuntu/releases/jaunty/ubuntu-9.04-desktop-i386.iso 这将使用 2 个连接来下载该文件。s 后面的参数值介于 1~5 之间,你可以根据实际情况选择。
断点续传在命令中使用 c 选项可以断点续传文件。如:
aria2c -c http://www.mirror.tw/pub/ubuntu/releases/jaunty/ubuntu-9.04-desktop-i386.iso 下载 torrent 文件你也可以使用 aria2 下载 BitTorrent 文件。如:
ZigBee-CC2530单片机 - 实现外部电压值的测量 程序源码 /* 包含头文件 */ #include "ioCC2530.h" #include <string.h> #define LED1 P1_0 // P1_0定义为P1_0 led灯端口 #define uint16 unsigned short #define uint32 unsigned long #define uint unsigned int unsigned int flag,counter=0; //统计溢出次数 unsigned char s[8];//定义一个数组大小为8 void InitLED() { P1SEL&=~0X01; //P1_0设置为普通的IO口 1111 1110 P1DIR |= 0x01; //配置P1_0的方向为输出 LED1=0; } void adc_Init(void) { APCFG |=1; P0SEL |= 0x01; P0DIR &= ~0x01; } /************************************************************ * 名称 get_adc * 功能 读取ADC通道0电压值 * 入口参数 无 * 出口参数 16位电压值,分辨率为10mV ***************获取ADC通道0电压值************************/ uint16 get_adc(void) { uint32 value; ADCIF = 0; //清ADC 中断标志 //采用基准电压avdd5:3.
(前排提醒,本文的人文内容部分稍稍带有艺术加工,请保持一定的幽默感进行阅读)
关注我最近想法的同学应该知道我最近都在把玩TVM,今天终于使用TVM得到了非常满意的结果,而专栏也很长时间没更新了,于是来安利(水)一篇。
本来可能用不到TVM,项目其实进展的很顺利,我们初始的tensorflow模型在android端得到了满意的latency,我也可以照常一边修炼我的仙,继续和有奶大定律, 自由单子, Kan-Extension等邪魔外道搏斗…一边稳稳的推进项目进度。
无奈scientist一意孤行要上Pytorch, 于是我们换了一个Pytorch模型…
先不说同样的SSD魔改模型,Pytorch在android端比tensorflow整整慢了5倍,光是把Pytorch模型移植到Android上都让开发团队整整褪层皮(Pytorch对Android的支持简直为0,tensorflow的工程支持相对pytorch简直无敌)。而这时候已经花了好多时间,项目眼看要delay…
头都炸了的我在打算手撸OpenCL调优之前,去问了下我们组的CV大神该怎么办,大神微微一笑,转身随风而去,只听云端传来3个字:“TVM~~~~~"
于是我就开始TVM的研究(踩坑)之路, 到今天为止终于把所有的路都踩平了之后,成功把我们的Pytorch模型用Auto-TVM调优成功且部署在了我们的android系统上,性能整整提高了8倍,比我们之前的tensorflow模型还要快。更重要的是,通过TVM,我们的调优完全不couple与硬件和模型Framework,就算以后换模型,换终端,或者哪天scientist想不开要换回tensorflow或是使用MXNet都无所谓,用auto-TVM自动调调就行了(只可惜了我的Cuda C编程调优都白学了)。
简单介绍下Auto-TVM的调优终端设备的用法
你可以有很多手机平板设备,安装好TVM RPC这个App之后,可以在App里输入Tracker的IP和端口,进行设备注册(另外输入一个设备ID来让Auto-TVM tuning程序找到)。Tracker是一个Python的程序,git clone TVM之后,按教程编译好,就可以按这个教程启动Tracker。Auto-TVM tuning程序也是一个python程序,它会连接Tracker(也可以和Tracker是一台机器)找到相应的设备ID的IP,然后和设备直接用RPC通信,Auto-TVM程序会根据程序预设的target(比如是不是arm cpu,要不要用OpenCL…) 来把你想要优化的Deep Learning模型直接编译为设备的machine code, 通过TVM RPC把code部署在终端,终端的TVM RPC App会测试这个模型的inference performance,然后回报给Auto-TVM tuning程序,然后Auto-TVM tuning程序会根据反馈,重新计算该如何优化编译,重新生成新的模型的machine code再次部署… 如此循环…直到达到预设的实验次数(比如2000),或太多次实验都没有提高提前结束(比如第一次就找到了最优优化结果)。最后TVM会根据调优时得到的最佳“编译参数”来最终编译你的deeplearning 模型为终端模型的machine code,最终完成优化编译过程。 以上只是简单介绍,具体请看TVM的论文,和去TVM官网看 tutorial,写得非常详细切提供了很多很好理解的范例代码。我的最终的tuning程序,就是魔改其中一个范例程序而来。
TVM踩坑记录
TVM目前还只是0.6版本,很多东西还不稳定,由于开发环境各异,有时候需要工程师自己解决一些开发团队在开发时没有碰到的问题,但是这些问题相对与TVM提供的巨大优势相比,都是小问题啦(工程能力越强,魔改力越强,你就可以越早体验新技术带来的好处呀。)。(我遇到的最坑的问题其实是公司网络各种IP禁止访问,封端口,使得android机和开发服务器一直连不上, 最终还是在自己的电脑上装了虚拟机,自建了一个小LAN才解决的这个问题)
1. 编译tvm4j-core出错: cannot find symbol [ERROR] symbol: class SharedSecrets
JDK11会遇到这个问题,因为JDK11已经把sun.misc.SharedSecrets换到别的地方了,建议不要尝试修改TVM源代码来fix这个问题,因为你会遇到其他更多问题,请下载JDK8,把JAVA_HOME设为JDK8的,一切就会很顺利
2. Android TVM RPC编译出错: #error "Unable to determine endianness of your machine; use CMake to compile"
Android RPC server fails to build
centos7在终端ping外网时显示网络不可达,我之前已经配置了centos7的nat模式下静态IP(可以看我另外一篇:centos7的nat模式配置静态IP),
我的配置完静态IP的文件如下所示
配置文件的路径:/etc/sysconfig/network-scripts/ifcfg-ens33
TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=static DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=yes IPV6_AUTOCONF=yes IPV6_DEFROUTE=yes IPV6_FAILURE_FATAL=no IPV6_ADDR_GEN_MODE=stable-privacy NAME=ens33 UUID=64ef9573-0206-47fb-ba71-dd6cbe12c54e DEVICE=ens33 ONBOOT=yes IPADDR=192.168.1.131 NETMASK=255.255.255.0 DNS1=192.168.1.2 在ifcfg-ens33添加:GATEWAY=192.168.1.2
该IP是自己的配置nat模式下静态IP的网关IP
保存退出后执行以下命令
service network restart
或
systemctl restart network.service
成功后再ping,就ok了,
另外在执行上面的命令的同时,会更新/etc/resolv.conf的文件内容,将DNS的IP更新进去
网上还有其他的版本说添加HWADDR和DNS2,在实验中发现这两个不加也可以,具体有什么用不清楚,有了解的请不吝赐教,如果感觉有用请点赞
学习过程跟进黑皮书《数据结构与算法分析》,主要代码大致与树种例程相同,若有疏漏或错误,请务必提醒我,我会尽力修正。
左式堆Leftist Heap:
因为基础的堆结构由数组实现,并不支持合并等高级操作(有办法实现,但效率并不那么理想),为解决这些问题,左式堆提供了一些方案。
左式堆同样遵守最小堆的基本堆序——任意节点的关键字值低于其子树中的所有节点,但与之不同的是,左式堆的基本结构还包含了Npl(Null path length),即从该结点到达一个没有两个孩子的结点的最短距离。并要求:任意结点的左孩子的Npl大于或等于右孩子的Npl。
声明部分:(函数对于的作用已经写在注释里了)
//----------声明部分----------// typedef struct TreeNode* PriorityQueue;//节点指针 struct TreeNode//节点结构 { int Element; PriorityQueue Left; PriorityQueue Right; int Npl;//Null Path Length }; PriorityQueue Initialize(void);//建立空堆 PriorityQueue Merge(PriorityQueue H1, PriorityQueue H2);//合并堆(驱动例程) static PriorityQueue Merge1(PriorityQueue H1, PriorityQueue H2);//合并堆(实际例程) void SwapChildren(PriorityQueue H);(交换H的左右子树) PriorityQueue Insert1(int key, PriorityQueue H);//插入节点 bool IsEmpty(PriorityQueue H);//是否为空堆 PriorityQueue DeleteMin1(PriorityQueue H);//删除最小值 //----------声明部分----------// 建立空堆Initialize:
PriorityQueue Initialize(void) { PriorityQueue H; H = new TreeNode; H->Left = H->Right = NULL; H->Npl = 0; return H; } 规定NULL的Npl为-1,则对任何一个没有两个子树的节点,其Npl为0。
NVM,用于在系统中安装多个版本 Node.js 环境,并可以自如切换。
在 Linux 中,安装 nvm 工具 Debian GNU/Linux 10 (buster) and Bash GitHub - nvm-sh/nvm: Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versions
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.36.0/install.sh | bash cat >> ~/.bashrc <<EOF export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm EOF 使用 nvm 安装 Node.js 环境 node.
直方图均衡化的原理及实现 一、直方图
1.1 直方图的概念
在图像处理中, 经常用到直方图, 如颜色直方图、 灰度直方图等。
图像的灰度直方图就描述了图像中灰度分布情况, 能够很直观的展示出图像中各个灰度级所占的多少。图像的灰度直方图是灰度级的函数, 描述的是图像中具有该灰度级的像素的个数: 其中, 横坐标是灰度级, 纵坐标是该灰度级出现的率。如下图所示
1.2 直方图的性质
① 直方图反映了图像中的灰度分布规律。 它描述每个灰度级具有的像素个数, 但不包含这些像素在图像中的位置信息。 图像直方图不关心像素所处的空间位置, 因此不受图像旋转和平移变化的影响, 可以作为图像的特征。
② 任何一幅特定的图像都有唯一的直方图与之对应, 但不同的图像可以有相同的直方图。
③如果一幅图像有两个不相连的区域组成, 并且每个区域的直方图已知, 则整幅图像的直方图是该两个区域的直方图之和。
1.3 直方图的应用
下图是四种常见的直方图的灰度分布规律
如果需要将上图中灰度偏暗、偏亮或偏集中的直方图调整为灰度均匀分布的直方图,就需要用到直方图均衡化算法。
二、直方图均衡化
2.1 直方图均衡化的概念
直方图均衡化(Histogram Equalization)是一种增强图像对比度(Image Contrast)的方法,其主要思想是将一副图像的直方图分布通过累积分布函数变成近似均匀分布,从而增强图像的对比度。为了将原图像的亮度范围进行扩展, 需要一个映射函数, 将原图像的像素值均衡映射到新直方图中, 这个映射函数有两个条件:
①不能打乱原有的像素值大小顺序, 映射后亮、 暗的大小关系不能改变;
② 映射后必须在原有的范围内,即像素映射函数的值域应在0和255之间;
综合以上两个条件,累积分布函数是个好的选择,因为累积分布函数是单调增函数(控制大小关系),并且值域是0到1(控制越界问题),所以直方图均衡化中使用的是累积分布函数。
2.2 累积分布函数的数学原理
因为图像由一个个像素点组成,所以图像直方图均衡化是通过离散形式的累积分布函数求解的,直方图均衡化过程中,映射方法是:
其中,s_k指当前灰度级经过累积分布函数映射后的值,n是图像中像素的总和,n_j是当前灰度级的像素个数,L是图像中的灰度级总数。
(直方图均衡化数学原理,详细查看:> https://blog.csdn.net/superjunenaruto/article/details/52431941)
2.3 直方图均衡化的步骤
①依次扫描原始灰度图像的每一个像素, 计算出图像的灰度直方图;
②计算灰度直方图的累积分布函数;
③根据累积分布函数和直方图均衡化原理得到输入与输出之间的映射关系。
④最后根据映射关系得到结果进行图像变换
2.4 参考下面这个例子可以更直观的理解直方图均衡化的原理及过程
三、代码块及实现效果
3.1 代码块
import cv2 import numpy as np from matplotlib import pyplot as plt ''' calcHist-计算图像直方图 函数原型:calcHist(images,channels,mask,histSize,ranges,hist=None,accumulate=None) images:图像矩阵,例如:[image] channels:通道数,例如:0 mask:掩膜,一般为:None histSize:直方图大小,一般等于灰度级数 ranges:横轴范围 ''' # 获取灰度图像 img = cv2.
JAVA数据库课程设计--学生选课管理系统的设计与实现(完整源代码)
第 PAGE \* Arabic \* MERGEFORMAT 24 页
一、课程设计目的
通过这次的设计,主要是做出一个小型的管理系统,来加强对JAVA所学知识的巩固和融会贯通,可以说是对一个学期所学知识的一个小结,加深对JAVA数据库的理解。
二、需求分析功能需求分析: 该系统具备管理学生信息、课程信息、选课信息的功能:用户通过输入账号和密码进下该系统后,可以进行一些基础维护(学生信息维护、课程信息维护、选课信息维护)。全部都可以进行增加、修改、删除、模糊查询。
三、数据项:
1表admin(用户表)
Field
Type
Null
Key
Comment
Username
char(10)
——
PRI
用户名
password
char(10)
——
——
密码
Name
Char(10)
——
——
用户昵称
2表S(学生信息表)
Field
Type
Null
Key
Comment
Sno
nvarchar(50)
——
PRI
学号
Sname
nvarchar(50)
——
——
姓名
Sx
nvarchar(50)
——
——
系别
3表C(课程信息表)
Field
Type
Null
Key
Comment
Cno
nvarchar(50)
——
PRI
课号
Cname
nvarchar(50)
谢邀。不知道题中的一段文字出自何处。“锁池”和“等待池”这种翻译我还是头一回见。不过,题主的思路已经对了,即不拘泥于文字,而是在考虑这两个东西在锁的调度(即决定哪个线程可以获得锁的过程)中起到什么作用。
Java平台中,每个对象都有一个唯一与之对应的内部锁(Monitor)。Java虚拟机会为每个对象维护两个“队列”(姑且称之为“队列”,尽管它不一定符合数据结构上队列的“先进先出”原则):一个叫Entry Set(入口集),另外一个叫Wait Set(等待集)。对于任意的对象objectX,objectX的Entry Set用于存储等待获取objectX对应的内部锁的所有线程。objectX的Wait Set用于存储执行了objectX.wait()/wait(long)的线程。
设objectX是任意一个对象,monitorX是这个对象对应的内部锁,假设有线程A、B、C同时申请monitorX,那么由于任意一个时刻只有一个线程能够获得(占用/持有)这个锁,因此除了胜出(即获得了锁)的线程(这里假设是B)外,其他线程(这里就是A和C)都会被暂停(线程的生命周期状态会被调整为BLOCKED)。这些因申请锁而落选的线程就会被存入objectX对应的Entry Set(以下记为entrySetX)之中。当monitorX被其持有线程(这里就是B)释放时,entrySetX中的一个任意(注意是“任意”,而不一定是Entry Set中等待时间最长或者最短的)线程会被唤醒(即线程的生命周期状态变更为RUNNABLE)。这个被唤醒的线程会与其他活跃线程(即不处于Entry Set之中,且线程的生命周期状态为RUNNABLE的线程)再次抢占monitorX。这时,被唤醒的线程如果成功申请到monitorX,那么该线程就从entrySetX中移除。否则,被唤醒的线程仍然会停留在entrySetX,并再次被暂停,以等待下次申请锁的机会。
如果有个线程执行了objectX.wait(),那么该线程就会被暂停(线程的生命周期状态会被调整为WAITTING)并被存入objectX的Wait Set(以下记为waitSetX)之中。此时,该线程就被称为objectX的等待线程。当其他线程执行了objectX.notify()/notifyAll()时,waitSetX中的一个(或者多个,取决于被调用的是notify还是notifyAll方法)任意(注意是“任意”,而不一定是Entry Set中等待时间最长或者最短的)等待线程会被唤醒(线程的生命周期状态变更为RUNNABLE)。这些被唤醒的线程会与entrySetX中被唤醒的线程以及其他(可能的)活跃线程共同参与抢夺monitorX。如果其中一个被唤醒的等待线程成功申请到锁,那么该线程就会从waitSetX中移除。否则,这些被唤醒的线程仍然停留在waitSetX中,并再次被暂停,以等待下次申请锁的机会。
@刘方外
我理解调用对象的 notifyAll方法后,waitSet 上的线程都会加入到 entrySet 中的吧?在一个持有锁的线程释放锁后,应该只有 entrySet 队列的线程可能获取锁,那这个通知是 park 来实现的吗?是否有保证获取锁公平性的相关设置?
1、从Java虚拟机性能的角度来说,Java虚拟机没有必要在notifyAll调用之后“将Wait Set中的线程移入Entry Set”。首先,从一个“队列”移动到另外一个“队列”是有开销的,其次,虽然notifyAll调用后Wait Set中的多个线程会被唤醒,但是这些被唤醒的线程极端情况下可能没有任何一个能够获得锁(比如被其他活跃线程抢先下手了)或者即便可以获得锁也可能不能继续运行(比如这些等待线程所需的等待条件又再次不成立)。那么这个时候,这些等待线程仍然需要老老实实在wait set中待着。因此,如果notifyAll调用之后就将等待线程移出wait set会导致浪费(白白地进出“队列”)。这点可以参考显式锁的实现:
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(Node, int)
/**
* Acquires in exclusive uninterruptible mode for thread already in
* queue. Used by condition wait methods as well as acquire.
*
* @param node the node
* @param arg the acquire argument
* @return {@code true} if interrupted while waiting
一、增删改操作
document.appendChild(newNode) 将newNode添加成当前节点的最后一个子节点
document.insertBefore(newNode,refNode) 将refNode节点之前插入newNode节点
document.replaceChild(newNode,oldNode) 将oldNode节点替换成newNode节点
document.removeChild(oldNode) 将oldNode子节点删除
document.createElement(变签名):创建标签。
document.cloneNode(boolean deep):当deep为true时,表示复制当前节点以及当前结点的全部后代节点。为false时,只复制当前节点。**注意:复制时也会复制改元素的属性。
二、option对象
var 变量 = new Option(text,value,defaultSelected,selected);
text:显示的内容。
value:option的value值。
defaultSelected:判断是不是默认项 option对象.[索引].defaultSelected 返回true和false。
selected:设置改option对象为默认选中。true/false
三、设置获取更改删除元素属性
1、获取自定义属性:
document.getAttribute(自定义属性名)//返回string
2、设置自定义属性
document.setAttribute(自定义属性名,自定义属性值)
注意:也可以获取(设置)节点本有的属性和值
3、移除属性
document.removeAttribute(属性名);
从DETR到ViT等工作都验证了Transformer在计算机视觉领域的潜力,那么很自然的就需要考虑一个新的问题,图像的特征提取,究竟是CNN好还是Transformer好?
其中CNN的优势在于参数共享,关注local信息的聚合,而Transformer的优势在于全局感受野,关注global信息的聚合。直觉上来讲global和local的信息聚合都是有用的,将global信息聚合和local信息聚合有效的结合在一起可能是设计最佳网络架构的正确方向。
如何有效的结合global和local信息,最近的几篇文章主要分成了两个方向:CNN based和Transformer based。以下主要解析一下CNN based和Transformer based的网络架构设计,其中CNN based涉及ResNet和BoTNet,Transformer based涉及ViT和T2T-ViT。
01
网络架构设计的相互关系 BoTNet在ResNet的基础上将Bottlenneck的3x3卷积替换成MHSA,增加CNN based的网络架构的global信息聚合能力。T2T-ViT在ViT的基础上将patch的linear projection替换成T2T,增加Transformer based的网络架构的local信息聚合能力。
02
ResNet&BoTNet ResNet的结构设计,ResNet主要由Bottleneck结构堆叠而成,一层Bottlenneck由1x1conv、3x3conv和1x1conv堆叠构成残差分支,然后和skip connect分支相加。BoTNet在Bottlenneck结构的基础上将中间的3x3conv替换成MHSA结构,跟之间的Non-local等工作非常相似,本质上在CNN中引入global信息聚合。
MHSA结构如上图所示,代码如下。
class MHSA(nn.Module): def __init__(self, n_dims, width=14, height=14): super(MHSA, self).__init__() self.query = nn.Conv2d(n_dims, n_dims, kernel_size=1) self.key = nn.Conv2d(n_dims, n_dims, kernel_size=1) self.value = nn.Conv2d(n_dims, n_dims, kernel_size=1) self.rel_h = nn.Parameter(torch.randn([1, n_dims, 1, height]), requires_grad=True) self.rel_w = nn.Parameter(torch.randn([1, n_dims, width, 1]), requires_grad=True) self.softmax = nn.Softmax(dim=-1) def forward(self, x): n_batch, C, width, height = x.
之前一直以为 this关键字 是指调用者对象,但是这次才真正理解,this代表当前对象,但是指向调用者对象,其实就是多态的用法,如下所示:B 继承了 A,在B 中调用A类的方法,在A 中用this 访问成员变量和方法,此时,如果用this访问成员变量,如下,this.s ,无论B 子类有没有 s属性,又或者s 的修饰符是 private 或者 public ,this.s 永远会打印出 当前类的 s属性值,原因:成员变量不能被重写,不能覆盖 ;再说,用this访问方法,如下所示: 在A 中 this.test() , 请注意,此时,this代表A 类,但是指向B ,如: A a = new B() ; 因为 B 类 重写了父类的test方法,所以会调用B 的test 方法 ; 再如,将A 类的test方法改成 private类型的,此时 this.test()将调用A 类的 test方法,因为此时虽然B 类也有test方法,但是这个方法不是重写A类的方法,是一个自己独有的方法,因为父类是private私有的类型,子类不能拥有,敬礼!
public class HelloA {
public static void main(String[] args) {
new B().print();
}
}
class B extends A{
private String s = "
11-1、在通信原理中采用差错控制的目的是什么? 答:为了降低误码率,提高可靠性。
11-2、什么是随机信道?什么是突发信道?什么是混合信道? 答:
随机信道:错码的出现是随机的,错码之间是统计独立的。
突发信道:错码是成串集中出现的,即在一些短促的时间段内会出现大量错码。
混合信道:既存在随机错码又存在突发错码的信道。
11-3、常用的差错控制方法有哪些?试比较其优缺点。 答:
前向纠错FEC:发端发送能纠错的码,收端能够检错并纠错,无需反馈信道。既能检错又能纠错,实时性好,但冗余度高,有效性低,设备复杂。
反馈重传ARQ(检错重发):收端一旦检出错,则通知发端重传,直到正确接收为止。可以检错但不能纠错。
混合差错控制HEC:以上两种的结合,纠错能力之内,则自动纠正,否则重传。
信息反馈IRQ(反馈校验):收端将信息原封不动转发回发端,与原发送信码比较。若不同,则认为有错,发端立即重发。原理和设备都很简单,但需要双向信道,传输效率也较低。
检错删除:在接收端发现错码后,立即将其删除,不要求重发。只适用于在少数特定系统中(发送码元中有大量多余度,删除部分接收码元不影响应用),接收端有少量损失但实时性好。
11-4、画出ARQ系统的组成方框图,并试述该系统的优缺点。 答:
优点:监督码元较少就能使误码率降到很低,即码率较高;检错的计算复杂度较低;检错用的编码方法和加性干扰的统计特性基本无关,能适应不同特性的信道。
缺点:需要双向信道重发,从而导致传输效率降低。干扰严重时甚至会因不断重传导致通信中断,所以不适用于实时场合。不适用于单向信道和一点到多点的通信系统。
11-5、什么是分组码?其构成有何特点? 答:
将信息码分组,为每组信息码附加若干监督码的编码称为分组码。
分组码一般用(n,k)表示,n为码组总位数,k为信息位位数,n-k=r为监督码元位数。
11-6、试述码率、码重和码距的定义。 答:
码率:信息位数与总码元位数之比,k / n 。
码重:码组中“1”的个数。
码距:两个码组对应位上数字不同的位数。
11-7、一种编码的最小码距与其检错和纠错能力有什么关系? 答:记码距为 d ,纠错码的个数为 t ,检错码的个数为 e ,则
d >= e + 1
d >= 2t + 1
d >= t + e + 1 (e>t)
11-8、什么是奇偶监督码?其检错能力如何? 答:分为奇数监督码和偶数监督码,监督位只有一位,偶数监督码中,满足所有码模二加为零。可以检测奇数个错码。
11-9、什么是线性码?它具有哪些重要性质? 答:信息位和监督位是由一些线性代数方程联系着的(按照一组线性方程构成的码)。
11-10、什么是循环码?循环码的生成多项式如何确定? 答:具有循环性的码,即任一码组循环一位以后,仍为该码中的一个码组。
11-11、什么是系统分组码?并举例说明。 答:将信源的信息序列分成独立的块进行处理和编码,信息位位置不变,监督位附加于其后。如汉明码,循环码。
11-12、何谓截短循环码?循环码它适用在什么场合? 答:
11-13、什么是BCH码?什么是本原BCH码?什么是非本原BCH码? 11-14、循环码、BCH码、RS码之间有什么关系? 11-15、卷积码和分组码之间有何异同点?卷积码是否为线性码? 11-16、卷积码适用于纠正哪类错码? 11-17、试述Turbo码和链接码的异同点。 11-18、LDPC码的全称是什么? 11-19、何谓TCM?其中文全称是什么?TCM中的网格图和卷积码的网格图有何不同?为什么? 答案仅供参考,如有错误感谢指正!
一、什么是重复注解允许在同一申明类型(类,属性,或方法)的多次使用同一个注解
二、一个简单的例子
java 8之前也有重复使用注解的解决方案,但可读性不是很好,比如下面的代码:
复制代码 代码如下:
public @interface Authority {
String role();
}
public @interface Authorities {
Authority[] value();
}
public class RepeatAnnotationUseOldVersion {
@Authorities({@Authority(role="Admin"),@Authority(role="Manager")})
public void doSomeThing(){
}
}
由另一个注解来存储重复注解,在使用时候,用存储注解Authorities来扩展重复注解,我们再来看看java 8里面的做法:
复制代码 代码如下:
@Repeatable(Authorities.class)
public @interface Authority {
String role();
}
public @interface Authorities {
Authority[] value();
}
public class RepeatAnnotationUseNewVersion {
@Authority(role="Admin")
@Authority(role="Manager")
public void doSomeThing(){ }
}
不同的地方是,创建重复注解Authority时,加上@Repeatable,指向存储注解Authorities,在使用时候,直接可以重复使用Authority注解。从上面例子看出,java 8里面做法更适合常规的思维,可读性强一点
三、总结
JEP120没有太多内容,是一个小特性,仅仅是为了提高代码可读性。这次java 8对注解做了2个方面的改进(JEP 104,JEP120),相信注解会比以前使用得更加频繁了。
文章参考了很多其他技术网站,然后自己再根据需求,调试出来的,感谢其他网站的筒子们,临时关了那些网站,无法附链接了,在此SAY SORRY
js版本的【GMT时间转换成北京时间】代码:
/****************************************************
功能描述:将GMT时间转换成北京时间
参数说明:
value:要格式化的时间
strFormat:格式,如:'Y-m-d H:i:s'
******************************************************/
this.GMTtoTime = function(value){
if(value=="" || value==null){
return "";
}
else{
var tempValue = value.replace("T", " ");
var dateBefore = tempValue.slice(0,10);
var timeBefore = tempValue.slice(11,19);
var dateArray = dateBefore.split("-");
var timeArray = timeBefore.split(":");
//注意,Date对象中的getMonth() 返回0~11
var feedDate = Date.UTC(dateArray[0],dateArray[1]-1,dateArray[2],timeArray[0],timeArray[1],timeArray[2],0) + 8*60*60;
var now = new Date();
now.setTime(feedDate);
if (now.getMonth()<10){
var m=0;
m=now.getMonth()+1;
var month = "0" + m;
}else{
var month = now.
一. Thread.yield( )方法:
使当前线程从执行状态(运行状态)变为可执行态(就绪状态)。cpu会从众多的可执行态里选择,也就是说,当前也就是刚刚的那个线程还是有可能会被再次执行到的,并不是说一定会执行其他线程而该线程在下一次中不会执行到了。
Java线程中有一个Thread.yield( )方法,很多人翻译成线程让步。顾名思义,就是说当一个线程使用了这个方法之后,它就会把自己CPU执行的时间让掉,让自己或者其它的线程运行。
打个比方:现在有很多人在排队上厕所,好不容易轮到这个人上厕所了,突然这个人说:“我要和大家来个竞赛,看谁先抢到厕所!”,然后所有的人在同一起跑线冲向厕所,有可能是别人抢到了,也有可能他自己有抢到了。我们还知道线程有个优先级的问题,那么手里有优先权的这些人就一定能抢到厕所的位置吗? 不一定的,他们只是概率上大些,也有可能没特权的抢到了。
packagecom.yield;public class YieldTest extendsThread {publicYieldTest(String name) {super(name);
}
@Overridepublic voidrun() {for (int i = 1; i <= 50; i++) {
System.out.println("" + this.getName() + "-----" +i);//当i为30时,该线程就会把CPU时间让掉,让其他或者自己的线程执行(也就是谁先抢到谁执行)
if (i == 30) {this.yield();
}
}
}public static voidmain(String[] args) {
YieldTest yt1= new YieldTest("张三");
YieldTest yt2= new YieldTest("李四");
yt1.start();
yt2.start();
}
}
运行结果:
第一种情况:李四(线程)当执行到30时会CPU时间让掉,这时张三(线程)抢到CPU时间并执行。
第二种情况:李四(线程)当执行到30时会CPU时间让掉,这时李四(线程)抢到CPU时间并执行。
调用接口的方法两种情况:
1:你已经实例化了这个接口
2:定义一个方法,给他的参数就是这个接口的类型。
这样就可以编译成功了。
但是同样,你给编译器一个假象。
编译器也还给你一个假象。就是没结果,彼此彼此
所以看出:调用一个方法必然是需要实例化的。
回到面向对象这一节:
你们班同学每个人都是不同的类,都同属于统一班级,
都有一个共同的技能:认真听课。
你可以调用这个方法
也可以通过你们的班级这个接口调用这个方法让你听课。
例:xxx班的xxx认真听课。
同样的,你还属于你们村。
你们村的人都有一个技能,唱歌
你自己可以去唱歌。
也可以通过xxx村的xxx去唱歌。
很明显,班级不会听课。
村子也不能唱歌。
都是需要一个具体的你进行操作的。
所以,一个接口只是一种类型。
不管它被实现了多少次,怎么实现的。
都跟你没有一点关系。
类型本身是没有操作的,除非你给他了一个对象。
不要纠结于他是怎么调用的。
你把对象都给他了 ,还问他怎么调用的。
还有一种可能,你的当前类继承了一个实现这个接口的类。
你自己就是这个对象!!!
问题明明就是这么简单,别自己想复杂了。
一个抽象接口,有很多实现类,通过接口调用某个方法的时候,怎么知道调用的是哪个实现类里的方法?
谢谢。
2014-07-02 更新
前三个回答是
可以
,不过依然没有找到我想要的答案。比如在
Eclipse
里查看别人的
jar包里的源码
,对于接口调用方法情况,如果直接按ctrl点进去查看源码,往往只能看到接口里方法的声明,无法获知具体调用的是哪个实现类的方法,特别是实现类非常多的情况,虽然这是Java多态的体现,但,有没有工具可以在
非调试状
态下知道调用是哪个实现类里的方法?
用对象的
getClass()
方法获得它的类,之后就可以随意去判断这是哪个实现类了。
多态是运行时的概念,在运行前是不可能知道究竟会使用哪个实现的。你能做的只是找到所有实现这个 interface 的类然后从逻辑上猜测大概会是哪个。
也可以使用instanceof判断
反射 or 把所有类都创建单个实例用hashmap存储
理论上可以,可用reflection等办法。
但据我所知,eclipse不支持你想要的功能。
原因是多态的特性使得对象的真实类型只能到运行时(runtime)才能被JVM确定。而eclipse的绝大多数refactoring和declaration jumping都是基于semantics的,也就是只能依靠在编译时(compile time)所能获得的信息。因此编译时获取的信息有有时只能推断到接口或者父类,这样就无法在编译时确定真实类型。eclipse对此无能为力,intelliJ也不行。
package Algorithm;
public class Algorithm_modTest
{
public static void main(String[] args)
{
modProcess mp = new modProcess(2,100,5);
mp.findModProcess();
mp.getResult();
}
}
class modProcess
{
int baseNumber;
int exponent;
int modNumber;
int minExponent;
int modResult;
modProcess(int b,int e,int m)
{
this.baseNumber = b;
this.exponent = e;
this.modNumber = m;
this.minExponent =1;
this.modResult = 0;
}
public void findModProcess()
{
if(this.exponent
{
this.modResult = getExponentValue(this.baseNumber, this.exponent)%this.modNumber;
}
else
{
this.minExponent = findMinExponent();//找到最小的指数
线程安全类是确保类的内部状态以及从方法返回的值在从多个线程并发调用时是正确的类。 Java中线程安全的集合类有Stack、Vector、Properties、Hashtable等。
堆栈(stack)
Java中的Stack类实现了基于后进先出(LIFO)原理的堆栈数据结构。因此,Stack类可以支持许多操作,比如push、pop、peek、search、empty等。
例子import java.util.*;
public class StackTest {
public static void main (String[] args) {
Stack stack = new Stack();
stack.push(5);
stack.push(7);
stack.push(9);
Integer num1 = (Integer)stack.pop();
System.out.println("弹出的元素是: " + num1);
Integer num2 = (Integer)stack.peek();
System.out.println("堆栈顶部的元素是: " + num2);
}
}
输出结果弹出的元素是: 9
堆栈顶部的元素是: 7
向量(vector)
Java中的Vector类实现了根据需要增长的对象数组。Vector类可以支持add(),remove(),get(),elementAt(),size()等方法。
例子import java.util.*;
public class VectorTest {
public static void main(String[] arg) {
Vector vector = new Vector();
vector.add(9);
vector.add(3);
vector.add("ABC");
java怎么判断是否是Long类型
发布时间:2020-04-28 13:42:40
来源:亿速云
阅读:706
作者:小新
今天小编给大家分享的是java怎么判断是否是Long类型,相信很多人都不太了解,为了让大家更加了解java,所以给大家总结了以下内容,一起往下看吧。一定会有所收获的哦。
java判断是否是Long类型
1、首先定义一个getType方法,接收一个Object类型的参数;
2、然后使用getClass方法获取class类型的对象;
3、再使用toString()方法转为字符串,并使用substring截取字符串获得变量类型;
4、最后根据变量类型和Long字符串进行对比即可public class HelloWorld {
public static void main(String[] args) {
Boolean res = getType(1232343234L);
if(res) {
System.out.println("是Long类型");
}else{
System.out.println("不是Long类型");
}
}
public static Boolean getType(Object o) {
String type = o.getClass().toString();
System.out.println(type);
type = type.substring(type.lastIndexOf('.') + 1, type.length());
if("Long".equals(type)) {
return true;
}
return false;
}
}
关于java怎么判断是否是Long类型就分享到这里了,希望以上内容可以对大家有一定的参考价值,可以学以致用。如果喜欢本篇文章,不妨把它分享出去让更多的人看到。
上次利用java自动的java.util.zip.ZipEntry和??java.util.zip.ZipFile来解压zip文件,今天发现程序在读取解压文件时居然报了空指针异常,debug程序后发现时读取不到文件,产生原先是zip压缩文件中含有中文的名称,读取文件名为乱码,
报找不到文件名,所以报了空指针,想到ant构建文件也有这个功能,换了apache的ant.jar居然解决了中文的问题。
备份下。
??import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Enumeration;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;/*** 读取zip压缩文件中文本的内容
* @author fish*/public class ReadZip {
public static void main(String args[]) {try {String fileName = "D:/workspace/java/src/ReadZip.zip";
//构造ZipFile
ZipFile zf = new ZipFile(new File(fileName));
//返回 ZIP file entries的枚举.
Enumeration extends ZipEntry entries = zf.getEntries();
while (entries.hasMoreElements()) {
ZipEntry ze = entries.nextElement();
System.out.println("name:"+ze.getName());
long size = ze.getSize();
if (size 0) {
System.out.println("Length is "
一元二次方程ax2+bx+c=0,输入a,b,c三个系数,求解方程,结果有三种情况:两个实数根、一个实数根、两个复数根。
/**
* Equation.java
*/
package cn.edu.uibe.oop;
/**
* 计算一元二次方程的根
* @author TongQiang
*
*/
public class Equation {
double a,b,c; //方程的系数
double x1,x2; //两个根
double r; //实部
double v; //虚部
int type; //0表示一个根,1表示两个实根,2表示两个复数的根
public Equation(double a,double b,double c){
this.a = a;
this.b = b;
this.c = c;
}
private double delta(){
return b*b-4*a*c;
}
public void calculate(){
double d = delta();
if(Math.abs(d) < 1E-5){
type = 0;
x1 = -b/(2*a);
properties
Properties文件是java中的一种配置文件,文件后缀为“.properties”,文件的内容格式是“key=value”的格式,用 # 作为注释。
我的properties 文件放在路径
写与读
向properties文件中写入数据
//创建一个properties对象
Properties pro = new Properties();
//创建一个输出流 里面路径填写文件的路径
OutputStream proos = new FileOutputStream("user.properties");
pro.setProperty("id", "1001");
pro.setProperty("username","你好");
pro.setProperty("password", "123");
//将数据储存到文件中,第一个参数是 输出流,第二个参数是注释
pro.store(proos,"User");
proos.close();
将文件中的数据取出
Properties pro = new Properties();
//创建一个输出流
InputStream prois = new FileInputStream("user.properties");
//将文件取出 传入一个 输出流
pro.load(prois);
int id = Integer.parseInt((String) pro.get("id"));
String username = (String) pro.get("username");
String password = (String) pro.get("password");
System.out.println(pro);
System.out.println(id);
System.out.println(username);
System.out.println(password);
prois.close();
运行结果
总结
到此这篇关于Java中使用Properties配置文件的文章就介绍到这了,更多相关Java用Properties配置文件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
一、Java提供finalize()方法,垃圾回收器准备释放内存的时候,会先调用finalize()。(1).对象不一定会被回收。(2).垃圾回收不是析构函数。(3).垃圾回收只与内存有关。(4).垃圾回收和finalize()都是靠不住的,只要JVM还没有快到耗尽内存的地步,它是不会浪费时间进行垃圾回收的。二、垃圾回收器:1、在Java中,当创建一个对象时,Java虚拟机(JVM)为该对象分配内存、调用构造函数并开始跟踪你使用的对象。当停止使用一个对象(就是说,当没有对该对象有效的引用时),JVM通过垃圾回收器将该对象标记为释放状态。2、当垃圾回收器将要释放一个对象的内存时,调用该对象的finalize()方法(如果该对象定义了此方法)。垃圾回收器以独立的低优先级的方式运行,只有当其线程挂起等待该内存释放的情况出现时,才开始运行释放对象的内存。(事实上,可以调用System.gc()方法强制垃圾回收器来释放这些对象的内存。)3、在以上的描述中,有一些重要的事情需要注意。首先,只有当垃圾回收器释放该对象的内存时,才会执行finalize()。如果在Applet或应用程序退出之前垃圾回收器没有释放内存,垃圾回收器将不会调用finalize()。三、finalize()方法的优缺点:1、根据Java文档,finalize()是一个用于释放非Java资源的方法。但是,JVM有很大的可能不调用对象的finalize()方法,因此很难证明使用该方法释放资源是有效的。2、Java1.1通过提供一个System.runFinalizersOnExit()方法部分地解决了这个问题。(不要将这个方法与Java1.0中的System.runFinalizations()方法相混淆。)不象System.gc()方法那样,System.runFinalizersOnExit()方法总结:并不立即试图启动垃圾回收器。而是当应用程序或Applet退出时,调用每个对象的finalize()方法。
阅读全文 >
我的系统是ubuntu-20.10-desktop-amd64,启动后黑屏,然后按ctrl+alt+f2(或者f3、f4...)可以切换终端
原因之一是gdm3与nvidia冲突,是的gdm3无法正常显示图形界面,出现黑屏的问题。
切换到其他终端然后删除nvidia组件
sudo apt-get remove --purge nvidia-*
执行成功之后,执行reboot重启即可正常进入桌面。
RedisUtil
介绍
最全的Java操作Redis的工具类,封装了对Redis五种基本类型的各种操作,力求符合Redis的原生操作,使用StringRedisTemplate实现!
解惑
很多人提出疑问“为什么没有操作Object的方法?”,请看这里介绍redistemplate和stringredistemplate。
用法
一、keys相关命令
NO
方法
描述
1
void delete(String key)
key存在时删除key
2
void delete(Collection keys)
批量删除key
3
byte[] dump(String key)
序列化key,返回被序列化的值
4
Boolean hasKey(String key)
检查key是否存在
5
Boolean expire(String key, long timeout, TimeUnit unit)
设置过期时间
6
Boolean expireAt(String key, Date date)
设置过期时间
7
Set keys(String pattern)
查找所有符合给定模式(pattern)的key
8
Boolean move(String key, int dbIndex)
将当前数据库的key移动到给定的数据库db当中
9
Boolean persist(String key)
移除key的过期时间,key将持久保持
10
Long getExpire(String key, TimeUnit unit)
java中取得当月最后一天的四种方法
第一种,使用Calendar的roll方法,在限制某个日期字段不改变的形式下,改变其他日期字段的值。
第二种,使用Calendar的getActualMaximum方法,获得指定日期字段的最大值。
第三种,使用Calendar的set和add方法,从下个月的第一天计算得到当前月的最后一天。
第四种,循环使用Calendar的add方法,加到本月的最后一天。
以上四种方法如下示例:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateTime {
public static void main(String[] args) throws ParseException {
DateTime dt = new DateTime();
Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2008-02-14");
date = dt.lastDayOfMonth(date);
System.out.println (new SimpleDateFormat("yyyy-MM-dd").format(date));
date = new SimpleDateFormat("yyyy-MM-dd").parse("2008-02-14");
date = dt.lastDayOfMonth2(date);
System.out.println (new SimpleDateFormat("yyyy-MM-dd").format(date));
date = new SimpleDateFormat("yyyy-MM-dd").parse("2008-02-14");
date = dt.lastDayOfMonth3(date);
System.out.println (new SimpleDateFormat("yyyy-MM-dd").format(date));
date = new SimpleDateFormat("yyyy-MM-dd").parse("2008-02-14");
date = dt.lastDayOfMonth4(date);
java函数输出js的hello world:
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class Maub {
public static void main(String args[]) throws ScriptException, NoSuchMethodException{
//引擎管理器
ScriptEngineManager m = new ScriptEngineManager();
//获取引擎
ScriptEngine engine = m.getEngineByName("JavaScript");
//执行javascript代码
engine.eval("function hello(name){print('hello '+name)}");
//Javascript实现了invocable调用接口
Invocable inv = (Invocable) engine;
//调用函数hello,传入world
inv.invokeFunction("hello","world");
}
}
调用文件里的js脚本:
import java.io.FileNotFoundException;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class Maub {
public static void main(String args[]) throws ScriptException, NoSuchMethodException, FileNotFoundException{//引擎管理器
对于很多初学 Java 线程的小伙伴们,很容易将 Thread 类里的 yield() 方法理解错误,或者理解得不够透彻,先看下源码:
public static native void yield();
是的,你没看错,Thread 类源码中定义的这个方法没有方法体,native 关键字修饰的方法表示原生态方法,方法对应的实现不在这个类文件里,而是在用其他语言(如 C 和 C++)实现的文件中。Java 语言本身不能对操作系统底层进行访问和操作(但可以通过 JNI 接口调用其他语言来实现对底层的访问)。所以,想要知道并理解 yield() 方法的具体实现过程,于初学者来说并没有必要。虽然“无代码无真相”,但采用大白话的解释或许更加通俗易懂吧。
Java线程调度的一点背景
在各种各样的线程中,Java 虚拟机必须实现一个有优先权的、基于优先级的调度程序。这意味着 Java 程序中的每一个线程被分配到一定的优先权,使用定义好的范围内的一个正整数表示。优先级可以被开发者改变。即使线程已经运行了一定时间,Java 虚拟机也不会改变其优先级。
优先级的值很重要,因为 Java 虚拟机和下层的操作系统之间的约定是操作系统必须选择有最高优先权的 Java 线程运行。所以我们说 Java 实现了一个基于优先权的调度程序。该调度程序使用一种有优先权的方式实现,这意味着当一个有更高优先权的线程到来时,无论低优先级的线程是否在运行,都会中断(抢占)它。这个约定对于操作系统来说并不总是这样,这意味着操作系统有时可能会选择运行一个更低优先级的线程。
理解线程的优先权
接下来,理解线程优先级是多线程学习很重要的一步,尤其是了解 yield() 函数的工作过程:
1、记住当线程的优先级没有指定时,所有线程都携带普通优先级。
2、优先级可以用从 1 到 10 的范围指定。10 表示最高优先级,1 表示最低优先级,5 是普通优先级。
3、记住优先级最高的线程在执行时被给予优先。但是不能保证线程在启动时就进入运行状态。
4、与在线程池中等待运行机会的线程相比,当前正在运行的线程可能总是拥有更高的优先级。
5、由调度程序决定哪一个线程被执行。
6、t.setPriority() 用来设定线程的优先级。
7、记住在线程 start() 方法被调用之前,线程的优先级应该被设定。
8、你可以使用常量,如 MIN_PRIORITY,MAX_PRIORITY,NORM_PRIORITY 来设定优先级。
现在,我们对线程调度和线程优先级有一定理解了,进入主题。
Thread.yield() 方法会使当前线程从执行状态(运行状态)变为可执行状态(就绪状态)。CPU 会从众多的可执行态里选择,也就是说,当前也就是刚刚调用 yield() 方法的那个线程还是有可能会被再次继续执行的。yield() 方法并不是让当前线程暂停,让出时间片去执行其他线程,而在下一次时间片内就一定不会执行了(当前线程只是转换为就绪状态,在下一个本该是自己的却让给其他线程的时间片内也可能再次继续被执行)。
很多人将 yield 翻译成线程让步。顾名思义,就是说当一个线程使用了这个方法之后,它就会把自己CPU执行的一段时间片让给自己或者其它的线程运行。
说明:获取的数据是操作系统整体的资源占用情况,不是当前 java进程占用的资源
1. 获取系统CPU占用情况 :
import java.lang.management.ManagementFactory;
import com.sun.management.OperatingSystemMXBean;
private static OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
public static int cpuLoad() {
double cpuLoad = osmxb.getSystemCpuLoad();
int percentCpuLoad = (int) (cpuLoad * 100);
return percentCpuLoad;
}
注意:JDK必须是1.8及以上的
返回的值是CPU的百分比,取的是整数值
2. 获取系统内存占用情况
import java.lang.management.ManagementFactory;
import com.sun.management.OperatingSystemMXBean;
private static OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
public static int memoryLoad() {
double totalvirtualMemory = osmxb.getTotalPhysicalMemorySize();
double freePhysicalMemorySize = osmxb.getFreePhysicalMemorySize();
double value = freePhysicalMemorySize/totalvirtualMemory;
int percentMemoryLoad = (int) ((1-value)*100);
发现一个坑:最近发现有同事按照本文方式配置jdk环境变量一直不成功,后来发现他是使用了“Oh-My-Zsh”,配置文件的路径不是/etc/profile或~/.bash_profile,它有自己的配置文件,所以还是推荐大家使用mac自带的终端或者iTerm2来配置。
————————正文开始——————-
Mac下添加java环境变量
方法一:全局配置
Crayon Syntax Highlighter v2.6.5
#临时提权
sudo su
#输入密码
vi /etc/profile
#配置JAVA_HOME,此处路径根据自己的版本填写
JAVA_HOME="/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/"
CLASS_PATH="$JAVA_HOME/lib"
#把JAVA添加到到环境变量PATH中
PATH=".:$PATH:$JAVA_HOME/bin"
#设置tomcat的主目录
#CATALINA_HOME="/usr/local/tomcat"(tomcat需自行提前安装好)
#将JAVA_HOME和CATALINA_HOME设置为环境变量
#export JAVA_HOME CATALINA_HOME
export JAVA_HOME 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #临时提权
sudo su
#输入密码
vi /etc/profile
#配置JAVA_HOME,此处路径根据自己的版本填写
JAVA_HOME="/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/"
CLASS_PATH="$JAVA_HOME/lib"
#把JAVA添加到到环境变量PATH中
PATH=".:$PATH:$JAVA_HOME/bin"
#设置tomcat的主目录
#CATALINA_HOME="/usr/local/tomcat"(tomcat需自行提前安装好)
#将JAVA_HOME和CATALINA_HOME设置为环境变量
#export JAVA_HOME CATALINA_HOME
export JAVA_HOME
[Format Time: 0.0017 seconds]
方法二:针对单独用户配置
Crayon Syntax Highlighter v2.
异常如下
2021-02-12 13:38:13.388 ERROR 6052 --- [io-8080-exec-10] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.apache.shiro.authz.UnauthenticatedException: This subject is anonymous - it does not have any identifying principals and authorization operations require an identity to check against. A Subject instance will acquire these identifying principals automatically after a successful login is performed be executing org.apache.shiro.subject.Subject.login(AuthenticationToken) or when 'Remember Me' functionality is enabled by the SecurityManager.
FTP(File Transfer Protocol 文件传输协议)是Internet 上用来传送文件的协议。在Internet上通过FTP 服务器可以进行文件的上传(Upload)或下载(Download)。FTP是实时联机服务,在使用它之前必须是具有该服务的一个用户(用户名和口令),工作时客户端必须先登录到作为服务器一方的计算机上,用户登录后可以进行文件搜索和文件传送等有关操作,如改变当前工作目录、列文件目录、设置传输参数及传送文件等。使用FTP可以传送所有类型的文件,如文本文件、二进制可执行文件、图象文件、声音文件和数据压缩文件等。
FTP 命令
FTP 的主要操作都是基于各种命令基础之上的。常用的命令有:
设置传输模式,它包括ASCⅡ(文本) 和BINARY 二进制模式;
目录操作,改变或显示远程计算机的当前目录(cd、dir/ls 命令);
连接操作,open命令用于建立同远程计算机的连接;close命令用于关闭连接;
发送操作,put命令用于传送文件到远程计算机;mput 命令用于传送多个文件到远程计算机;
获取操作,get命令用于接收一个文件;mget命令用于接收多个文件。
import java.net.Socket;
import org.apache.log4j.Logger;
/**
* 角色——服务器A
* @author Leon
*
*/
public class ServerA{
public static void main(String[] args){
final String F_DIR = "c:/test";//根路径
final int PORT = 22;//监听端口号
Logger.getRootLogger();
Logger logger = Logger.getLogger("com");
try{
ServerSocket s = new ServerSocket(PORT);
logger.info("Connecting to server A...");
logger.info("Connected Successful! Local Port:"+s.getLocalPort()+". Default Directory:'"
flutter 安装部署问题总结
1、Mac版本下安装cocoapods,主要原因是rvm没有安装,ruby没有选择使用
\curl -sSL https://get.rvm.io | bash -s stable
出现长时间打不开,安装GPG等密钥工具,导入密码后也无法安装,首先检查https://get.rvm.io网址是否可访问,不可访问就没有办法。
解决方法:
curl -sSL https://github.com/rvm/rvm/tarball/stable -o rvm-stable.tar.gz
tar -xzvf rvm-stable.tar.gz
cd rvm-rvm-6bfc921/
./install --auto-dotfiles
source /Users/zhangjianyong/.rvm/scripts/rvm
rvm install 2.7.2
rvm use 2.7.2
sudo gem install cocoapods
2、如果出现No devices available
配置sdk位置
flutter config --android-sdk /Users/zhangjianyong/Library/Android/sdk
重启Android Studio 即可
3、flutter 如果使用Provider 进行状态管理。一定分好层,否则会监测不到。
@override Widget build(BuildContext context) { return Scaffold( body: Container( margin: EdgeInsets.only(top: 0), color: Colors.white, child: ChangeNotifierProvider<CustomerFeeInfoNotefier>.value( value: mCustomerFeeInfoNotefier, child: Column( children: [ Consumer<CustomerFeeInfoNotefier>( builder: (context, textValueAvaliableNotifier, child) { return __renderList(mCustomerFeeInfoNotefier); }) ], )))); } 4、在使用flutter调试支付宝时,由于大部分第三方插件不支持沙箱支付,需要修改源码。以flutter_alipay为例,需要在flutter的sdk下找到FlutterAlipayPlugin.
java调用另一个类的方法:1、类方法用static修饰,代码为【public static void sayStatic()】;2、没有static修饰的方法,代码为【 public void sayInstance()】。
java调用另一个类的方法:
java类有两种方法一种是类方法就是用static修饰的,一种是实例方法,就是没有static修饰的方法。类方法可以同时类名,方法名的方式调用。而实例方法必须先生存类的实例在通过实例.方法名的方式调用。例如:public class MethodCall
{
public static void main(String[] args)
{
Test.sayStatic();
Test test = new Test();
test.sayInstance();
}
}
class Test
{
public static void sayStatic()
{
System.out.println("这是一个静态方法。");
}
public void sayInstance()
{
System.out.println("这是一个实例方法。");
}
}相关免费学习推荐:java基础教程
一、迭代器概述
1、什么是迭代器?
在Java中,有很多的数据容器,对于这些的操作有很多的共性。Java采用了迭代器来为各种容器提供了公共的操作接口。这样使得对容器的遍历操作与其具体的底层实现相隔离,达到解耦的效果。
在Iterator接口中定义了三个方法:
2、迭代器使用
public static void main(String[] args)
{
List list=new ArrayList<>();
list.add("abc");
list.add("edf");
list.add("ghi");
for(Iterator it=list.iterator();it.hasNext();)
{
System.out.println(it.next());
}
}
执行结果:
二、ArrayList的Iterator实现
private class Itr implements Iterator
{
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
...
}
在ArrayList内部定义了一个内部类Itr,该类实现了Iterator接口。
在Itr中,有三个变量分别是
cursor:表示下一个元素的索引位置
lastRet:表示上一个元素的索引位置
expectModCount:预期被修改的次数
下面看一下Itr类实现了Iterator接口的三个方法:
public boolean hasNext()
展开全部
super在java的子类中指代父类引用
java中,super的几种用法:
1、子类的构造函数如果要引用super的话,必须把super放在函数的首e68a84e8a2ad3231313335323631343130323136353331333339663936位class Base {
Base() {
System.out.println("Base");
}
}
public class Checket extends Base {
Checket() {
super();//调用父类的构造方法,一定要放在方法的首个语句
System.out.println("Checket");
}
public static void main(String argv[]) {
Checket c = new Checket();
}
}
如果想用super继承父类构造的方法,但是没有放在第一行的话,那么在super之前的语句,肯定是为了满足自己想要完成某些行为的语句,但是又用了super继承父类的构造方法。那么以前所做的修改就都回到以前了,就是说又成了父类的构造方法了。
2、在Java中,有时还会遇到子类中的成员变量或方法与超类(有时也称父类)中的成员变量或方法同名。因为子类中的成员变量或方法名优先级高,所以子类中的同名成员变量或方法就隐藏了超类的成员变量或方法,但是我们如果想要使用超类中的这个成员变量或方法,就需要用到super.class Country {
String name;
void value() {
name = "China";
}
}
class City extends Country {
String name;
void value() {
name = "Hefei";
super.value();//不调用此方法时,super.name返回的是父类的成员变量的值null
System.out.println(name);
System.out.println(super.name);
}
public static void main(String[] args) {
长话短说,废话不说
一、第一种方式,通过HttpClient方式,代码如下:
public static String httpGet(String url, String charset)
throws HttpException, IOException {
String json = null;
HttpGet httpGet = new HttpGet();
// 设置参数
try {
httpGet.setURI(new URI(url));
} catch (URISyntaxException e) {
throw new HttpException("请求url格式错误。"+e.getMessage());
}
// 发送请求
HttpResponse httpResponse = client.execute(httpGet);
// 获取返回的数据
HttpEntity entity = httpResponse.getEntity();
byte[] body = EntityUtils.toByteArray(entity);
StatusLine sL = httpResponse.getStatusLine();
int statusCode = sL.getStatusCode();
if (statusCode == 200) {
json = new String(body, charset);
谢邀。这不是数学问题而是语文问题。有些概念的定义里面必须要指涉一个大空间,这是这个定义本身的属性。虽然有时候这个指涉会被省略,但是省略并不代表可以抛开不管。最简单的例子如同dense,我们不会说一个集合dense,只会说一个集合在另一个大的集合里面dense。
然后我们继续理一下概念。紧接着的就是nowhere dense,这里用词上就和dense有关,那自然也是跟背景空间有关的。
下一个概念就是meagre set,或者是叫 set of 1st category,因为是用上面的概念定义的,所以也跟背景空间有关。
那么自然就有not meagre set,或者叫comeagre set或者set of 2nd category,指的是上面的集合的补集,所以也与背景空间有关。
最后就是Baire set,定义是相对于自己not meagre。因为在定义里把指涉确定了,所以就与指涉无关了。这里就是术语可能会含混的地方,我记得有些教材会把这种集合叫做set of 2nd category,然后反面是1st cat。这有点术语滥用的问题,但看上下文通常是能看出来的。
至于如果你问为什么指涉不同判断的结论会不同,这只能说不需要啊,定义里面并没有保证这一点。或者说这些概念是来自于dense,本质上dense是强烈依赖与背景空间的,所以后续概念也一样。
再举个直观点的例子,任意一个扭结都是天经地义同胚于S1的,但是需要研究扭结能不能解开的问题。这就要引入同痕的概念。任何扭结在R4里面是能解开的,但是在R3里面却未必。
Java 重载、重写、构造函数的实例详解
方法重写
1、重写只能出现在继承关系之中。当一个类继承它的父类方法时,都有机会重写该父类的方法。一个特例是父类的方法被标识为final。重写的主要优点是能够定义某个子类型特有的行为。
class Animal {
public void eat(){
System.out.println ("Animal is eating.");
}
}
class Horse extends Animal{
public void eat(){
System.out.println ("Horse is eating.");
}
}
2、对于从父类继承来的抽象方法,要么在子类用重写的方式设计该方法,要么把子类也标识为抽象的。所以抽象方法可以说是必须要被重写的方法。
3、重写的意义。
重写方法可以实现多态,用父类的引用来操纵子类对象,但是在实际运行中对象将运行其自己特有的方法。
public class Test {
public static void main (String[] args) {
Animal h = new Horse();
h.eat();
}
}
class Animal {
public void eat(){
System.out.println ("Animal is eating.");
}
}
class Horse extends Animal{
public void eat(){
在Java中,针对类、成员方法和属性提供了四种访问级别,分别是private、default、protected和public。接下来通过一个图将这四种控制级别由小到大依次列出,如图1所示。
图1 访问级别
图1中展示了Java中的四种访问控制级别,具体介绍如下:
● private(当前类访问级别):如果类的成员被private访问控制符来修饰,则这个成员只能被该类的其他成员访问,其他类无法直接访问。类的良好封装就是通过private关键字来实现的。
● default(包访问级别):如果一个类或者类的成员不使用任何访问控制符修饰,则称它为默认访问控制级别,这个类或者类的成员只能被本包中的其他类访问。
● protected(子类访问级别):如果一个类的成员被protected访问控制符修饰,那么这个成员既能被同一包下的其他类访问,也能被不同包下该类的子类访问。
● public(公共访问级别):这是一个最宽松的访问控制级别,如果一个类或者类的成员被public访问控制符修饰,那么这个类或者类的成员能被所有的类访问,不管访问类与被访问类是否在同一个包中。
接下来通过一个表将这四种访问级别更加直观的表示出来,如表1所示。
表1 访问控制级别
小提示:
如果一个Java源文件中定义的所有类都没有使用public修饰,那么这个Java源文件的文件名可以是一切合法的文件名;如果一个源文件中定义了一个public修饰的类,那么这个源文件的文件名必须与public修饰的类的类名相同。
猜你喜欢
转自http://blog.sina.com.cn/s/blog_700aa8830101jtlf.html
Java中对象的创建
clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象。所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象。那么在java语言中,有几种方式可以创建对象呢?
1 使用new操作符创建一个对象
2 使用clone方法复制一个对象
那么这两种方式有什么相同和不同呢? new操作符的本意是分配内存。程序执行到new操作符时, 首先去看new操作符后面的类型,因为知道了类型,才能知道要分配多大的内存空间。分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化,构造方法返回后,一个对象创建完毕,可以把他的引用(地址)发布到外部,在外部就可以使用这个引用操纵这个对象。而clone在第一步是和new相似的, 都是分配内存,调用clone方法时,分配的内存和源对象(即调用clone方法的对象)相同,然后再使用原对象中对应的各个域,填充新对象的域, 填充完成之后,clone方法返回,一个新的相同的对象被创建,同样可以把这个新对象的引用发布到外部。
复制对象 or 复制引用
在Java中,以下类似的代码非常常见:
Person p = new Person(23, "zhang");
Person p1 = p;
System.out.println(p);
System.out.println(p1);
当Person p1 = p;执行之后, 是创建了一个新的对象吗? 首先看打印结果:
com.pansoft.zhangjg.testclone.Person@2f9ee1ac
com.pansoft.zhangjg.testclone.Person@2f9ee1ac
可已看出,打印的地址值是相同的,既然地址都是相同的,那么肯定是同一个对象。p和p1只是引用而已,他们都指向了一个相同的对象Person(23, "zhang") 。 可以把这种现象叫做引用的复制。 (关于引用和对象的区分,可以参考我之前的文章Java中的String为什么是不可变的? -- String源码分析 , 其中有一节讲到了引用和对象的区分)。上面代码执行完成之后, 内存中的情景如下图所示:
而下面的代码是真真正正的克隆了一个对象。
Person p = new Person(23, "zhang");
Person p1 = (Person) p.clone();
System.out.println(p);
System.out.println(p1);
从打印结果可以看出,两个对象的地址是不同的,也就是说创建了新的对象, 而不是把原对象的地址赋给了一个新的引用变量:
com.pansoft.zhangjg.testclone.Person@2f9ee1ac
com.pansoft.zhangjg.testclone.Person@67f1fba0
以上代码执行完成后, 内存中的情景如下图所示:
深拷贝 or 浅拷贝
时间管理的目的应该是充分利用时间来创造最大的价值。
一、使用时间日志
第一步:将所有的任务放入工作篮,不论是谁在什么时候交给我的任务,统统放进工作篮里。
第二步:将可以置之不理的任务清除掉;将必须在某天处理或者必须转交别人处理的任务拿出来;将那些可以在两分钟之内完成的任务立即完成。
第三步:将需要在特定日期处理的事情写进日程表;将需要别人处理的事情立即转交并且设置到期提醒;将需要现在处理的事情摆在办公桌上。
第四步:在自己最高效的时段,做最重要的事情;其他的事情也做合理安排。
二、提高工作效率的方法
1.找出重要的事情在高效时段搞定:每天早晨别一上班就急着投入工作,先看看今天工作的重点是什么,哪些事情是重要并且紧迫的。将这些事情安排在你的高效时段完成。
2. 回顾你需要发布或者呈送给上司的资料。
3. 看新闻用RSS:这样的好处是你不用频繁地在地址栏输入URL,更重要的是RSS广告很少,也没有铺天盖地的超链接,能够让你将注意力始终保持在你关心的内容上。
4. 减少检查邮件的次数:每天两次足够了。
5.能休息的时候尽量休息:一般情况下,休息时间定为半小时,在这半小时中脑子里什么都不想,好好地放松一下。这非常有利于精力的恢复。
三、职业价值观
职业价值观,它是价值观在工作中的具体体现。
1.管理:工作的目的和价值在于获得对他人或某事物的管理支配权,能指挥和调遣一定范围内的人或事物。
2.成就感:工作的目的和价值在于不断创新,不断取得成就,不断得到领导与同事的赞扬,或不断实现自己想要做的事。
3.社会交际:工作的目的和价值在于能和各种人交往,建立比较广泛的社会联系和关系,甚至能和知名人物结识。
四、时间管理法之四象限法则
4.1 四象限法则概述
它可以帮助你判断事情的轻重缓急,并告诉你如何做出有针对性的处理。
第一象限:重要而且紧急
这些事情必须马上去做,否则后果将会非常严重。但是在你立即去做的同时你应该思考这样一个问题:真的有那么多重要而且紧急的事情吗?
第二象限:重要但不紧急
这些事情虽然看起来不紧急,但是我们可不能置之不理。如果你现在不重视它,它随时都会发展成重要而且紧急的事情。
即使没有立即去做的必要,也至少要做一份时间计划表。
第三象限:不重要但紧急
举例:办公室里的突然来电、临时会议等。在这个象限,我们应该思考这个问题:我们如何尽量减少第三象限的事务?
第四象限:不重要而且不紧急
举例:看无聊的电视节目、一个人闲逛等。这个象限里的事情都是用来打发时间的,在这个象限,我们应该思考这个问题:我们在工作中是否有必要进入这个象限?
4.2 四象限法则的“任督二脉”
如何评估一件事情的重要程度和如何得知一件事情的紧迫程度。
职业价值观,那就是你评估一件事情重要程度的标准,而紧迫程度则是任务的时间底线。
4.3 处理四象限事务的原则
第一象限:没什么好说的了,立即去做!
第二象限:有计划去做!我们应该将时间投资于第二象限,不能因为它是不紧急的就不去处理。我们应该在第一时间对它进行任务分解,并且制定时间表;然后我们每次投入很少的时间,就可以完成一项庞大的任务。
第三象限:交给别人去做!我们应该清楚地认识到,第三象限的事务是我们忙碌而且盲目的源头。
要走出第三象限,就得依靠“猴子法则”
猴子法则:主管人员之所以时间不够用,一个很重要的原因在于没有做好授权分责,将太多本该部属去做的工作招揽到了自己身上,以至于永远在苦苦追赶工作进度。这些工作就是活蹦乱跳、随时可能跳到你身上的“猴子”。如果你能让别人去抚养他们自己的猴子,他们就能真正地管理自己的工作,你也就有足够的时间去处理自己的事情。
第四象限:尽量别去做!这是一个用于缓冲调整的象限。
附:第二象限工作法
首先,需要对第二象限的事务进行目标描述和任务分解。
造成你手足无措、效率低下、抗干扰能力差的原因之一就是你把“项目”当成了“行动”。
项目。它并不是一个单一的行动,而是由若干个单一的行动所组成的。
行动。就是可执行的步骤。
第二象限工作法步骤:在纸上先将项目分解成若干“行动”,然后去找到“下一步行动”,然后去执行它。
找出“下一步行动”的秘诀
秘诀一:动词开头
一个好的“下一步行动”应该是以动词开头的,比如“打电话给某某”、“准备会议资料”、“回复E-mail”,等等。
秘诀二:内容清晰
比如“准备会议资料”,虽然是动词开头,但是描述得不是很清晰,“需要准备哪些资料”、“几点开会”、“会议上要提出什么问题”,等等,这些东西还需要我们在行动之前一一落实。
秘诀三:描述结果
任务开始之前就对想要的结果进行描述,描述得越清晰,产生的能量就越大。
秘诀四:设定开始时间、周期、最后期限。
4.4 四象限法小结
1、我们根据自己的职业价值观评估某件事务的重要程度。
2、我们根据事务的截止日期判断事务的紧迫程度。
3、我们应将自己所有的日常事务放到四象限中分析。
4、我们对四个象限内的事务有不同的处理方法和原则。
5、我们应该将自己的主要精力集中在解决第二象限内的事务。
6、我们平时经常制定的工作计划和工作目标都是相对于第二象限来说的。
利用ppt的控件工具箱中的shockwave flash object控件,添加一个swf文件到ppt。然后右击这个swf文件编辑其属性时,把EmbedMovie一项的值改为True,就表示将其嵌入ppt,你就可以删除swf源文件了。
使用“Shockwave Flash Object”控件法插入flash的具体操作:
1)运行PPT,切换到要插入Flash动画的幻灯片。
2)单击“视图”菜单,在弹出的下拉菜单中单击“工具栏”,再在弹出的子菜单中单击“控件工具箱”,便出现“控件工具箱”。
3)单击“控件工具箱”中的“其他控件”(工具箱中的最后一个按钮,即上图中用圈圈住的),弹出ActiveX控件窗口,窗口中列出了系统已经安装的所有ActiveX控件。利用键盘上的光标控制键,在控件列表中找到“Shockwave Flash Object”并单击,此时系统会自动关闭控件窗口。
4)将光标移动到PPT的编辑区域中,光标变成“十”字形,按下鼠标并拖动,画出适当大小的矩形框,这个矩形区域就是播放动画的区域。
5)右单击矩形框,在出现的快捷菜单中单击“属性”,出现“属性”窗口。
6)单击“属性”窗口中的“自定义”一栏,此栏右端便出现一按钮。单击该按钮,出现“属性页”窗口,在“影片URL[M]”右侧文本框中输入“我的文件”Flash动画的完整路径(如果Flash动画与PPT文件处于同一目录中,也可以只输入Flash动画文件名),且必须带后缀名“.swf”。别的项目采用系统默认的即可,最后按“确定” 返回PPT。
7)放映该幻灯片,你所期待的画面就出现了。
提示:
a) 使用该方法的前提是系统中须有“Shockwave Flash Object”控件。这个问题不用担心,此控件绝大多数机器中都已安装。
b) 在步骤5中双击矩形框也可以打开“属性”窗口。
c)也可以在“属性”窗口“Movie”一栏右侧的文本框中直接输入Flash动画的路径而不用步骤6自定义的方式。
d) 设定的矩形框的大小就是放映时动画窗口的大小,当然它的大小是可以通过拖动矩形框的句柄随意改变的。Flash动画播放时,鼠标处在Flash播放窗口,响应Flash的鼠标事件;处在Flash播放窗口外,响应PPT的鼠标事件。
很多素材图片上都被加上了各种各样的水印,而我们偏偏非常需要这张图片,又有很多人认为水印是无法去除的,只能使用图章、涂抹来修补,如果遇到水印覆盖部分的色彩复杂的图片,也只能望图兴叹了。
其实在光学的理论上来说,水印图片是可以完美还原的,我们这里不谈理论,只谈操作。
来看一个加了水印的图片。
要想去除水印,我们要确定两点,第一,水印的原始颜色是什么?第二,透明度是多少?
这两点确实是问题,很大的问题,这里,我们来猜测一下,从图上看,水印的颜色可能是红色(FF0000);确认了这一点,我们新建一层,画上红色的水印来调整透明度,看看在什么数值的时候,和图片的效果像近。BTW,大部分人调整透明度的时候,喜欢用整数,比如20%,50%,85%……
看到了吗?60%,和原始水印一模一样,你可以放大你的水印和原水印重合的部分,用吸管来判断。FF0000,60%。OK,确定了这两点,我们还原有望了。回到原始的水印图片,我们选出水印的选区,新建一层并填充红色。(记得保存选区待用)
调整两个图层的顺序,将原背景层的图层模式调整为差值。
选中图层一,调整图层输出色阶为255×60%=153。
拼合图层,载入水印选区,调整输出色阶为255×(1-60%)=102。
看到什么了?水印几乎完美的消失了,是的,几乎,虽然PS做不到理论上的完美,但足以骗过我们的眼睛了。
看一下对比:
随手将知识分享给爱学习的小伙伴们吧!
用的越多,不懂的就越多
why?
java异常体系结构如下
Throwable类:所有的异常类,都直接或者间接的继承这个类。三个重要的方法:
堆栈跟踪是方法调用过程的轨迹,它包含了程序执行过程中方法调用的顺序和所在源代码行号。
堆栈跟踪信息从下往上,是方法调用的顺序。
Throwable类的两个直接子类:
Error:是程序无法修复的严重问题,程序员无法修复,这能让程序终止,比如jvm内部错误、存溢出和资源耗尽等严重情况。
Exception:是程序可以恢复的程序,是程序员可以从掌控的,比如,除零异常,空指针访问,网络连接终端,读取不存在等。
在Exception下面又有两个异常:
非受检异常指的是java.lang.RuntimeException和java.lang.Error类及其子类,所有其他的异常类都称为受检异常。两种类型的异常在作用上并没有差别,唯一的差别就在于使用受检异常时的合法性要在编译时刻由编译器来检查。正因为如此,受检异常在使用的时候需要比非受检异常更多的代码来避免编译错误。
1 受检查异常:指除RuntimeException以外的异常类。共同特点是,编译器会检查这类异常是否进行了处理,要么捕获,要么不抛出,否则会发生编译错误,种类很多。
2 非受检查异常(运行时异常):运行时异常是继承RuntimeException类的直接子类或者间接子类,运行时异常往往是程序员所犯的错误导致的 。特点是编译器不检查这类异常是否得到了处理,对于这类异常不捕获也不抛出,程序也可以编译过,一旦遇到就导致程序终止。
对于运行时异常通常不采用抛出或捕获处理方式,而是应该提前预判,防止这种发生异常,做到未雨绸缪。例如除零时候,在进行除法运算之前应该判断除数是非零的,修改示例代码如下,从代码可见提前预判这样处理要比通过try-catch捕获异常要友好的多
所以checked exception就是要强制你去处理这个异常(不管你throws多少层,你终归要在某个地方catch它);而runtime exception则没有这个限制,你可以自由选择是否catch。
FANUC数据寄存器和位置寄存器的运用
一、寄存器指令 Registers① 寄存器指令R[i] i=1~200
② 位置寄存器指令PR[i] i=1~100
③ 位置寄存器要素指令PR[i,j] i=1~100,j=1~6
其中,i表示寄存器的号码;j表示位置寄存器的要素号码;
若需要对默认寄存器数量进行扩展,可在控制启动模式中按图1所示完成设置:
(通过 PREV+NEXT+重启控制柜 进入控制启动(CTRL START)模式)
图1
(1)数值寄存器指令R[i]
数值寄存器指令支持“=”(赋值),“+”,“-”,“*”,“/”,“MOD”,“DIV”算术运算。
(2)位置寄存器指令PR[i]
位置寄存器指令支持“=”(赋值),“+”,“-”算术运算。
(3)位置寄存器要素指令PR[i,j]
位置寄存器要素指令支持“=”(赋值),“+”,“-”,“*”,“/”,“MOD”,“DIV”算术运算。
二、查看寄存器值(1)查看数值寄存器的值
步骤:
1)按【Data】键,再按F1【TYPE】(类型)出现以下内容(如下图2所示):
Registers:数值寄存器;
Position Reg:位置寄存器;
图2
2)移动光标选择【Registers】(数值寄存器),按【ENTER】(回车)值键,如图3所示;
图3
3)把光标移至寄存器号后,【ENTER】(回车)键,输入注释;
4)把光标移到值处,使用数字键可直接修改数值。
(2)查看位置寄存器的值
步骤:
1)按【Data】键,显示右图4;
图4
2)按F1【TYPE】(类型),出现以下内容:
Registers:数值寄存器;
Position Reg:位置寄存器;
3)移动光标选择【Position Reg】(位置寄存器),按【ENTER】(回车)键,如右图5所示;
图5
4)把光标移至寄存器号后,按【ENTER】(回车)键 ,输入注释。
5)把光标移到值处,按F4【POSITION】(位置)键,显示具体数据信息;
“ R ”表示已完成示教的位置寄存器
“ * ”表示尚未示教的位置寄存器
6)按F5【REPRE】(形式)键,如下图6所示,移动光标到所需要的项并按【ENTER】(回车)键,或通过数字键,可以切换数据形式;
• Cartesian(正交):直角坐标系
• Joint(关节):关节坐标系
图6
把光标移至数据处,可以用数字键直接修改数据。
之前就听过数字华容道,但是一直没有上手,今天发现室友再玩,我就下了一个,试了一下3X3 26秒,挺简单的 有玩了下5X5 说实话,前面3行很顺利,但是最后2行就比较“碰运气” 以及烧脑了。真不是谦虚,我完成了,但我知道我真的靠运气,紧接着玩8X8 到最后两行摆弄了20分钟,直接放弃,我实在不想破坏上一行,哎,,Ծ^Ծ,, ,紧接着我的脑子突然出现一种“无上限解法”,也就是说,不管你是 8X8 也好, 100X100 也罢,我都可以完成,并且一点困难都不会有,
接下来介绍方法
我们都知道数字华容道,分为3X3 4X4 5X5 nXn 但是不管怎么样他大体都是正方形, 也就是说,我们可以把 8X8 的华容道变成 7X7 ,紧接着变成6X6 最后一定会变成 3X3
详细如下图
下图是 4X4 一共16个格子
我们先拼两边的数字 让他变成 3X3
如下图所示
这会就简单了,3X3 一个7岁小孩在知道规则的情况下也可以解除了
那么,只要这个7岁小孩会解 3X3 那么他也会解 100X100 毫不夸张的说,只要时间够 1000X10000 也可以解。
知道这个方法的,就当没看到我这个文章好了
希望可以帮助玩华容道的朋友
有好方法也可以和我分享。
torch提供的DataLoader可以提供一个可迭代对象iterable object(注意不是迭代器,iterator),利用python本身良好的生态环境,实现简洁、节省内存资源的数据读取。而DataLoader只是一个iterable object,只能像python list一样用for循环去取,不能像iterator一样,可以使用next方法,在一些场景下缺乏灵活性。
可能就是因为上述原因,torch在历史某个版本使用了DataLoaderIter对象。
这两个clas的具体使用以及其源码解读参考:
PyTorch学习笔记(6)——DataLoader源代码剖析
Pytorch数据读取(Dataset, DataLoader, DataLoaderIter)
为了说明哪些场合可能需要用到DataLoaderIter,下面举个例子
例如:
import torch from torch.utils.data import RandomSampler,DataLoader from utils.dataloader_iter import DataLoaderIter class myDataset(torch.utils.data.Dataset): ''' create my own torch Dataset implement torch.utils.data.Dataset ''' def __init__(self, dataSource): ''' :param dataSource: iterable object like list datasource means a list contain all data sample e.g. [obj1,obj2...] ''' self.dataSource = dataSource def __getitem__(self,index): element = self.dataSource[index] return element def __len__(self): return len(self.dataSource) template = [{"
constant 一维向量 R 快捷键1
constant2Vector 二维向量 RG 快捷键2
constant3Vector 三维向量 RGB 快捷键3
constant4Vector 四维向量 比三维多alpha 快捷键4
Add 加法,将两个通道上的数值或者纹理增加到一起 快捷键a
sub 减法 去掉共有的纹理
multiply 混合、乘法 取纹理重叠 快捷键m
divide 除法 快捷键d
abs 绝对值
appendVector 增加通道
TextureSample 纹理贴图
Panner 坐标平移 正负来代表纹理在该轴平移的方向,数值代表速度 快捷键 P
Rotator 旋转 以选定的X和Y的坐标交汇点进行一定速度的旋转 一般坐标设定为0.5
TextureCoordinate 纹理坐标 纹理数量等于UV值相乘 U为横向 V为竖向 快捷键U
Desaturation 去色 去除颜色,当赋予Fraction为0时,无作用,数值越靠近1,去色越明显
DepthFade 深度衰减 减少物体之间混合时生硬的效果 接线不透明度,默认Fadedistance为100,值越小接触点的透明度越低,根据需求定值
Time 时间 时间推进,一般连接正弦/余弦
Sine 正弦 在-1到0之间浮动的抛物线(曲线) 和time配合使用,比如可以用在物体自发光闪烁上(在-1到1之间反复运动)
Cosine 余弦 同上
Mask 分化蒙版,用来屏蔽、分离通道,分化多维向量的值等
Lab3将在Lab2的基础上使用随机约束和环境结构来改进完善实验代码。Lab3中将对generator和initiator之间的数据生成和数据传输的处理进行改进,还将完善何时结束测试,将其主动权交于generator而不再是test组件。在组件结构方面,在原有的initiator、generator、agent、test组件的基础上,再加上monitor和checker,并且使其构成一个有机的整体,最终可以通过在线比较数据的方式完成对MCDT的测试。
一、随机约束 实验要求:
继承Lab2的大部分代码,基于Lab2对需要生成的数据包有了新的约束要求。数据类chnl_trans不再只局限于包含一个数据,而是多个数据,同时跟数据之间时间间隔的控制变量也在该类中声明为随机成员变量。将原本在chnl_root_test类中用来结束仿真的$finish()变迁到generator中。使用“restart”命令多次重启,比对连续两次生成的随机数据。然后再在仿真器命令行处使用“vsim -novopt -solvefaildebug -sv_seed 0 work.tb1”来加载仿真。仿真参数“-solvefaildebug”是为了调试随机变量的,而“-sv_seed NUM”则是为了传递随机的种子。最后再使用“vsim -novopt -solvefaildebug -sv_seed random work.tb1”命令加载仿真,对比前后两次的数据是否相同。 二、更加灵活的测试控制 如果要实现不同的test类,例如chnl_basic_test、chnl_burst_test、chnl_fifo_full_test,那么对于不同的test需要对chnl_generator的随机变量做出不同的控制,继而进一步控制其内部随机的chnl_trans对象。也就是说,随机化也是可以分层次的,例如在test层可以随机化generator层,而依靠generator被随机化的成员变量,再来利用它们进一步随机化generator中的chnl_trans对象,由此达到顶层到底层的随机化灵活控制。从这个角度出发,需要将generator从agent单元中搬迁出来,并且搁置在test层中来方便test层的随机控制。
实验要求:
将generator搬迁到test层次中,需要将gen和agent中组件的mailbox连接起来,方便gen与agent中init的数据通信。实现在test中使用do_config()对gen进行随机化控制。使用仿真时传递的参数来完成测试的选择。在以后的递归测试,即创建脚本命令,由仿真器读入,分别传递不同的随机种子和测试名称即可完成对应的随机测试。在之前的仿真命令添加额外的命令“+TESTNAME=testname”。 三、测试平台的结构 新增monitor和checker两个组件,在顶层环境中,将checker置于test层中,而不是agent中。
实验要求:
在chnl_monitor类和mcdt_monitor类各自的mon_trans()方法中需要采集正确的数据,将它们写入mailbox缓存,同时将捕捉的数据打印出来,便于调试。在chnl_agent中,对chnl_monitor对象开始例化、传递虚接口和使其运行。在chnl_checker的任务do_compare()中,需要从checker自己的数据缓存mailbox中分别取得一个输出端的采集数据和一个输入端的采集数据,进而将它们的内容比较。在顶层环境chnl_root_test类中,需要对mdct_monitor和chnl_checker进行例化、传递虚接口,并且将chnl_monitor、mcdt_monitor的邮箱句柄分别指向chnl_checker中的信箱实例。 四、代码实现 随机约束 实验要求1: chnl_trans类实现随机化
class chnl_trans; rand bit[31:0] data[]; //动态数组 rand int ch_id; //发送到哪一个channel rand int pkt_id; //第几个数据包,即第几个trans rand int data_nidles; //data之间空闲间隔周期 rand int pkt_nidles; //数据包之间空闲间隔周期 bit rsp; //响应标志位 local static int obj_id = 0; // Specify constraint to match the chnl_basic_test request constraint cstr{ data.size inside {[4:8]}; foreach(data[i]) data[i] == 'hC000_0000 + (this.
1、概述 占位符通常出现在sql语句中,目的是提高代码的复用性,和执行效率,我们可以通过占位符 来对数据先不处理,后续输入。 2、例子 什么是占位符 //在这个sql语句中?即为占位符,对于这个完整的sql语句,我们不处理数据,先把框架写出来 String sql = "update student set name = ? where id = ?"; 如何填充占位符 因为占位符往往跟preparedStatement相关联 注意的点:
(1)ps.setObject()中两个参数,左边的为index,即第几个占位符,需要从1开始!!!!右边即为占位符的值。
JAVA——List中剔除空元素(null)的三种方法汇总 1、 list.removeAll(Collections.singleton(null));
List<String> list = new ArrayList<String>(); list.add(""); list.add("a"); list.add(null); list.add(" "); System.out.println(list); System.out.println(list.size()); list.removeAll(Collections.singleton(null)); System.out.println(list); System.out.println(list.size()); 2、
List nullList = new ArrayList();
nullList.add(null);
list.removeAll(nullList);
List<String> list = new ArrayList<String>(); list.add(""); list.add("a"); list.add(null); list.add(" "); System.out.println(list); System.out.println(list.size()); List l = new ArrayList(); l.add(null); list.removeAll(l); System.out.println(list); System.out.println(list.size()); 3、使用迭代器
List<String> list = new ArrayList<String>(); list.add(""); list.add("a"); list.add(null); list.add(" "); System.out.println(list); System.out.println(list.size()); Iterator iterator = list.iterator(); while (iterator.hasNext()) { if(null == iterator.
meta标签分两大部分:http-equiv和name变量。 http-equiv类似于HTTP的头部协议,它回应给浏览器一些有用的信息,以帮助正确和精确地显示网页内容。 常用的http-equiv类型有:
1.expires(期限)
说明:可以用于设定网页的到期时间。一旦网页过期,必须到服务器上重新调阅。
用法:<meta http-equiv=“expires” content=“Wed, 26 Feb 1997 08:21:57 GMT”>
注意:必须使用GMT的时间格式。
2.Pragma(cach模式)
说明:禁止浏览器从本地机的缓存中调阅页面内容。
用法:<meta http-equiv=“Pragma” content=“no-cache”>
注意:这样设定,访问者将无法脱机浏览。
3.Refresh(刷新)
说明:需要定时让网页自动链接到其它网页的话,就用这句了。
用法:<meta http-equiv=“Refresh” conternt=“5;URL=http://www.yahoo.com”>
注意:其中的5是指停留5秒钟后自动刷新到URL网址。
4.Set-Cookie(cookie设定)
说明:如果网页过期,那么存盘的cookie将被删除。
用法:<meta http-equiv=“Set-Cookie” content=“cookievalue=xxx;
expires=Wednesday, 21-Oct-98 16:14:21 GMT; path=/”>
注意:必须使用GMT的时间格式。
5.Window-target(显示窗口的设定)
说明:强制页面在当前窗口以独立页面显示。
用法:<meta http-equiv=“Window-target” content="_top">
注意:用来防止别人在框架里调用你的页面。
5.Content-Type(显示字符集的设定)
说明:设定页面使用的字符集。(我们在前面字体设计中已经介绍过它的作用)
用法:<meta http-equiv=“Content-Type” content=“text/html; charset=gb2312”>
meat标签的name变量语法格式是: <meta name=“xxx” content=“xxxxxxxxxxxxxxxxxx”>
其中xxx主要有下面几种参数:
1.Keywords(关键字)
说明:keywords用来告诉搜索引擎你网页的关键字是什么。
举例:<meta name =“keywords” content=“life, universe, mankind, plants,
relationships, the meaning of life, science”>
如下两条SQL语句,一个不走索引,一个走索引。
在这里,为什么第一条语句未加单引号就不走索引,而第二条加单引号的就走索引呢?
原因是第一条语句由于类型不匹配,MySQL会做隐式的类型转换,都将其转换为浮点数在比较;而第二条语句因为类型一致,不会转浮点数,就是字符串之间的比较,所以就能正常走索引。
一.进一步了解隐式转换
对于第一种情况:
比如where string = 1;需要将索引中的字符串转换成浮点数,但是由于'1','1','1a'都会比转化成1,故MySQL无法使用索引只能进行全表扫描,故造成了慢查询的产生。
这里并不是因为字符串字段值转换成了浮点数?而'1',' 1','1a'转换成1,是整数,类型不匹配导致只能进行全表扫描,而是因为都转换浮点数了,'1','1','1a'本来三个不同的值都是相同的值了,还是打破了有序的规则。
mysql> SELECT CAST(' 1' AS SIGNED)=1;
+-------------------------+
| CAST(' 1' AS SIGNED)=1 |
+-------------------------+
| 1 |
+-------------------------+
1 row in set (0.00 sec)
mysql> SELECT CAST(' 1a' AS SIGNED)=1;
+--------------------------+
| CAST(' 1a' AS SIGNED)=1 |
+--------------------------+
| 1 |
+--------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> SELECT CAST('1' AS SIGNED)=1;
+-----------------------+
| CAST('1' AS SIGNED)=1 |
### 循环结构 : while 循环
"""特征:减少代码冗余,提升代码效率"""
"""
语法:
while 条件表达式:
code1
code2
...
1.初始化一个变量
2.写上循环的条件表达式
3.自增自减的变量值
"""
打印1~100
i = 1
while i<=100:
# 要执行的逻辑 ...
print(i)
i += 1
"""
初始化一个变量 i
第一次循环:
i <= 100 条件成立,执行循环
直接打印 print(i) => 1
i += 1 => i = 2
第二次循环:
回到17行,重新回到判断,看一看是否满足条件
2 <= 100 条件成立,执行循环
直接打印 print(i) => 2
i += 1 => i = 3
第三次循环:
回到17行,重新回到判断,看一看是否满足条件
3 <= 100 条件成立,执行循环
一、 连接MYSQL。
格式: mysql -h主机地址 -u用户名 -p用户密码
1、例1:连接到本机上的MYSQL。
首先在打开DOS窗口,然后进入目录 mysqlbin,再键入命令mysql -uroot -p,回车后提示你输密码,如果刚安装好MYSQL,超级用户root是没有密码的,故直接回车即可进入到MYSQL中了,MYSQL的提示符是:mysql>;
2、例2:连接到远程主机上的MYSQL。假设远程主机的IP为:110.110.110.110,用户名为root,密码为abcd123。则键入以下命令:
mysql -h110.110.110.110 -uroot -pabcd123
(注:u与root可以不用加空格,其它也一样)
3、退出MYSQL命令: exit (回车)
二、修改密码。
格式:mysqladmin -u用户名 -p旧密码 password 新密码
1、例1:给root加个密码ab12。首先在DOS下进入目录mysqlbin,然后键入以下命令
mysqladmin -uroot -password ab12
注:因为开始时root没有密码,所以-p旧密码一项就可以省略了。
2、例2:再将root的密码改为djg345。
mysqladmin -uroot -pab12 password djg345
三、增加新用户。(注意:和上面不同,下面的因为是MYSQL环境中的命令,所以后面都带一个分号作为命令结束符)
格式:grant select on 数据库.* to 用户名@登录主机 identified by "密码"
例1、增加一个用户test1密码为abc,让他可以在任何主机上登录,并对所有数据库有查询、插入、修改、删除的权限。首先用以root用户连入MYSQL,然后键入以下命令:
grant select,insert,update,delete on *.* to test1@"%" Identified by "abc";
但例1增加的用户是十分危险的,你想如某个人知道test1的密码,那么他就可以在internet上的任何一台电脑上登录你的mysql数据库并对你的数据可以为所欲为了,解决办法见例2。
例 2、增加一个用户test2密码为abc,让他只可以在localhost上登录,并可以对数据库mydb进行查询、插入、修改、删除的操作 (localhost指本地主机,即MYSQL数据库所在的那台主机),这样用户即使用知道test2的密码,他也无法从internet上直接访问数据 库,只能通过MYSQL主机上的web页来访问了。
grant select,insert,update,delete on mydb.* to test2@localhost identified by "
赋值运算符用来把右侧的值传递给左侧的变量(或者常量);可以直接将右侧的值交给左侧的变量,也可以进行某些运算后再交给左侧的变量,比如加减乘除、函数调用、逻辑运算等。
Python 中最基本的赋值运算符是等号=;结合其它运算符,=还能扩展出更强大的赋值运算符。
基本赋值运算符
=是 Python 中最常见、最基本的赋值运算符,用来将一个表达式的值赋给另一个变量,请看下面的例子:
#将字面量(直接量)赋值给变量 n1 = 100 f1 = 47.5 s1 = "http://www.baidu.com/python/" #将一个变量的值赋给另一个变量 n2 = n1 f2 = f1 #将某些运算的值赋给变量 sum1 = 25 + 46 sum2 = n1 % 6 s2 = str(1234) #将数字转换成字符串 s3 = str(100) + "abc" 连续赋值
Python 中的赋值表达式也是有值的,它的值就是被赋的那个值,或者说是左侧变量的值;如果将赋值表达式的值再赋值给另外一个变量,这就构成了连续赋值。请看下面的例子:
a = b = c = 100
=具有右结合性,我们从右到左分析这个表达式:
c = 100 表示将 100 赋值给 c,所以 c 的值是 100;同时,c = 100 这个子表达式的值也是 100。b = c = 100 表示将 c = 100 的值赋给 b,因此 b 的值也是 100。以此类推,a 的值也是 100。 最终结果就是,a、b、c 三个变量的值都是 100。
插值法(最邻近,双线性,双三次)的原理及实现 常用的插值方法有最邻近插值法、双现象插值法和双三次插值法等,主要用于图像的放大或缩小。
缩小图像(或称为下采样(subsampled) 或降采样(downsampled) ) 的主要目的有两个: 1、 使得图像符合显示区域的大小; 2、 生成对应图像的缩略图。
放大图像(或称为上采样(upsampling) 或图像插值(interpolating) ) 的主要目的是放大原图像,从而可以显示在更高分辨率的显示设备上。
一、最邻近插值法
最邻近插值(The nearest interpolation)即是选取一个最靠近的像素为它的像素值,这是最简单的一种插值方法,不需要计算。在待求像素的四邻像素中,将距离待求像素最近的邻接像素灰度值赋予待求像素。设i+u, j+v (i, j为正整数, u, v为大于零小于1的小数, 下同)为待求象素坐标, 则待求象素灰度的值 f(i+u, j+v) 如下图所示:
如果(i+u, j+v)落在A区,即u<0.5, v<0.5,则将左上角象素的灰度值赋给待求象素,同理,落在B区则赋予右上角的象素灰度值,落在C区则赋予左下角象素的灰度值,落在D区则赋予右下角象素的灰度值。
特点:最邻近元法计算量较小,但可能会造成插值生成的图像灰度上的不连续,在灰度变化的地方可能出现明显的锯齿状。
代码块:
import cv2 import numpy as np def function(img): height,width,channels =img.shape emptyImage=np.zeros((800,800,channels),np.uint8) sh=800/height sw=800/width for i in range(800): for j in range(800): x=int(i/sh) y=int(j/sw) emptyImage[i,j]=img[x,y] return emptyImage img=cv2.imread("lenna.png") zoom=function(img) print(zoom.shape) cv2.imshow("nearest interp",zoom) cv2.imshow("image",img) cv2.waitKey(0) 二、双线性插值法
双线性插值(Bilinear interpolation):已知X-Y平面内四个像素点的坐标 (x0, y0) 、(x1, y0)、(x0, y1) (x1, y1),要得到四点构成 区间内某一点上的像素值。
7-2 一元多项式的乘法与加法运算 (20 分) (链表实现)
设计函数分别求两个一元多项式的乘积与和。
输入格式:
输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。
输出格式:
输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0。
输入样例:
4 3 4 -5 2 6 1 -2 0
3 5 20 -7 4 3 1
输出样例:
15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1
5 20 -4 4 -5 2 9 1 -2 0
代码如下:
#include <stdio.h> #include <stdlib.h> typedef struct PolyNode{//结构,用来存放多项式结点 int coef;//系数 int expon;//指数 struct PolyNode * next; }Node, *pNode; typedef struct poly{//结构,用来表示多项式 pNode front;//指向多项式的第一项 pNode rear;//指向多项式的最后一项 }Poly, *pPoly; Poly create(int coef, int expon);//创建仅含一个系数为coef指数为expon的结点的多项式并将其返回 void attach(int coef, int expon, pPoly p);//将一个系数为coef指数为expon的结点附在多项式p后 Poly addpoly(Poly p1, Poly p2);//两多项式相加,并将结果多项式返回 Poly nodemulpoly(Node node, Poly p);//用多项式中的一项乘以另一个多项式p,返回结果多项式 Poly mulpoly(Poly p1, Poly p2);//将多项式p1与多项式p2相乘,返回结果多项式 void printpoly(Poly p);//输出多项式p int main() { int n1, n2; scanf("
目录
以下代码段执行后的输出结果为
java语言的下面几种数组复制方法中,哪个效率最高?
在 myjsp.jsp 中,关于下面的代码说法错误的是: ( ) 下面代码的输出是什么?
关于ThreadLocal类 以下说法正确的是
下面程序的输出是:()
使用mvc模式设计的web应用程序具有以下优点,除了?
Java数据库连接库JDBC用到哪种设计模式?
关于Java和C/C++的比较,下列哪个描述是错误的?
关于volatile关键字,下列描述不正确的是?
JVM内存不包含如下哪个部分( )
以下哪些继承自 Collection 接口()
事务隔离级别是由谁实现的?
计算机所能处理的最小的数据项称为()
顺序执行下列程序语句后,则b的值是()
下面有关forward和redirect的描述,正确的是() ?
下列那些方法是线程安全的(所调用的方法都存在)
以下代码段执行后的输出结果为 public class Test { public static void main(String args[]) { int x = -5; int y = -12; System.out.println(y % x); } } 正确答案: D 你的答案: D (正确)
-1 2 1 -2 来源:https://www.nowcoder.com/questionTerminal/7b4ec6887dc04af992ce10dadfb532bb
Y(被除数) % X(除数) 当除数与被除数的符号相同时,取余和取模的结果是完全相同的; 当除数与被除数的符号不相同时,结果不同。
具体说,取余结果的符号与被除数相同;取模结果的符号与除数相同。
1.取余 rem(3,2)=1 rem(-3,-2)=-1 rem(3,-2)=1 rem(-3,2)=-1 2.
FileNotFoundError: [Errno 2] No such file or directory: 'xxx/xxx/xxx/xxx_.xxx.xxx.csv' 我检查了一下确实没有这个路径的文件,
解决方法:按照报错的路径新建文件即可
一个示例说明
源码并不难懂:
public JSONObject fluentPut(String key, Object value) { map.put(key, value); return this; }
时隔多月,我终于想起了这个内容没有更新完成。
接着上次的内容,管理员有自己的登录页面,
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>管理员登录页面</title> <style> .fn{ height:25px; } </style> </head> <body> <form action="/Student_grade/admin/admin_loginservlet" method="post"> <img src="/Student_grade/imge/yun.jpg" alt="yun" width="100%";height="100%" > <div style="font-family:verdana;padding:10px;border-radius:10px;width:330px;border:5px solid #4169E1;position:absolute;top:30%;left:40%;background-color:rgb(255,255,255,0.3)"> <h1 align="center"style="font-size:40px;">管理员登录端口</h1> <b style="font-size:25px;">账号:</b><input type="text" value="admin" name="userid" placeholder="请输入账号" size="25" class="fn"/><br><br> <b style="font-size:25px;">密码:</b><input type="password" name="password" placeholder="请输入密码" size="25" class="fn"/><br><br> <input type="submit" value="登录" style="font-size:18px;"/> <input type="reset" value="重置" style="font-size:18px;"/> <br> <a href="
编写Python脚本把sqlAlchemy对象转换成dict的教程
在用sqlAlchemy写web应用的时候,经常会用json进行通信,跟json最接近的对象就是dict,有时候操作dict也会比操作ORM对象更为方便,毕竟不用管数据库session的状态了。
假设数据库里有一张post表,其中一种方法就是
p = session.query(Post).first()
p.__dict__
但由于p是sqlAlchemy的对象,所以p.__dict__中会有一些其他的属性比如_sa_instance这种我们不需要关注的
那么我们可以给model的基类加一个方法,假设models.py中原来是这样
Base = sqlalchemy.ext.declarative.declarative_base()
class Post(Base):
__tablename__ = 'post'
id = Column(Integer, primary_key=True)
title = Column(String)
那么我们可以加一个to_dict()方法到Base类中
def to_dict(self):
return {c.name: getattr(self, c.name, None) for c in self.__table__.columns}
Base.to_dict = to_dict
这样就可以
p = session.query(Post).first()
p.to_dict()
当然,如果model没有和table绑定的话model里是没有__table__的信息的,可能也会出问题,不过我目前觉得这样最方便了.
完 谢谢观看
异常描述:
OSError: [Errno 30] Read-only file system
解决办法:
终端输入
sudo mount -uw /
不成功报错:mount_apfs: volume could not be mounted: Operation not permitted
解决方案
在Mac OS10.11之后,Apple公司为了提高系统环境安全,引入了一个内核保护措施–SIP(System Integrity Protection,系统完整性保护),又称Rootless mode机制。
在SIP机制下,系统默认会锁定/system、/sbin、/usr这三个目录,即使切换到root用户也只能查看,不能进行其他操作。SIP可以有效地防止恶意程序对电脑进行破坏。
查看SIP状态
csrutil status
1.重启电脑,进入恢复模式,禁用SIP
重启电脑,同时按住Command+R进入恢复模式。
进入到了恢复模式的菜单栏 -> 实用工具 ->打开终端 关闭保护机制 csrutil disable 重启 reboot 2.将根目录变为可读写的(重启后失效)
sudo mount -uw /
操作成功后,根目录读写功能已开启,你可以操作根目录了。
如果执行命令失败,错误如下,则是因为RIP未被禁用。 mount_apfs: volume could not be mounted: Operation not permitted mount: / failed with 77 关闭保护机制 csrutil disable 3.最后设置完毕,重启电脑到恢复模式,启用SIP模式
开启保护机制
问题 在 iOS 下关闭浏览器窗口(切换至后台)或者切换标签时, Audio 仍然继续循环播放音频文件。
方法 使用循环存储时间来检查用户是否在网页上, timeupdate 事件是在音频 Audio 的播放位置发生改变时触发。
var lastSeen; var loop = function (){ lastSeen = Date.now(); setTimeout(loop, 50); }; loop(); var music = document.getElementById('music'); music.addEventListener('timeupdate', function (){ if(Date.now() - lastSeen > 100){ this.pause(); } }, false);
检查 WaitGroup 是否是以指针传递。
一、 curl查询公网出口IP 不管是在家里还是办公室,或者是公司的主机,很多时候都是在内网中,也就是说很多都是通过 NAT上网的,有时候需要查询下出口的公网IP,如果有浏览器,可以用百度或者google搜 ip 这个关键词得到公网IP。
# curl ipinfo.io { "ip": "114.110.1.38", "hostname": "No Hostname", "city": "Beijing", "region": "Beijing Shi", "country": "CN", "loc": "39.9289,116.3883", "org": "AS4808 CNCGROUP IP network China169 Beijing Province Network" }% # curl ip.cn 当前 IP:114.110.1.38 来自:北京市 xxx北京分公司 # curl cip.cc IP : 114.110.1.38 地址 : 中国 北京市 数据二 : 北京市 | xxx北京分公司 URL : http://www.cip.cc/114.110.1.38 # curl myip.ipip.net 当前 IP:114.110.1.38 来自于:中国 北京 北京 联通/电信 # curl ifconfig.
P5461 赦免战俘 输入输出样例 输入 3 输出 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 0 1 1 1 1 0 0 0 1 0 0 0 1 0 0 1 1 0 0 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 分治和递归的思想
1、试问数字信号的最佳接收以什么指标作为准则? 答:差错概率最小准则和输出信噪比最大准则,其中差错概率最小准则用于设计最佳接收机,输出信噪比最大准则用于设计匹配滤波器。
2、试写出二进制信号的最佳接收的判决准则。 答:最大似然准则。公式见书P253(9.2-10)
3、对于二进制双极性信号,试问最佳接收判决门限值应该等于多少? 答:等概条件下,判决门限为零。
4、试问二进制确知信号的最佳形式是什么? 答:双极性信号,两种码元波形相反,相关系数最小,即 ρ = -1。
5、试画出二进制确知信号最佳接收机的方框图。 答:见书256页。
6、对于二进制等概率双极性信号,试写出其最佳接收的总误码率表示式。 答:见书 P259 公式(9.4-17)。
7、试述数字信号传输系统的误码率和信号波形的关系。 答:当两信号相同时,ρ = 1,此时误码率最大,为 1 / 2 ;当两信号波形相反时, ρ = -1,此时误码率最小。
8、何谓匹配滤波?试问匹配滤波器的冲激响应和信号波形有何关系?其传输函数和信号频谱又有什么关系? 答:
用线性滤波器对接收信号滤波时,使抽样时刻上线性滤波器的输出信噪比最大就是匹配滤波。当 K 取一时,匹配滤波器的冲击响应信号是输入信号沿 y 轴镜像折叠后再向右平移T得到,其中 T 大于等于输入信号宽度。
传输函数等于信号码元频谱的复共轭(除常数因子外)。
9、试述滤波器的物理可实现条件。 答:接收滤波器输入端的信号码元在抽样时刻 t0 之后必须为零。
10、试问如何才能使普通接收机的误码率达到最佳接收机水平? 答:使普通接收机的信噪比等于最佳接收机的码元能量和噪声功率谱密度之比(或答使普通接收机带宽等于码元传输速率)。
11、何谓相关接收?试画出接收2FSK信号的相关接收方框图。 答:相关接收是将输入信号与参考信号进行相关运算,然后再进行抽样判决比较的数字信号接收形式。
12、试比较相关接收与匹配滤波的异同点。试问在什么条件下两者能够给出相同的输出信噪比? 答:
相同点:都是最佳接收方法。
不同点:匹配滤波的输出是输入信号与输入信号的镜像再向右平移t0的卷积运算,相关接收的输出是输入信号的自相关函数。
在抽样时刻两者的输出信噪比相同。
13、对于理想信道,试问最佳基带传输系统的发送滤波器和接收滤波器特性之间有什么关系? 答:二者相等,是H(f)的1/2次幂。
原标题:Python 人脸识别就多简单,看这个就够了!
基于业内领先的 C++ 开源库 dlib 中的深度学习模型,用 Labeled Faces in the Wild 人脸数据集进行测试,有高达99.38%的准确率。
1.安装
最好是使用 Linux 或 Mac 环境来安装,Windows 下安装会有很多问题。在安装 face_recognition 之前你需要先安装以下几个库,注意顺序!
1.1 先安装 cmake 和 boostpip installcmake
pip installboost
1.2 安装 dlibpipinstall dlib
此处安装可能要几分钟。如安装出错,建议使用 whl 文件来安装
下载地址:https://pypi.org/simple/dlib/
1.3 安装 face_recognition
face_recongnition 一般要配合 opencv 一起使用
pip installface_recognition
pip installopencv-python
2. 人脸识别
首先获取人脸中的信息
kobe_image = face_recognition.load_image_file( "kobe.jpg") # 已知科比照片
jordan_image = face_recognition.load_image_file( "jordan.jpeg") # 已知乔丹照片
unknown_image = face_recognition.load_image_file( "unkown.jpeg") # 未知照片
题目如下:
成绩在[90,100],奖励笔记本电脑
成绩在[75,89],奖励游戏一天
成绩在[60,74],奖励试题一套
成绩在[0,59],奖励辅导班补习
输错,这显示错误
代码如下:
<!--成绩在[90,100],奖励笔记本电脑 成绩在[75,89],奖励游戏一天 成绩在[60,74],奖励试题一套 成绩在[0,59],奖励辅导班补习 输错,这显示错误--> <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>成绩决定奖惩</title> <script type="text/javascript"> var grade = prompt("请输入你的成绩:"); if(grade > 100 || grade < 0 || isNaN(grade)){ alert("哪有成绩是 "+ grade +"的,走开"); }else if(grade >= 90){ alert("成绩 " + grade +"分,奖励一台笔记本电脑"); }else if(grade >= 75){ alert("成绩 " + grade +"分,奖励游戏一天"); }else if(grade >= 60){ alert("
一、字符串常用方法
str.capitalize() #字符串首字母大写
str.center(20,'-') #把字符串居中,两边以'-'填充,长度一共为20
str.index('p') #返回字符'p'在字符中的下标,找不到下标时会报错
str.isalnum() #判断字符串里只能有英文、数字 ,返回布尔值
str.isalpha() #判断是否只为英文的,汉字也可以
str.count('a') #返回'a'字符在字符串中的个数
str.endswith('.jpg') #判断字符串是否以xx结尾
str.startswith('138') #判断字符串是否以xx开头
str.upper() #字母都给变成大写的
str.lower() #字母都给变成小写的
str.find('p') #返回字符'p'在字符中的下标,找不到时就返回-1
str.isdigit() #判断是否为纯数字
str.isspace() #判断是否全都是空格
str.strip() #去掉字符串两边的东西,默认是去掉两边的空格和换行符的
str.lstrip() #只去掉左边的空格跟换行符
str.rstrip() #只去掉右边的空格跟换行符
str.replace('a','b') #替换字符串,把前面的a替换成后面的b
str.zfill(2) #在前面补0,补到长度为2
str.split(',') #1.以‘,’分割字符串 2.将字符串变成一个list 3.默认是以空格跟换行符分割的
'\n'.join(stus) #1.将数组元素以换行符\n来拼接成字符串 2.将list变成字符串 3.以某个字符串连接
str[1] #字符串也可以根据下标来取值
str.format() #字符串的格式化
二、String模块
import String
string.ascii_letters #所有的大写+小写字母
string.ascii_lowercase #所有的小写字母
string.ascii_uppercase #所有的大写字母
string.digits #所有的数字
string.punctuation #所有的特殊字符
图像畸变矫正——透视变换 由于相机制造精度以及组装工艺的偏差引入的畸变,或者由于照片拍摄时的角度、旋转、缩放等问题, 可能会导致原始图像的失真,如果要修复这些失真,我们可以通过透视变换,对图像进行畸变矫正。
透视变换的原理推导
透视变换(Perspective Transformation)是将图片投影到一个新的视平面(Viewing Plane), 也称作投影映射(Projective Mapping)。透视变换的目的就是把现实中为直线的物体, 在图片上可能呈现为斜线, 通过透视变换转换成直线的变换。
仿射变换(Affine Transformation或 Affine Map) , 又称为仿射映射, 是指在几何中, 图像进行从一个向量空间进行一次线性变换和一次平移, 变换为到另一个向量空间的过程。我们常说的仿射变换是透视变换的一个特例。
以上便是透视变换的原理图,即将源图像通过投影映射,从原图像平面变换到新图像平面。通用的变换公式为:
(X,Y,Z)是原图像平面坐标点, 对应得到变换后的图像平面坐标点为(X’;Y’;Z’) ,因为我们处理的是二维的图像,所以可以令Z’=1,并将变换后的图像坐标除以Z’,将图片由三维降维为两维,然后可以得到以下方程:
一般地, 我们令a33=1(方便得到X’,Y’,使方程3等号左侧分母为1), 展开上面公式, 得到一个点的情况:
方程3中共有8个未知数(aij),如果要解出该未知数,需要列八组方程,即分别在源图像和目标图像上人为选择四个点(通常选择图片的四个顶点)
在源图像上选四个坐标点,分别为A: (x0,y0),(x1,y1),(x2,y2),(x3,y3)
在目标图像上选四个坐标点,分别为B: (X’0,Y’0),(X’1,Y’1),(X’2,Y’2),(X’3,Y’3)
带入方程3,可以得出方程4,如下:
使用python,将上述推导过程定义为函数WarpPerspectiveMatrix(src, dst),计算出变换矩阵warpMatrix,如下:
import numpy as np def WarpPerspectiveMatrix(src, dst): assert src.shape[0] == dst.shape[0] and src.shape[0] >= 4 #assert语句:用以检查某一条件是否为True,若该条件为False则会给出一个AssertionError。 #注意这里src和dst的输入并不是图像,而是图像对应的顶点坐标点矩阵。 nums = src.shape[0] A = np.zeros((2*nums, 8)) # A*warpMatrix=B B = np.zeros((2*nums, 1)) for i in range(0, nums): A_i = src[i,:] B_i = dst[i,:] A[2*i, :] = [A_i[0], A_i[1], 1, 0, 0, 0, -A_i[0]*B_i[0], -A_i[1]*B_i[0]] B[2*i] = B_i[0] A[2*i+1, :] = [0, 0, 0, A_i[0], A_i[1], 1, -A_i[0]*B_i[1], -A_i[1]*B_i[1]] B[2*i+1] = B_i[1] A = np.
软件设计师是软考中级职称,相比高级的难度而言,中级难度较低,每个人花些时间都能顺利通过的,考试分为上午的选择题和下午的综合题,这里跟大家分享一些自己备考时使用的资料和经验
一、先对自己进行评估:
因为每个人的知识点掌握情况和学校教学内容的不一致,这里以我个人情况进行说明,大家做个参考就行:
大家先了解一下软件设计师的考纲:
有些同学刚看到考纲会有一些担心,感觉有些东西都还没学过,但是没学过的也没关系喔。
大家要明白一点,软件设计师考察的内容广度比较高,即内容多、杂,但是深度很浅,没学过的部分系统刷遍视频,认真刷题足矣。
二、刷题、刷题、刷题,看视频为辅:
刷题真的很重要,很多题目都是每年反复考,把近几年的真题刷过一遍并且理解差不多就已经十拿九稳了。
分享不易,麻烦大家点一下赞呗~
链接:https://pan.baidu.com/s/1VXSjPRgA7uDYHf6suWBrvw
提取码:ymod
这是重头戏哦,一定要多刷题,真题全都没有水印、从2004-2019年,答案跟题目是分开的,word跟PDF格式
三、备考流程:
1、看视频过一遍基础知识点:首先是去B站上搜软件设计师,然后从头到尾把知识点都快速刷一遍,有些内容大家很早就学过,但是时间一久已经忘得差不多了,很有必要从头过一遍基础知识点,同时手机还可以下载刷题软件,方便记忆错题和知识点。
2、通过刷题掌握知识点:本人是大二下学期考的中级,很顺利一次就通过了,当时是花两个月的时间备考(因为还要上课,其实能自己复习的时间并不是很多),一个月的时间看视频,一个月的时间刷真题,例如考纲中的计算机网络、信息安全知识、多媒体基础、知识产权知识这四部分是完全没学过的,但是通过看视频+做题+考试的难度不深,很顺利的通过了考试,尤其这四部分几乎都是靠背靠记的,把历年真题自己做错的记起来或者理解,已经够稳了,没必要翻教程。刚开始刷题的时候肯定会错蛮多的,特别是没学过的部分,但是不要灰心,把错的部分理解和记起来,你会发现接下去几乎都会反复出现。
3、要不要看书?软考的官方教材是蓝本本,很厚很厚,看书只会打击自己,书里内容太多了太详细了,但是考试压根不会这样考,看书会让自己的复习进度相当慢,你自己也记不了这么多。当时我自己也买了,教材+习题+辅导,但是最后我自己翻都没翻过,白白浪费钱。。最后就送人了。大家只要明白软考考察的是广度,不是深度,刷过视频+做题就够了,最重要的是刷历年真题,很多东西都是反复考。大家把刷过的真题做错部分认真理解和记起来就够了。
最后祝大家考试顺利,顺利拿证,有不懂的地方都可以评论下方进行留言,如果链接过期也可以评论留言,我会私发给大家
一起探索C++类内存分布 C++ 类中内存分布具体是怎么样,尤其是C++中含有继承、虚函数、虚拟继承以及菱形继承等等情况下。
由于在linux下没有windows下显示直观,我们采用vs2015进行调试。
部署环境
我们在 属性->C/C++ ->命令行 -> /d1 reportSingleClassLayoutXXX ,XXX表示类名;
单个基础类
class Base { private: int a; int b; public: void test(); }; 内存分布:
class Base size(8): +-- - 0 | a 4 | b +-- - 总结:我们发现普通类的内存分布是根据声明的顺序进行的,成员函数不占用内存。
基础类+继承类
class Base { int a; int b; public: void test(); }; class Divide :public Base { public: void run(); private: int c; int d; }; 内存分布:
class Divide size(16) : +-- - 0 | +-- - (base class Base) 0 | | a 4 | | b | +-- - 8 | c 12 | d +-- - 总结:根据内存分布,我们发现普通继承类,内存分布也是按照声明的顺序进行的,成员函数不占用内存;类的顺序是先基类,后子类。
B+TREE PARENT PAGE This is the parent class that both the Internal Page and Leaf Page inherited from and it only contains information that both child classes share. The Parent Page is divided into several fields as shown by the table below.
首先,研究头文件,熟悉这个类,然后实现这个类对应的get以及set方法
src/include/storage/page/b_plus_tree_page.h
namespace bustub { #define MappingType std::pair<KeyType, ValueType> #define INDEX_TEMPLATE_ARGUMENTS template <typename KeyType, typename ValueType, typename KeyComparator> // define page type enum enum class IndexPageType { INVALID_INDEX_PAGE = 0, LEAF_PAGE, INTERNAL_PAGE }; /** * Both internal and leaf page are inherited from this page.
题目描述
《庄子》中说到,“一尺之棰,日取其半,万世不竭”。第一天有一根长度为 a(a≤10^9) 的木棍,从第二天开始,每天都要将这根木棍锯掉一半(每次除 2,向下取整)。第几天的时候木棍会变为 1?
输入格式
无
输出格式
无
输入输出样例
输入 #1
100
输出 #1
7
#include<iostream> using namespace std; int main() { long long int a,i=1; //木头长度为10的九次方,数据比较大,要用long long int //第一天长度为a,从第二天开始才开始锯,所以i=1 cin>>a; while(a!=1) { a=a/2; i=i+1; } cout<<i; return 0; }
转发地址:
https://www.cnblogs.com/hf8051/p/4729904.html
今天
select * from 表名 where to_days(时间字段名) = to_days(now());
昨天
SELECT * FROM 表名 WHERE TO_DAYS( NOW( ) ) - TO_DAYS( 时间字段名) = 1
昨天之前
昨天
SELECT * FROM 表名 WHERE TO_DAYS( NOW( ) ) - TO_DAYS( 时间字段名) > 1
明天
SELECT * FROM 表名 WHERE TO_DAYS( 时间字段名) - TO_DAYS( NOW( ) ) = 1
7天
SELECT * FROM 表名 where DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= date(时间字段名)
混杂设备的定义 定义: 在Linux驱动当中把无法归类的五花八门的设备定义为混杂设备(用miscdevices结构体),简化字符设备创建的流程,混杂设备也是字符设备,它可以替代字符设备的设计模型。
查看混杂设备的方式 进入 /sys/class/misc 目录 然后使用Linux指令 ls 查看。 [root@GEC6818 misc]# ls CEC android_adb_enable device-mapper psaux HPD apm_bios mtp_usb s3c-jpg alarm ashmem network_latency s3c-mfc android_adb cpu_dma_latency network_throughput sec-g2d 进入 /dev 目录 然后使用Linux指令 ls 或 ls -l查看。 [root@GEC6818 /dev]# ls -l total 0 crw-rw---- 1 root root 10, 242 Jan 1 12:00 CEC crw-rw---- 1 root root 10, 243 Jan 1 12:00 HPD crw-rw---- 1 root root 10, 59 Jan 1 12:00 alarm crw-rw---- 1 root root 10, 62 Jan 1 12:00 android_adb crw-rw---- 1 root root 10, 61 Jan 1 12:00 android_adb_enable crw-rw---- 1 root root 10, 134 Jan 1 12:00 apm_bios crw-rw---- 1 root root 10, 63 Jan 1 12:00 ashmem 混杂设备的主设备号默认为10,我们也可以\Documentation\devices.
k8s创建静态pod 静态Pod是由kubelet进行管理的仅存在于特定Node上的Pod。它们不能通过API Server进行管理,无法与ReplicationController、Deployment或者DaemonSet进行关联,并且kubelet无法对它们进行健康检查。静态Pod总是由kubelet创建的,并且总在kubelet所在的Node上运行。
配置文件方式 增加kubelet的配置文件 –pod-manifest-path=/etc/kubelet.d/
[root@tom ~]# cat /usr/lib/systemd/system/kubelet.service [Unit] Description=Kubernetes Kubelet Documentation=https://github.com/GoogleCloudPlatform/kubernetes After=docker.service Requires=docker.service [Service] #WorkingDirectory=/var/lib/kubelet ExecStart=/usr/local/bin/kubelet --runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice --address=192.168.11.110 --hostname-override=192.168.11.110 --cgroup-driver=cgroupfs --pod-infra-container-image=mirrorgooglecontainers/pause-amd64:3.0 --experimental-bootstrap-kubeconfig=/etc/kubernetes/bootstrap.kubeconfig --kubeconfig=/etc/kubernetes/kubelet.kubeconfig --cert-dir=/etc/kubernetes/ssl --cluster-dns=10.254.0.100 --cluster-domain=cluster.local. --hairpin-mode=promiscuous-bridge --allow-privileged=true --fail-swap-on=false --serialize-image-pulls=false --max-pods=30 --logtostderr=true --v=2 --pod-manifest-path=/etc/kubelet.d/ Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target [root@tom ~]# [root@tom ~]# cat /etc/kubelet.d/static-web.yaml apiVersion: v1 kind: Pod metadata: name: static-web labels: role: myrole spec: containers: - name: web image: nginx:1.17.6 ports: - name: web containerPort: 80 protocol: TCP [root@tom ~]# [root@tom kubelet.
抽空查看以前的开发日志,发现了一些“问题”日志,决定整理后陆陆续续发出来吧,也为有需要的话小伙伴提供点帮助。
在springboot启动之时,报错了,一看应该就是连接MySql数据库时出的问题。create connection SQLException, url: jdbc:mysql://localhost:3306/mp_student?useUnicode=true&characterEncoding=UTF-8, errorCode 0, state 01S00
java.sql.SQLException: The server time zone value '�й���ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
控制台洋洋洒洒几百个错误刷屏,内心居然能够波澜不惊,看来已经是见过世面的人了(另类老司机?)。
简单翻译一下,就是服务器时区跟数据库所用时区不一样,需要在服务器端或者JDBC驱动配置里面指定一个,否则就不给你用。
好吧,我投降,因为我不能不用呀。总不能改电脑的时区吧,那就怎么简单怎么来吧,在 JDBC URL 后面加个参数。?serverTimezone=UTC
如果你有多个参数,像我一样,就&serverTimezone=UTC
完整路径如下:jdbc:mysql://localhost:3306/mp_student?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
其实,也可以设置为我们所在的东八区,毕竟只要设置了就行,当然,你生产环境还是得设置你所在地区的时区,或者业务要求的时区jdbc:mysql://localhost:3306/mp_student?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
简单解释一下
UTC: Coordinated Universal Time, 国际协调时间,也称世界标准时间。
1、官网下载linux版本rpm包 https://pan.baidu.com/download
2、上传到服务进行安装 [root@dukeServer ~]# rpm -ivh baidunetdisk-3.5.0.x86_64.rpm 会遇到需要依赖包报错,这是使用yum 安装缺失的依赖包。
或者
[root@dukeServer ~]# yum -y install baidunetdisk-3.5.0.x86_64.rpm 直至安装成功
3、启动百度云盘报错 提示:
libstdc++.so.6: version `GLIBCXX_3.4.20' not found 查看:
[root@dukeServer ~]# strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX GLIBCXX_3.4 GLIBCXX_3.4.1 GLIBCXX_3.4.2 GLIBCXX_3.4.3 GLIBCXX_3.4.4 GLIBCXX_3.4.5 GLIBCXX_3.4.6 GLIBCXX_3.4.7 GLIBCXX_3.4.8 GLIBCXX_3.4.9 GLIBCXX_3.4.10 GLIBCXX_3.4.11 GLIBCXX_3.4.12 GLIBCXX_3.4.13 GLIBCXX_3.4.14 GLIBCXX_3.4.15 GLIBCXX_3.4.16 GLIBCXX_3.4.17 GLIBCXX_3.4.18 GLIBCXX_3.4.19 GLIBCXX_DEBUG_MESSAGE_LENGTH 缺失高版本3.4.20,在尝试安装3.4.20,
yum provides libstdc++.so.6
无果。
最终下载到一个更高版本
libstdc.so_.6.0.26.zip
点击下载
将其解压后,拷贝到/usr/lib64/ 路径下,在创建软连接后解决问题。
#拷贝
[root@dukeServer ~]# cp -ri /home/softwares/libstdc++.
今年参加电赛,选择了E题。赛题基本要求:
这道题大体来说有两个方案。
方案一:用五个晶体管放大电路分别产生波形。(好处:好调试,同时不会因为其中一个元器件故障导致其他的波形都出不了结果。劣处:工作量大)
方案二:只用一路放大电路,通过改变阻值,来产生不同波形(好处:焊接电路的工作量更小。劣处:不好调试,其中一部部分出了问题可能所有波形都没法显示。)
比赛时稳妥起见我们选择了方案一。乘放假时间自己把第二种方案再试一试。本篇博客主要是基于方案二写的,本人水平有限,不一定都正确,有问题欢迎一起探讨。
一、放大电路部分 1、电路设计
S2:顶部失真
S1:底部失真
S5:双向失真
S6:交越失真(这里软件有一个bug,S6使用开关控制,一旦闭合就会出现仿真错误,但是直接用线连接,则没有问题,我也不知道为啥。)
基本的电路设计就是这样,但可能具体参数还要稍微调一调,尤其是红框的两个电阻。
C2将前后两个部分隔离开来,使前后的静态工作点彼此独立,方便调试。
2、仿真结果
这个地方根据仿真应该0.8V左右,但是实际电路测出来只有81mv我检查了焊接是没有问题,而且这里就这么几个元器件,我感觉是三极管出了问题,换了三极管之后直接变成了5V,基本等于电源电压,找了好久都没找到问题。后来我又换了一次,结果还是81mv,应该不是三极管问题/后来通过更改R4阻值,才达到要求。而此时测量c极电压,已经4.6v了,跟仿真相差太大!不过功能是能实现的。
在我把正弦波和双向失真调好后,就出去吃饭了,结果放了几个小时,c极电压莫名其妙变成了5v,而且怎么调r4都没用。我唯一做过的更改就是离开之前,重新焊接了一个元器件,我怀疑是不是温度太高把三极管损坏了。这次又换了个三极管,还真就正常了。
(2)R11最开始选的68k 仿真没问题,但实际操作出来没法产生失真波形,最后只得更改成可调电阻慢慢调。
4、实际结果
交越失真效果不是特别明显。先暂时这样,后面再改进。
二、信号调理电路 经信号调理电路输入到STM32进行fft。
stm32ADC只能接收0-3.3v,所以需要对输出信号进行处理,利用加法器,将信号全部抬高至正,同时保证电压在0-3.3v范围内。
三、软件设计 //暂时空着,等我做出来了再补充
使用Django3发送邮件报错 问题描述: 在实现邮箱验证功能时,向测试QQ邮箱发了一封邮件,但是失败了,返回异常如下:
raise SMTPServerDisconnected("Connection unexpectedly closed") smtplib.SMTPServerDisconnected: Connection unexpectedly closed 解决方法: 在settings设置里多添加一行代码:
EMAIL_USE_SSL = True EMAIL_USE_TLS那个设置就不用写了。
另外注意EMAIL_HOST_PASSWORD参数的设置,这个是邮箱的授权码,不是自己的邮箱密码。
QQ邮箱的端口号设置EMAIL_PORT = 465。
提示信息:
fatal: [localhost]: FAILED! => {“changed”: true, “cmd”: “/usr/local/bin/helm upgrade –install ks-openldap /etc/kubesphere/openldap-ha -f /etc/kubesphere/custom-values-openldap.yaml –set fullnameOverride=openldap –namespace kubesphere-system\n”, “delta”: “0:00:00.667982”, “end”: “2020-07-08 06:34:49.019851″, “msg”: “non-zero return code”, “rc”: 1, “start”: “2020-07-08 06:34:48.351869”, “stderr”: "Error: render error in \“openldap-ha/templates/statefulset.yaml\”: template: openldap-ha/templates/statefulset.yaml:25:9: executing \“openldap-ha/templates/statefulset.yaml\” at <(.Values.ldap.replication) and eq .Values.ldap.replication \“true\”>: can’t give argument to non-function .Values.ldap.replication", “stderr_lines”: ["Error: render error in \“openldap-ha/templates/statefulset.yaml\”: template: openldap-ha/templates/statefulset.yaml:25:9: executing \“openldap-ha/templates/statefulset.yaml\” at <(.Values.ldap.replication) and eq .
路由 定义你的各个路由 1.任务:
1.路由 /crisis-center 用来打开 crisis-center 组件。
2.路由 /heroes-list 用来打开 heroes-list 组件。
2.相关代码
/* src/app/app.module.ts */ imports: [ BrowserModule, RouterModule.forRoot([ {path: 'crisis-list', component: CrisisListComponent}, {path: 'heroes-list', component: HeroesListComponent}, ]), ], 更新你的组件以添加 router-outlet 1.任务:
1.需要更新模板,以便根据 URL 路径动态加载一个组件。
2.相关代码
/* src/app/app.component.html */ <router-outlet></router-outlet> 用 UI 元素控制导航 1.任务:
1.添加按钮进行导航。
2.相关代码
/* src/app/app.component.html */ <nav> <a class="button" routerLink="/crisis-list">Crisis Center</a> | <a class="button" routerLink="/heroes-list">Heroes</a> </nav> <router-outlet></router-outlet> 标出活动路由 1.任务:
1.添加导航按钮为激活时候的css样式。
2.相关代码
/* src/app/app.component.html */ <nav> <a class="
在写配置文档的时候,把logging的formatter格式也进行了ini文档中,如下所示
[Log] name=test_name filename=my_log.log level = INFO formatter = %(name)s - %(filename)s -%(funcName)s - %(asctime)s - 日志信息:%(message)s 读取是用的ConfigParser这个类通过read和get去读取,下图是自己封装好的读取配置文件
from configparser import ConfigParser import os class MyConfig(ConfigParser): def __init__(self): """将ConfigParser的初始化方法搬上来,另外通过动态获取方式拿到配置文件的路径,并读取配置文件 """ super().__init__() dir_log = os.path.dirname(os.path.realpath(__file__)) path_log = os.path.join(dir_log, "config.ini") self.read(path_log,encoding="utf-8") 在我自己定义的Logger类中使用到上述的这个类,并且用get方法获得文件中的值
class MyLogger(Logger): def __init__(self): # 获取配置文件的内容 conf = MyConfig() name = conf.get("Log","name") file = conf.get("Log","filename") level = conf.get("Log","level") fmt_str = conf.get("Log","formatter") ... # 省略后续,不重要 运行的时候,发现会报一个错误,configparser.InterpolationMissingOptionError: Bad value substitution
configparser.InterpolationMissingOptionError: Bad value substitution: option 'formatter' in section 'LOG' contains an interpolation key 'name' which is not a valid option name.