Java大纲
- java类库
- 内置类库
- java.基础
- java.lang
- java.util
- java.io
- java.nio
- java.net
- java.beans
- java.text
- java.applet
- java.awt
- javax.扩展
- javax.swing
- javax.net
- java.基础
- 外部类库
- 日志
- slf4j
- JSON解析库
- Jackson
- 单元测试库
- JUnit
- Mockito
- JUnit Runner
- junit.framework
- 通用类库
- Apache Commons
- Google Guava
- Http 库
- Apache HttpClient
- Apache HttpCore
- XML解析库
- Xerces
- JAXB
- Dom4j
- JAXP
- Xstream
- Excel读写库
- Apache POI API
- 字节码库
- javassist
- Cglib Nodep
- 数据库连接池库
- DBCP
- C3p0
- Commons Pool
- 消息传递库
- Tibco RV
PDF处理库
- iText
- Apache FOP- 日期和时间库
- JodaTime JAVA8后可以放弃
- 集合类库
- Apache Commons Collections
- Trove
- Google Collections
- Goldman Sachs collections
- FastUtil
- 邮件API
- Apache Commons Email
- HTML解析库
- JSoup
- 加密库
- Commons Codec
- 嵌入式SQL数据库库
- H2
- Apache Derby
- HSQL
- JDBC故障诊断库
- P6spy
- 序列化库
- Google Protocol Buffer
- 网络库
- Netty
- Apache MINA
- 日志
- 类库家族
- org.apache
- hadoop
- commons
- .lang3
- lang
- shiro
- http
- .client
- .impl
- lucecn
- ibatis
- maven
- org.springframework
- com.google
- inject
- Guice是Google开发的一个轻量级,基于Java5(主要运用泛型与注释特性)的依赖注入框架(IOC)。Guice非常小而且快。Guice是类型安全的,它能够对构造函数,属性,方法(包含任意个参数的任意方法,而不仅仅是setter方法)进行注入。
- org.junit
- Runner
- org.eclipse
- jetty
- Jetty是一个纯粹的基于Java的网页服务器和Java Servlet容器。尽管网页服务器通常用来为人们呈现文档,但是Jetty通常在较大的软件框架中用于计算机与计算机之间的通信。
- jetty
- com.fasterxml
- jackson
- org.elasticsearch
- org.mockito
- io.netty
- channel
- handler
- Netty 是一个基于NIO的客户、服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户、服务端应用。Netty相当于简化和流线化了网络应用的编程开发过程,例如:基于TCP和UDP的socket服务开发。
- com.amazonaws
- services
- org.jboss
- netty
- com.netflix
- org.harmcrest
- org.codehaus
- com.alibaba
- otter
- otter是一个基于数据库增量日志解析,准实时同步到本机房或异地机房的mysql/oracle数据库. 一个分布式数据库同步系统。
- otter
- org.slf4j
- com.intellij
- org.hibernate
- org.bouncycastle
- io.undertow
- org.apache
- 内置类库
- 关键技术
- Java 基础
- 数据类型
- String
- 运算
- 关键字
- Object
- 继承
- 反射
- 异常
- 泛型
- 注解
- 特性
- Java 容器(集合)
- Map & Collection
- 设计模式
- 源码
- Java 并发
- 线程…
- Java I/O
- 磁盘操作
- 字节操作
- 字符操作
- 对象操作
- 网络操作
- NIO
- java虚拟机
- 特性
- 优势
- 平台无关、安全、可网络移动
- 缺点
- 性能
- 内存管理,不明确
- 线程调度,不明确
- 反编译容易
- 引用、描述信息多
- 混淆器
- 引用、描述信息多
- 优势
- 类加载器
- 字节码文件结构
- 双亲委派机制
- 类的生命周期
- 加载,验证,准备,解析,初始化
- 使用、卸载
- 类初始化时机
- 主动引用
- 被动引用
- 类加载器分类
- 启动类加载器
- 扩展类加载器
- 应用程序类加载器
- 自定义类加载器实现
- 运行时数据区
- 程序计数器
- 虚拟机栈
- 本地方法栈
- 方法区(共享)
- 运行时常量池
- 堆(共享)
- 垃圾回收
- 判断生死
- 引用计数算法
- 可达性分析算法
- 方法区的回收
- finalize()
- 引用类型
- 强软弱虚
- 垃圾收集算法
- 标记-清除算法
- 复制算法
- 标记-整理算法
- 分代收集算法
- 垃圾收集器
- Serial收集器
- ParNew收集器
- Parallel Scavenge收集器
- Serial Old收集器
- Parallel Old收集器
- CMS收集器
- G1收集器
- 判断生死
- 内存分配及回收策略
- Minor GC 和 Full GC
- 内存分配策略
- Full GC 的触发条件
- 垃圾回收
- 直接内存
- NIO DirectByteBuffer
- 执行引擎
- 特性
- Java 基础
- 编程规范
- Alibaba
Tech大纲
人生
- life
内功-基础
- algorithm
- os
- linux
- windows
- design
- ds
- se-software engineering
- network
- ccna
招式-技术
- front
- java
- bigdate
- hadoop
- spark
- hdfs
- hive
- kudu
- yarn
- zookeeper
- hbase
- graph
- janusgraph
- neo4j
- orientdb
- db
- mysql
- postgres
- oracle
- es
- python
- front
- angular
- opm-Operation and Maintenance
- docker
- k8s
- jenkins
- bamboo
- tool
- digtal
- hexo
- markdown
机器学习
- NER
面试
- interview
阶段一
阶段一:Java核心
- 阶段一:Java核心(右)
- 数据结构
- 算法
- 操作系统
- 计算机网络
- 设计模式
- 阶段一:Java核心(左)
- Spring
- Hadoop
心中有树
AI开发环境搭建
一、配置
- OS: Ubuntu 23.04
- 显卡: GeForce RTX 4060
- 内存: 64G
- 显卡驱动: 530.30.02
- cuda: 12.1.0
- cuDNN: 8.9.0
二、显卡驱动
- 安装
1
2
3
4方式1:
系统->Software&Updates->Additional Drivers ,选择Using NVIDIA driver metapackage from nvidia-driver-525(proprietary) , Apply Changes即可。
方式2:
卸载干净nvidia显卡驱动,由cuda安装(目前采用这种方式) - 验证
1
2
3
4
5
6(1)查看显卡型号
$ lspci | grep -i nvidia
(2)查看显卡驱动版本
$ cat /proc/driver/nvidia/version
(3)详细的NVIDIA显卡信息
$ nvidia-smi (-L)
三、CUDA
CUDA全称Compute Unified Device Architecture,是由NVIDIA推出的一种计算架构,通过CUDA我们可以使用NVIDIA GPU进行计算。
CUDA Toolkit视为开发CUDA程序的工具包(类似于VS之于C++),但我们不仅在开发CUDA程序时需要CUDA Toolkit,很多时候,由于硬件、软件环境的不同,他人编译好的CUDA程序我们是不能直接运行的,于是我们就要在自己的计算机上编译他人写好的CUDA代码
- 安装
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15下载地址获取:
https://developer.nvidia.com/cuda-toolkit-archive 选择版本-->runfile(local)
下载:
wget https://developer.download.nvidia.com/compute/cuda/12.1.0/local_installers/cuda_12.1.0_530.30.02_linux.run
安装:
sudo sh cuda_12.1.0_530.30.02_linux.run
配置:
/usr/local目录下软连接设置(切换)
查看指向:stat cuda
删除链接:sudo rm -rf cuda
创建链接:sudo ln -s /usr/local/cuda-12.0 /usr/local/cuda
sudo ln -s /usr/local/cuda-12.1 /usr/local/cuda
~/.bashrc 配置环境变量
export PATH=$PATH:/usr/local/cuda/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib64 - 验证
1
2
3
4
5
6
7
8方式1:
nvcc -V
输出Cuda版本等信息
方式2:
cuda-samples/Samples/1_Utilities/deviceQuery
make clean & make
./deviceQuery
输出Result = PASS
三、cuDNN
NVIDIA cuDNN是用于深度神经网络的GPU加速库。它强调性能、易用性和低内存开销。NVIDIA cuDNN可以集成到更高级别的机器学习框架中,如谷歌的Tensorflow、加州大学伯克利分校的流行caffe软件。简单的插入式设计可以让开发人员专注于设计和实现神经网络模型,而不是简单调整性能,同时还可以在GPU上实现高性能现代并行计算。
- 安装
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16下载地址获取:
https://developer.nvidia.com/rdp/cudnn-archive选择cudnn-linux-x86_64对应
下载:
wget https://developer.download.nvidia.com/compute/cudnn/redist/cudnn/linux-x86_64/cudnn-linux-x86_64-9.0.0.312_cuda12-archive.tar.xz
安装:
解压下载好的tar.xz文件
tar -xvf cudnn-linux-xxx.tar.xz
将解压的文件拷贝到cuda对应目录,进行cudnn的安装
sudo cp include/* /usr/local/cuda-12.1/include
sudo cp lib/libcudnn* /usr/local/cuda-12.1/lib64
sudo chmod a+r /usr/local/cuda-12.1/include/cudnn*
sudo chmod a+r /usr/local/cuda-12.1/lib64/libcudnn*
删除
sudo rm -f /usr/local/cuda-12.1/include/cudnn*.h
sudo rm -f /usr/local/cuda-12.1/lib64/libcudnn* - 验证
1
2
3
4
5
6
7
8
9
10
11
12
13方式1:
cat /usr/local/cuda/include/cudnn_version.h | grep CUDNN_MAJOR -A 2
方式2:
cudnn_samples_v8/mnistCUDNN
make clean & make
./mnistCUDNN
报错:nvcc fatal : Unsupported gpu architecture 'compute_35'
修改mnistCUDNN/Makefile:
ifeq ($(GENCODE_FLAGS),)
# Generate SASS code for each SM architecture listed in $(SMS)
#$(foreach sm,$(SMS),$(eval GENCODE_FLAGS += -gencode arch=compute_$(sm),code=sm_$(sm)))
$(foreach sm,$(filter-out 35,$(SMS)),$(eval GENCODE_FLAGS += -gencode arch=compute_$(sm),code=sm_$(sm)))
输出Test passed!
四、CUDA与CUDNN的关系
CUDA看作是一个工作台,上面配有很多工具,如锤子、螺丝刀等。cuDNN是基于CUDA的深度学习GPU加速库,有了它才能在GPU上完成深度学习的计算。它就相当于工作的工具,比如它就是个扳手。但是CUDA这个工作台买来的时候,并没有送扳手。想要在CUDA上运行深度神经网络,就要安装cuDNN,就像你想要拧个螺帽就要把扳手买回来。这样才能使GPU进行深度神经网络的工作,工作速度相较CPU快很多。
五、Pytorch
基于conda进行python环境管理,创建环境ai_env,后续相关命令基于该环境进行。
- 安装
1
2
3
4
5下载地址获取:
https://pytorch.org/get-started/locally/选择CUDA12.1对应命令
安装:
GPU: conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia
CPU: conda install pytorch torchvision torchaudio cpuonly -c pytorch - 验证
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24ai_env环境下,执行如下代码:
import torch
print('CUDA版本:',torch.version.cuda)
print('Pytorch版本:',torch.__version__)
print('显卡是否可用:','可用' if(torch.cuda.is_available()) else '不可用')
print('显卡数量:',torch.cuda.device_count())
print('是否支持BF16数字格式:','支持' if (torch.cuda.is_bf16_supported()) else '不支持')
print('当前显卡型号:',torch.cuda.get_device_name())
print('当前显卡的CUDA算力:',torch.cuda.get_device_capability())
print('当前显卡的总显存:',torch.cuda.get_device_properties(0).total_memory/1024/1024/1024,'GB')
print('是否支持TensorCore:','支持' if (torch.cuda.get_device_properties(0).major >= 7) else '不支持')
print('当前显卡的显存使用率:',torch.cuda.memory_allocated(0)/torch.cuda.get_device_properties(0).total_memory*100,'%')
输出:
CUDA版本: 12.1
Pytorch版本: 2.2.0
显卡是否可用: 可用
显卡数量: 1
是否支持BF16数字格式: 支持
当前显卡型号: NVIDIA GeForce RTX 4060 Laptop GPU
当前显卡的CUDA算力: (8, 9)
当前显卡的总显存: 7.7540283203125 GB
是否支持TensorCore: 支持
当前显卡的显存使用率: 0.0 %
五、显卡驱动 & CUDA & cuDNN & Pytorch版本选择
Ubuntu安装和查看已安装软件包
终端通过命令行方式进行的软件包安装、卸载和删除的方法。
一、Ubuntu中软件安装方法
1、APT方式
(1)普通安装:apt-get install softname1 softname2 …;
(2)修复安装:apt-get -f install softname1 softname2... ;(-f Atemp to correct broken dependencies)
(3)重新安装:apt-get --reinstall install softname1 softname2...;
2、Dpkg方式
(1)普通安装:dpkg -i package_name.deb
3、源码安装(.tar、tar.gz、tar.bz2、tar.Z)
首先解压缩源码压缩包然后通过tar命令来完成
1 | a.解xx.tar.gz:tar zxf xx.tar.gz |
然后进入到解压出的目录中,建议先读一下README之类的说明文件,因为此时不同源代码包或者预编译包可能存在差异,然后建议使用ls -F –color或者ls -F命令(实际上我的只需要 l 命令即可)查看一下可执行文件,可执行文件会以*号的尾部标志。
一般依次执行
1 | ./configure |
即可完成安装。
二、Ubuntu中软件包的卸载方法
1、APT方式
(1)移除式卸载:apt-get remove softname1 softname2 …
;(移除软件包,当包尾部有+时,意为安装)
(2)清除式卸载:
1 | apt-get --purge remove softname1 softname2...;(同时清除配置) |
2、Dpkg方式
(1)移除式卸载:dpkg -r pkg1 pkg2 …;
(2)清除式卸载:dpkg -P pkg1 pkg2…;
三、Ubuntu中软件包的查询方法
Dpkg 使用文本文件来作为数据库.通称在 /var/lib/dpkg 目录下. 通称在 status 文件中存储软件状态,和控制信息. 在 info/ 目录下备份控制文件, 并在其下的 .list 文件中记录安装文件清单, 其下的 .mdasums 保存文件的 MD5 编码.
体验使用数据库的时刻到了:
1 | $ dpkg -l Desired=Unknown/Install/Remove/Purge/Hold | Status=Not/Installed/Config-files/Unpacked/Failed-config/Half-installed |/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err: uppercase=bad) ||/ Name Version Description +++-===========-================-======================================== ii aalib1 1.4p5-28 ascii art library - transitional package ii adduser 3.85 Add and remove users and groups ii alien .63 install non-native packages with dpkg ... ... |
每条记录对应一个软件包, 注意每条记录的第一, 二, 三个字符. 这就是软件包的状态标识, 后边依此是软件包名称, 版本号, 和简单描述.
第一字符为期望值,它包括:
u 状态未知,这意味着软件包未安装,并且用户也未发出安装请求.
i 用户请求安装软件包.
r 用户请求卸载软件包.
p 用户请求清除软件包.
h 用户请求保持软件包版本锁定.
第二列,是软件包的当前状态.此列包括软件包的六种状态.
n 软件包未安装.
i 软件包安装并完成配置.
c 软件包以前安装过,现在删除了,但是它的配置文件还留在系统中.
u 软件包被解包,但还未配置.
f 试图配置软件包,但是失败了.
h 软件包安装,但是但是没有成功.
第三列标识错误状态,可以总结为四种状态. 第一种状态标识没有问题,为空. 其它三种符号则标识相应问题.
h 软件包被强制保持,因为有其它软件包依赖需求,无法升级.
r 软件包被破坏,可能需要重新安装才能正常使用(包括删除).
x 软包件被破坏,并且被强制保持.
也可以以统配符模式进行模糊查询, 比如我要查找以nano字符开始的所有软件包:
1 | $ dpkg -l nano* Desired=Unknown/Install/Remove/Purge/Hold | Status=Not/Installed/Config-files/Unpacked/Failed-config/Half-installed |/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err: uppercase=bad) ||/ Name Version Description +++-==============-==============-============================================ ii nano 1.3.10-2 free Pico clone with some new features pn nano-tiny <none> (no description available) un nanoblogger <none> (no description available) |
以上状态说明: 系统中安装了 nano 版本为 1.3.10-2 ;安装过 nano-tiny , 后来又清除了; 从未安装过nanoblogger .
如果觉得 dpkg 的参数过多, 不利于记忆的话, 完全可以使用 dpkg-query 进行 dpkg 数据库查询.
应用范例:
查询系统中属于nano的文件:
1 | $ dpkg --listfiles nano |
三、其他应用总结
1 | apt-cache search # ------(package 搜索包) |
apt-get install
下载软件包,以及所有依赖的包,同时进行包的安装或升级。如果某个包被设置了 hold (停止标志,就会被搁在一边(即不会被升级)。更多 hold 细节请看下面。
apt-get remove [–purge]
移除 以及任何依赖这个包的其它包。
–purge 指明这个包应该被完全清除 (purged) ,更多信息请看 dpkg -P。
apt-get update
升级来自 Debian 镜像的包列表,如果你想安装当天的任何软件,至少每天运行一次,而且每次修改了
/etc/apt/sources.list 後,必须执行。
apt-get upgrade [-u]
升 级所有已经安装的包为最新可用版本。不会安装新的或移除老的包。如果一个包改变了依赖关系而需要安装一个新的包,那么它将不会被升级,而是标志为 hold。apt-get update 不会升级被标志为 hold 的包 (这个也就是 hold 的意思)。请看下文如何手动设置包为 hold。我建议同时使用 ‘-u’ 选项,因为这样你就能看到哪些包将会被升级。
apt-get dist-upgrade [-u]
和 apt-get upgrade 类似,除了 dist-upgrade 会安装和移除包来满足依赖关系。因此具有一定的危险性。
apt-cache search
在软件包名称和描述中,搜索包含xxx的软件包。
apt-cache show
显示某个软件包的完整的描述。
apt-cache showpkg
显示软件包更多细节,以及和其它包的关系。
Java基础
java基础
java基础最重要的资料就是官方白皮书,诸多基础概念,白皮书写的都比较详细,不可忽略的内容。如需细品的Jave SE Platform 概览图:
概念
Java Runtime Environment (JRE)
Java Runtime Environment (JRE) 提供运行用 Java 编程语言编写的应用和小程序所需的库、Java 虚拟机和其他组件。此外,JRE 还包括两项关键的部署技术:Java 插件 — 使小程序可以在常用浏览器中运行;以及 Java Web Start — 通过网络部署独立的应用。它还是用于企业软件开发和部署的 Java 2 Platform, Enterprise Edition (J2EE) 的基础。JRE 不包含用于开发应用和小程序的工具和实用程序,如编译器或调试器。
Java Development Kit (JDK)
JDK 是 JRE 的超集,不但包含 JRE 中的所有内容,还包含开发应用和小程序所需的工具,如编译器和调试器。上面的示意图阐释了 Java SE 平台中的所有技术以及彼此之间关系。
Java SE API
Java SE 应用编程接口 (API) 定义了应用或小程序对编译后的 Java SE 类库中的功能请求和使用的方式。(Java SE 类库也是 Java SE 平台的一部分。)
Java SE API 由核心技术、桌面(或客户端)技术以及其他技术组成。
- 核心组件提供在数据库访问、安全性、远程方法调用 (RMI) 和通讯等关键领域编写强大的企业级程序的基本功能。
- 桌面组件添加了全面的特性,帮助构建可为部署产品(如 Java 插件)、组件建模 API(如 JavaBeans)以及图形用户界面提供丰富用户体验的应用。
- 其他组件完善了此功能。
Java 虚拟机
Java 虚拟机确保了 Java SE 平台的硬件和操作系统无关性、轻量级编译代码(字节码)和平台安全性。
Java 平台工具
Java SE 平台可与一系列工具协同工作,这些工具包括集成开发环境 (IDE)、性能和测试工具以及性能监视工具。
个人理解
java是一个很大的生态,写代码的时候只是从源代码的角度涉及很小一块,我把编出的代码看作是四方库;java整体上,核心流程大致涉及:四方库、三方库、二方库、编译器、类加载器、JVM。
java程序的整体过程可以描述为:根据业务需要引入二方库、三方库,根据java语法编写源代码(四方库),完成后将源代码提交给编译器编译为字节码;使用java内置类加载器或自己编写的类加载器(四方库)加载字节码供jvm解释执行,jvm将字节码根据不同的操作系统平台解释成不同的机器指令,在操作系统允许的权限下,调用机器资源达到预期目标。
细节过程并不严谨,且在这个过程中,继续分析:可分为-编写、编译、解释、执行;整个过程是由多个组件合作完成的,不同阶段参与度是不同的,比如四方库的编写,属于构建,自由发挥的空间比较大;编译器、类加载器、JVM环节如果已经选定,属于使用,多是优化配置;当然java白皮书中对各组件并没有十分严格的限制,jdk中也只是提供了某些默认实现,如果需要或者有能力,完全可以自行实现从编译器、类加载器、JVM相关组件,也确实有。有几点需要注意,并不是所有的组件都是java语言实现的,比如编译器、部分类加载器、JVM并不是Java实现的;二方库和三方库并没有明确的限定,二方库特指jdk中已经集成了的,比如derby;
按照这条主线上涉及的组件或环节,再衍生分析对java的学习思路。
依据语法,写出编译器能识别的内容,依据语言特性组织代码之间的关系;衍生出对操作系统内存、cpu、设备的操作,对数据结构、算法、设计模式的应用。依据对二方库、三方库的依赖,衍生出ant、maven、gradle等技术。自定义类加载器和提供第三方库的角度,衍生出各种第三方库,如spring、hadoop等生态。根据执行过程中优化需求,衍生出对jvm的内存结构、垃圾回收机制、垃圾收集器实现机制的了解。java的多线程特性,引出并发编程方面的需求,需要关注线程状态、多个线程通信、线程安全等内容。java的网络特性,衍生出对计算机网络协议方面的需求,如netty、rpc/grpc等技术。数据的传递又涉及序列化、反序列化技术,如json、protobuf等格式。
总而言之,技术的学习应当明确对一种技术,目标到底是使用还是构建。虽然构建有助于使用,但学习过程中并不是所有的技术都必须构建的,学习过程中尽量时刻明确定位,避免陷入其中。
再谈具体的知识点,具体的知识点是为知识体系的构建服务的,解决问题的本质是在知识体系下选取合适的知识点应用到合适的位置和阶段上。
java的生态很大,比如spring技术栈、hadoop技术栈都有足够多的内容供学习研究,但还是力求知其然知其所以然,知道自己从事或学习的知识在一颗大树的什么位置,向上向下都是有关联和方向的。
计算机技术学习的路上有很多知识点,日新月异,变化繁多。但总有些东西是基础中的基础,万变不离其中,我们暂称其为内功,另外一些则是招式,当然并没有十分明确的界限。比如数据结构、算法、设计模式,这些大概可以称为内功,而编程语言、框架等则可称为招式。
Java主线,所有均为对象,对象内容的存储内存的分配也是以堆为主;只是存在了一些特殊情况,比如基础类型、string,本地方法,即时编译等情况,无外乎是因为使用频率或效率、空间原因,做出的优化策略。所以java需要把握主线
数据类型
基础数据类型:
- 字符型(char):16bit、‘\u0000–u\ffff’、‘\u0000’
- 布尔型(boolean):1bit、true/false、false
- 数值型
- 整数类型
- 字节(byte):8bit、-128–127、0
- 短整型(short):16bit、-32768–32768、0
- 整型(int):32bit、–、0
- 长整型(long):64bit、–、0
- 浮点类型
- 浮点数(float):32bit、–、0.0f
- 双精度浮点数(double):64bit、–、0.0d
- 整数类型
引用数据类型:
- 类(class)
- 接口(interface)
- 数组(array)
String
String 不属于基础类型, String 属于对象。
String类中使用字符数组保存字符串,private final char value[],所以string对象是不可变的。
String中的对象是不可变的,也就可以理解为常量,线程安全。
运算
关键字
Object
继承
反射
异常
泛型
注解
特性
简单易学;
面向对象(封装,继承,多态);
平台无关性(Java虚拟机实现平台无关性);
可靠性;
安全性;
支持多线程(C++语言没有内置的多线程机制,因此必须调用操作系统的多线程功能来进行多线程程序设计,而Java语言却提供了多线程支持);
支持网络编程并且很方便(Java语言诞生本身就是为简化网络编程设计的,因此Java语言不仅支持网络编程而且很方便);
编译与解释并存;
Spring大纲
spring系列
- framework
- boot
- cloud
- data
- cloud data flow
- security
- session
- web flow
关于技术
“ 宙斯征服众神,凯撒征服大陆,灵魂征服身体,知识征服容颜”
老冯是一个技术人,IT世界里的;
程序员老冯是我,也是这一方阵地,偶尔伤春悲秋,终究这里还是一个技术的世界,记录过去、现在、将来关于技术的所学、所思、所想、所悟,如果恰巧能够以不那么技术化的方式,写一写技术,也算遂我所愿了。
整洁代码以其对细节的关注,荣耀了深埋于我们现有、或曾有、或该有的壮丽文化之下的智慧根源—出自《代码整洁之道》,彼时便被技术书籍的这种气质所折服,原来技术书籍也可以这样写,这分明是一种艺术;如同对的时间遇到对的人,程序大抵是在正确的时间将正确的值赋给正确的数据处理单元进而得到正确的结果。技术的范围很大,我所能写不过是关于IT世界里小小一片,从一个小小视角。但愿尽我所能,有所记录,有所思考,关于技术,关于技术学习。
01
—
匠心
关于技术人,我有一个相对狭隘的定义,技术源于匠心,技术人也应该有一颗匠人之心。技术人看待自己写的程序,如同看待自己的孩子,如果恰好是从零开始构建的,那就更幸运了,这孩子便如同亲生;而大部分时候技术人是要维护他人的程序的,这便如同抚养他人的孩子,这便需要技术人的博爱了。如果恰好这程序的亲生父母当真视之如亲生,那便是技术人的幸运了,视如己出也未尝不可。技术人的特质说不十分清楚,也不敢妄下断言,只是一种直觉,基于这些年的所见、所闻、所感。如今负责部门大部分的技术面试,也让我有机会见识到更多的“技术人”,而这种见识某种程度上要比同事之间技术层面的了解更为深入,针针见血、刀刀见红,使出浑身解数在回合间切磋,有大牛、有小白,从20多岁到40多岁,有高山仰止、有唏嘘不已。技术的世界里,除却技术能力之外,我也时常揣度一个人的技术特质,如果恰好有幸彼此成为同事,那便可有更多的机会加以印证,只是时常不在多数。
02
—
工欲善其事必先利其器
如果说技术学习的道路上有什么能够让我无论如何强调其重要性都不为过的东西,那一定是Google和英语。试想一下,众里寻他千百度,蓦然回首就在Google处,这便是效率;至于英语,鉴于诸多技术官网、问题论坛均为英文,读官方文档或者原始材料绝对是相对事半功倍的事情。所以,无论采用什么手段,无论付出什么努力,一定一定要解决这两个问题,因为它们代表的近乎是另一个世界,至少是一条捷径。
03
—
终身学习
IT世界的技术人终身学习是一种宿命,如果说任何行业都需要终身学习,我并不反对,也确实广为流传,但IT技术人的终身学习是关乎“生死存亡”的,技术的更新迭代快得让人发指,新技术层出不穷。比如初识编程时的Delphi、VB已然接触不到,Android 、IOS横空出世,大数据、机器学习也甚嚣尘上,Java也从1.4到了13, spring从2到了5以及衍生出的boot、cloud,从ssh到ssm等等等等,不一而足。当然,有些东西倒是不怎么变化的,我常称之为内功,如:数据结构、算法、编程思想、设计模式、软件工程、项目管理等等之类。由此而来对应的招式,如:DB(关系、列、图)、语言(Java、Go、Python、js等)、框架(Spring、Hibernate等)、工具(docker、idea、git、maven等)。招式与内功各有千秋,既然如此区分,自然对待方式有所不同,各有各道,但终身学习应当是逃不掉。
04
—
系统化学习
关于技术学习,这是我觉得最有用的一句话。关于技术,如今已经有太多的渠道可以获取,大多情况,只要你想你便可以得到相应的资源,遍地的开源项目、技术博客、官方文档、教学视频,无论收费或者免费,总能铺天盖地。面对这般境况,鉴别资源确实是很重要的能力,但这种能力不是天生的,是建立在广泛涉猎后的有目的学习的基础上。那如何有目的的去筛选自己需要的知识呢?建立知识系统,这是我所能想到的最有效的学习方式,即系统化学习。试想,想学习一种新技术,首先通过官网总览所有的能力,构建出对这项技术的初步印象,进而通过搜索工具明确初步印象中模糊的概念或者知识点,最后将这些明确的知识点以系统化的方式组合起来,无论组合得多么蹩脚或者错误,只要是自行思考的结果,那脑海中便有了关于这项技术的技术树或者知识图谱,就像一个大纲,至少是一个属于自己的系统性的东西。之后,随手看技术文档也好,实际应用也好,都不要忘记这个系统,最终的落脚点也一定在丰富这张图上。日积月累,时常琢磨,修修补补,维护好这个系统,关于这项技术便逐渐成长至于根深叶茂。这便是我关于系统化学习的理解,后续的技术文章大抵也是按这个思路来组织。
05
—
两个角度
使用与构建;面对复杂的知识系统,如果能够不时的从这两个角度分别加以审视,也是一种不错的体验,就如同一个人如果能够区分理想和现实一样,自然活得更加明白一些。关于技术,大多时候我们是处于使用者的位置,比如spring大多数时候我们需要做的是学习如何配置、如何集成、如何加载,这显然是站在使用者的角度学习去如何运用以至于熟能生巧;如果换一个角度,一个构建者的角度,考虑如何去实现一个自己的spring,如何解决配置、加载、依赖注入、集成,那将是一个截然不同的世界。事实上,大多时候我是容易不知不觉迷失在使用和构建两个角度的混沌之中,尤其是初次面对一种新技术,做到随时切换到两个不同的角度去审视,审视自己的需求,进而隔离击破,是相当困难的。只好时常提醒,想来是一个不错的办法,时常提醒自己分析一下目前关注的点到底是使用者的角度还是构建者的角度,当真大有裨益。
06
—
征服
征服才是技术人的本能;技术人要征服的不是技术本身,而是技术路上的障碍。犹豫不决、拖延、三分钟热度、害怕拒绝、自我设限、逃避现实、总是找借口、恐惧、拒绝学习,这些障碍和技术无关,却成了真正的阻碍。技术人的本能便是征服,也唯有征服。
如果说技术有内功与招式,技术学习同样也是;如果说工欲善其事必先利其器、终身学习、系统化学习、两个角度算得上是学习的一些招式,那匠心与征服可算得上是技术学习的内功了。
学而不已,阖棺乃止,技术人尤当如此。