在pom中直接引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> 设置以下两项(第一项如已设置直接设置第二项) 1、“File” -> “Settings” -> “Build,Execution,Deplyment” -> “Compiler”,选中打勾 “Build project automatically” 。
2、 组合键:“Shift+Ctrl+Alt+/” ,选择 “Registry” ,选中打勾 “compiler.automake.allow.when.app.running”
无聊写了一个html页面的语音系统(第一次写网页),其实也算不上系统,就跟vbs差不多,vbs是输入CreateObject(“SAPI.SpVoice”).Speak "此处填写你想让电脑说的话"保存为vbs,而这个是可以看见页面效果的的,注释也写得很详细了
下面贴上代码,直接复制保存就可以用
<!DOCTYPE html> <html> <head> <title>myweb</title> <style> html{ height: 100%; background-color: gray; } div{ width: 900px; margin: 100px auto 0; } .input_box{ width: 100%; height: 380px; outline: none; /*去掉轮廓线*/ border: 10px solid #000; box-sizing: border-box;/*怪异盒模型*/ resize: none;/*禁止拖拽*/ border-radius: 20px;/*圆角*/ padding: 20px; background-color: rgba(255,255,255,5); font-size: 20px; } .speech{ height: 55px; width: 100%; font-size: 18px; outline: none; border: none; background-color:#000; color: #fff; cursor: pointer;/*鼠标样式,小手*/ border-radius: 20px; } .speech:hover{/*hover伪类选择器 当鼠标滑过speech改变背景颜色*/ background-color: #ea4c89 } </style> </head> <body> <div> <textarea class="
文章目录 用python 判断一个单链表是否有环.第二次做DAY20201130[141. 环形链表](https://leetcode-cn.com/problems/linked-list-cycle/)方法1 路径记录法方法2 快慢指针法第1种解法另一种写法 用python 判断一个单链表是否有环. https://leetcode.com/problems/linked-list-cycle/
思路1:
判断一个单链表是否有环,
可以用 set 存放每一个 节点, 这样每次 访问后把节点丢到这个集合里面.
其实 可以遍历这个单链表, 访问过后,
如果这个节点 不在 set 里面, 把这个节点放入到 set 集合里面.
如果这个节点在 set 里面 , 说明曾经访问过, 所以这个链表有重新 走到了这个节点, 因此一定有环
如果链表都走完了, 把所有的节点都放完了. 还是没有重复的节点, 那说明没有环.
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ @Time : 2019/1/12 00:59 @File : has_circle.py @Author : frank.chang@shoufuyou.com https://leetcode.com/problems/linked-list-cycle/ 141. Linked List Cycle Easy 1231 93 Favorite Share Given a linked list, determine if it has a cycle in it.
一、用户权限表设计 本系统的业务数据库选择的是mysql数据库,采用分库的方式来开发以及权限的控制,两个数据的名字分别为:core_db_01(业务数据库)、core_db_02(权限数据库)。下面是商城权限表设计,如需要建表语句的朋友,请留言。
1、用户登录表结构:
2、用户基础信息表结构:
3、系统菜单表结构:
4、用户角色表结构:
5、菜单角色表结构:
6、用户角色表结构:
7、系统编码表:
二、商品表结构设计 1、等待更新
编剧:朱金灿
来源:http://blog.csdn.net/clever101
版权声明:
本剧本受天朝的《非法出版物保护法》和温总、胡总关于保护不和谐言论的讲话精神保护,遵循GPL协议,即任何人可以分发、修改本剧本,但必须同时公开其剧本台词。若有关出版社对出版本剧本感兴趣,请联系本人的法律顾问北京市非诚不要扰律师事务所权大于法律师,电话:010-17769394(一起出来搞三搞四)。
演员:
男播音员一名
女播音员一名
外景记者一名
若干人客串被访名人和非名人
新闻联播音乐响起
男播音员:观众朋友们,大家好。欢迎收看CCLV新闻联播 (LV语气加重)
女播音员:今天是 2010年12月30日,农历腊月初五,今天是一年一度的***公司 年会日
男播音员:我是李咏
女播音员:我是董卿
男播音员:由于CCLV新闻部的播音员昨晚喝了三鹿牌奶粉,集体三聚氰胺中毒住 院,因此今天的节目由我俩代为主持,今天节目主要内容有...
女播音员掏出小镜子照镜子,看到男播音员在看她,赶紧收起镜子,调皮的笑
男播音员盯着女播音员看
男播音员:镜头切过来啦!干哈呢干哈呢,不许笑,严肃点,这正新闻联播呢。
男播音员转向观众:真是对不起观众朋友,我们保证CCLV在2012年伦敦奥运期间 决不会再出现这样的技术失误,耶(做李咏的动作)
女播音员:别噎着了,这是新闻联播,不是非常六加一,矜持点,你刚才说到哪 了?
男播音员:今天节目的主要内容有
女播音员抢话:今天节目的内容很黄很暴力
男播音员:嗯?
女播音员:噢不,很傻很天真
男播音员:啊?
女播音员:哦不不,很那个,咏哥,这个字我不认识啊。不好意思啊,我的语文是跟体育老师学的。
男播音员:什么字啊?
女播音员:一个框,上边一个八,下边一个口
男播音员:哦,这个字啊,读冏啊,耶(做李咏的动作)
女播音员:很冏很雷人
男播音员:好了好了,下边请看详细内容
男播音员:首先是财经方面的新闻。今年股市萎靡不振。为此记者走访了一些股民朋友,请他们谈一下今年股市。
男记者(面向观众介绍自己):大家好,我是大沈阳。
男记者:大叔,股票炒得挺好吧?
股民:好啊,那是相当的好!
男记者:请问大叔,我听说中石油最近跌得很厉害啊?
股民(举起手指):假象,绝对的假象!不会下蹲的股票是跳不高的。股评家说了,买了中石化,生活不用怕;买了中石油,生活不用愁。
男记者:大叔,过年有啥打算?
股民(双手一摊,做无奈状):还打算啥呀?搁家解套呗!石油套----岗岗的-- --老他妈难解了!问君能有几多愁,恰似满仓中石油。
男记者:大叔说话真是风趣!多谢大叔接受我们的采访!现在把信号切回到电视台的直播间。
女播音员:感谢前方同事发回的报道。下边播送一条体育新闻。鉴于现在中国足球不景气的现状,中国足协决定改革现有的联赛体制,筹办中国监狱足球超级联赛。目前中国足协主席南勇,前主席谢亚龙,国足领队蔚少辉等足协首脑人物齐聚辽宁省看守所,就这一决策进行集体研究。请看我们驻沈阳特派记者大沈阳从辽宁看守所发回的采访报道。
记者:请问蔚领队,为什么想到要在监狱举办足球联赛呢?
蔚少辉(一摆手,大声说):哥是出来打酱油的!不要问哥!
这时蔚少辉手机铃响,他接手机,用手拨开记者身体,说:哥们,让一下,你挡
着我的手机信号了。
听完电话他对记者说:不好意思,失陪了!我妈喊我回家吃饭!(然后离开)
记者又问南勇:请问南主席,为什么想到要在监狱举办足球联赛呢?
南勇:首先监狱是弱势群体,扶助弱势群体嘛,其次因为我爸不是李刚,我爸要是李刚的话,我能举办中国公务员足球超级联赛。
记者又问谢亚龙:请问谢主席,为什么想到要在监狱举办足球联赛呢?
谢亚龙:首先,我认为这是一个对中国足球发展非常给力的决定。你应该知道的,叉腰肌这玩儿很好很强大啊,自从中国男足练了叉腰肌,嘿,还真对得起这双臭脚,我们中国足球有指望了。你要练俯卧撑你都不好意思跟人打招呼。经过我们足协集体调查,发现监狱是个练叉腰肌的好地方。因为监狱作息规律,管理严格,国足那帮孙子在外面还是不是闹个泡吧赌球什么的,在监狱里踢球,环境单纯,球员只好乖乖练叉腰肌了。我们冲出亚洲暂时没希望,赶超朝鲜还是有希望的。
记者:非常感谢足协领导百忙之中接受我们的采访,现在把信号切回到电视台的直播间。
男播音员:感谢前方记者发回的报道,我们祝愿中国足球在2011年雄起。下边播送一条科技新闻。著名的互联网公司Q讯发表公开信:我们刚刚做了一个艰难的决定,Q讯聊天工具和365度电脑管家你只能挑一个。为此本台邀请了365度公司总裁周大炮来谈谈对Q讯此举的看看。
男播音:周总,你好,欢迎来到CCLV新闻直播室,相信你已经看看Q讯公司致用户的公开信,能谈谈你对此事的看法吗?
周大炮:我们能不能这么理解:选择365度是因为它能查毒,所以默认它进入系统,就像保姆能进入房间打扫一样;选择Q讯是因为它利于交流,就像司机能便利交通一样。那么如此,你一司机凭啥进我房间?我的保姆在我房间关你屁事?你还威胁我说如果我不辞退保姆,就把我的奔驰车开走。
男播音员:好,非常感谢周总光临我们的直播室。看来中国的互联网不是江湖,胜似江湖啊!(作点评状)
男播音员:观众朋友,现在我们对2010年做一个简单回顾。2010年,京沪高铁顺利通车,登月工程成功实施,两会顺利闭幕,上海世博圆满结束,亚运精彩广州绽放,舟曲泥石流冲不倒中国人的坚强,鬼子霸占钓鱼岛的阴谋彻底破产,长城永不倒,自强创辉煌,阳光总在风雨后,中国的2010很精彩,中国的2011值得期待,让我们携手共创2011的辉煌!今天的新闻联播节目到此结束,谢谢各位观看,再见。(男播音员起身准备离去)(这段朗读要讲究抑扬顿挫)
女播音员(以手势作阻止男播音员状):稍等稍等,最后插播条征婚启事,林志玲委托我给他的小马驹萌萌诚征另一半,年龄不限,收入不限,性别不限。
男播音员:快走啦,咱们的赶去主持赢在中国,据说那边也三聚氰胺中毒了。( 男播音员拽着女播音员下台)
女播音员:马上好马上好,国家兴亡,匹女有责
男播音员:还国家兴亡,匹马有责呢
女播音员:对对,匹马有责
一、分支
1、查看远程的分支
命令:git branch 事例 yuancandeMacBook-Pro-2:NJZ_Tourist yuancan$ git branch * master v1.3.0 命令:git branch -a 事例 yuancandeMacBook-Pro-2:NJZ_Tourist yuancan$ git branch -a * master v1.3.0 v1.3.1 remotes/origin/HEAD -> origin/master remotes/origin/master remotes/origin/v1.3.0 remotes/origin/v1.3.1 remotes/origin/v2.0.0 2、切换分支
命令:git checkout 分支名称 事例 yuancandeMacBook-Pro-2:NJZ_Tourist yuancan$ git checkout v1.3.0 Switched to branch 'v1.3.0' 3、合并分支
第一步:切换到主分支 yuancandeMacBook-Pro-2:NJZ_Tourist yuancan$ git checkout master Switched to branch 'master' 第二步:在主分支上合并分支 yuancandeMacBook-Pro-2:NJZ_Tourist yuancan$ git merge v1.3.0 Updating cfbdc69..9a80336 4、新建分支
命令:git branch 分支名称 事例 1、在本地新建一个分支 git branch v1.
:nth-child(even) 控制偶数样式
:nth-child(odd)控制奇数样式
:nth-child(2n+1)控制2n+1行样式
语法:
:nth-child(an+b)
下面就把CSS3标准中nth-child()用法大致介绍给大家:
CSS3伪类选择器:nth-child()
简单的归纳下nth-child()的几种用法。
第一种:简单数字序号写法
:nth-child(number)
直接匹配第number个元素。参数number必须为大于0的整数。
例子:
li:nth-child(3){background:blue;}
第二种:倍数写法
:nth-child(an)
匹配所有倍数为a的元素。其中参数an中的字母n不可缺省,它是倍数写法的标志,如3n、5n。
例子:
li:nth-child(3n){background:red;}
第三种:倍数分组匹配
:nth-child(an+b) 与 :nth-child(an-b)
先对元素进行分组,每组有a个,b为组内成员的序号,其中字母n和加号+不可缺省,位置不可调换,这是该写法的标志,其中a,b均为正整数或0。如3n+1、5n+1。但加号可以变为负号,此时匹配组内的第a-b个。(其实an前面也可以是负号,但留给下一部分讲。)
例子:
li:nth-child(3n+1){background:red;}
li:nth-child(3n+5){background:blue;}
li:nth-child(5n-1){background:yellow;}
li:nth-child(3n±0){background:green;}
li:nth-child(±0n+3){background:orange;}
第四种:反向倍数分组匹配
:nth-child(-an+b)
此处一负一正,均不可缺省,否则无意义。这时与:nth-child(an+1)相似,都是匹配第1个,但不同的是它是倒着算的,从第b个开始往回算,所以它所匹配的最多也不会超过b个。
例子:
li:nth-child(-3n+8){background:red;}
li:nth-child(-1n+8){background:blue;}
第五种:奇偶匹配
:nth-child(odd) 与 :nth-child(even)
分别匹配序号为奇数与偶数的元素。奇数(odd)与(2n+1)结果一样;偶数(even)与(2n+0)及(2n)结果一样。
作者观点:表格奇偶数行定义样式就可以写成
.table > tr:nth-child(even) > td {background-color: #f00;} (偶数行)
.table > tr:nth-child(odd) > td {background-color: #c00;} (奇数行)
jQuery中用此方法可以实现条纹效果:
$(“table tr:nth-child(even)”).addClass(“hangbg”);
even 可以换成别的参数,上面介绍的五种情况都可以。
后面的addClass(“hangbg”) hangbg 是个CSS class名称。
Kettle设置参数 通过js脚本设置参数变量并进行赋值,让参数变得可动态变化,便于后期定时任务的执行
生成记录 添加一个"输入->生成记录"对象,用于变量的声明
javascript代码 添加一个"脚本->Javascript脚本"对象,用于动态设置变量值(这里的例子我写的是动态获取日期参数,你可以根据你的需求进行定义和赋值,照葫芦画瓢就行)
Date.prototype.Format = function(fmt) { //author: meizz var o = { "M+": this.getMonth() + 1, //月份 "d+": this.getDate(), //日 "h+": this.getHours(), //小时 "m+": this.getMinutes(), //分 "s+": this.getSeconds(), //秒 "q+": Math.floor((this.getMonth() + 3) / 3), //季度 "S": this.getMilliseconds() //毫秒 }; if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); for (var k in o) if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.
Java脚本处理数据 当你在查这个问题时,说明大家还都是了解java开发的。其实最初使用kettle时还没注意到可以直接使用java代码进行数据处理,因为涉及到筛选数据,然后就各种添加字段处理、过滤等转换,写了十几个,结果当发现可以用java处理时,直接先写好java方法,然后打包成jar后丢到kettle里面就可以直接使用了,顿时觉得太爽了!哈哈哈
这里我贴了一个我自己写的用来格式化日期的方法,供亲参考学习,详细代码可点击下载。
准备工作 先写好java方法(这里根据自己实际情况自己写方法就行,我这边只说明方法,供参考) 注:java文件要指定包名
测试java编译是否成功(需要先在java文件写好main方法) E:\code\foresee\kt\java>java qiuqing.FormatUtils 将java方法编译后打包成jar文件 打开cmd,根据自己实际情况执行命令
E:\code\foresee\kt\java>javac qiuqing\FormatUtils.java E:\code\foresee\kt\java>jar cvf qiuqing-format.jar qiuqing\FormatUtils.class 测试jar包是否打包成功
需要用压缩工具打开jar包,修改jar包里面(qiuqing-format.jar\META-INF\MANIFEST.MF)文件,添加Main-Class配置,然后覆盖保存,最后打开cmd,执行cmd运行测试。 Manifest-Version: 1.0 Created-By: 1.8.0_51 (Oracle Corporation) Main-Class: qiuqing.FormatUtils 5.将打包好的jar包放到kettle目录下的lib文件夹内, 重新启动kettle
使用说明 转换中添加一个java脚本,双击打开
代码调用(以下代码仅供参考)
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.Locale; import qiuqing.FormatUtils; public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException { Object[] r = getRow(); if(r == null){ setOutputDone(); return false; } try{ String timeLocal = get(Fields.In,"time_local").getString(r); String request = get(Fields.
#include<stdio.h>
2 #include<string.h>
3 4 int main()
5 {
6 char a[30];
7 char b[30];
8 bzero(b,sizeof(b)); //bzero();函数用来清0,b数组;
9 char ch;
10 int i=0,k,j,g=0;
11 while((ch=getchar())!=EOF) //ctrl+d的值是EOF,所以用它判断字符输入结束
12 {
13 a[i]=ch;
14 i++;
15 }
16 for(k=0;k<i;k++)
17 {
18 int flag=0;
19 for(j=k-1;j>=0;j--) //遍历数组
20 {
21 if(a[j]==a[k])
22 {
23 flag=1;
24 }
25 }
26 if(flag==0)
27 {
28 b[g++]=a[k];
}
30 }
31 printf("%s",b);
32 return 0;
C++类有继承时,析构函数必须为虚函数。如果不是虚函数,则使用时可能存在内在泄漏的问题。
如果自己设计的C++类体系中存在继承关系,请注意父子类的析构函数关键字设置。虚函数是在基类中被声明为 virtual,并在派生类中重新定义的成员函数,可实现成员函数的动态重载。 当一个类作为基类时,它的析构函数应该为虚析构函数(基类析构函数前加virtual关键字),这样才能保证调用子类的析构函数。
如过基类的析构函数不是虚析构函数,所以是根据指针的类型调用析构函数,而不是根据指针指向对象的类型调用析构函数,此时就不能执行子类的析构函数了。
测试代码:
#include <string> #include <iostream> class BaseClass { public: BaseClass() : m_pValue(NULL) { } /*virtual */~BaseClass() { delete m_pValue; m_pValue = NULL; std::cout << "BaseClass virtual construct." << std::endl; } void SetValue(int v) { if (!m_pValue) { m_pValue = new int(v); } else { *m_pValue = v; } } private: int* m_pValue; }; class SubClass : public BaseClass { public: SubClass() : BaseClass() , m_pstrName(NULL) { } /*virtual */~SubClass() { delete m_pstrName; m_pstrName = NULL; std::cout << "
第一步:打印出当前的java.library.path有哪些目录:
执行 vi Test.java
切换编辑模式 i
插入如下代码:
public class Test { public static void main(String[] args) { System.out.println("java.library.path:-----------"); System.out.println(System.getProperty("java.library.path")); } } 退出编辑 ESC
保存并退出 :wq
执行javac Test.java
执行 java Test
返回:
第二步:配置环境变量(/etc/profile)
执行: vi /etc/profile
插入: i
在文件内容的最下面加入以下内容:
#set java environment JAVA_HOME=/usr/java/jdk1.8.0_73 JRE_HOME=/usr/java/jdk1.8.0_73/jre CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin LD_LIBRARY_PATH=$PATH:$JAVA_HOME/bin export JAVA_HOME JRE_HOME CLASS_PATH PATH LD_LIBRARY_PATH 如下图:
退出编辑: ESC 保存并退出: :wq
然后执行: source /etc/profile
这样可以使配置不用重启即可立即生效。
三、再查看现在的java.library.path
至此,结束。
http://www.m5home.com/blog/archives/2016/12/103.html 第一步是给root用户设置个密码.
我没试过空密码行不行,不折腾.
sudo passwd root
第二步是在配置文件里设置自启动:
1,编辑/etc/lightdm/lightdm.conf:
sudo gedit /etc/lightdm/lightdm.conf
[Seat:*]
autologin-guest=false
autologin-user=root
autologin-user-timeout=0
greeter-session=lightdm-gtk-greeter
2,编辑/root/.profile文件,增加tty -s &&:
sudo gedit /root/.profile # ~/.profile: executed by Bourne-compatible login shells.
if [ "$BASH" ]; then
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
fi
tty -s && mesg n || true
然后重启就行了.
关闭guest用户 $ sudo vi /usr/share/lightdm/lightdm.conf.d/50-ubuntu.conf Ubuntu安装完成默认是普通权限的用户,root用户需要手动开启,并且还不含opne-ssh模块
1.给root用户设置密码
# sudo passwd root
会提示输入unix的新密码,这就是root的密码
2.测试root用户登录
# sudo su 或者 su root
""" 把链表相邻元素翻转,例如给定链表1->2->3->4->5->6->7, 则翻转后的链表变为2->1->4->3->6->5->7 """ class LNode: def __init__(self): self.data = None self.next = None def reverse(head): """ 方法功能:把链表相邻元素翻转 :param head: :return: """ if head is None or head.next is None: return cur = head.next pre = head next = None while cur is not None and cur.next is not None: next = cur.next.next pre.next = cur.next cur.next.next = cur cur.next = next pre = cur cur = next if __name__ == '__main__': i = 1 head = LNode() tmp = None cur = head while i < 8: tmp = LNode() tmp.
一、概述
最硬核的java全栈知识体系学习: https://www.processon.com/u/601ce2e4e658154911df021b/profile#pc https://blog.csdn.net/qq_28245087/article/details/112061984 为了方便中小型企业想拥有自己的商城而设计,他不单单是一个网上商城,还是一个强大的线下商品进销存管理系统。
二、功能模块
1、用户功能模块 为了更好的对系统进行管理和维护,设定了不同权限的用户来管理商城系统,对商城进行商品的进销存管理,商品发布修改,订单的处理,发货管理,用户贯穿着整个商城系统。商城的用户设定了不同的角色,不同的角色拥有不同对商城的操作权限。商城的用户来源有自主注册、管理员添加、第三方来源。
用户分为:超级管理员、普通管理员、一般用户、会员用户。
用户的登录分为两块,一块是前端登录、另一块是后台登录。前端登录分为系统用户和第三方登录。后台管理登录可以是管理员和员工,管理员由超级管理员添加,员工由有操作权限的管理员添加。
2、单位管理 单位管理功能模块,主要是为了单位更好的管理下属单位和不同部门下的人员管理。通过系统的管理更方便的查询某部门下的员工信息以及部门的职责和任务。
3、商品管理 对商城添加商品和发布商品进行线上销售,功能包括商品的属性信息(价格、大小、库存、商品类别、商品图片、详情、类别、重量、负责人、上架时间、出售时间)等
4、库存管理
通过系统可以快速的定位到商品的具体位置、库存量、进出库时间、来源渠道方式、负责人。
5、购物车管理 主要是用户在商城上选择商品加入购物车,同时管理员也很清楚的查询到,加购的商品有那些,从而判断出用户的喜好及热销商品。
6、订单管理 用户在商城上选择好商品并提交了订单,这里管理员也很清楚的查看订单的状态。
7、支付管理 目前只做支付宝和微信支付,其他支付功能后续在跟进。
8、评论管理 只有购买过的商品才能进行评论。 9、积分管理 积分可通过充值获得、购物获得、朋友赠送得到。 10、商品分享管理 对喜欢的商品可以分享到QQ、微信、微博等第三方平台。 11、统计管理 按年、按月、按周、按天等不同时段统计出销售金额,并算出利润。统计出销售最好的商品,点击最高的商品列表、用户的访问来源监控统计,用户访问日志记录分析。
12、日志记录 对用户的访问时间、离开时间、查看那些商品、来源入口进行记录、管理员操作商品的记录。 13、配送管理 主要是货物的配送方式及物流跟踪。
以下所有内容基于个人理解,如有错误、纰漏请指出,谢谢。
1.基本思想:将有真相关的指令分隔到不同的循环周期内执行。
2.方法(以第6章第5题(2)为例):
(1) 寻找指令依赖的关键路径(即答案中的“数据流图”)
这里暂时不需要考虑循环控制部分(指令6-9)。
(2) 在这条关键路径(1->2->4->5)上指令的数量,就是做软件流水时需要展开循环的次数(原因:保证有相关的指令能被分隔到不同循环执行)。下面先关注这条关键路径。
显然,在原来的代码中,指令执行是按上表中每一列从上到下的顺序执行的。而软件流水,实际上把它改成了每一行从左到右执行。
这种执行顺序的更改为什么是正确的?原因是(1)中确定的依赖关系。上面表格中每条指令只依赖于在它上方的指令:指令1写寄存器F2;指令2读F2,写F4;指令4读F4,写F6;指令5读F6。从左向右的执行,依然能保证:每次指令1执行后,碰到的第一条指令2一定是依赖于它的指令2;指令2往后碰到的第一条指令4一定是依赖于它的指令4;指令4往后碰到的第一条指令5一定是依赖于它的指令5。
可能导致错误的情况是:同一个寄存器被不同指令写了。可以通过事先进行重命名解决这个问题。
取循环i-3的指令5,循环i-2的指令4,循环i-1的指令2和循环i的指令1构成软件流水的循环体。
(3) 不在关键路径上的指令怎么办?将它和某个关键路径上的指令绑定在一起(所谓绑定,意思是它们在软流水中取自同一个循环)。原则是:指令和与自己有相关的指令之间不能有间隔。
在这个例子里,指令3和指令4之间有相关,它们之间不能有间隔。因此指令3要和指令2绑定在一起。这里说明一下,参考答案里的指令3和指令1绑定的图是不正确的。
不能有间隔的原因:假如3和1取自同一循环,指令4要使用3(蓝色圈)的结果,但是从左往右执行时,这个结果会被另一个3(红色圈)覆盖。而如果3和2取自同一循环就不会出错。
(4) 于是我们可以得到下面的表
其中高亮部分是软件流水的主体循环代码,上方是装入代码,下方是排空代码。
下面终于可以写代码了!激动!
(5) 四次循环展开,然后按照上面的规则取出我们需要的指令:
是不是豁然开朗!不是也没关系!仔细感受一下!
注意:指令3的目标寄存器已经被重命名成F8了,原因在(2)的末尾提过了。
(6) 我们基本上已经把循环写出来了,除了……循环。
这是用来控制循环的4条代码。显然6和7不变,它们的作用和for循环里的i++一样。第8条指令Set Greater Than,当R1大于800的时候,R3 = 1;然后第9条指令根据R3的值确定是否跳转。
回顾一下(4)中的表格:主体循环结束后,代码中已经没有指令1了。也就是说,最后一次执行指令1,对应的是最后一次循环。
软件流水的正确性的关键在于保证软件流水后的代码和原来的代码逻辑相同。回顾原来的代码:最后一次执行指令1,对应的也是最后一次循环。
综合上面两段的意思,软件流水代码的最后一次循环中执行的L.D F2, 0(R1),与原来代码中最后一次循环执行的L.D F2, 0(R1)应该取同一个内存地址的数。因此两个R1应该是相等的,第8条指令不需要改变。
最后一件事:延迟槽。指令9后有一个延迟槽,需要找一条指令来填充。第7条是最优的,因为它和8, 9没有相关关系。于是软件流水代码如下:
假如我们这里是把第6条填到了延迟槽里,那指令8中的800应该修改为792。为什么?留作思考题,感兴趣的又不是很明白的同学可以来问我。(我真是有毒)
(7) 到现在我们已经完成了这个题目的要求。现在可以尝试写一下装入和排空代码。
我先把上面的表格和代码搬运下来:
这里其实可以直接按照表格把代码写下来:
但是注意:整个程序第一次取到的应该是0(R1)和0(R2)的值,因此要对装入代码的偏移量进行修正。最简单粗暴的办法是:
当然,如果这个看起来太诡异了,也可以把它们放在后面:
这里装入和排空代码和答案上不完全一样,因为在没有相关时这些指令都可以进行调度,遇到具体的情况时具体做就可以了。
3.验证
验证自己的填写的偏移量是否正确:
给R1,R2设定一个初始值(建议刚好使原循环需要执行的次数与上述过程中展开次数相同,如R1=R2=768刚好能使循环执行4次),计算load/store指令的内存地址,比较原循环和软件流水中的内存地址是否相同。
参考资料:
[1] 胡伟武等. 计算机体系结构[M]. 2017.
[2] 习题课_第6章[S]. 2018.
[3] 第6章到第9章参考答案[H]. 2018.
[4] 循环的软流水原理和实例展示[EB/OL]. csdn链接
致谢 全文出自:hc大佬 hithub
邮箱:huangcheng14@mails.ucas.edu.cn
查看JS Object对象信息 //假设_obj 是要查看的对象 var property = ""; for (var item in _obj ) { property += "属性:" + item + "数值:" + _obj [item] + "\n"; } console.log(property) 今天碰到的问题,顺便记录一下
转载自:https://blog.csdn.net/sinat_21813453/article/details/80267684
以前一直都在学习springmvc的框架,这次要学习一下新技术,spring boot。
发现部署项目之后,能够正常运行,但是无论输入什么都是404,也不提示什么,就一行404,网上看了好多大神的帖子,发现都无济于事,然后我突发奇想,把idea的所有依赖库都删除掉。
然后重新下载,
然后重启一下就没问题了。
记得配置文件一定要配置好。
参考博文:https://blog.csdn.net/gwcgwcjava/article/details/46722907
对于我通过response.getOutputStream的方式下载文件,为文件设置文件名
//1.设置文件ContentType类型,这样设置,会自动判断下载文件类型 response.setContentType("multipart/form-data"); //2.设置文件头:最后一个参数是设置下载文件名(假如我们叫a.pdf) response.setHeader("Content-Disposition", "attachment;fileName="+"a.pdf");