码农翻身公众号的文章阅读笔记记录, 这个公众号以通俗易懂的语言和幽默的漫画来表达计算机技术,能够让人有代入感,且能够愉快的学习,非常值得大家去阅读学习。
现将自己之前的笔记整理,算是温故而知新。
Java 基础
Java 一个帝国的诞生
C语言 和 UNIX 有极大优势 :操作系统 、编译器、数据库 、网络系统
两大缺点:指针 、 内存管理
为了吸引更多的程序员加入我们, 我们要建立一个新的语言,这个语言应该有这样的特性:
语法有点像C , 这样大家容易接受
没有C语言那样的指针
再也不要考虑内存管理了, 实在受不了了
真正的可移植性, 编写一次, 到处运行
面向对象
类型安全
还有,我们要提供一套高质量的类库, 随语言发行。
增加了一个抽象层 在操作系统与应用程序之间, Java虚拟机
Applet 浏览器插件 ,图形界面的程序
J2SE Swing 桌面方向 , 太重
J2ME 失败
J2EE 服务器方向 , 强大、健壮、安全、简单、跨平台
适合开发复杂的大型项目
Weblogic 中间件 Eclipse 开发平台
帝国的诞生
构建工具 、 应用服务器、 Web开发、 开发工具
Hadoop : 进入大数据领域
Android : 进入手机端
特性
Java注解是怎么成功上位的?
XML方式配置
注解方式
注解:元数据 , 对数据进行解释定义 ,提供了额外的语义
注解的注解 ,对注解的意义进行定义 ,ANNOTATION_TYPE
运行时通过反射去执行被注解的方法
Java帝国之泛型
解决集合类型,运行时才抛出的Class Cast 异常 , 提前检查
java泛型实现策略 编译时 擦除泛型标识 ,加入自动转型代码
特例:Apple 继承 Fruit , 但 ArrayList<Fruit> 与 ArrayList<Apple> 之间没有关系
print(ArrayList<? extends Fruit> list)
一个故事讲明白线程的私家领地:ThreadLocal
上层方法设置了一个变量, 多层调用后, 某个方法需要使用变量
用方法传递的方式,额外增加传递参数, 改造成本也大
用静态方法方式传递,不支持并发
ThreadLocal 维护本线程的变量
Java IO 的自述
InputStream
OutputStream
Reader/Writer 接口
NIO non-blocking IO
Channel
Buffer
Selector
小白科普:Netty有什么用?
服务端RPC调用 高并发
框架及标准协议
Java帝国之宫廷内斗
JDBC 事务支持 ACID 单库时代
Web时代--大型应用 分布式事务
两阶段提交协议: 准备阶段 、提交阶段, XA协议
JTA Java Transaction API
设计比较理想化 实际应用中在高并发和高性能场景下 难支持
实际按: 基本可用 最终一致性
BASE模型 最终一致性 , 中间处理 遵循幂等性
Java帝国之安全争斗
Java认证与授权服务 Java Authentication Authorization Service , JAAS
JSecurity :
主体、角色、权限
支持注解 @RequiresAuthentication @RequiresPermissions @RequiresRoles
Realm : 应对不同数据源 数据格式 : IniRealm 、 JDBCRealm 、 LDAPRealm
配置数据库连接 、 配置sql 、 多个Realm时配置处理策略
Subject -- Security Manager { Authenticator (AuthenticationStrategy), Authorizer } -- Realm Session管理
进入 apache 被改名为 Shiro
Java 帝国之动态代理
不支持动态性 不能用声明的方式编程 运行时对类进行修改
1、什么是声明式编程
需求缘由
在某些函数调用前后加上日志记录
给某些函数加上事务的支持
给某些函数加上权限控制
示例
1、对于所有以DAO结尾的类,所有的方法执行之前都要调用TransactionManager.begin(),执行之后都要调用TransactionManager.commit(), 如果抛出异常的话调用TransactionManager.rollback()。
2、对于com.coderising这个package下所有以add开头的方法,在执行之前都要调用Logger.startLog()方法, 在执行之后都要调用Logger.endLog()方法。
方式:AOP
能够读取这个XML中的声明, 并且能够找到那些需要插入日志的类和方法, 接下来就需要修改这些方法了
2、Java动态代理
在运行时动态的生成类,并且作为一个真实对象的代理来做事情
基于接口的方式, 被代理类需要是实现接口的, 生成的代理类也是基于此接口,具体的增强功能类XXHandler需要实现InvocationHandler接口,用invoke方法写扩展代码,用Proxy.newProxyInstance(....) 来动态生成代理类,实际运行时通过反射方法调用原先类的方法 method.invoke(target,args) 。
3、CGLib : Code Generation Library
运用继承的方式生成代理类 ,扩展逻辑放在 XXInterceptor
使用ASM动态地在内存中创建类
FastClass 提高运行性能
4、官方的方式是 兄弟关系、 CGLib是父子关系
持久化:Java帝国反击战
持久化 解决掉电时 数据或对象 丢失问题
Java对象序列化 反序列化 效率较低
数据库存储 关系数据库 JDBC协议 ,手动处理逻辑很多
中间件 EJB 需要较重容器来运行 Websphere、Weblogic、 JBoss
开发繁琐、难于测试、性能低下
轻量级 O/R Mapping 框架
Hibernate \ iBatis
Spring JDBCTemplate
EJB3.0 JPA
Mybatis
序列化:一个老家伙的咸鱼翻身
把一个Java对象变成二进制的字节流,或者反过来把字节流编程Java对象
xml \ json 语言中立
protobuf 协议
JSP: 一个装配工的没落
页面模板 和数据 装配起来,变成 html 发送给浏览器
CGI html 字符串拼接
服务端动态页面 ASP JSP 标签库
模板引擎 Freemaker Velocity
可以脱离Web环境使用, 可以做动态页面的静态化
JavaScript 前端进行数据装配组装
Servlet:我还活着呢!
好基友 Servlet+JSP
Servlet Container : Tomcat \ Jetty
Application Server : Web Container \ EJB Container
Weblogic \ WebSphere \ JBoss \ Apusic (金蝶)
框架 Struts \ SpringMVC \ SpringBoot
Netty JavaNIO : Netty居然完全不用Servlet Container
JDBC的诞生
socket编程 : 应用层协议
Connection \ Statement \ ResultSet
Driver 反射获取连接 \ DriverManager 注册
直接JDBC方式 冗余代码太多 :
作为一门语言,所能提供的就是贴近底层(socket)的抽象,这样通用性最强,至于想消除重复代码,完全可以再封装、再抽象、再分层
JDBCTemplate :
- 指定数据库连接参数
打开数据库连接
- 声明SQL语句
预编译并执行SQL语句
遍历查询结果
- 处理每一次遍历操作
处理抛出的任何异常
处理事务
关闭数据库连接”
O/R Mapping :
原则
1. 数据库的表映射为Java 的类(class)
2. 表中的行记录映射为一个个Java 对象
3. 表中的列映射为Java 对象的属性。
问题:
1、Java类的粒度要精细的多,有时候多个类合在一起才能映射到一张表
2、Java的面向对象有继承,而数据库都是关系数据,根本没有继承这回事
3、对象的表示问题
4、对象的关联问题
5、数据导航
6、对象的状态
Hibernate 和 JPA
连接池: 动态代理创建数据库连接
中间件
Java 帝国之消息队列
同步处理需要等待,耦合性高, 第三方不稳定,导致处理体验欠佳
消息队列 异步解耦 消息的持久化 , 消息处理的幂等性
一个著名的日志系统是怎么设计出来的
Logger \ Formatter \ Appender 正交性
Log4j
java.util.logging : Logger \ Formatter \ Handler
logback
SLF4j : Simple Logging Facade for Java
一个著名的任务调度系统是怎么设计的
Linux crontab
minute hour day month week command
(0-59) (0-23) (1-31)(1-12)(0-6)(要执行的命令)
调度: Job \ Trigger \ Scheduler 调度器
持久化 、 高可用 、 锁
SELECT * FROM LOCKS where LOCK_NAME='TRIGGER' FOR UPDATE
Quartz
JVM
学习Java虚拟机没用?听听当事人是怎么说的!
虚拟机: 有自己的指令集 、 有自己独有的可执行文件 、 有自己独特的基于栈而不是寄存器的执行方式 、 垃圾回收机制
字节码、栈帧
我是一个Java class
ClassLoader 类加载器 , 全路径 ,父类加载机制
文件验证器 : 文件信息 、字节码 、超类 、覆盖 、 跳转指令
类加载 对象实例化 方法区
局部变量区 、 操作数栈
Java栈 栈帧
调式 中断
垃圾回收 引用计数法(只是理论) 根可达性算法 (实际)
javac 生成 , src bin
Java虚拟机的Heap监狱
分区域: 新生代(eden ,s1 , s2) 、老年代
垃圾回收: 可达性分析 复制算法 , 清除算法
堆外内存 Socket数据 ,二次复制
直接分配堆外内存:ByteBuffer buffer = ByteBuffer.allocateDirect(1024*1024*128);
适用那些分配次数少,读写操作很频繁的场景 , 很适合Netty 用对象池管理
一件程序员必备武器的诞生
调式的需求 、找bug
Java文件编译成class文件以后,其中有个叫做LineNumberTable的区域,它描述了Java源代码和字节码行号(字节码偏移量)之间的对应关系
jdb:Java Debugger
获取一个线程的状态, 挂起一个线程,让线程恢复执行, 设置一个线程,单步执行
获取线程的当前栈帧,调用栈帧,栈帧对应的方法名
获取变量的值, 设置变量的值
设置断点,清除断点
查看类的信息,方法,字段 等等
JVM TI : JVM Tool Interface , JVM TI Agent
JDWP 通行协议
JDI Java Debug Interface
JDPA : Java Platform Debugger Architecture
聊聊Java平台上的非Java语言
Java虚拟机定义了一个"软CPU" , 有一套自己的指令, 这意味着任意一门编程语言,只要能编译成Java的字节码指令,或者在运行时动态地生成字节码指令,就可以运行在java虚拟机中。
Jython和JRuby :
Groovy : Gradle项目 Grail项目
Scala 和 Clojure : 面向对象遇上了函数式编程
ASM:一个低调成功者的自述
可以动态地修改已经编译过的class,还可以动态地生成新的java class ,动态 , 可以是完全在运行时,在内存中完成
-与jsp的JavaComplier接口区别, 它是在运行时动态编译一个java源代码,是生成新的类,不能对现有的class进行修改。
为什么需要动态修改 :
核心类:ClassReader 、 ClassWriter 、 ClassVisitor
CGLib 在 ASM 基础上进行了封装,便于使用 , 应用到spring和hibernate 中
其他
Java能抵挡住JavaScript的进攻吗
Node.js
非阻塞异步IO :
Tomcat 在处理连接的时候能实现非阻塞,但是在真正处理请求的时候还是需要同步操作
不是异步操作更好,而是在高并发的环境异步操作更有效 , 很多系统 都是IO密集的
事件队列 -- 事件循环 -- 多个事件循环 -- Handler
Verticle http服务器 和一个事件循环 关联
Event bus ,通过消息传递 线程之间的数据
Vert.x :