目录
计算机组成原理:
数据表示
1. 基本概念
- 真值:+0101,-0100
- 机器数: [x]原=0101
2. 几种机器数
- 原码:x = -0101,[x]原 = 1101
- 反码:x = -0101,[x]反 = 1010
- 补码:x = -0101,[x]补 = 1011
- 移码:x = -0101,[x]移 = 2^n + x = 0011
PS:这里说说对补码与移码自己的理解。补码是为了化减法为加法方便计算机设计运算,移码是为了方便比较大小,用在浮点数的阶码中。
补码—— 任何一个有模的系统中,减法都可以通过加其补码来表示。最简单的例子就是以12为模的钟表, 比如现在是3点,那么-5个小时就等于+7个小时,都是10点。这里7就是5的补码。
移码——数据对应关系一次挪动一下位置,使得看起来小的数真值也小。比如原本0000表示0,现在表示-128,然后0001表示-127,一直到1111表示+127,这样就方便比较了。
3. 定点数与浮点数
定点数:小数点固定 x.xxxxxx,表示范围受限,忘掉它吧
浮点数:数的范围和精度分别表示。
一般格式 :EEEE......EMMM.......M,E部分是阶码(数的范围i),M部分是尾数(数的精度)。缺点:阶码和尾数位数不固定,太灵活了 (可能有误差
IEEE754格式:跟我背下来----
32位的是(单精度):1位符号位S + 8位偏指数E + 23位有效尾数M,偏移值为127。
64位的是(双精度):1位符号位S + 11位偏指数E + 52位有效尾数M,偏移值为1023。
真值就是(32位为例) N = (-1)^S * 2^(E-127) * 1.M
浮点数的特殊情况:
E=0,M=0:机器零
E=255,M=0:无穷大,对应于x/0
E=255,M!=0:非数值NaN,对应0/0
ps:附上一份IEEE754文档:https://files.cnblogs.com/files/flashsun/7542008-2008.pdf
4. 数据校验
基本原理:增加冗余码
码距:合法编码之间不同二进制位数的最小值
码距与检错、纠错能力:
-
- 码距 d>=e+1:检查e个错误
- 码距 d>=2t+1:纠正t个错误
- 码距 d>=e+t+1:同时检查e个错误,并纠正t个错误。(e>=t)
PS:这里说下我的理解,增加码距就是增加非法编码的数量,看到非法编码就算检查出错误了,而非法编码距离哪个合法编码比较进就认为正确的应该是什么(简单理解,可参考下面的图),也就是可以纠正错误。这里看到过一个好的几何理解图,仔细品味下:
举个例子:比如一共有8位,码距为1则检查不出任何错误,因为所有编码都是合法编码。如果码距为2,那合法编码应该像 00000000,00000011,00001100,00001111这样,那如果出现00000001这样的非法编码就出错了,可检查一位错,但如果两位同时错了,则有可能又跳到另一个合法编码上了,就检查不出2位错。
那如果码距是3,那合法编码应该像 00000000,00000111,00111000,00111111 这样,那如果出现一位错 00000001,或者两位错00000011,都是非法编码,都能检查出错误,并且此时可以纠正00000001为00000000,纠正00000011为00000111。但是三位同时错就检查不出了。
常见校验策略:奇偶校验,CRC校验,海明校验
ps:海明编码最强视频演示教程:https://www.youtube.com/watch?
该部分转载于:【重学计算机】计算机组成原理 - 闪客sun - 博客园
数据库部分:
--针对bookshop数据库:
--1、 创建一个视图cust_view,该视图只含收件人姓张的客户信息。(10分)
create view cust_view
as
select *
from customer
where receiver like '张%'
--2、 利用cust_view视图分别添加一条姓张的和不姓张的顾客数据。(注意:分别查看customer表和该视图的结果。)(15分)
insert into cust_view values('ab','张强',1,'')
insert into cust_view values('abc','不姓张',1,'')
--3、 创建一个视图cust_view1,该视图只含收件人姓张的客户信息,带with check option 子句。(10分)
create view cust_view1
as
select *
from customer
where receiver like '张%'
with check option
--4、 利用cust_view1视图分别添加一条姓张的和不姓张的顾客数据。(注意:分别查看customer表和该视图的结果。)(15分)
insert into cust_view1 values('abcd','张强',1,'')
insert into cust_view1 values('abccde','不姓张',1,'')
--5、 通过视图cust_view删除所有姓张的收件人且名字为2个汉字的客户数据。(10分)
delete
from cust_view
where receiver like '张_'
--6、 通过视图cust_view修改表内某一客户的姓名(请给出以下几种情况进行测试:1、customer表中不存在的一个客户;2、customer表中存在且没有销售记录的一个客户;3、customer表中存在且有销售记录的一个客户。)(15分)
update cust_view
set cust_name = '张'
where cust_name = 'x'
update cust_view
set cust_name = '张'
where cust_name = 'zhangtao'
update cust_view
set cust_name = '张'
where cust_name = 'zbowen'
--7、 从基本表employee和sales,创建一个视图sales_view,该视图包含业务员的编号、姓名、销售总金额。(10分)
create view sales_view(业务员编号 , 姓名 , 销售总额)
as
select emp_no , emp_name , sum(total_amt)
from employee , sales
where employee.emp_no = sales.sale_id
group by emp_no , emp_name
--8、 将上述视图中E0017业务员的销售总金额改为6000元。能成功吗?如果失败说明原因。(10分)
update sales_view
set 销售总额 = 6000
where 业务员编号 = 'E0017'
--不能成功 , 修改视图实际上是修改基本表 , 但是基本表里面没有销售总金额这一类
--对视图或函数 'sales_view' 的更新或插入失败,因其包含派生域或常量域。
--9、 删除上述所有已经创建的视图。(5分)
drop view cust_view , cust_view1 , sales_view
leetcode每日一题:
一道怎么看 , 怎么像的 dp 动态规划 题. 但是关键是怎么进行状态转移.
我需要去救公主 , 而且我又不能死 , 还要花费最小的血量. 在每一个坐标 , 我都希望「从出发点到当前点的路径和」尽可能大(使得我后面能够花费的血量最少 , 才能使我救到公主),而「从出发点到当前点所需的最小初始值」尽可能小. 一般的 dp 很难满足两种状态量的转移. 所以公主不救了 , 摆烂.
这时公主大喊一声: 傻x , 等着 , 我去找你. 逆向思维的话 就只需要得到「存活在该点 , 之前需要的最少的血量」, 为什么不需要「从出发点的最大路径和」呢? 因为逆向走到该点就已经满足了我能够用当前血量救到公主(简而言之就是 , 这就是我从该点到公主所在位置的最小权值 , 所以我根本不需要该点的最大路径让花费的血量最少 , 因为我已经是花费最少的情况了). 此外 , 因为我的血量至少为1才能存活 . 所以 , 就存在状态转移 -- dp[i][j] = max(1 , min(dp[i + 1][j] , dp[i][j + 1]) - dungeon[i][j]) .取 max(1) 的原因是: 当我需要的血量是负数时 , 也就是我捡了很多的血量 , 使得我在改节点只需要负的血量就能使我到达公主的位置 .这显然是不合理的 , 因为我们最少的血量都要为1.
于是 , 公主成功找到了我.
class Solution {
public:
int calculateMinimumHP(vector<vector<int>>& dungeon) {
int n = dungeon.size() , m = dungeon[0].size();
vector<vector<int>>dp(n + 1 , vector<int>(m + 1 , INT_MAX));
dp[n][m - 1] = 1 , dp[n - 1][m] = 1;
for(int i = n - 1;i >= 0;i --){
for(int j = m - 1;j >= 0;j --){
dp[i][j] = max(1 , min(dp[i][j + 1] , dp[i + 1][j]) - dungeon[i][j]);
}
}
return dp[0][0];
}
};
Java学习:
ArrayList 数组:
1.声明ArrayList数组
ArrayList<auto> arrayList = new ArrayList<auto>();
//auto : Boolean Byte Short Integer Long Float Double Character
2.添加元素
arrayList.add(int , auto);
//int -> 位置 , auto -> 数据
3.将一个数组中的全部数据添加到另一个里面
arrayList.addAll(int , ArrayList);
//int -> 位置 , ArrayList -> 相同类型数组
4.数组清空
arrayList.clear();
5.拷贝
ArrayList<String> cloneSites = (ArrayList<String>)sites.clone();
//类c++vector<int>b = a;
6.判断数组中是否存在x
boolean bo = arrayList.contains(x);
7.删除符合条件的数组元素
sites.removeIf(e -> e.contains("Tao"));
numbers.removeIf(e -> (e % 2) == 0);;
8.赋值
auto array = arrayList.get(n) <=> (c ++)auto array = array[n];
9.长度,是否为空
arraylist.size() , arraylist.isEmpty();
10.查找第一个匹配字符 , 查找最后一个匹配字符
arraylist.indexOf(auto) , arraylist.lastindexOf(auto);
11.删除某等值元素
arraylist.remove(auto);
12.保留重叠部分
arraylist.retainAll(sites);
13.修改元素
arraylist.set(int , auto);
//int 表示下标
我有一壶酒 可以慰风尘.