《码农翻身》读书笔记

寒假居然读完了这本书,只能说明这本书写的真的很有意思。
有些地方也并不是在讲故事,配合图示和代码看真的做到了“深入浅出”

各种"没什么用"的小知识点

cpu是阿甘,可以直接内存访问,缓存优先级最高,操作系统决定切换管理,由cpu执行分时切换进程。

TCP/IP三次握手 因为两边都要知道自己的收信能力和发信能力没有问题,就是8个事情,第一次握手成功,一个发信没问题,另一个收信没问题,三次以后才会两边确定都没有问题

局部性原理 时间局部性(如果程序中的某条指令一旦执行,不久之后可能再次被执行;如果某数据被访问,不久之后可能会再次访问)和空间局部性(如果程序访问了某个存储单元,不久之后附件的存储单元也将被访问)。
局部性原理在java虚拟机中的运用在于可以找到热点代码(hotspot),然后编译成原生代码(native code),提高执行效率。
局部性原理在系统中的运用,程序会被分块进行装载到内存中。

虚拟内存就是cpu利用内存管理单元把虚拟内存映射到真实物理内存,cpu和操作系统一起营造的假象

文件是最小的存储单位

CPU和各种设备
怎么知道设备?给每个设备编号,比如硬盘是0x320,图形控制器是0x3D0,这个端口就是I/O端口。
怎么找到这些设备?CPU还会和内存商量好,把这些I/O端口映射到内存中去,这样就可以像直接访问内存地址一样,被称为内存映射I/O。
怎么和设备具体交互?轮询,中断。轮询就是不停的询问正在运行的程序弄好了没;中断就是cpu给某个进程留个中断信号,先忙其他的进程,等那个进程发来中断信号,先保存其他的进程,去运行这个进程。具体怎么忙由中断控制器决定

补码为什么是反码加一
在计算机内部,使用补码表示二进制数,如果是正数,补码是其本身,如果是负数,把除符号位的二进制数取反加一。
先说求模这个问题,现在是7点,想让表回到4点,一种是向前进9格、21格、33格...,一种是向后退3格、15格...时钟的模是12,那二进制数的模是多少呢,对于一个4位的二进制数,一共有16种情况应该是16,但是二进制不像钟表是从1开始算的,所以两个数取反加起来才等于15,所以取反之后再加一就等于模16了。然后16必须要多一位,多的一位就可以表示成符号位了。

关于java

我看到了门口的一棵橡树,于是起名叫做Oak。但是发现已经有叫Oak的了,我端起桌子上一杯来自爪哇(java)岛的名叫java的咖啡,那就叫java吧。
James Gosling肯定很爱咖啡,因为魔数是8个16进制数,想变成单词,那就是A-F。在wiki上,James Gosling说的大概意思就是本来也没定,然后反正前32位准备用做识别是不是java的class文件,然后他在美国的一个Palo Alto的餐馆吃饭,当地最有名的乐队是Grateful Dead(感恩至死摇滚乐队),为了纪念一个成员,修了个庙堂叫做Cafe Dead。突然他发现正好这8个字母用做16进制数,然后又把后面的Dead改为Babe。

JAVA虚拟机是基于堆栈的虚拟机。每个线程有一个栈,每一个栈有很多工作台(栈帧),每个栈帧代表一个方法调用。一旦调用新方法,就会形成一个新的工作台,压在旧工作台上面,方法调用完成栈顶的工作台就会销毁,往下继续。

序列化解决了将内存中的java对象转换成二进制代码存储到硬盘上,解决了持久化的问题。
数据库是一种持久化的方式。数据库这套东西被称为JDBC。

JDBC——EJB——Hibernate——iBatis——Spring——JPA

但是JDBC问题很多,做一个简单的查询都需要很多代码,如果进行权限、事务、分布式等问题,那就更加麻烦,于是提出中间件的概念。具体由提供商实现,这就是最开始的EJB。EJB很难调试,所以很不爽。
Hibernate(冬眠)出现了,最早的对象关系映射(O/R Mapping)框架。
同年,iBatis出现了。
直到2004年,Spring的出现宣布不使用EJB,EJB彻底完了。Spring提供了自己访问数据库的方式JDBCTemplate,而且容易集成Hibernate和MyBatis等框架。
EJB3.0退出了Java Persistence API(JPA),在战略标准层面一统江湖。

消息队列

如果很多服务在一个后台一台虚拟机里就可以,那就效率极高。
但是一台放不下呢,就会有一个多个虚拟机通信。
虚拟机通信之间可以做成两个web服务通信。
要做成异步通信,我们做好发个消息放里面,至于那边什么情况我不管,那边只需要能读消息的时候就读就可以了。
抽象成: 消息生产者——>消息队列<——消息消费者
继续抽象: 发布/订阅模型,把队列和topic抽象成消费的目的地,消费者和生产者是同样的。

XML与Annotation

XML的好处在于不修改java代码,可以集中修改。
注解的好处在于靠近代码,容易阅读,灵活修改。

日志系统

Appender Logger Formatter 正交化
Logger一般传入Class全名或者包名,这样就可以实现不同的logger完全笛卡尔所有的类名是没有问题的。
Log4j开始最早出现,然后java官方出了logging包,logback后面又出现了。
于是出现了抽象层Slf4j(Simple Logging Facade for Java)
Slf4j+logback 最为流行

序列化

XML变成二进制流,关键信息不紧凑。
JSON比较好。
新方案,增加中间层,消息序列化格式和编程语言无关。

线程的锁与Atomic类

多线程并发操作一个变量是用Synchronized悲观锁实现。
Atomic系列类,将内存里的值取出来和现在的值比对上,一致的时候决定操作。
复杂数据结构包装成AtomicReference,解决ABA问题。
一般可以直接使用ConcurrentLinkedQueue,AtomicReference没那么简单

Spring看AOP和IoC

一个系统中有很多地方是通用的,比如日志、安全、事务、性能统计。
以统计一个函数的运行时间为例,每个方法都要运行的话,那就需要像下面这样

    long start = System.currentTimeMillis();
    algo(); // 执行代码块
    long end = System.currentTimeMillis();
    System.out.println(end - start);

这会导致统计等相关的代码淹没掉真正的代码

换种思路

模版方法模式:抽象类定义两个方法,一个方法是普通方法实现了上面的统计代码,中间的algo()方法留给子类去实现。 问题:父类定义一切,子类只能无条件接受。
装饰者模式:定义一个Command接口,里面有一个execute方法,定义各种装饰者,包含一个变量Command实例,每个装饰者的execute方法把自己的代码加进去,然后同时执行this.command.execute()方法。 问题:调用麻烦,灵活使用。

AOP面向切面编程:自己专门用aspectj包实验了一番,这篇博客不错,首先使用动态代理,反射那样去弄肯定没有问题。

具体怎么写,自己实践了很长时间,主要是aspectj织入的语法琢磨了半天。

Web

https:浏览器发出安全请求-->服务器发送数字证书(包含服务器的公钥)-->浏览器用预置的CA列表验证证书-->浏览器生成随机的对称密钥,用服务器的公钥加密-->服务器用自己的私钥解密,得到对称密钥--> 双方都知道了对称密钥,加密通信

密码到token 先注册appid和appsecret,这样知道是注册的应用,别人的账户和密码登录后会在认证系统生成token,为了保证token不可见,一般用授权码实现,授权码虽然可见但是会有一些防御限制。

Redis缓存服务器分布式:余数算法,tk那个项目就是这么搞得。
一致性hash算法,转圈圈;Hash槽算法。

代码管理

github的特色:不锁定,允许冲突,进行merge
java和xml:约定重于配置

发表评论

电子邮件地址不会被公开。