etcd的项目:https://github.com/coreos/etcd/releases/tag/v3.2.10 ,下载最新版本etcd。
系统:
etcd-1:192.168.159.129
etcd-2:192.168. 159.130
etcd-3:192.168. 159.131
1.在windows环境下下载etcd-v3.2.10-linux-amd64.tar.gz,并提供etcd命令。
通过putty或MobaXterm将压缩包上传到三个linux系统中,再进行解压。
tar –xzvf ext etcd-v3.2.10-linux-amd64.tar.gz
cd etcd-v3.2.10-linux-amd64
cp etcd etcdctl /user/local/bin/
2.在三个节点上创建etcd数据目录。
mkdir –p /var/lib/etcd
3.在每个节点上创建etcd的配置文件
首先在每个节点上创建目录和文件,sudo vi /etc/etcd/etcd.yml,打开文件进行配置。
name : etcd-1
data-dir : /var/lib/etcd
initial-advertise-peer-urls : http://192.168.159.129:2380
listen-peer-urls : http://192.168.159.129:2380
listen-client-urls : http://192.168.159.129:2379,http://127.0.0.1:2379
advertise-client-urls : http://192.168.159.129:2379,http://127.0.0.1:2379
initial-cluster-token : etcd-cluster-token
initial-cluster : etcd-2=http://192.168.159.130:2380,etcd-1=http://192.168.159.129:2380,etcd-3=http://192.168.159.131:2380
initial-cluster-state : new
name : etcd-2
data-dir : /var/lib/etcd
listen-client-urls : http://192.168.159.130:2379,http://127.0.0.1:2379
advertise-client-urls : http://192.168.159.130:2379,http://127.0.0.1:2379
listen-peer-urls : http://192.168.159.130:2380
initial-advertise-peer-urls : http://192.168.159.130:2380
initial-cluster : etcd-1=http://192.168.159.129:2380,etcd-2=http://192.168.159.130:2380,etcd-3=http://192.168.159.131:2380
initial-cluster-token : etcd-cluster-token
initial-cluster-state : new
name : etcd-3
initial-advertise-peer-urls : http://192.168.159.131:2380
listen-peer-urls : http://192.168.159.131:2380
listen-client-urls : http://192.168.159.131:2379,http://127.0.0.1:2379
advertise-client0urls : http://192.168.159.131:2379,http://127.0.0.1:2379
initial-cluster-token : etcd-cluster-token
initial-cluster : etcd-2=http://192.168.159.130:2380,etcd-1=http://192.168.159.129:2380,etcd-3=http://192.168.159.131:2380
initial-cluster-state : new
data-dir : /var/lib/etcd
系统默认的etcd版本是2.x,需要在/etc/profile 这个全局变量文件里加入export ETCDCTL_API=3
保存。
输入命令 source profile
系统重读配置文件
4.启动服务,进行测试
执行sudo etcd --config-file=/etc/etcd/etcd.yml &
命令,启动三个节点上的etcd服务。
启动成功后,进行测试。
在etcd-1上输入指令 etcdctl put xuelei 123
,在etcd-2上输入指令etcdctl get xuelei
,看etcd-2上能否获取到键值对。
5.注意
① 可以下载MobaXterm来链接Linux系统,这样可以方便执行粘贴复制。
② 可以通过MobaXterm或putty将压缩包上传到Linux系统。
③ sudo apt-get install xx 可以安装缺少的指令。
④ 在编写配置文件时注意,数据均为JSON格式,是键值对,在 : 前后需加上空格,否则会报错误。
6.etcd集群搭建必需配置参数
参数 | 描述 | 默认/推荐设置 |
---|---|---|
name | etcd实例的名称 | |
data-dir | 数据保存的路径 | |
listen-client-urls | 对外提供服务的地址 | http://ip:2379, http://127.0.0.1:2379 |
listen-peer-urls | 和同伴通讯的地址 | http://ip:2380 |
advertise-client-urls | 对外公布的该节点客户端监听地址 | http://ip:2379, http://127.0.0.1:2379 |
initial-advertise-peer-urls | 该节点同伴监听地址 | http://ip:2380 |
initial-cluster | 集群中所有节点的信息 | |
initial-cluster-token | 创建集群的token | 这个token需要在集群中保持唯一 |
initial-cluster-state | 集群状态 | 新创建集群的时候,这个值为new,已存在的集群,这个值为existing |
SQL的语言分类
DQL(Data Query Language):数据查询语言 select
DML(Data Manipulate Language):数据操作语言 insert 、update、delete
DDL(Data Define Languge):数据定义语言 create、drop、alter
TCL(Transaction Control Language):事务控制语言 commit、rollback
1.数据库的好处
(1)可以持久化数据到本地
(2)结构化查询
2.数据库的常见概念
DB:数据库,存储数据的容器
DBMS:数据库管理系统,又称为数据库软件或数据库产品,用于创建或管理DB
SQL:结构化查询语言,用于和数据通信的语言。
3.数据库存储的特点
(1)数据库存放到表中,然后表再放到库中
(2)一个库可以有多张表,每张表具有唯一的表名用来标识自己
(3)表中有一个或多个列,即“字段,相当于java中的属性
(4)表中的每一行数据,相当于java中“对象”
4.MySQL的优点
(1) 开源、免费、成本低
(2) 性能高、移植性也好
(3) 体积小,便于安装
5.MySQL服务的启动和停止
方式一:计算机—右键管理—服务
方式二:通过管理员身份运行
net start 服务名 (启动服务)
net stop 服务名 (停止服务)
6.MySQL服务的登陆和退出
方式一:通过mysql自带的客户端,只限于root用户
方式二:通过windows自带的
登陆:mysql [-h 主机名 -P端口号] -u用户名 -p密码
退出:exit 或 ctrl+c
7.MySQL的常见命令
(1)查看当前所有的数据库
show database;
(2)打开指定的库
use 库名
(3)查看当前库的所有表
show tables;
(4)查看其他库的所有表
show tables from 库名;
(5)创建表
create table 表名(
列名 列类型,
…
);
(6)查看表结构
desc 表名;
(7)查看服务器的版本
方式一:登陆到Mysql服务端
select version();
方式二:没有登录到Mysql服务端
mysql –version 或 mysql -V
8.MySQL的语法规范
1.不区分大小写,但建议关键字大写,表名、列名小写
2.每条命令最好用分号结尾
3.每条命令根据需要,可以进行所街或换行
4.注释
单行注释:#注释文字
单行注释:– 注释文字
多行注释:/* 注释文字 */
语法
select 查询列表
from 表名
【where 筛选条件】
group by 分组的字段
【having 分组胡的筛选】
【order by 排序列表】 【asc desc】
筛选条件的分类
(1).简单条件运算符
> < = <> != >= <= <=>安全等于
(2).逻辑运算符
&& and
or ! not
(3).模糊查询
like:一般搭配通配符使用,用于判断字符型数值或数值型
通配符:%任意多个字符,_任意单个字符
between and
in
is null / is not null
is null pk <=>
is null :仅仅可以判断null值,可读性较高。
<=>:既可以判断null值,又可以判断普通的数值,可读性较低。
去重
select distinct id from user;
+的作用
mysql里仅仅只有一个功能:运算符
select 100+90;
select ‘123’+90;其中一方为字符型,若转换成功则继续做加法运算
select ‘john’+90;若转换失败,则将字符型转换为0
select null+0; 若其中一方为null,则结果肯定为null
查询员工名和姓连接成一个字段,并显示为 姓名
select concat(‘a’,’b’,’c’);
ifnull(money,0)
如果为null,则为0
isnull函数
如果为null,返回1,否则返回0
10.单行函数
字符函数:
length 字符串长度
concat 连接字符串
substr 截取字符串
instr 查看字符串中某子字符串位置
trim 去前后相同字符
upper
lower
lpad 左填充
rpad 右填充
数学函数:
round 四舍五入
ceil 向上取整
floor 向下取整
truncate 截断
rand 获取随机数,返回0-1之间的小数
mod 求模
日期函数:
now
curdate curtime
year month
monthname 以英文形式返回月
day hour minute second
str_to_date
date_format
datediff 求相差天数
其他函数:
version
database
user
password(‘字符’) 返回该字符的密码形式
md5(‘字符’) 返回该字符的md5加密形式
控制函数:
if(条件表达式,表达式1,表达式2)
case
case 变量或表达式或字段
when 常量1 then 值1
…
else 值n
end
case 变量或表达式或字段
when 条件1 then 值1
…
else 值n
end
11.分组函数
sum 求和
avg 平均值
max 最大值
min 最小值
count 计算个数
(1)
sum、avg处理数值类型
max、min、count可以处理任何类型
(2)都忽略null值
(3)可以和distinct搭配实现去重的运算
(4)统计行数,效率
count(字段):统计该字段非空值的个数
count(*):统计结果集的行数
MYISAM存储引擎下,count(*)的效率最高
INNODB存储引擎下,count(*)和count(1)的效率差不多,比count(字段)要高一些
(5)和分组函数一同查询的字段要求是group by后的字段
可以先写select,from,gourp by,再写where,having
1.分组查询中的筛选条件分为两类
①分组函数做条件肯定是放在having子句中。
②能用分组前筛选的,就优先考虑使用分组前筛选。
数据源 | 位置 | 关键字 | |
---|---|---|---|
分组前筛选 | 原始表 | group by子句的前面 | where |
分组后筛选 | 分组后的结果集 | group by子句的后面 | having |
2.group by子句支持单个字段分组,多个字段分组(多个字段之间用逗号隔开没有顺序要求)
3.也可以添加排序(排序放在整个分组查询的最后
12.分组查询
select 分组函数,列 (要求出现在group by的后面)
from 表
【where 筛选条件】
group by 分组的列表
【order by 子句】
select avg(salary),department_id,job_id
from employees
gourp by job_id,department_id
having avg(salary)>10000
order by avg(salary) desc;
13.进阶6:连接查询
含义:又称多表查询,当查询的字段来自多个表时,就会用到多表查询
笛卡尔乘积现象:当查询多个表时,没有添加有效的链接条件,导致多个表所有行实现完全连接。
发生原因:没有有效的连接条件
如何避免:添加有效的连接条件
按功能分类:
内连接:
等值连接、非等值连接、自连接
外链接:
左外连接、右外连接、全外连接(mysql不支持)
交叉连接
(1) SQL92语法
①等值连接
select 查询列表 from 表1 别名,表2 别名
where 表1.key = 表2.key
【and 筛选条件】
【group by 分组字段】
【having 分组后的筛选】
【order by 排序字段】
特点:
a.一般为表其别名
b.多表的顺序可以调换
c.n表连接至少需要n-1个连接条件
d.等值连接的结果是多表的交集部分
②非等值连接
select 查询列表 from 表1 别名,表2 别名
where 非等值的连接条件
【and 筛选条件】
【group by 分组字段】
【having 分组后的筛选】
【order by 排序字段】
③自连接
select 查询列表 from 表1 别名1,表1 别名2
where 等值的连接条件
【and 筛选条件】
【group by 分组字段】
【having 分组后的筛选】
【order by 排序字段】
(2) SQL99语法
select 查询列表
from 表1 别名 【连接类型】
join 表2 别名
on 连接条件
【where 筛选条件】
【group by 分组】
【having 筛选条件】
【order by 排序列表】
【limit 子句]
分类:
内连接:inner
外连接:
左外:left 【outer】
右外:right 【outer】
全外:full 【outer】
交叉连接:cross
①内连接
分类:
等值、非等值、自连接
特点:
①表的顺序可以调换
②内连接的结果 = 多表的交集
n表连接至少需要n-1个连接文件
②外连接
应用场景:用于查询一个表中有,另一个表没有的记录
特点:
a.外连接的查询结果为主表中的所有行
如果从表中有和它匹配的,则显示匹配的值
如果从表中没有和它匹配的,则显示null
外连接查询结果 = 内连接结果 + 主表中有而从表没有的记录
b.左外连接,left join 左边的是主表
右外连接,right join 右边的是主表
全外连接,full join 两边都是主表
c.左外和右外交换两个表的顺序,可以实现同样的效果。
d.全外连接 = 内连接的结果 + 表1中有但表2没有的 + 表2中有但表1没有的。
e.一般用于查询除了交集部分的剩余的不匹配的行。
③交叉连接
特点:
类似于笛卡尔积
(3) sql92和sql99 PK
功能:sql99支持的较多。
可读性:sql99实现连接条件和筛选条件的分离,可读性较高。
14.进阶7:子查询
含义:
嵌套在其他语句中的select语句,成为子查询或内查询;
外面的语句可以使insert、update、delete、select等,一般select作为外面语句较多。
分类:
按子查询出现的位置:
select后面:
仅仅支持标量子查询
from后面:
支持表子查询
where或having后面:
标量子查询 (单行) √
列子查询 (多行) √
行子查询
exists后面 (相关子查询):
标量子查询
列子查询
行子查询
表子查询
按结果集的行列数不同:
标量子查询 (结果集只有一行一列)
列子查询 (结果集只有多行一列)
行子查询 (结果集有多行多列)
表子查询 (结果集一般为多行多列)
where或having后面
特点:
a.子查询放在小括号内
b.子查询一般放在条件的右侧
c.标量子查询,一般搭配着单行操作符使用
> < >= <= = <>
列子查询,一般搭配着多行操作符使用
in、any/some、all
d.子查询的执行优先于主查询执行,主查询的条件用到了子查询的结果
(1)标量子查询
案例:返回job_id与141号员工相同,salary比143号员工多的员工 姓名、job_id和工资
#①查询141号员工的job_id
select job_id
from employees
where employee_id=141
#②查询143号员工的salary
select salary
from employees
where employee_id=143
#③查询员工的姓名,job_id和工资,要求job_id=①并且salary=②
select last_name,job_id,salary
from employees
where job_id = (
select job_id
from employees
where employee_id=141
) and salary>(
select salary
from employees
where employee_id=143
);
案例:查询最低工资的员工姓名和工资
①最低工资
select min(salary) from employees
②查询员工的姓名和工资,要求工资=①
select last_name,salary
from employees
where salary=(
select min(salary) from employees
);
(2)列子查询(多行子查询)
案例:返回location_id是1400或1700的部门中的所有员工姓名
#①查询location_id是1400或1700的部门编号
select distinct department_id
from departments
where locaion_id in(1400,1700)
#②查询员工姓名,要求部门号是①列表中的某一个
select last_name
from employees
where department_id in ( --也可替换为 = any
select distinct department_id
from departments
where locaion_id in(1400,1700)
);
案例:查询所有的是领导的员工姓名
①查询所有员工的manager_id
select distinct manager_id from employees
②查询姓名,employee_id属于①列表的一个
select from employees
where employee_id in(
select manager_id from employees
);
(3)行子查询(结果集一行多列或多行多列)
案例:查询员工编号最小并且工资最高的员工信息
select *
from employees
where (employee_id,salary)=(
select min(employee_id),max(salary)
from employees
);
15.进阶8:分页查询
应用场景:当要显示的数据,一页显示不全,需要分页提交sql请求
语法:
select 查询列表 7
from 表 1
join type join 表2 2
on 连接条件 3
where 筛选条件 4
group by 分组字段 5
having 分组后的筛选 6
order by 排序的字段 8
limit offset,size; 9
-- offset要显示条目的起始索引(起始索引从0开始)
-- size 要显示的条目个数
特点:
①limit语句放在查询语句的最后
②公式
要显示的页数page,每页的条目数size
select 查询列表
from 表
limit (page-1)*size,size;
16.进阶8:联合查询
union 联合 合并:将多条查询语句的结果合并成一个结果
语法:
查询语句1
union
查询语句2
union
...
应用场景:
要查询的结果来自于多个表,且多个表没有直接的连接关系,但查询的信息一致时
特点:
①要求多条查询语句的查询列数是一致的
②要求多条查询语句的查询的每一列的类型和顺序最好一直
③union关键字默认去重,如果使用union all 可以包含重复项
1.插入
方式一
语法:
insert into 表名(字段名...) values(值...);
特点:
(1) 要求值的类型和字段的类型要一致或兼容
(2) 字段的个数和顺序不一定与原始表中的字段个数和顺序一致
但必须保证值和字段一一对应
(3) 假如表中有可以为null的字段,注意可以通过以下两种方式插入Null值
①字段和值都省略
②字段写上,值使用null
(4) 字段和值的个数必须一致
(5) 字段名可以省略,默认所有列
方式二
语法:
insert into 表名 set 字段=值,字段=值,…;
两种方式的区别:
1.方式一支持一次插入多行,语法如下
insert into 表名 values(值,…), (值,…),… ;
2.方式一支持子查询,语法如下:
insert into 表名 查询语句:
2.修改
修改单表的记录
语法:
update 表名 set 字段=值,字段=值 【where 筛选条件】;
修改多表的记录
语法:
update 表1 别名
left right inner join 表2 别名 on 连接条件
set 字段=值,字段=值
【where 筛选条件】;
3.删除
方式一:使用delete
(1)删除单表的记录
语法:delete from 表名 【where 筛选条件】 【limit 条目数】
(2)级联删除
delete 别名1,别名2 from 表1 别名1
inner left right join 表2 别名2 on 连接条件
【where 筛选条件】
方式二:使用truncate
语法:truncate table 表名
两种方式的区别【面试题】
1.truncate删除后,如果再插入,标识列从1开始
delete删除后,如果再插入,标识列从断点开始
2.delete可以添加筛选条件
truncate不可以添加筛选条件
3.truncate效率较高
4.truncate没有返回值
delete可以返回受影响的行数
5.truncate不可以回滚
delete可以回滚
1、库的管理
1.创建库
create database 【if not exists】 库名 【character set 字符集名】;
2.修改库
alter database 库名 character set 字符集名;
3.删除库
delete database 【if exists】 库名;
2、表的管理
1.创建表
create table 【if not exists】表名(
字段名 字段类型 【约束】,
...
);
2.修改表
(1)添加列
alter table 表名 add column 列名 类型 【first|after 字段名】
(2)修改列
alter table 表名 modify column 列名 新类型 【新约束】;
(3)修改列名
alter table 表名 change column 旧列名 新列名 类型;
(4)删除列
alter table 表名 drop column 列名;
(5)修改表名
alter table 表名 rename 【to】 新表名;
3.删除表
drop table 【if exists】表名
4.复制表
(1)复制表的结构
create table 表名 like 旧表;
(2)复制表的结构+数据
create table 表名
select 查询列表 from 旧表 【where 筛选】;
3、数据类型
1.数值型
(1)整型
tinyint | smallint | mediumint | int/integer | bigint | |
---|---|---|---|---|---|
字节 | 1 | 2 | 3 | 4 | 8 |
特点:
①都可以设置无符号和有符号,默认有符号,通过unsigned设置无符号
②如果超出了范围,会报out or range 异常,插入临界值
③长度可以不指定,默认会有一个长度
长度代表显示的最大宽度,如果不够则左边用0填充,但需要搭配zerofill,并且默认变为无符号类型
(2)浮点型
定点数:decimal(M,D)
浮点数:
float(M,D) 4
double(M,D) 8
特点:
①M代表整数部位+小数部位的个数,D代表小数部位
②如果超出范围,则保 out or range异常,并且插入临界值
③M和D都可以胜率,但对于定点数,M默认为10,D默认为0
④如果精度要求较高,则优先考虑使用定点数
(3)字符型
char、varchar、binary、varbinary、enum、set、text、blob
char:固定长度的字符,写法为char(M),最大长度不能超过M,其中M可以省略,默认为1
varchar:可变长度的字符varchar(M),最大长度不能超过M,其中M可以省略
4、常见的约束
not null | 非空,该字段的值必填 |
---|---|
unique | 唯一,该字段的值不可重复 |
default | 默认,该字段的值不用手动插入就有默认值 |
check | 检查,mysql不支持 |
primary key | 主键,该字段的值不可重复并且非空 |
froeign key | 外键,该字段的值引用了另外的表的字段 |
主键和唯一的区别【面试题】
区别:
1.一个表至多有一个主键,但可以有多个唯一
2.主键不允许为空,唯一可以为空
相同点:
都具有唯一性
都支持组合键,但不推荐
外键
1.用于限制两个表的关系,从表的字段值引用了主表的某字段值
2.外键列和主表的被引用列要求类型一致,意义一样,名称无要求
3.主表的被引用列要求是一个key(一般就是主键)
4.插入数据,先插入主表
删除数据,先删除从表
方式一:级联删除
alter table stuinfo add constraint fk_stu_major foreign key(majorid) references major(id) on delete cascade;
方式二:级联置空
alter table stuinfo add constraint fk_stu_major foreign key(majorid) references major(id) on delete set null;
2.创建表时添加约束
create table 表名(
字段名 字段类型 not null,
字段名 字段类型 unique,
constraint 约束名 foreign key(字段名) reference 主表 (被引用列)
);
注意:
支持类型 | 可以起约束名 | |
---|---|---|
列级约束 | 除了外键 | 不可以 |
表级约束 | 除了非空和默认 | 可以,但对主键无效 |
列级约束可以在一个字段上追加多个,中间用空格隔开,没有顺序要求。
3.修改表时添加或删除约束
(1)非空
添加非空
alter table 表名 modify column 字段名 字段类型 not null;
删除非空
alter table 表名 modify column 字段名 字段类型;
(2)默认
添加默认
alter table 表名 modify column 字段名 字段类型 default 值;
删除默认
alter table 表名 modify column 字段名 字段类型;
(3)主键
添加主键
alter table 表名 add 【constraint 约束名】 primary key(字段名);
删除主键
alter table 表名 drop primary key;
(5)唯一
添加唯一
alter table 表名 add unique(字段名);
删除唯一
alter table 表名 drop index 索引名;
(5)外键
添加外键
alter table 表名 add foreign key(字段名) references 主表(被引用列);
删除外键
alter table 表名 drop foreign key 约束名;
1、事务:一条或多条sql语句组成一个执行单位,一组sql语句要么都执行,要么都不执行。
2、特点(ACID):
A.原子性(Atomicity):一个事务是不可再分割的整体,要么都执行要么都不执行;
B.一致性(Consistency):一个事务可以使数据从一个一致状态切换到另外一个一致的状态;
C.隔离性(Isolation):一个事务不受其他事务的干扰,多个事务互相隔离的;
D.持久化(Durubility):一个事务一旦提交了,则永久的持久化到本地。
3、事务的使用步骤:
隐式(自动)事务:没有明显的开始和结束,本身就是一条事务可以自动提交,比如insert、update、delete
显示事务:具有明显的开启和结束
使用显示事务:
①开启事务
set autocommit=0;
start transaction; --可省略
②编写一组逻辑sql语句
注意:sql语句支持的是insert、update、delete
设置回滚点:
savepoint 回滚点名;
③结束事务
提交:commit
回滚:rollback
回滚到指定的地方:roolback to 回滚点名;
4、并发事务
1.事务的并发问题是如何发生的?
多个事务同时操作同一个数据库的相同数据时
2.并发问题都有哪些?
脏读:一个事务读取了其他事务还没有提交的数据,读到的是其他事务“更新”的数据。
不可重复读:一个事务多次读取,结果不一样
幻读:一个事务读取了其他事务还没有提交的数据,只是读到的是 其他事务“插入”的数据。
3.如何解决并发问题?
通过设置隔离级别来解决并发问题。
4.隔离级别
mysql默认的事务处理级别是’REPEATABLE-READ’,也就是可重复读。
默认系统事务隔离级别是READ COMMITTED,也就是读已提交。
脏读 | 不可重复读 | 幻读 | |
---|---|---|---|
read uncommitted:读未提交 | × | × | × |
read committed:读已提交 | √ | × | × |
repeatable read:可重复读 | √ | √ | × |
serializable:串行化 | √ | √ | √ |
1、含义:mysql5.1版本出现的新特性,本身是一个虚拟表,它的数据来自于表,通过执行时动态生成。
好处:
1.简化了Sql语句
2.提高了sql的重用性
3.保护基表的数据,提高了安全性
2、创建
create view 视图名
as
查询语句;
3、修改
方式一:
create or replace view 视图名
as
查询语句;
方式二:
alter view 视图名
as
查询语句;
4、删除
drop view 视图1,视图2,...;
5、查看
desc 视图名;
show create view 视图名;
6、使用
insert、update、delete、select
注意:视图一般用于查询的,而不是更新的,所以具备以下特点的视图都不允许更新
①包含分组函数、group by、distinct、having、union
②join
③常量视图
④where后的子查询用到了from中的表
⑤用到了不可更新的视图
7、视图和表的对比
关键字 | 是否占用物理空间 | 使用 | |
---|---|---|---|
视图 | view | 占用较小,只保存sql逻辑 | 一般用于 查询 |
表 | table | 保存实际的数据 | 正增删改查 |
1、系统变量
说明:变量由系统提供的,不用自定义
语法:
①查看系统变量
show 【global|session】 variables like '';--默认是session
②查看指定的系统变量的值
select @@【global|session】.变量名; --默认是session
③为系统变量赋值
set 【global|session】 变量名=值;
set @@global.变量名=值
set @变量名 = 值;
2、自定义变量
1.用户变量
作用域:针对于当前连接(会话)生效
位置:begin end 里面,也可以放在外面
使用:
①声明并赋值:
set @变量名=值:
set @变量名:=值;
select @变量名:=值;
②更新值
--方式一:
set @变量名=值:
set @变量名:=值;
select @变量名:=值;
--方式二:
select xx into @变量名 from 表;
③使用
select @变量名;
2.局部变量
作用域:仅仅在定义它的begin end 中有效。
位置:只能放在begin end 中,而且只能放在第一句。
create procedure pro1()
begin
declare i int default 1;
end
①声明
declare 变量名 类型 【default 值】
②赋值或更新
--方式一:
set @变量名=值:
set @变量名:=值;
select @变量名:=值;
--方式二:
select xx into 变量名 from 表;
③使用
select @变量名;
3、存储过程和函数
说明:都类似于java中的方法,将一组完成特定功能的逻辑语句包装起来,对外暴露名字。
好处:
①提高了重用性
②sql语句简单
③减少了和数据库服务器连接的次数,提高了效率
(1)创建
create procedure 存储过程名(参数模式 参数名 参数类型)
begin
存储过程体
end
注意:
①参数模式:in、out、inout,其中in可以省略。
②存储过程体的每一条sql语句都需要用分号结尾。
(2)调用
call 存储过程名(实参列表);
#举例
调用in模式的参数:call sp1('值');
调用out模式的参数:set @name; call sp1(@name);select @name;
调用inout模式的参数:set @name = 值; call sp1(@name); select @name;
(3)查看
show create procedure 存储过程名;
(4)删除
drop procedure 存储过程名;
(1)创建
create function 函数名(参数名 参数类型) returns 返回类型
begin
函数体
end
注意,函数体中必须要有return 语句。
(2)调用
select 函数名(实参列表);
(3)查看
show create function 函数名;
(4)删除
drop function 函数名;
4、流程控制结构
1.分支结构
(1) if 函数
语法:
if(条件,值1,值2)
位置:可以作为表达式放在任何位置
(2)case结构
语法1:
case 表达式或字段
when 值1 then 语句1;
...
else 语句n;
end [case];
语法2:
case 表达式或字段
when 条1 then 语句1;
...
else 语句n;
end [case];
位置:可以放在任何位置
如果放在begin end 外面,作为表达式结合着其他语句使用。
如果放在begin end 里面,一般作为独立的语句使用。
(3) if 结构
语法:
if 条件1 then 语句1
elseif 条件2 then 语句2
...
else 语句n;
end if;
位置:只能放在begin end 中。
2.循环结构
位置:只能放在begin end中
特点:都能实现循环结构
对比:
①这三种循环都可以省略名称,但如果循环中添加了循环控制语句(leave或iterate)则必须添加名称。
②loop 一般用于实现简单的死循环
while 先判断后执行
repeat 先执行后判断,无条件至少执行一次。
(1)while
语法:
【名称:】while 循环条件 do
循环体
end while 【名称】;
(2)loop
语法:
【名称:】loop
循环体
end loop 【名称】;
(3)repeat
语法:
【名称:】repeat
循环体
until 结束条件
end repeat 【名称】;
3.循环控制语句
leave:类似于break,用于跳出所在的循环
iterate:类似于continue,用于结束本次循环,继续下一次
题型:选择10道+多选5道+编程3道+问答3道
选择题:
1.下面哪些不是SpringMVC的注解?
A.@RestController 这个是SpringBoot的注解
B.@PathVariable
C.@Mapper
D.Component
2.session和cookie的区别
①cookie以文本文件格式存储在浏览器中,session存储在服务端。
②cookie的存储限制了数据量,而session是无限量的。
③设置cookie时间可以使cookie过期。但是使用session-destory(),我们将会销毁会话。
④我们可以轻松访问cookie值但是我们无法轻松访问会话值,因此session更安全
多选题:
1.稳定排序有哪些
冒泡排序,插入排序,桶排序,计数排序,归并排序,二叉树排序,基数排序
ps:不稳定排序:选择排序、希尔排序、堆排序、快速排序
2.HashTable和HashMap的区别
①HashMap是继承自AbstractMap类,而HashTable是继承自Dictionary类。不过它们都实现了同时实现了map、Cloneable(可复制)、Serializable(可序列化)这三个接口。
②Hashtable比HashMap多提供了elments() 和contains() 两个方法。
③HashMap的key-value支持key-value,null-null,key-null,null-value四种。而Hashtable只支持key-value一种(即key和value都不为null这种形式)。既然HashMap支持带有null的形式,那么在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断,因为使用get的时候,当返回null时,你无法判断到底是不存在这个key,还是这个key就是null,还是key存在但value是null。
④HashTable是线程安全的,HashMap是非线程安全的。
⑤初始容量大小和每次扩充容量大小的不同
Hashtable默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。
⑥6、计算hash值的方法不同
为了得到元素的位置,首先需要根据元素的 KEY计算出一个hash值,然后再用这个hash值来计算得到最终的位置。
Hashtable直接使用对象的hashCode。hashCode是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值。然后再使用除留余数发来获得最终的位置。
3.哪些方法可以使线程放弃锁资源
A.wait
B.sleep sleep不会放弃锁
C.join
D.yield yield也不会释放锁
问答题:
1.抽象类和接口的区别
2.final、finally、finalize的区别
final是一个修饰符,可以修饰变量、方法和类。如果final修饰变量,意味着该变量的值在初始化后不能被改变。
java运行使用finalize()方法在垃圾收集器将对象从内存中清除出去之间作必要的清理工作。这个方法时由垃圾收集器在确定这个对象没有被引用时对这个对象调用的,但是什么时候调用finalize没有保证。
finally是一个关键字,与try、catch一起用于异常的处理。finally块一定会被执行,无论try块中是否有发生异常。
3.实现三种线程安全的单例模式
//1.通过JVM类的加载机制,Class被类加载后,且在线程使用之前,会执行类的初始化,而JVM会在初始化期间获取一个锁,该锁可以同步多个线程对同一个类的初始化
public class Singleton{
/*
内部类
*/
private static class SingletonHandle{
static Singleton singleton = new Singleton();
}
/*
获取对象,返回单实例对象
*/
public static Singleton getInstance(){
//获取静态变量将导致SingletonHandle 类初始化
//类的初始化,JVM保证有且仅有一个线程执行该类的初始化
return SingletonHandle.singleton;
}
}
//2.通过enum的本身特性,JVM保障每个枚举类型的单实例对象
public class Singleton2{
/*
获取对象
*/
public static Singleton2 getInstance(){
return SingletonEnum.INSTANCE.getInstance();
}
private enum SingletonEnum{
//单实例对象
INSTANCE(new Singleton2());
//单例
private Singleton2 singleton2;
SingletonEnum(Singleton2 singleton2){
this.singleton2 = singleton2;
}
//获取单实例对象
public Singleton2 getInstance(){
return singleton2;
}
}
}
//3.这里是双重检查锁定的优化,在singleton3=new Singleton3();这段代码这里,可能出现多线程竞争,所以必须使用volatile关键字。
class Singleton3{
private static volatile Singleton3 singleton3;
//获取实例对象
public static Singleton3 getInstance(){
//优化双重检查锁定
if(singleton3==null){
synchronized(Singleton3.class){
if(singleton3==null){
// + volatile关键字
singleton3 = new Singleton3();
}
}
}
return singleton3;
}
}
编程题:
1.求链表倒数第k个节点值
2.根据成绩给幼儿园同学数组发糖果,求所需糖果最小数,要求:当前孩子成绩比他周围孩子高,那么他的糖果数也要高于他们
3.马里奥跳板,求最小跳跃次数
1.操作系统的目标
(1)方便性 (2)有效性 (3)可扩充性 (3)开放性
2.各操作系统的特点
单道批处理系统、多道批处理系统、分时系统、实时系统
批处理系统:多道性、无序性、调度性,系统利用率高、吞吐量大、平均周转时间长、但无交互能力。
分时系统:有多路性、独立性、及时性和交互性。有较好的人机交互的特性,并且可以实现共享主机。
实时系统:有多路线、独立性、及时性、交互性和可靠性。实际上是指操作系统工作时,其各种资源可以根据需要随时进行动态分配。由于各种资源可以进行动态分配,因此,其处理事务的能力较弱、速度较快。
总结:从可靠性:实时系统更强,从交互性:分时系统更强。
3.操作系统的基本特性
并发、共享、虚拟、异步
4.概念
并发性是指两个或多个事件在同一时刻发生。
并行性是指两个或多个事件在同一时间间隔内发生。
在OS中,把通过某种技术将一个物理试实体变为若干个逻辑上的对应物的功能称为虚拟。
1.程序并发执行的特征
(1)间断性:程序在并发执行的时候,因为是共享资源,以及完成同一项任务而相互合作,致使在这些并发执行的程序之间形成了相互制约的关系,导致程序执行呈现:执行–暂停–执行。
(2)失去封闭性:当系统中有多个并发执行的程序时,各个资源是他们所共享的,这些资源的状态也由这些程序所改变,所以一个程序的运行环境会受到其他程序的影响。
(3)不可再现性:程序在并发执行时,由于失去了封闭性,也将导致其有失去可再现性。
3.进程的特征与三种基本状态
特征:
(1)动态性 (2)并发性 (3)独立性 (4)异步性
状态:
(1)就绪状态 (2)执行状态 (3)阻塞状态
三种基本状态转换:
处于就绪状态的进程,在调度程序为之分配了处理机之后便开始执行,就绪 → 执行
正在执行的进程如果因为分配它的时间片已经用完,而被剥夺处理机,执行 → 就绪
如果因为某种原因致使当前的进程受阻,使之不能执行。 执行 → 阻塞
4.进程控制块PCB的作用
(1) 作为进程存在的唯一标志
(2) 能实现间断性运行方式
(3) 提供进程管理所需要的信息
(4) 提供进程调度所需要的信息
5.线程与进程的区别联系
定义:
进程:进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位(包括程序段,相关数据段,进程控制块PCB)。
线程:线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。
关系:
一个线程可以创建和撤销另一个线程。同一个进程中的多个线程之间可以并发执行。相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中额度其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。
区别:
主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其他进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
优缺点:
线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源的管理和保护;而进程相反。同时,线程适合于在SMP机器上允许,而进程则可以跨机器迁移。
6.进程间的通信是如何实现的?
早期的的属于低级通信,原因:(1)效率低,生产者每次只能向缓冲池投放一个信息。(2)通信对用户不透明,隐藏了通信的具体细节。现在发展为高级通信:用户可以利用操作系统所提供的一组通信命令传送大量数据。操作系统隐藏了进程通信的实现细节,或者说,通信过程对用户是透明的。
高级通信机制:
1.共享存储器系统
实际操作中对应的是“剪贴板”(剪贴板实际上是系统维护管理的一块内存区域)的通信方式。
2.消息传递系统(进程间的数据交换以消息(message)为单位)
当今最流行的微内核操作系统中,微内核与服务器之间的通信,都采用了消息传递机制
3.管道通信系统(连接读写进程实现他们之间通信的共享文件)
(pipe文件,类似于先进先出的队列,由一个进程写,一个进程读)
管道分为匿名管道、命名管道。匿名管道是未命名的、单向管道,通过父进程和一个子进程之间传输数据。匿名管道只能实现本地机器上两个进程之间的通信,不能实现跨网络的通信。命名管道不仅可以在本机上实现两个进程间的通信,还可以跨网络实现进程间的通信。
4.客户机-服务器系统
包括:套接字(socket),远程过程调用和远程方法调用。
7.什么是临界区?如何解决冲突?
每个进程中访问临界资源的那段程序成为临界区,每次只准许一个进程进入临界区,进入后不允许其他进程进入。
(1)如果有若干进程要求进入空闲的临界区,一次仅允许一个进程进入;
(2)任何时候,处于临界区内的进程不可多于一个。如已有进程进入自己的临界区,则其他所有试图进入临界区的进程必须等待;
(3)进入临界区的进程要在有限的时间内推出,以便其他进程能及时进入自己的临界区。
(4)如果进程不能进入自己的临界区,则应让出CPU,避免进程出现“忙等”现象。
8.进程同步原则
进程同步的主要任务:是对多个相关进程在执行次序上进行协调,使并发执行的诸进程之间能有效地共享资源和相互合作,从而使程序的执行具有可再现性。同步机制遵循的原则:
(1) 空闲让进
(2) 忙则等待(保证对临界区的互斥访问)
(3) 有限等待(避免死等)
(4) 让权等待(当进程不能进入自己的临界区时,应该释放处理机,以免陷入忙等状态)
9.进程同步
由于进程同步产生了一系列经典的同步问题“生产者-消费者”问题,“哲学家进餐”问题,“读者-写者”问题。
解决方法:
(1)整型信号量
(2)记录型信号量,针对多个并发进程仅共享一个临界资源的情况。
(3)AND信号量,针对一个进程需要获得两个或更多的共享资源后才能执行其任务。
(4)管程
P(S):请求资源,V(S):释放资源。
10.程序和进程的区别
程序:计算机指令的集合,它以文件的形式存储在磁盘上。程序是静态实体,在多道程序系统中,它是不能独立运行的,更不能与其他程序并发执行。
使用系统资源情况:不使用(程序不能申请系统资源,不能被系统调度,也不能作为独立运行的单位,它不占用系统的运行资源)。
进程:进程是进程实体(包括:程序段、相关的数据段、进制控制块PCB)的运行过程,是一个程序在其自身的地址空间中的一次执行活动。是系统进行资源分配和调度的一个独立单位。
使用系统资源情况:使用(进程是资源申请、调度和独立运行的单位,因此,它使用系统中的运行资源)。
1.处理机调度的层次
(1) 高级调整
主要用于多道批处理系统中,又称长作业调度,调度对象是作业,根据某种算法决定将后备队列中的哪个作业调入内存。
(2) 低级调度
操作系统中最基本的一种调度方式(频率最高),其所调度的对象是进程(或内核级线程)。主要功能是,根据某种算法,决定就绪队列中的哪个进程应获得处理机,并由分派程序将处理机分配给选中的进程。在多道批处理、分时和实时三种类型的OS中都存在,又称为短作业调度。
(3) 中级调度
又称为内存调度,目的是为了提高内存利用率和系统吞吐率。
2.作业调度的算法
(1) 先来先服务算法(FCFS)
最简单额度调度算法,既可以用于作业调度,也可用于进程调度,系统按照作业到达的先后顺序进行调度,或者是优先考虑在系统中等待时间最长的作业
(2) 短作业优先调度算法(SJF)
实际情况短作业占有比例很大,为了使他们比长作业优先执行,而产生了短作业优先的调度算法,作业越短优先级越高,缺点是必须知道作业的运行时间,对长作业不利,人机无法实现交互,未完全考虑作业的紧迫程度。
(3) 优先级调度算法(PSA)
优先级:
对于先来先服务算法,作业的等待时间就是他的优先级,等待时间越长优先级越高。
对于短作业优先算法,作业时间的长短就是它的优先级。
在优先级算法中,基于作业的紧迫程度。
(4) 高响应比优先调度算法(HRRN)
在FSFS中只是考虑作业的等待时间而忽略作业的运行时间,SJF算法正好相反。高响应比算法既考虑作业的等待时间,又考虑作业的运行时间。
优先权 = (等待时间 + 要求服务时间)/ 要求服务时间
由于等待时间与服务时间之和就是作业的响应时间,顾优先级相当于响应比:Rp
Rp = (等待时间 + 要求服务时间)/ 要求服务时间 = 响应时间 / 要求服务时间
3.什么是死锁,死锁产生的4个条件
死锁定义:
在两个或多个并发进程中,如果每个进程持有某种资源而又都等待别的进程释放它或它们现在保持着的资源,在未改变这种状态之前都不能向前推进,称这一组进程产生了死锁。通俗的讲,就是两个或多个进程被无限期地阻塞、相互等待的一种状态。
产生死锁的必要条件(缺一不可):
(1) 互斥条件 一个资源一次只能被一个进程调用。
(2) 请求保持条件 一个进程因请求资源而阻塞时,对已经获得资源保持不放。
(3) 不可抢占条件 进程已获得的资源在未使用完之前不能被抢占。
(4) 循环等待条件 若干进程之间形成一种头尾相接的循环等待资源的关系。
4.预防避免死锁的方法
(1) 破坏”互斥”条件
所有进程可以同时访问共享资源。但由于互斥条件是非共享设备所必须的,不仅不能改变,还应加以保证。
(2) 破坏”请求和保持”条件
规定所有进程在开始运行之前,都必须一次性的申请其在整个运行过程所需要的全部资源。
优点:简单,安全。 缺点:资源严重浪费,恶化了系统的利用率。
(3) 破坏“不剥夺“条件
进程逐个的提出资源请求,当一个已经保持了某些资源的进程,再提出新的资源请求而不能立即得到满足时,必须释放它已经保持了的所有资源,待以后需要时再重新申请。
缺点:实现复杂,代价大,反复地申请和释放资源,而使进程的执行无限的推迟、延长了进程的周转时间,增加系统开销,降低系统吞吐量。
(4) 破坏”环路等待”条件
将所有的资源按类型进行线性排队,并赋予不同的序号。所有进程请求资源必须按照资源递增的次序提出,防止出现环路。
缺点:1.序号必须相对稳定,限制了新设备类型的增加。2.作业(进程)使用资源顺序和系统规定的顺序不同而造成资源浪费。3.限制了用户编程。
算法:利用银行家算法避免死锁
进程\资源情况 | Work | Need | Allocation | Work+Allocation | Finish |
---|---|---|---|---|---|
Available,可利用资源 ,表示一类可利用的资源数目。
Max,最大需求矩阵,表示进程i需要Rj类资源的最大数目。
Allocation,分配矩阵,表示进程i当前已分的Rj类资源的数目。
Need,需求矩阵,表示进程i还需要Rj类资源K个方能完成任务。
Work,工作向量,表示系统可提供给进程继续运行所需的各类资源数目。
5.死锁的检测和解除
(1)死锁的检测
①资源分配图:
圆圈代表一个进程,方框代表一类资源。
资源请求边由进程P指向资源R;资源分配便由资源R指向进程P。
②死锁原理
S为死锁状态的充分条件是:当且仅当S状态的资源分配图是不可完全简化的。
③死锁中的数据结构
(2)死锁的解除
①抢占资源:从一个或多个进程中抢占足够数量的资源,分配给死锁进程,以解除死锁状态。
②终止进程:终止系统中的一个或多个死锁进程,直至打破循环环路,使系统从死锁状态解脱出来。
1.存储器的多层结构
寄存器 |
---|
高速缓存 |
主存储器 |
磁盘缓存 |
固态磁盘 |
可移动存储介质 |
最高层为CPU寄存器,紧接着三层为主存,最底两层是辅存。
2.程序的装入和链接
用户程序要在系统中运行,必须先将它装入内存,然后再将其转变为一个可以执行的程序,通常都要经过以下几个步骤:
(1)编译,由编译程序(Compiler)对用户源程序进行编译,形成若干个目标模块(Object Module)。
(2)链接,由链接程序(Linker)将编译后形成的一组目标模块以及它们所需要的库函数链接在一起,形成一个完整的装入模块(Load Module)。
(3)装入,由装入程序(Loader)将装入模块装入内存。
3.连续分配存储管理方式
(1) 单一连续分配
(2) 固定分区分配
(3) 动态分区分配
(4)动态可重定位分区分配算法
其中动态分区分配将涉及到分区分配中实际需要的数据结构,分区分配算法和分区的分配与回收操作。
回收操作包括,三中合并以及一种插入。
内存分配流程:
4.动态分区分配算法
(1) 首次适应算法(FF)
要求地址空间递增的顺序链接,在分配内存时从链首开始查找,直到有一个满足的空间为止。该算法优先利用内存中低址空间,保留了高址空间,缺点是低址部分不断被划分,留下许多内存碎片。
(2) 循环首次适应算法(NF)
为了防止留下碎片,减少低址空间开销,NF算法每次从上一次分配的地方继续分配,该算法需要一个起始查询的指针用于指示下一次查询的空间地址。缺点是:缺乏大的空间分区。
(3) 最佳适应算法(BF)
每次作业分配时,总是把满足要求,又是最小的空间分配给作业,该算法把空间分区按其容量大小从小到大排列成空闲区链,缺点是:留下许多内存碎片。
(4) 最坏适应算法(WF)
总是挑选最大的空闲区域分配给作业使用,优点是不至于使空间区间太小,产生碎片的可能性小,缺点是:缺乏大的空间分区。
5.动态可重定位分区分配
(1)紧凑
通过移动内存中作业的位置,把原来多个分散的小分区拼接成一个大分区的方法。
缺点:需要对移动了的程序或数据进行重定位。
(2)动态重定位
当系统对内存进行了“紧凑”,而使若干程序从内存的某处移至另一处时,不需对程序做任何修改,只要用该程序在内存的新起始地址去置换原来的起始地址即可。这一过程需要硬件支持——重定位寄存器。
6..对换
是指把内存中暂时不能运行的进程或者暂时不用的程序和数据换出到外存上,以便腾出足够的内存空间,再把已具备运行条件的进程或进程所需要的程序和数据换入内存。
对换是改善内存利用率的有效措施,它可以直接提高处理机的利用率和系统的吞吐量。
类型:
①整体对换:进程对换,在中级调度中以整个进程为单位。
需要系统实现三方面功能:对对换空间的管理、进程的换出和进程的换入
②页面(分段)对换。
7.分页存储管理方式
分页存储的基本方法:
(1) 页面和物理块
页面:分页存储管理将进程的逻辑地址空间分成若干页,并从0开始编号,把内存的物理地址分成若干块(物理块)
(2) 地址结构
前一部分为也好P,后一部分为位(偏)移量W,对于特定的机器,其地址结构一定。给定逻辑地址A,页面的大小为L,则页面P和页内地址D有以下关系: P=INT[A/L]; d=[A] MOD L ,INT是整除函数。
例如:页面大小1kb ,设A=2170B,得P=2,d=122。
物理地址=(P=2对应的物理块地址)*1024B+122B
(3) 页表
记录相应页在内存中对应的物理块号
(4) 地址转换机构
将用户逻辑空间的地址,转变为空间中的物理地址。
8.分段存储管理方式
分段管理方式的引入原因:
(1) 一般程序分为若干段,如:主程序段、数据段、栈段等,每个段大多试一个相对独立的单位。
(2) 实现满足信息共享、信息保护、动态链接、以及信息动态增长等需要。
9.分页和分段的区别
共同点:二者都采用离散分配方式,且都地址映射机构来实现地址的转换
不同点:
(1) 页是信息的物理单位。采用分页存储管理方式是为了实现离散分配方法。提高内存的利用率,采用分段目的主要在于能更好的满足用户的需求。
(2) 页的大小固定且有由系统决定,在采用分页存储管理方式中直接由硬件实现。而段的大小不固定,决定于用户所填写的程序
(3) 分页的用户程序地址空间是一维的。分页完全是系统的行为,分段系统中是二维的。
10.段页式存储管理方式
基本原理是分段和分页相结合,其地址结构由:段号、段内页号、页内地址三部分组成。在段页式系统中获得一条指令需要三次访问内存,第一次访问内存中的短标,第二次访问内存中的页表,第三次访问内存中的数据。
11.Windows下的内存是如何管理的?
Windows提供了3中方法来进行内存管理:
(1) 虚拟内存,最适合用来管理大型对象或者结构数组;
(2) 内存映射文件,最适合用来管理大型数据流(通常来自文件)以及单个计算机上运行多个进程之间共享数据;
(3) 内存堆栈,最适合用来管理大量的小对象
Windows操作内存可以分两个层面:物理内存和虚拟内存。
其中物理内存由系统管理,不允许应用程序直接访问。
1.操作系统的内容分为几块?为什么叫做虚拟内存?他和主机的关系如何?内存管理属于操作系统的内容吗?
操作系统的主要组成部分:进程和线程的管理,存储管理,设备管理,文件管理。虚拟内存是一些系统页文件,存放在磁盘上,每个系统页文件大小为4K,物理内存也被分页每个页大小也为4k,这样虚拟页文件和物理内存也就可以对应,实际上虚拟内存就是用于物理内存的临时存放的磁盘空间。页文件就是内存页,物理内存中每页叫物理页,磁盘上的页文件叫虚拟页,物理页+虚拟页就是系统所有使用的页文件的总和。
2.请求分页存储管理方式
请求页面机制:作用是把用户的逻辑地址映射为内存空间中的物理地址。
结构:
页面 | 物理块号 | 状态P | 访问字段A | 修改位M | 外存地址 |
---|---|---|---|---|---|
状态P:指示页面是否调入内存,供程序访问时参考。
访问字段A:用于记录本页在一段时间内被访问的次数,供换出页面时参考。
修改位M:标识页面调入内存是否被修改过,供置换页面时参考。
外存地址:用于指示该页在外存上指示地址。
内存分配:
最小物理块数:
若采用单地址指令,且采用直接寻址,需要物理块数是2,一块用于存放指令页面,另一块用于存放数据页面。
若采用间接寻址至少需要3块。
3.虚拟存储器页面置换算法
(1) 最佳置换算法(Optimal)
一种理论的算法,选择淘汰的页面是以后一定不再使用的页面(理想化的),该算法无法实现,只能作为其他算法好坏的一个评价对比。
(2) 先进先出算法(FIFO)
总是最先淘汰最先进去的页面,该算法容易实现。缺点:通常程序调入内存的先后顺序和程序执行的先后顺序不一致,导致缺页率高。
(3) 最近最久未使用(LEU)
FIFO算法性能差,LRU算法根据页面调入内存的先后顺序决定,因为违反预测未来的使用情况,就是用过去的使用情况作为将来的使用情况的近似。
(4) 最少使用算法(LFU)
在每个页面设置一个移位寄存器记录该页面的访问频率,最近时期最少使用的页面被淘汰。
1.IO软件的层次结构
(1)用户层IO软件 (2)设备独立性软件 (3)设备驱动程序 (4)中断处理程序 (5)硬件
I/O设备一般是由执行I/O操作的机械部分和执行控制I/O的电子部件组成。通常将这两部分分开,执行I/O操作的机械部分就是一般的I/O设备,而执行控制I/O的电子部件则称为设备控制器或适配器。
设备控制器的主要功能是:控制一个或多个I/O设备,以实现I/O设备和计算机之间的数据交换。
2.对IO设备的控制方式
(1) 使用轮询的可编程方式
CPU不停地检查设备的状态,以字节为单位,非中断方式,利用率低
(2) 使用中断可编程的IO方式
添加CPU中断,提高了CPU的利用率
(3) 直接存储方式
以数据块为单位,放宽响应时间
(4) IO通道的方式
以数据块组成的一组数据块为单位,大幅度提高CPU的利用率
3.设备分配
(1) 设备分配中的数据结构
①设备分配表DCT ②控制器控制表,通道控制表,系统设备控制表
(2) 设备分配需要考虑的因素
①设备的固有属性 ②独占设备的分配策略 ③设备的分配算法 ④设备分配中的安全性
(3) 独占设备的分配程序
4.设备驱驱动程序
设备处理程序又称为设备驱动程序,它是I/O系统的高层与设备控制器之间的通信程序。
设备驱动程序的处理过程:
(1)将抽象要求转换为具体要求。
(2)对服务请求进行校验。
(3)检查设备的状态。
(4)传送必要的参数。
(5)启动I/O设备
5.SpooLing系统的构成
(1) 输入井和输出井
(2) 输入缓冲区和输出缓冲区
(3) 输入进程和输出进程
(4) 井管理程序
6.与设备无关的I/O软件
为了实现与设备的无关性而引入了逻辑设备与物理设备两个概念。逻辑设备表LUT*。
7.缓存区
引入缓冲区的原因:
(1)缓和CPU与I/O设备间速度不匹配的矛盾。
(2)减少对CPU的中断频率,放宽对CPU中断响应时间的限制。
(3)解决数据粒度不匹配的问题。
(4)t提高CPU和I/O设备之间的并行性。
分类:
(1) 单缓冲区,处理时间是:max(c,T) + M
(2) 双缓冲区,处理时间是:max(C+T)
缓冲池:在池中设置了多个可供若干个进程共享的缓冲区。
缓冲池与缓冲区的区别:缓冲区仅仅是一组内存块的链表,而缓冲池则是包含了一个管理的数据结构及一组操作函数的管理机制,用于管理多个缓冲区。
缓冲池组成:空白缓冲队列emq,输入队列inq,输出队列outq。
8.磁盘系统的性能改善
(1)选择好的磁盘调度算法,以减少磁盘的寻道时间。
(2)提高磁盘I/O速度,以提高对文件的访问速度。
(3)采取冗余技术,提高磁盘系统的可靠性。
1.文件逻辑结构管理
(1) 按文件的有无结构分
① 有结构文件(记录式文件) ② 无结构文件(流式文件)
(2) 按文件组织方式分
① 顺序文件 ② 索引文件 ③ 索引顺序文件
1.外存的组织方式
(1) 连续组织方式
又称为连续分配方式,要求每一个文件分配一个相邻的盘块
优点:顺序访问容易,访问连续文件非常容易,访问速度非常快
缺点:要求为文件分配连续的空间,必须事先知道文件的长度,不能灵活的删除插入记录动态增长的文件难分配空间
(2) 链接组织方式(分为隐式链接和显示链接)
采用链接组织的方式可以为文件分配多个不连续的盘块。
优点:①消除磁盘的外部碎片,提高内存的利用率。
②对插入删除修改非常容易。
③可以适应文件的动态增长。
(3)索引组织方式
分为单索引和多索引组织方式。
1.WEB.xml
<!-- 1.注册监听器,监听服务器的启动,在启动时,自动加载spring相关的xml文件 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value><!--配置service及以下 -->
</context-param>
<!-- 2.配置SpringMVC入口servlet,所有*.form请求,都会进入spring中 -->
<!-- 并在服务器启动时,默认加载位于web.inf文件夹中的viewSpace.xml,以配置springMVC -->
<!-- 配置service以上 -->
<servlet>
<servlet-name>viewSpace</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup> <!-- 设置此选项后,servlet会在服务器一启动就创建-->
</servlet>
<servlet-mapping>
<servlet-name>viewSpace</servlet-name>
<url-pattern>*.form</url-pattern>
<url-pattern>*.css</url-pattern>
<url-pattern>*.jpg</url-pattern>
<url-pattern>*.js</url-pattern>
<url-pattern>*.png</url-pattern>
</servlet-mapping>
<!-- 3.配置字符集过滤器,解决中文乱码问题 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.viewSpace-servlet.xml
<!-- controller及以上,在此处配置 -->
<!-- 开启扫描注解,指定要扫描的包,多个包的话,名字之间可以用逗号隔开,防止多次扫描,因为application也里也有扫描,该配置文件只扫描controller及以上-->
<context:component-scan base-package="cn.dlian">
<context:exclude-filter type="annotation" expression="org.springframwork.stereotype.Service" />
<context:exclude-filter type="annotation" expression="org.springframwork.stereotype.Repository" />
</context:component-scan>
<!-- 开启此选项,才能在重定向时使用RedirectAttributes -->
<mvc:annotation-driven />
<!-- 开启validator校验器进行字段校验 -->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
<!-- 给Controller注入Service -->
<bean id="userInfoController" class="cn.dlian.controllers.UserInfoController"
p:userInfoService-ref="userInfoService"
/>
<!-- 屏蔽Repository和Service扫描 -->
<context:component-scan base-package="cn.dlian">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository" />
</context:component-scan>
<!--配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="../**/*.form" /> <!--拦截器映射-->
<mvc:exclude-mapping path="/**/login.form" /> <!--不包含的请求映射(不拦截) -->
<mvc:exclude-mapping path="/**/index.form" />
<bean class="cn.dlian.interceptors.LoginInterceptor" /> <!--处理拦截事务的拦截器类-->
</mvc:interceptor>
</mvc:interceptors>
<!-- 外部访问资源文件,需要对路径进行映射 -->
<mvc:resources location="WEB-INF/css/" mapping="/css/**"/>
<mvc:resources location="WEB-INF/js/" mapping="/js/**"/>
<mvc:resources location="WEB-INF/img/" mapping="/img/**"/>
<mvc:resources location="WEB-INF/fonts/" mapping="/fonts/**"/>
<mvc:resources location="WEB-INF/plugins/" mapping="/plugins/**"/>
<mvc:resources location="WEB-INF/ajax/" mapping="/ajax/**"/>
3.Controller
//一、传递普通参数
@Controller("parController")//给该注解别名,其他地方调用的对象名就为parController
@RequestMapping("/")
public class ParamController{
@RequestMapping("otherPage")
public String jumpOtherPage(){
System.out.println("第一个请求!");
return "otherPage.jsp";
//return "redirect:otherPage.jsp";
}
@RequestMapping("sendParam")
public String sendParam(@RequestParam(value="username",required=false) String userName,@Reqeust("password") String userPass){
System.out.println("账号"+userName);
System.out.println("密码"+userPass);
return "showParam.jsp";
}
@RequestMapping("sendParamWithRequest")
public String sendParamWithRequest(@RequestParam("username") String userName,@Reqeust("password") String userPass,HttpServletRequest request){
System.out.println("账号"+userName);
System.out.println("密码"+userPass);
request.setAttribute("userName",userName);
return "showParam.jsp";
}
@RequestMapping("sendSameNameWithRequest")
public String sendSameNameWithRequest(@RequestParam String username,@Reqeust String password,HttpServletRequest request){
System.out.println("账号"+username);
System.out.println("密码"+password);
request.setAttribute("userName",username);
return "showParam.jsp";
}
@RequestMapping("sendSameNameWithRequestRedirect")
public String sendSameNameWithRequest(@RequestParam String username,@Reqeust String password) throws UnsupportedEncodingException{
return "redirect:showParam.jsp?username="+URLEncoder.encode(username,"utf-8")+"&password="+password;
}
@RequestMapping("sendSameNameWithRequestRedirectSpring")
public String sendSameNameWithRequestRedirectSpring(@RequestParam String username,@Reqeust String password,Redirect attrs) throws UnsupportedEncodingException{
attrs.addAttribute("username",username);
attrs.addAttribute("password",passwrod);
return "redirect:showParam.jsp" ;
}
}
//路径参数
@Controller
@RequestMapping("/")
public class PathVariableController{
//getPage3By100Items
@Request String multiPageQuery(@PathVariable int pageNo,@PageVariable int countPage){
System.out.println(pageNo+" "+countPage);
return "otherPage.jsp";
}
}
//三、传递表单数据到实体对象中(模型属性)
@Controller
@RequestMapping("/")
public class UserController{
@ReqeustMapping(value="login",method={RequestMethod.POST})
public String login(@ModelAttribute("user") User pUser){
//模型属性会自动放入reqeust中
}
}
//四、控制器跳转至另一个控制器
//转发
return "sendSameNameParamWithRequest.form";
//重定向利用RedirectAttributes attrs
4.字段校验
hibernate-validator-x.jar
jboss-logging-x.jar
validation-api-x.jar
public class User{
@Pattern(regexp="^\\S{3,16}$",message="账号名必须是3-16位的非空白字符!")
private String username;
@NotNull(message="此字段不能为null!")
@NotEmpty(message="此字段不能为空!")
@Length(min=3,max=16,message="密码必须是3-16位!")
priavte String password;
}
@Controller
@ReqeustMapping("/")
public class UserControlelr{
@RequestMapping("login")
public String login(@Valid @ModelAttribute User user,BindingResult bindingResult){
//BindingResult存放出错信息
//首先判断字段校验是否通过,若未通过,则不需要进行登陆验证!
if(bindingResult.hasErrors()){
return "index.jsp";
}
//登陆验证
if("zhangsan".equals(user.getUserName())&&"123456".equals(user.getUserpass())){
return "loginSuccess.jsp";
}
return "loginFailed.jsp";
}
}
5.ModelAndView
@Controller
@RequestMapping("/")
public class UserController{
@RequestMapping("login")
public ModelAndView login(@ModelAttribute User user){
ModelAndView mav = new ModelAndView("index.jsp");
mav.addObject("otherInfo","呵呵");
return mav;
}
}
6.注解
@Repository Dao层
@Service Service层
@Controller
@Autowired 变量
@Qualifier(“userInfoDao”) 跟在auto下面,只有匹配名字的bean才能注入进来
@ResponseBody 添加此注解,表示返回的字符串不是页面地址,而是响应体正文
7.application.xml
去掉bean
<!-- 在application.xml里屏蔽controller扫描
在viewSpace-servlet.xml里屏蔽Repository和Service扫描
<!-- application和viewSpace都需要打开扫描注解 -->
<context:component-scan base-package="cn.dlian">
<context:exclude-filter type="annotation" expression="org.springframwork.stereotype.Controller" />
</context:component-scan>
8.自动生成实体类使用
<!-- 下面添加一个bean的设置,使其能够扫描myBatis的Dao层接口,自动生成实体类使用 -->
<!-- applicationContext.xml -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfiger"
p:basePackage="cn.dlian.dao"
/>
9.HandlerInterceptor接口
public class LoginInterceptor implements HandlerInterceptor{
//请求执行之后,再执行的方法,一般在此处清理释放资源
public void afterCompletion(HttpServletRequest req,HttpServletResponse resp,Object obj,Exception exc) throws Exception{}
//正在执行请求,准备跳转页面之前执行的方法,一般在此处我们可以处理一部分请求或添加一部分响应头等
public void postHandle(HttpServletRequest req,HttpServletResponse resp,Object obj,ModelAndView mav) throws Exception{}
//正在执行请求,准备跳转页面之前执行的方法,一般在此处我们可以处理一部分请求或添加一部分响应头等
public boolean preHandle(HttpServletRequest req,HttpServletResponse resp,Object obj) throws Exception{
User user = req.getSession().getAttribute("loginUser");
if(user==null){
req.sendRedirect("index.jsp");
return false; //阻止继续向下传递请求
}
return true; //放行
}
}
HTTP请求处理流程-SpringMvc
在SpringMVC的http请求处理过程中,包括了前端控制器(DispatcherServlet)、处理映射器(HandlerMapping)、处理适配器(HandlerAdapter)、处理器((Handler)Controller)、视图解析器(ViewReslover)、视图(View)这六大主要对象。他们负责对http请求做处理。
第一步:前端控制器dispatcher接受请求
Client—url—>Dispatcher
第二步:前端控制器去发起handler映射查找请求
Dispatcher—HttpServletRequest—> HandlerMapping
第三步:处理器映射器查找hanlder并返回HandlerExetuionChain
Dispatcher <—HandlerExeutionChain—HandlerMapping
第四步:前端控制器发起请求处理器适配器请求执行
Dispatcher—Handler—> HandlerAdapter
第五步:处理器适配器去调用handler执行
HandlerAdapter—HttpServletRequest> Handler(Controller)
第六步:处理器处理后返回ModelAndView给HandlerAdapter
HandlerAdapter <—ModelAndView—Handler(Controller)
第七步:处理器适配器将ModelAndView返回给前端控制器
Dispatcher <—ModelAndView—HandlerAdapter
第八步:前端控制器请求视图解析器解析ModelAndView
Dispatcher—ModelAndView—> ViewReslover
第九步:视图解析器解析视图后返回视图View给前端控制器
Dispatcher <—View—ViewReslover
第十步:前端控制器请求视图要求渲染视图
Dispatcher—>View—>render
第十一步:前端控制器返回响应
Response <—Dispatcher
1.接口与抽象类的区别?
参数 | 抽象类 | 接口 |
---|---|---|
默认的方法实现 | 它可以有默认的方法实现 | 接口完全是抽象的。它根本不存在方法的实现 |
实现 | 子类使用extends关键字来继承抽象类。如果之类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现。 | 子类使用关键字implements来实现接口。它需要提供接口中所有声明的方法的实现。 |
构造器 | 抽象类可以有构造器 | 接口不能有构造器 |
访问修饰符 | 抽象方法可以有public、protected和default这些修饰符 | 接口方法默认修饰符是public。不可以使用其它修饰符 |
main方法 | 抽象方法可以有main方法并且我们可以运行它 | 接口没有main方法,因此我们不能运行它。 |
多继承 | 抽象类可以继承一个类或实现多个接口 | 接口只可以继承一个或多个其他接口 |
速度 | 它比接口的速度要快 | 接口是稍微有点慢的,因为它需要时间去寻找在类中实现的方法。 |
添加新方法 | 如果要往抽象类中添加新的方法,可以给他提供默认的实现。因此不需要改变现在的代码。 | 如果要往接口中添加方法,那么必须改变实现该接口的类。 |
2.什么是JDBC?
JDBC代表Java数据库连接(Java Database Connectivity),它是用于Java编程语言和数据库之间的数据库无关连接的标准Java API,换句话说:JDBC是用于在Java语言编程中与数据库连接的API。
3.给一个try{}catch{}finally{}的程序题,写出其输出结果
4.HTTP请求在SpringMVC里的处理过程
这个好可惜,自己有学过这块内容,但是脑子里只能模糊的记忆着。
在SpringMVC的http请求处理过程中,包括了前端控制器(DispatcherServlet)、处理映射器(HandlerMapping)、处理适配器(HandlerAdapter)、处理器((Handler)Controller)、视图解析器(ViewReslover)、视图(View)这六大主要对象。
(顺序可能不太对)
1.数据库多表的连接有哪些?
我首先说了可以让两张表里相同的字段直接用 = 连接,然后又说了左连接left join on,右连接right join on,等值连接join on。
2.Java高并发有哪些解决高并发的方法?volatile类型变量有什么作用?
我先说了volatile和synchronized,面试官继续问volatile变量有什么作用?
心里大概清楚volatile的作用,但是因为时间长了忘了原子性和可见性这两个名词,然后就没答出来。。。
volatile变量提供顺序和可见性保证,例如JVM或JIT为了获得更好的性能会对语句进行重排序,但是volatile类型变量即使在没有同步快的情况下赋值,也不会与其他语句进行重排序。volatile提供happens-before的保证,确保一个线程的修改能对其他线程是可见的。某些情况下,volatile还能提供原子性,如读64位数据类型,像long和double都不是原子的,但volatile类型的double和long就是原子的。
3.Java是怎样释放一个对象的?
我说的是,可以让这个对象的引用直接等null,当该对象不存在引用后,依靠JVM的垃圾自动回收机制,进行回收。
可能是我第一问的回答不是他想要的答案。
又问Java怎样立即释放一个对象?
我emmm….,这个还真没有了解过。
Java定义了一个特殊的方法叫做finalize(),它提供了C++析构函数的一些功能。但是,finalize()并不完全与C++的析构函数一样,并可以假设它会导致一系列的问题。finalize()方法作用的一个关键元素是Java的垃圾回收器。
在Java中,当你创建 一个对象时,Java虚拟机(JVM)为该对象分配内存、调用析构函数并开始跟踪你使用的对象。当你停止使用一个对象(也就是说,当没有对该对象的有效引用时),JVM通过垃圾回收器将该对象标记为释放这状态。
finalize方法是在Object类中定义的,因此所有的类都继承了它。子类覆盖finalize()方法以整理系统资源或者执行其他清理工作,finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。
4.各学科成绩(数据结构、算法、计算机网络)
略~
5.计算机网络的体系结构?各层有什么作用?
因为长时间没有看计算机网络方面的知识,所以只说了五层协议每一层的名字。
1.应用层的任务是通过应用进程间的交互来完成特定网络应用。
2.运输层的主要任务就是负责向两台主机进程之间的通信提供通用的数据传输服务。
运输层主要使用以下两种协议:
(1)传输控制协议TCP,提供面向连接的,可靠的数据传输服务。
(2)用户数据协议UDP,提供无连接的,尽最大努力的数据传输服务(不保证数据传输的可靠性)。
3.网络层负责为分组交换网上的不同主机提供通信服务。
4.数据链路层通常简称为链路层。两台主机之间的数据传输,总是在一段一段的链路上传送的,这就需要使用专门的链路层的协议。在两个相邻节点之间传送数据时,数据链路层将网络层交下来的IP数据报组装成帧。
5.物理层的作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异。
6.问项目经验
我讲了最近做的课设,前端使用了JQuery+AJAX,后端使用了SSM框架集。
MyBatis与Spring Data、Hibernate的区别。
(当时问了与Spring的区别,不知道啥意思,我讲了与Hibernate的区别,下面才了解了是SpringData = =)
我说,Hibernate是一个傻瓜式的框架,它的使用很方便,但是一个很简单的语句经过它处理,可能需要很复杂的处理过程。而MyBatis虽然写配置文件的时候可能有些麻烦,但是处理效率很高。(应该是讲错了。。。)
它们的区别见另一位博文https://www.cnblogs.com/liaojie970/p/7743068.html
7.双端队列的插入手写代码,不行的话说清思路
非常糟糕,一时大脑一片空白,之前只是简单知道双端队列的功能,却不知道具体的实现。。。下来看了下才发现,好简单。。。
头插入:首先创建一个临时指针指向头节点,然后让头指针指向加入进来的节点,如果队列开始为空,则让尾指针也指向加入进来的节点;如果队列不为空,那么让原头节点的prev指针指向新加入进来的节点即可,最后链表大小+1。
//LinkedList源码
public void addFirst(E e) {
linkFirst(e);
}
private void linkFirst(E e) {
final Node<E> f = first;
final Node<E> newNode = new Node<>(null, e, f);
first = newNode;
if (f == null)
last = newNode;
else
f.prev = newNode;
size++;
modCount++;
}
/**
* Links e as last element.
*/
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
8.servlet是单例还是多例?为什么?怎样来判断它是单例还是多例?
想了十几秒钟,说了是单例的。面试官看我停顿这么长时间就继续细问了后面两个问题。
因为如果是多例的,那么每有一个请求都必须创建一个servlet,这样当请求多的时候,会占用很多资源。
可以在serlvet里添加一个静态变量,在它的构造方法里进行自增打印,来看构造器执行了几次。
9.前端到数据库的数据传输是怎样的?
我说,前端发送GET或POST请求,到Servlet,servlet调用service层方法,service层调用dao层方法访问数据库,连接数据库用JDBC。。。
10.GET和POST请求的区别。
我说,使用GET请求,发送的数据会在地址栏里显示,使用POST请求,发送的数据不会再地址栏显示。回答了些皮毛。。。除了我回答的一点,还有:
1.GET请求,请求的数据会附加在URL之后,以?分割URL和传输数据,多个参数用&俩捏。URL的编码格式采用的是ASCII编码,而不是uniclde,即是说所有的非ASCII字符都要编码之后在传输。POST请求会把请求的数据放置在HTTP请求体里。因此GET请求的数据会暴露在地址栏里,而POST请求则不会,而是在请求体里。
2.传输数据的大小
由于特定浏览器和服务器对URL的长度有限制,因此,发送GET请求时,传输数据会受到URL长度的限制。
对于POST请求,由于不是URL传值,理论上是不会受限制的,但是实际上各个服务器会规定对POST请求提交数据大小进行限制。
3.POST请求的安全性比GET更高。
11.课设有没有写登陆?登陆信息怎么保存的?
我说,有,我目前是保存在session中的,当然也可以保存在cookie里。
技术面试结束,后面又和项目主管面试,问的不是技术问题,但是二面自我感觉不好。
项目主管上来就问我,你现在是大三,后面考研不? 不。
那你为啥不考研? 我不想学习了。。。
Oh My God! 蹦出了自己心底的真实想法(手动滑稽)。
这样就开始了不在状态的面试。。。
讲清了为啥不考研后,让我做自我介绍,主要从以下方面:
自己擅长的地方,以后主要学习什么语言,希望在公司得到哪些提高(具体)?
自己的优点和缺点?
期间还询问了我一些其他方面的事情,感觉很多地方回答的不好。