数字计算机五大部件
依据于冯诺依曼体系
-
CPU(控制器和运算器两大部件)
相当于人类的大脑运算器
不与输入输出设备打交道;
作用:算数运算、逻辑运算、数据传输等数据加工处理
数据来源:内存;
数据输出:内存;(而不是磁盘)控制器
作用:控制程序的执行;
管理所有设备寄存器
频率和CPU一样;
临时存储指令和数据的地方;
间接的将数据搬送至内存;缓存
分等级,等级越往下,频率越低;
频率低于CPU;
发现里面有数据不用问内存要,可以提高效率;
单位容量小,以M为单位;总线(Bus)
作用:设备之间控制和传输信号
相当于1车道,CPU控制谁先走 -
存储器(内存)
掉电易失;但运算速度快;
临时记录数据、程序; -
输入设备
将数据或者程序输入到计算机中,例如键盘、鼠标
-
输出设备
将数据或程序的处理结果展示给用户,例如显示器、打印机等
编程基础
计算机语言
人与计算机之间交互的语言
机器语言
* 一定数组成二进制的0和1的序列,称为机器指令。机器指令的集合就是机器语言。
* 与自然语言差异太大,难学、难懂、难记、难chacuo
汇编语言
* 用一些助记符号代替机器指令,称为汇编语言,ADD A,B 值得是将寄存器A的数和寄存器B的数相加得到的数放到寄存器A中;
* 汇编语言写好的程序需要汇编程序转化为机器指令(过程叫做汇编/编译)
* 汇编语言只是稍微好记了些,可以认为就是机器指令对应的助记符。只是符号本身接近自然语言
语言分类
低级语言
* 面向机器的语言,包括机器语言、汇编语言
* 不同机器不能通用,不同机器需要不同的机器指令或者汇编程序
高级语言
* 接近自然语言和数学语言的计算机语言
* 高级语言首先书写源程序,通过编译程序将原程序转化为机器指令的程序
从低级语言到高级语言
语言越高级;越接近人类的自然语言和数学语言
语言越低级,越能让机器理解
高级语言和低级语言之间需要一个转化的攻击:编译器、解释器
C、C++等语言的源代码需要本地编译
Java、Python、C#的源代码需要被解释器编译成中间代码(Bytecode),在虚拟机上运行
编译语言,将源程序转化为目标机器的CPU指令
解释语言,解释后转换成字节码,运行在虚拟机上,解释器执行中间代码
程序Program
程序
* 算法+数据结构=程序
* 数据一切程序的核心
* 数据结构是数据在计算机中的类型和组织方式
* 算法是处理出具的方式,算法有优劣之分
Python 语言类型
Python是动态类型、强类型语言
- 静态编译语言
- 实现声明变量的类型,类型不能再改变
- 编译时检查
- 动态编译语言
- 不用实现声明类型,随时可以赋值为其他类型
- 编程是不知道是什么类型,很难推断,只有在运行时报错才知道
- 强类型语言
- 不同类型之间操作,必须强制类型的转化
- 弱类型语言
- 不同类型之间可以操作,自动隐式转换,例如JavaScript中console.log(1+‘a’)
【注意】
python中有隐式转换,但很弱
1+True+2.0 (都转化为浮点数)
print(2,3) #都转化为元组
进制
转为十进制—按位乘以权累加求和
- 0b1110 计算为
1 * 2 ** 3+ 1 * 2 ** 2 + 1 * 2 ** 1 + 0 * 2 **0 =14 - 0x41计算为4*16+1*1=65
转为二进制
0xF8按位展开即可,得到0b1111 1000
127除以基数2,知道商为0位置,反向提取余数
转为十六进制
127除以基数16,直到商为0为止,反向提取余数
位运算
& 位与运算
按每一位相乘
9 & 8 # 结果为9
0000 1001
0000 1000 &
0000 1000 = 9
判断偶数和奇数
9 & 1 =1 奇数
8 & 1 = 0 偶数
| 位或运算
按位相加,0+0=0;0+1=1,1+0=1,1+1=1
9 | 1 = 9
0000 10001
0000 00001 |
0000 10001 = 9
~ 按位取反运算
~12 = -13
0000 1100
1111 0011 #这是计算机中的取反(负数)
1000 1101 > -13 #转化为自然语言
^ 异或运算
不同位为真(1),同位为假(0)
9^8=1
0000 1001
0000 1000
0000 0001 >>1
10^ 9 =3
0000 1010
0000 1001
0000 0011 ->3
10 ^ -9 = -3
0000 1010
1111 0111 #-9的补码
1111 1101 转为原码 1000 0011 ->-3
<< 左移运算
<<# 表示为向左移动#位 (等价于 数字*2**#)
8<<2 =32
0000 1000 #二进制
0010 0000 ->32
>> 右移运算
>># 表示为向右移动#位 (等价于 数字//2**#)
8>>2 =2
0000 1000 #二进制
0000 0010 ->2
原码 反码 补码,负数表示形式
- 原码
5 => 0b 101
1 => 0b 1
-1 =>-0b 1
bin(-1) - 反码
正数的反码与原码相同,负数的反码符号位不变,其他为按位取反 - 补码
正数的反码与原码相同,负数的反码符号位不变,其他为按位取反后+1 - 负数表示形式
在计算机中,都是按照补码来显示,人所认识的都是自然语言(原码)
5+ -1=4
0000 0101
1111 1111 #负数的补码
0000 0100 ->4
Python 基础语法
-
f前缀
3.6版本开始,新增前缀,格式化字符串a = 5
b = ‘abc’
f’{a} + {b}’‘5+abc’ #输出结果
-
转义序列
\ \t \r \n ’ "
前缀r,把里面的所有字符当做普通字符对待 -
缩进
约定使用4个空格缩进 -
标识符
- 一个名字,用来指代一个值
- 只能是字母、下划线和数字
只能以字母或下划线开头
- 不能是python的关键字,例如def、class就不能作为标识符
- Python是对大小写敏感
Python 易错点
-
字符串比较大小
将字符串转为为ASCII码进行比较
-
字符串拼接
1+‘a’ #报错,强类型语言必须转化为同一类型
1+int(‘a’) #报错,字符串’a’无法转化为整数
str(1)+‘a’ #正确 -
// 地板除(向下取整)
>>>-5//2 >>>-3
按-5除以2计算(-2.5),向下取整结果为-3
>>>-(5//2) >>>-2
先计算5//2向下取整为2,结果为-2 -
单目和双目
单目运算符–操作一个数字
双目运算符–操作两个数字
优先级:单目 > 双目
-
GC 垃圾回收
变量引用计数为0,进行GC(不是立即,计算机会在适合的时间GC)
①不常用的变量(计数为0)进行内存清理,对现有内存进行整理(规整)
②清理循环引用的变量 -
易错点1
- 列表list(iterable) -> 返回一个new_list
- [iterable] ->不会迭 代,只有一个元素iterable
- 元组构造方法tuple()h和()同上
list(‘abcde’) ->[‘a’,‘b’,‘c’,‘d’,‘e’]
[‘abcde’] -> [‘abcde’] -
list.insert(index,value)
可以超过索引上下界限 -
list.clear()
慎重使用,影响GC机制,引用计数为0 -
列表*重复的坑
lst=[[1,2,3]]*3
lst -> [[1,2,3],[1,2,3],[1,2,3]]
lst[0][0]=100
lst -> [[100,2,3],[100,2,3],[100,2,3]] -
‘’.join(iterable)
‘&’.join(list(range(10))) #错误,只能用字符串拼接
‘&’.join(map(str,range(10))) #map返回一个可迭代对象
-> 1&2&3&4&5&6&7&8&9 -
str.split()和str.partition()
- split(sep=None,maxsplit=-1) ->
list of strings
按尽可能多的空白字符串作为分隔符(\n,\r,\r\n,’ '),不保留分割符 - partition() ->
(head,sep,tail)
#默认一刀两断,保留分割符,简化版的split()
- split(sep=None,maxsplit=-1) ->
-
ramdom模块中的sample()和choice()区别
列表list、链表linked、quese、stack
-
列表
- 线性数据结构(本质是数组,但是被包装过),在内存中是连续排列的,GC机制会规整一片连续的内存空间给list使用
- 特点:有序的(但非大小个排序),有索引,从0开始,可以插队
- 优缺点
跟效率有关系,例如移除第一位和最后一位元素
定位(使用索引)速度快,移除或者插队会影响效率
-
queue (线性内存)队列
- 特点:不可以插队(只能在开头、结尾增减元素)
- 顺序:先进先出 or 后进先出
-
stack 栈
- 特点:后进先出(罗盘子、子弹夹);
- 不可以插队(只能在结尾增减元素)
-
链表 linked
- 手拉手模型,单向链表、双向链表(从某一方向开始数)查找数据只能从某一头开始(数据散落在线性内存地址)
- 优缺点:利于数据的增删,不利于查找
深拷贝和浅拷贝
-
思考
lst0 = list(range(4))
lst5 = lst0.copy()
print(lst5 == lst0)
lst5[2] = 10
print(lst5 == lst0) ?是否相等 -
浅拷贝 shadow copy --引用类型(是一个复杂类型时需要小心)
lst0 = [1, [2, 3, 4], 5]#[2,3,4] 门牌号码,内存地址
lst5 = lst0.copy()
lst5 == lst0 #返回True,内容相同
lst5[2] = 10
lst5 == lst0 #内容不同
lst5[2] = 5
lst5[1][1] = 20 #内容相同
lst5 == ls0 #最后返回True,因为多值[2,3,4]内存地址是一样的 -
深拷贝
深拷贝把所有引用复制一遍,即完全复制黏贴import copy
lst0 = [1, [2, 3, 4], 5]#[2,3,4] 门牌号码,内存地址
lst5 = copy.deepcopy()
lst5 == lst0 #返回True,内容相同
lst5[2] = 10
lst5 == lst0 #内容不同
lst5[2] = 5
lst5[1][1] = 20 #内容相同
lst5 == ls0 #最后返回True,因为多值[2,3,4]内存地址是一样的