《深入理解计算机系统》学习笔记 - 第四课 - 机器级别的程序
Lecture 05 Machine Level Programming I Basics 机器级别的程序
文章目录
- Lecture 05 Machine Level Programming I Basics 机器级别的程序
- intel 处理器的历史和体系结构
- 芯片的构成
- AMD 公司(Advanced Micro Devices,先进的微型设备)
- C, 汇编, 机器代码
- 定义
- 汇编/机器代码
- C程序转换为目标代码
- 编译为汇编代码
- 汇编的特性:数据类型
- 汇编的特性:操作
- 机器指令解析示例
- 反汇编代码
- 反汇编器 objdump
- 反汇编 gdb
- 汇编基础:寄存器,操作数,移动
- 寄存器
- 移动数据 mov
- 简单的内存地址模式
- 地址模式示例
- 实际中交换方法
- 完整的内存地址模式
- 地址计算指令 `lea`
- 示例
- 算术运算 和 逻辑运算
- 示例
- 《深入理解计算机系统》书籍学习笔记
intel 处理器的历史和体系结构
- 复杂指令集电脑(complex instruction set computer)
- 精简指令集电脑 Reduced Instruction Set Computers(RISC)
芯片的构成
broadwell 型号模型:
- 一个芯片有多个内核。
- 芯片的边缘有许多接口连接其余的设备。
- DDR是连接到主存储器的方式,即所谓的DRAM 动态 RAM。
- PCI 是与外围设备的连接。
- SATA 是与不同类型盘的连接。
- 以太网接口,连接到一个网络。
因此,所有集成到单个芯片上的不仅仅是处理器本身,而是很多逻辑单元粘在一起所组成的更大的系统。
AMD 公司(Advanced Micro Devices,先进的微型设备)
紧随Intel公司的后面,相对落后一点,但是价格便宜。
C, 汇编, 机器代码
定义
- 架构(ISA: Instruction set architecture, 指令集架构)
需要理解或编写汇编/机器代码的处理器设计部分。
指令和指令集:这是编译器的目标,为你提供一系列指令,告诉机器确切地做什么。
发明硬件地人们想到了各种巧妙地实施指令方式,其中一些非常快,但需要大量地硬件,有些很慢,但根本不需要太多硬件。因此他们设法创建了这种称为指令集架构地抽象。
编译器地目标就是他们。
而如何最好地实现它是硬件研究者地工作。
-
微架构
对架构的补充。
低级别地东西,如何实现它被称为微结构 -
代码形式
- 机器代码
处理器执行的字节级程序。 - 汇编代码
机器代码的文本表示形式。
- 机器代码
一些指令架构集:
* intel: x86,IA32, Itaniu, x86-64.
* ARM (Acorn RISC Machine,橡树种子精简指令机器)
ARM指令体系结构。
他们向公司出售使用其涉及的许可权力,他们真正卖的是知识产权而不是芯片。
汇编/机器代码
处理器部分:
-
PC: Program counter 程序计数器
存储下一条指令的地址。 -
Register file 寄存器文件,寄存器集
大量使用的程序文件 -
Condition Code 条件码
状态寄存器。
存储最近的算术或者逻辑运算的结果状态:产生的值为0?为正值或者负值?
用于实现条件分支
存储部分:
- Memory 内存
字节可寻址数组
代码和用户数据
用于支持程序的堆栈
内存是你可以逻辑地认为只是一个字节数组,这就是机器程序员所看到的。
如前所述,它实际上是一种用不同方式实现虚构对象,操作系统和硬件之间存在一种协作,他们称之为虚拟内存,使处理器上运行的每个程序看起来拥有自己独立的字节数组,它们可以访问。即使它们实际上在物理内存内部都是共享这些字节数组。
C程序转换为目标代码
你有一个程序,是c程序,包含多个文件,将使用一些库代码。
编译过程:将你写的代码内容,转换为机器代码,并将其与编译后的,编译器为库生成合并代码,最终生成一个文件,可执行文件。
步骤:
- 文本形式的c程序文件,通过编译器生成文本形式的汇编代码
- 汇编代码,通过汇编器生成二进制的目标程序(字节形式)
- 通过链接器,将不同的文件融合在一起,包含你单独的文件,已编译版本和库代码,最终生成一个可执行程序。
- 实际有一些库在程序首次开始执行时动态导入的。
汇编器:
- 将
.s
汇编文件转换为.o
目标文件 - 二进制编码指令
- 几乎完整的可执行代码映像
- 缺少不同文件中代码之间的链接(链接器来完成)
链接器:
- 解决文件之间的引用
- 与静态运行时(run-time)库结合使用,例如:malloc(),printf()等
- 一些库是动态链接的。当程序开始执行时链接。
编译为汇编代码
- c编码
long plus(long x, long y);void sumstore(long x, long y, long *dest)
{long t = plus(x,y);*dest = t;
}
- 汇编码
运行命令,生成汇编代码:gcc -Og -S sum.c
-Og: O optimize 优化。指定编译器做什么样的优化的规范。
如果不给它指示,它将生成完全未经过优化的代码,实际上很难读该代码,它的运行过程非常繁琐。
-O1: 这是过去打开优化器的过程,gcc 做了很多优化,为了优化目的,使代码很难理解。
因此,最近几代GCC中的一个出现这个名未g的调式级别
.file "sum.c".text.globl sumstore.type sumstore, @function
sumstore:
.LFB0:.cfi_startprocpushq %rbx.cfi_def_cfa_offset 16.cfi_offset 3, -16movq %rdx, %rbxcall plusmovq %rax, (%rbx)popq %rbx.cfi_def_cfa_offset 8ret.cfi_endproc
.LFE0:.size sumstore, .-sumstore.ident "GCC: (GNU) 8.5.0 20210514 (Red Hat 8.5.0-15.0.2)".section .note.GNU-stack,"",@progbits
以句点开头的.
,这些实际上指示它们是别的东西,它们与某些被需要的信息有关,要给调试器提供,使他能够定位程序的各个部分,一些信息告诉链接器,这是一个全局定义的函数,还有一些其他信息,我们暂时不需要考虑,忽视这些信息,是它们更具有可读性。
百分号前缀%: 寄存器名称
pushq: 将东西推到栈上。
movq: 将它从一个地方复制到另一个地方。
call:调用一些过程
popq: 和pushq相对的命令,从栈中取出东西。
ret:特定函数的返回。
每一行都是一个指令(用文本写的),每条都将变成目标代码文件中的一个实际指令。
汇编的特性:数据类型
-
整型数据类型:1,2,4,8 字节
在整数数据类型,它们不区分符号与无符号的存储方式。
地址和指针,都是以数字形式存储在计算机中。 -
浮点数数据类型:4,8,10 字节
-
代码;一系列指令编码的字节序列
-
没有聚合类型:数组和结构体
只是在内存中巧妙地分配了字节
汇编的特性:操作
-
实现算术运算方法通过寄存器和内存数据
-
在内存和寄存器之间转换数据
- 从内存中将数据加载到寄存器
- 将寄存器的数据存储到内存
-
转移控制
- 非条件跳转 到/从 过程
- 条件分支
机器指令解析示例
- c代码
将t的值存存储到dest指定的位置。
*dest = t
- 汇编代码
movq %rax, (%rbx)
移动8字节值到内存:4字
操作数:
* t: 寄存器 %rax* dest: 寄存器 %rbx* *dest: 内存 M[%rbx]
- 目标代码
3 字节指令。
0x40059e: 48 89 03
存储地址 0x40059e
拓展:
变量的所有名称,在汇编代码级别,机器代码级别完全丢失,东西都变成了寄存器和内存中的某个位置。
反汇编代码
先生成目标代码:gcc -Og sum.c -c
反汇编器 objdump
objdump -d sum.o
- 用于检查目标代码
- 分析一系列指令的代码
- 产生汇编代码的进士索引
- 可以在a.out(可执行文件) 或者 .o(目标文件)运行
反汇编得到的汇编代码:
0000000000000000 <sumstore>:0: 53 push %rbx1: 48 89 d3 mov %rdx,%rbx4: e8 00 00 00 00 callq 9 <sumstore+0x9>9: 48 89 03 mov %rax,(%rbx)c: 5b pop %rbxd: c3 retq
反汇编 gdb
gdb 是一个非常强大的调试程序。
你可以单步检查程序并对其中的程序进行一些操作,如果它的源代码可用,可以用它来调试。
安装gdb:
yum install gdb
调试程序:
gdb sum
disassemble sumstore
gdb 作用:
- 可以单步检查程序并对其中的程序进行一些操作。(源代码调试)
- 可以用来反汇编
反汇编是一种可以用作任何逆向工程工具的工具。
反汇编Microsoft Word:
Microsoft Word 和其他程序一样,只是一个可执行文件,而那个可执行文件只是一堆编码指令的字节。
如果你能找到文件位置,应用程序的实际可执行文件的位置。
objdump -d WINWORD.EXE
汇编基础:寄存器,操作数,移动
寄存器
如果使用的是%r 开头的寄存器,你会得到64位。
如果使用的是 %e 开头的寄存器版本,你会得到32位。
%e 版本指示较大%r 实体低32位。
实际用法更多,你也可以引用低阶16位,和低8位。
从IA32 到 x86-64的变化之一是将寄存器数量增加一倍。
移动数据 mov
指令:
movq Source, Dest
操作数类型:
-
立即数 Immediate: 整型常数
示例:$0x400, $-533
和C常量,但是以$
为前缀
编码1,2,4字节 -
寄存器 Register :16个寄存器中的一个
示例:%rax, %r13
%rsp
保留自己的特殊用途
其他的寄存器有特殊用途对于特殊指令。 -
内存 Memory: 在寄存器给出的地址上有8个连续字节的内存
最简单的示例:(%rax)
各种其他“地址模式”
注意事项:
- 将立即值作为目的地没有意义,它是常数
- 出于硬件设计者的方便,它不允许你直接从一个内存位置复制到另一个内存位置。
你需要两个指令,一个从内存中读取值,将其复制到寄存器。第二个是在寄存器中取值并将其写入内存。
q: quad 四字节
简单的内存地址模式
- 正常模式
(R) Mem[Reg[R]]
寄存器R指定内存地址。
示例:
movq (%rcx), $rax
- 位移模式(Displacement)
D(R) Mem(Reg[R] + D)
寄存器R指定内存区域开始的位置。
常量位移D指出偏移量。
示例:
movq 8(%rbp), %rdx
地址模式示例
- c语言代码
void swap(long *xp, long*yp)
{long t0 = *xp;long t1 = *yp;*xp = t1;*yp = t0;
}
- 汇编代码
运行命令:gcc -S -Og swap.c
swap:movq (%rdi), %rax # t0 = *xpmovq (%rsi), %rdx # t1 = *ypmovq %rdx, (%rdi) # *xp = t1movq %rax, (%rsi) # *yp = t0ret
寄存器对应的值:
- %rdi xp
- %rsi yp
- %rax t0
- %rdx t1
操作流程:
实际中交换方法
实际中我们只会使用中间变量来进行交换:
void swap(long *xp, long*yp)
{long t0 = *xp;*xp = *yp;*yp = t0;
}
我们用命令得到汇编代码,会发现和上面的汇编代码是一样的。
为什么?
回到前面我们所说的mov指令。它不允许你直接从一个内存位置复制到另一个内存位置。
你需要两个指令,一个从内存中读取值,将其复制到寄存器。第二个是在寄存器中取值并将其写入内存。
所以 *xp = *yp
的执行就是:
long t1 = *yp
*xp = t1
所以实际中我们这么只使用一个中间变量进行操作,和使用两个中间变量进行操作并没有多大影响。
只是代码更简洁一点而已。
完整的内存地址模式
- 常用形式
D(Rb, Ri, S) Mem[Reg[Rb] + S*Reg[Ri]+D]
D: Displacement, 位移。恒定位移 1,2,4 字节
Rb: Base Register, 基础寄存器。 16个寄存器中的一个。
Ri: Index Register, 索引寄存器。特别是%rsp。
S: Scale, 缩放。 1,2,4,8 固定是这些数。
这是实现数组索引的一种自然方式。
如果这是一组数组索引,我们必须通过我的数据类型的字节数来缩放索引值,如果它是一个int我们必须将索引缩放四倍,如果它是long,我们必须将其缩放八倍。(这就是S必须是1,2,4,8这些数)
- 特殊形式
缺失其中一些项。
(Rb,Ri) Mem[Reg[Rb]+Reg[Ri]] D(Rb,Ri) Mem[Reg[Rb]+Reg[Ri]+D] (Rb,Ri,S) Mem[Reg[Rb]+S*Reg[Ri]]
示例:
0xf000 = 1111 0000 0000 0000
2 * 0xf000 = 二进制左移1位 = 0001 1110 0000 0000 0000 = 0x1e000
2 * 0xf000 = 2 * 15 = 30 = 0x1e000
地址计算指令 lea
lea : load effective address, 加载有效地址。
对上面内存地址模式的运用。
leaq Src, Dst
Src : 地址模式表达式
Dst : 设置dst为用表达式表示的地址
使用:
-
计算没有内存引用的地址
例如:p = &x[i]
-
计算算术表达式: x + k*y
k = 1,2,4,或8
示例
- c 代码
long m12(long x)
{return x*12;
}
- 汇编码
教程中得到:
leaq (%rdi,%rdi,2), %rax # t <- x+x*2
salq $2, %rax # return t<<2
我得到:
leaq (%rdi,%rdi,2), %rdx
leaq 0(,%rdx,4), %rax
算术运算 和 逻辑运算
- 两个操作数的指令
格式 计算
addq Src,Dest Dest = Dest + Src
subq Src,Dest Dest = Dest - Src
imulq Src,Dest Dest = Dest * Src
salq Src,Dest Dest = Dest << Src
sarq Src,Dest Dest = Dest >> Src
shrq Src,Dest Dest = Dest >> Src
xorq Src,Dest Dest = Dest ^ Src
andq Src,Dest Dest = Dest & Src
orq Src,Dest Dest = Dest | Src
- 一个操作数的指令
incq Dest Dest = Dest + 1
decq Dest Dest = Dest - 1
negq Dest Dest = - Dest
notq Dest Dest = ~Dest
注意事项:
- 操作数的顺序与你期望他们的顺序相反,源操作数在前,目的操作数在后面。
示例
- c代码
long arith(long x, long y, long z)
{long t1 = x+y;long t2 = z+t1;long t3 = x+4;long t4 = y * 48;long t5 = t3 + t4;long rval = t2 * t5;return rval;
}
- 汇编代码
leaq (%rdi,%rsi), %rax # t1
addq %rdx, %rax # t2
leaq (%rsi,%rsi,2), %rdx # 3y
salq $4, %rdx # t4 = 4 * 3y
leaq 4(%rdi,%rdx), %rcx # t5
imulq %rcx, %rax # rval
- 寄存器对应的变量
%rdi x
%rsi y
%rdx z
%rax t1,t2, rval
%rdx t4
%rcx t5
《深入理解计算机系统》书籍学习笔记
《深入理解计算机系统》学习笔记 - 第一课 - 课程简介
《深入理解计算机系统》学习笔记 - 第二课 - 位,字节和整型
《深入理解计算机系统》学习笔记 - 第三课 - 位,字节和整型
《深入理解计算机系统》学习笔记 - 第四课 - 浮点数
《深入理解计算机系统》学习笔记 - 第四课 - 机器级别的程序
相关文章:
《深入理解计算机系统》学习笔记 - 第四课 - 机器级别的程序
Lecture 05 Machine Level Programming I Basics 机器级别的程序 文章目录 Lecture 05 Machine Level Programming I Basics 机器级别的程序intel 处理器的历史和体系结构芯片的构成AMD 公司(Advanced Micro Devices,先进的微型设备) C, 汇编, 机器代码定义汇编/机器…...
云原生(Cloud Native)——概念,技术,背景,优缺点,实践例子
云原生(Cloud Native)是一种构建和运行应用程序的方法,这些应用程序充分利用云计算的优势。云原生应用程序通常设计为在现代、动态的环境中运行,如公共云、私有云和混合云。这种方法强调微服务架构、容器化、自动化、易于管理和可…...
ElasticSearch之线程池
ElasticSearch节点可用的CPU核的数量,通常可以交给ElasticSearch来自行检测和判定,另外可以在elasticsearch.yml中显式指定。样例如下: node.processors: 2如下表格中的processors即CPU核的数量。 线程池的列表 线程池名称类型线程数量队列…...
StoneDB-8.0-V2.2.0 企业版正式发布!性能优化,稳定性提升,持续公测中!
11月,StoneDB 新版本如期而至,这一个月来我们的研发同学加班加点,持续迭代:在 2.2.0 版本中,我们针对用户提出的需求和做出了重量级更新,修复了一些已知和用户反馈的 Bug,同时对部分代码进行…...
【数据结构 — 排序 — 插入排序】
数据结构 — 排序 — 插入排序 一.排序1.1.排序的概念及其运用1.1.1排序的概念1.1.2排序运用1.1.3 常见的排序算法 二.插入排序2.1.直接插入排序2.1.1.算法讲解2.1.2.代码实现2.1.2.1.函数定义2.1.2.2.算法接口实现2.1.2.3.测试代码实现2.1.2.4.测试展示 2.2.希尔排序2.2.1.算法…...
物联网后端个人第十四周总结
物联网方面进度 1.登陆超时是因为后端运行的端口和前端监听的接口不一样,所以后端也没有报错,将二者修改一致即可 2.登录之后会进行平台的初始化,但是初始化的时候会卡住,此时只需要将路径的IP端口后边的内容去掉即可 3.阅读并完成了jetlinks…...
在uniapp中,可以使用那些预定义的样式类
u-flex:设置元素为弹性布局。u-flex-v:设置元素为纵向弹性布局。u-flex-h:设置元素为横向弹性布局。u-p-10:设置元素的上下左右边距为10rpx。u-p-t-10:设置元素的上边距为10rpx。u-p-b-10:设置元素的下边距…...
mybatis的数据库连接池
直接看原文 原文链接:【MyBatis】 连接池技术_mybatis自带连接池-CSDN博客 本文先不说springBoot整合mybatis后的 本文讲的是没有被springBoot整合前的mybatis自己的默认的连接池 --------------------------------------------------------------------------------------…...
Vue 的 el-select 下拉选项中,只有当文字超出时才显示提示框,未超出的则不显示
Vue 的 el-select 下拉选项中,只有当文字超出时才显示提示框,未超出的则不显示 <template><div><el-select v-model"selected" placeholder"请选择"><el-optionv-for"item in options":key"it…...
【Python】pptx文件转pdf
要将PPTX文件转换为PDF格式,你可以使用Python的python-pptx库来读取PPTX文件,然后使用comtypes库在Windows上或unoconv在Linux上来进行转换。但是,需要注意的是,comtypes依赖于Microsoft Office,而unoconv依赖于LibreO…...
response应用及重定向和request转发
请求和转发: response说明一、response文件下载二、response验证码实现1.前置知识:2.具体实现:3.知识总结 三、response重定向四、request转发五、重定向和转发的区别 response说明 response是指HttpServletResponse,该响应有很多的应用&…...
CentOS常用基础命令大全(linux命令)2
CentOS常用基础命令大全(linux命令) 1.关机 (系统的关机、重启以及登出 ) 的命令 shutdown -h now 关闭系统(1) init 0 关闭系统(2) telinit 0 关闭系统(3) shutdown -h hours:minutes & 按预定时间关闭系统 shutdown -c 取消按预定时间关闭系统 sh…...
分析阿里巴巴的微服务依赖图和性能
论文对阿里巴巴集群中部署的大规模微服务进行了全面的研究。他们分析了 7 天内 20,000 多个微服务的行为,并根据收集的 100 亿条调用跟踪来分析它们的特征。该论文获得SOCC 2021最佳论文奖。 他们发现: 微服务图在运行时是动态的 大多数图形像树一样分…...
Linux——基本指令(一)
写在前面: 我们云服务器搭建的Linux系统,使用的镜像版本CentOS 7.6,使用的Xshell远程连接云服务器 前面我们使用超级管理员root账号登录,一般我们使用普通用户登录,那么如何创建新用户呢? 1.创建新用户 (…...
虚幻学习笔记10—C++函数与蓝图的通信
一、前言 除了上一章C变量与蓝图通信讲的变量能与蓝图通信外,还有函数和枚举也可以和蓝图通信。函数的关键字为”UFUNCTION“、枚举的关键字为”UENUM“。 二、实现 2.1、BlueprintCallable蓝图中调用 该函数时带执行的,带入如下。编译成功后在蓝图中输…...
无重复字符的最长子串(LeetCode 3)
文章目录 1.问题描述2.难度等级3.热门指数4.解题思路方法一:暴力法方法二:滑动窗口 参考文献 1.问题描述 给定一个字符串 s ,请你找出其中不含有重复字符的最长子串的长度。 s 由英文字母、数字、符号和空格组成。 示例 1: 输…...
交付《啤酒游戏经营决策沙盘》的项目
感谢首富客户连续两年的邀请,交付《啤酒游戏经营决策沙盘》的项目,下周一JSTO首席学习官Luna想让我分享下系统思考与投资理财,想到曾经看过的一本书《深度思维》,看到一些结构来预判未来。不仅仅可以应用在企业经营和组织发展上&a…...
油猴(Tampermonkey)浏览器插件简单自定义脚本开发
介绍 浏览器插件,包括油猴插件和其他插件,通过它们可以实现浏览器网页的定制化与功能增强。 其他插件一般只有某种具体的功能,且已经写死而不能更改,比如Adblock插件只用于去广告。 油猴插件是一款用于管理用户脚本的插件&…...
BGP综合
1、使用PreVal策略,确保R4通过R2到达192.168.10.0/24。 2、使用AS_Path策略,确保R4迪过R3到达192.168.11.0/24。 3、配置MED策略,确保R4通过R3到达192.168.12.0/24。 4、使用Local Preference策略,确保R1通过R2到达192.168.1.0…...
库函数qsort的使用及利用冒泡排序模拟实现qsort
文章目录 🚀前言🚀void*类型指针🚀库函数qsort的使用🚀利用冒泡排序实现库函数qsort() 🚀前言 今天阿辉将为大家介绍库函数qsort的使用,还包括利用冒泡排序模拟实现qsort以及void*类型的指针,关…...
mybatis和mybatisplus中对 同namespace 中id重复处理逻辑源码解析
一、背景 同事在同一个mapper.xml (namespace相同),复制了一个sql没有修改id,正常启动项目。但是我以前使用mybatis的时候如果在namespace相同情况下,id重复,项目会报错无法正常启动,后来看代码…...
linux下部署frp客户端服务端-内网穿透
简介 部署在公司内部局域网虚拟机上的服务需要在外网能够访问到,这不就是内网穿透的需求吗,之前通过路由器实现过,现在公司这块路由器不具备这个功能了,目前市面上一些主流的内网穿透工具有:Ngrok,Natapp&…...
Markdown to write
这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…...
ResNeXt(2017)
文章目录 Abstract1. Introductionformer workour work 2. Related Work多分支卷积网络分组卷积压缩卷积网络Ensembling 3. Method3.1. Template3.2. Revisiting Simple Neurons3.3. Aggregated Transformations3.4. Model Capacity 4. Experiment 原文地址 源代码 Abstract 我…...
DreamPlace 的下载安装与使用
DreamPlace 是一款芯片放置工具,用于宏单元(macro)和标准单元(Standard Cell)的放置以及布线,并计算 HPWL、Overlap 等用于衡量芯片性能的参数。 一、环境 1. 系统环境:Ubuntu 20.04 DreamPla…...
FPGA模块——SPI协议(读写FLASH)
FPGA模块——SPI协议(读写FLASH) (1)FLASH芯片 W25Q16BV(2)SPI协议(3)芯片部分命令1.Write Enable(06h)2.Chip Erase (C7h / 60h)3.写指令(02h&am…...
SQL自学通之表达式条件语句与运算
目录 一、目标 二、表达式条件语句 1、表达式: 2、条件 2.1、WHERE 子句 三、运算 1、数值型运算: 1.1、加法() 1.2、减法 (-) 1.3、除法(/) 1.4、乘法 (*) 1.5、取模 (%) 优先级别…...
公网域名如何解析到内网IP服务器——快解析域名映射外网访问
在本地搭建主机应用后,由于没有公网IP或没有公网路由权限,在需要发布互联网时,就需要用到外网访问内网的一些方案。由于内网IP在外网不能直接访问,通常就用通过外网域名来访问内网的方法。那么,公网域名如何解析到内网…...
线程安全与并发区别
在并发编程中,"线程安全 "和 "并发 "是相关的概念,但它们有着不同的含义。 线程安全 如果一个类或方法可以同时被多个线程使用,而不会导致数据损坏或意外行为,那么这个类或方法就被认为是线程安全的。即使多…...
SEO优化是什么,如何进行SEO优化
SEO(Search Engine Optimization)是指通过对网站进行优化,提高其在搜索引擎中的排名,从而增加有机流量和改善用户体验的一系列技术和方法。 进行SEO优化可以帮助网站获得更多的有机搜索流量,并提升网站的曝光度和可见…...
企业网站开发的设计流程/哪里有营销策划培训班
现在从事技术支持工作,需要经常到服务器操作,但不能复制,带来太多不便; 记得操作过程中资源管理器突然是显示“无响应”,需要等待或重启,当时有点急,就重启了,但重启之后,…...
学习网页设计的网站/百度正式员工工资待遇
最近使用compare时发现不能正常使用了,打开后提示许可证被撤销,解决方案为: 1 找到“C:\Users[你的用户名]\AppData\Roaming\Scooter Software\Beyond Compare 3”目录 2 将目录下的内容全部删除,再重新启动compare即可 若此时在…...
国家防控疫情/广州seo排名收费
下面链接介绍对WLAN的安全加密部分的内容,主要对WinAircrackPack工具的在Wlan方面的应用分析,介绍常见几种的加密方式,以及再使用无线设备时候的注意事项。详情:[url]http://network.51cto.com/art/200902/109520_3.htm[/url]本文…...
网站产品展示怎么做/灰色项目推广渠道
前几天酷壳发布过“vim简明攻略”,不知道大家练得怎么样了。如果你练了一下,那么这里这个速查卡就会对你有帮助了。以前本站也有过一个(vim速查卡),不过其太简单了。我觉得这个很不错,很全,很直…...
杭州网站建设公司哪家好/百度官方人工客服电话
今天已完成的工作由汪鸿同学完成了场景流设计用例文档的草稿,由张颖同学完成了具体的大部分测试用例设计文档,由李建文同学完成初步系统的需求分析报告稳定,由杨瑞丰同学和胡俊辉同学摸索使用QTP的Web测试流程,并对这个测试工具有…...
做app和做网站哪个容易/信息流广告模板
sql server存储过程中SELECT 与 SET 对变量赋值的区别 SQL Server 中对已经定义的变量赋值的方式用两种,分别是 SET 和 SELECT。 对于这两种方式的区别,SQL Server 联机丛书中已经有详细的说明,但很多时候我们 并没有注意,其实这…...