目录
2.2 冯诺依曼结构(Von Neumann Architecture)
一.Java EE发展历程
詹姆斯 高斯林是Java主要创始人,在1990年代初,开发Java的主要目的是用于 “嵌入式开发” 。当年最主流的语言C/C++,他们团队想要开发“智能面包机”,但由于团队成员编程能力薄弱,为了解决这个问题,发明了一个新的语言,最早叫Oak。
当时虽然产品失败,但是这个语言非常好用。恰巧互联网也刚开始起步,使用浏览器打开网页是一个比较重要的应用场景,网景(netscape)公司希望打开的网页不要只是静态的(报纸/杂志...),希望能和用户进行更多的交互,于是与詹姆斯 高斯林合作,将Oak改名为Java,这个时候Java是用来给 网页 开发逻辑的(Java是在进行“前端”开发),相关技术Applet(图书馆老的Java书有提到)
好景不长,微软的IE后来居上,抢夺了网景公司大部分的市场份额,将浏览器和操作系统捆绑销售。当时的IE也是支持Java进行前端开发的,但微软野心很大,想搞自己的语言(J++),与Java发生了冲突矛盾,微软便在IE全面封杀Java,使得Java从巅峰跌落...
但是J++没有抓住机会,反而被JavaScript抢占前端开发市场,JavaScript这个名字就是为了蹭Java的热度起的,一火就是30年,JS目前仍是前端开发最主力的语言...
Java继续寻求出路 :1)做服务器开发(后端开发) 2)做嵌入式开发
于是Java在自身基础上推出几个版本:1)Java标准版J2SE 2)Java企业版J2EE(标准版之上扩展了一部分) 3)Java精简版J2ME(标准版之上去掉了一部分)
后来又分别改成Java SE/Java EE/Java ME
Java EE开始往服务器开发这条路挺进。当年 服务器开发 领域的王者是PHP,Java仿照PHP开发了一套JSP,理念与PHP相似,但不能超越PHP。当年网站开发技术栈主要是“LAMP”:Linux、Apache、MySQL、PHP。
Java ME开始往嵌入式方向挺进。手机(功能机:摩托罗拉、诺基亚...)开始崛起,并且可以安装第三方程序-->Java ME的方式来开发的。
这两条路使得Java重回巅峰...
但是时代在前进,新的风暴又出现了...
后端领域:以PHP为首的后端开发技术,随着网站的规模变大(2010年之后),逐渐难以适应了...
移动端开发领域:2007年,乔布斯发布了第一代iPhone(载入史册的大事,标志着移动互联网时代的开启,智能手机时代的开启)2011-2012年左右,iPhone4最有影响力的版本出现了,功能机遭遇滑铁卢,导致Java ME 这一套技术体系也被雪藏...
Java还需要继续寻找出路...
后端领域:Java开始逐渐摒弃JSP这一套技术,并且Java社区中诞生了新的王者-->Spring(以Spring为首的一组框架,提供了 后端开发 的全套解决方案)并非常好地适应了 大规模网站 的开发。在Spring的加持下,Java逐渐反超了PHP,成为后端开发的No.1...
移动端开发领域:虽然Java ME倒了,但是新的王者诞生了-->Android(背后是Google)...
安卓诞生的时候,谷歌当时本来想以python作为安卓开发的语言,但是python之父龟叔(名字前三个字Gui)闹离职,和Google搞得不愉快,于是Google选择Java作为安卓的开发语言。
并且做手机开发的不少人都是Java程序员,以Java作为开发语言,就能很好的把之前那批Java ME的人招安过来。安卓上的开发者多了,应用程序多了,吸引到更多的用户,吸引到更多开发者-->正向循环...
这两条路使Java重回巅峰,一跃冲到编程语言排行榜No.1的位置...
微软也有尝试做一些事情,联合诺基亚推出了一套Windows系统的智能手机(2010年之后)-->windows phone手机(lumia系列),但生态系统几乎为0,能玩的游戏很少且要付费。
随着时间的进一步发展,2020年之后,Java也面临新的挑战...
后端领域:Java迎来最大的挑战者Golang,即Go语言(师出名门),作者是肯汤姆逊(C语言之父),丹尼斯里奇和肯汤姆逊使编程语言的活化石,早年在 贝尔实验室 搞出了 C语言+Unix,后来肯汤姆逊去了谷歌,Go语言就是C语言原班人马打造,成为C语言的继任者...
Java风格:规范,一板一眼,使得Java开发程序经常“模式套模式,框架罗框架”,开发程序显得很笨重,开发大规模程序是有优势的,开发中小规模的程序反而成为了制约 ...
Go语言风格:简单直接(核心语法都是和C语言一样,非常精简)
Go也抓住了后端开发的新的契机:分布式-->微服务化(因为一个网站后端越来越重,越来越复杂...与其一个程序解决所有问题,不如搞很多程序,相互配合,每个程序都可以变得更简单,功能更单一。多个服务器有的用Java 有的用Go,可选空间更大了)
目前Go语言在当前业界影响力是非常大的,成为Java最大的挑战者。目前Java的市场份额仍然比Go更大,即使如此,也不得不正视Go带来的威胁...
移动端开发领域:虽然安卓仍然如日中天,有一个核心问题:当年Oracle因为眼馋 安卓的收益,直接把谷歌告了,索要使用Java的授权费。
谷歌很难受...
1)开始主推Kotlin作为安卓的开发语言(Kotlin是JetBrains推出的,IDEA也是JetBrains推出的,并且谷歌在JetBrains公司有股份),Kotlin也是把编程语言 编译成兼容JVM的字节码,使得Kotlin可以白嫖Java生态(生态很重要)(后来其他人看了都说好,Scala groovy 这几个语言也是一样的效果)
2)谷歌准备推出下一代移动端操作系统。下一代系统搭载的编程语言是谷歌自研的Dart(开发平台Flutter),野心很大,想要写一套代码就可以兼容 安卓、IOS、Windows、网页前端...Dart语言语法基本 6 分像 Java,4 分像 JS,于2017年诞生。
上述的这些事情就是20-30年左右的事情,技术更新换代了好几次...作为程序员要始终保持终身学习的姿态,才不能被行业淘汰。但是数据结构、数据库、操作系统、网络...核心知识是不变的
虽然一直没有提到C++,但是C++始终在背后操盘,无论哪个技术兴起或衰落,都是C++赢了...
上述技术底层核心都是C++构成的:JVM-->C++ Go的运行-->C++ 操作系统-->C++ AI-->C++
C++也有挑战者:1)自己。最近几年 C++新版本加入很多莫名其妙的东西,导致C++的社区比较难受 2)Rust(比Go还新的语言)。Rust主打的是性能不属于C++,同时比C++更方便进行内存管理,但是Rust最大的问题是语法上十分的复杂。
现在Java EE主要用于进行服务器后端开发,即开发网站。学完Java EE就有能力独立开发出一个简单的网站。Java EE初阶主要为了网站开发奠定基础知识,Java EE进阶主要学习Spring这一套框架,学完就能很快开发网站,Spring学习的时候费劲,学会用起来就很爽了...
二.计算机相关知识
2.1 计算机发展史
1940年代,第一台电子计算机ENIAC(埃尼阿克)用于军事领域(冯诺依曼 计算机祖师爷 参与研发)。
- 艾伦 图灵(Alen Turing)也是计算机祖师爷,主要从理论上奠定了通用计算机的模型。
- 约翰 冯 诺依曼(John von Neumann)既有理论贡献,也实际研发出了计算机。冯诺依曼除了研究计算机,还参与了曼哈顿计划,是奥本海默的技术顾问。
后来计算机成为了民用的重要支撑。计算机内部构造大同小异,当前计算机的内部构造整体的规则就是冯诺依曼结构体系。
2.2 冯诺依曼结构(Von Neumann Architecture)
- CPU 中央处理器(包括运算器和控制器):进行算术运算和逻辑判断
- 存储器:分为内存和外存(硬盘 软盘 光盘 U盘),用于存储数据(使用二进制方式存储)
- 输入设备:用户给计算机发号施令的设备
- 输出设备:计算机给用户汇报结果的设备
针对存储空间
硬盘>内存 >> CPU
针对数据访问速度
CPU>>内存>硬盘
2.3 CPU
1.cpu做得好的公司
1)英特尔 2)AMD 3)高通....
英特尔虽然是老牌cpu厂商,但是目前来说,英特尔的市值只有AMD的一半左右。服务器领域,AMD也在蚕食Intel的市场。
桌面(消费市场) :Intel-->酷睿/酷睿ultra AMD-->锐龙
服务器(商业市场):Intel-->至强(e3 e5 都是早期的至强) AMD-->霄龙
2.cpu架构
- x86/x64架构 给 桌面端/服务器 来使用(性能释放更强,功耗更高)
- arm 架构 给 移动端/嵌入式 使用的 (性能更弱,功耗低,更省电)
- RISC-V(罗马数字5) 一套开源的cpu指令架构 国内从RISC-V切入来制造自己的cpu,目前国内最好的cpu大概相当于Intel10代的i3水平,足以支持军事用途。
3.cpu的核心参数
- 核心数:cpu中包含的独立处理核心的数量,每个核心都能独立执行指令,处理数据和运行程序。核心数越高,计算机性能越好。
*有几个方框就可以认为有几个核心
最早的cpu都是单核,因此当时cpu注重提高运算速度。需要让cpu集成程度更高,包含更多的运算单元,才能算的快。单个运算单元的量级已经达到了nm,经典力学失效,进入到量子力学的领域,工艺上的挑战越来越大。
横向发展不行,单核不行,多核来凑。08年左右,Intel发布“双核心”处理。后来发布“四核心”cpu,还不满足,希望四个核心每个核心都能一人干两个人的活-->“超线程技术” 4核8线程。目前,一般都是6核12线程 / 8核16线程。
对于程序员来说,最重要的任务就是充分利用好多核cpu的资源-->“并发编程” 程序员在代码中把任务拆成多个,使用不同核心分别执行.... - 频率:cpu的运算速度,使用 频率 来描述,表示处理器每秒可执行的指令数,单位Hz。频率越高,理论上性能也就越强。
:一秒运算22亿次,通常是处理器的默认运算速度,也称为基础频率,是衡量处理器性能的一个重要指标,但并不是处理器能够达到的最高速度。
:实际运行速度,实时变化的。随着速度越高,消耗电量更高,发热更多,因此计算机都有“功耗墙”,cpu温度达到一定阈值,就会自动降频。散热越好,可以让频率达到更高水准-->“超频”。平时实用阶段,cpu 频率达到 6.0GHz 就是极限了。
- 衡量一个cpu的性能 主要是看核心数是否多 频率是否高 ,更多的参数不一一展开了。
4.cpu的寄存器 (Register)
存储数据 主要是靠 内存 和 硬盘。实际上,cpu 在运算的时候,需要先把数据从内存读到 cpu 里,才能进行运算,寄存器就是 cpu 内部存储数据的部分。
寄存器特点:存储空间比内存小(kb) 速度比内存快 成本比内存高 易失性(断电后会丢失)
由于寄存器空间太小,因此cpu在计算的时候需要反复从内存加载数据,效率比较有影响,于是现代cpu引入了缓存 。缓存越大,对于有些场景性能提升是非常大的。amd 有一个 次旗舰的 cpu-->7800 x3d,有一个超大缓存 L3 (96MB),游戏性能和 Intel 旗舰 cpu 14900k旗鼓相当,被称为“一代神U”。一般都是三级缓存:
L1 缓存空间最小,速度最快 ;L3缓存空间最大,速度最慢(也比 内存 快很多)
某个内存数据经常使用,寄存器又存不下,就可以放到缓存中。数据使用频率越高,就放到L1中。
对于Java程序员来说,开发程序往往不会对 缓存 区分那么细,通常把寄存器 和 缓存视为一个整体。
CPU的内部构造不做过多讨论,计科专业会详细讲解这部分内容。
2.4 指令
1.概念
指令是计算机能够理解和执行的最基本的操作命令。C/Java语言编写的程序最终都要被翻译成“cpu上执行的二进制指令”,cpu指令 就是 汇编语言。
机器语言(二进制)<——> 汇编语言(单词符号)
不同的cpu支持的指令是不同的:x86和ARM的指令是不能通用的-->兼容性问题
2.指令表
一个 CPU 能执行哪些指令,可以认为是 cpu 最初设计的时候,就已经确定好了。存在一个"表格"描述了都有哪些指令,下面是一个简化表格:
RAM:内存,全称 随机访问存储器 内存比较大 (16GB--->160亿) ,因此地址经常使用16进制表示
A B 名字都是虚构的,真实的 cpu 寄存器名字形如 eax, ebx, esp,ebp...
真实的cpu指令表复杂很多,此处假设每个指令只有 8 bit,实际上一个指令更长。
3.指令格式
- 每条指令通常由操作码(Opcode)和操作数(Operand)组成,二进制表示
- 操作码(表示指令是干啥的):指定CPU要执行的操作类型,如加法、减法、跳转等
- 操作数(类似于参数):提供操作所需的 数据 或 数据在内存中的 地址
假设一个指令:0010 0000 --> 将地址为 0000 的数据 加载到 A寄存器 中。
C语言写好的程序,先编译成可执行的文件(exe)(包含了这个程序运行时要执行的指令和依赖的数据),双击运行时,操作系统就会把exe加载到内存中。下面的表格是模拟的加载到内存之后的过程(简化版):
CPU 中存在了一个特殊的寄存器-->"程序计数器(PC)” (在exe加载到内存之后,就能被系统自动设置好) 保存了接下来要从哪个内存位置 执行指令
此处可以认为,程序计数器就被设为0了,接下来从0号内存开始执行指令。同时随着指令的执行,这里的值也会随着更新,默认情况下 地址+1 自增执行指令(顺序执行)
如果遇到“跳转类语句”(if, while, for, 函数调用...)会被设为其他的值
4.指令执行阶段
主要有三个重要阶段:
- 取指令:CPU从内存中取出下一条要执行的指令。这个阶段通常涉及将程序计数器 (PC) 的值加载到指令地址寄存器,并从内存中读取指令
- 指令解码:CPU解析取出的指令,确定指令的操作码和操作数。
操作码指示要执行的操作类型,操作数则是 操作的数据 或 数据的地址。 - 执行指令:CPU执行指令所指定的操作。包括算术或逻辑运算、数据传输、控制操作等。这个阶段可能涉及多个步骤,包括算术逻辑单元(ALU)的计算、寄存器之间的数据移动等。
上述过程对cpu来说不是一件简单的事,但由于cpu运算速度太快了,一秒能执行几十亿次上述的运算。
对于Java程序员了解这些就够了,一个比较典型的 指令级 开发的场景 “打热补丁”。
比如: 发现服务器存在严重 bug ,但是又不能重启程序修复 bug (最多是在某些特定时间才能重启....) 此时就可以考虑"打热补丁"。写的程序的指令也是在内存中的,对应的有 bug 的代码 也是其中的一段指令。找到有 bug 的代码指令,直接修改这里的指令;或者在这个指令前加上跳转指令,让有 bug 逻辑不去执行,而是去执行新增的一个正确的指令.....等到合适的时间节点再彻底修复
对于有些特殊行业的程序员,比如外挂/黑客/病毒/渗透....需要深入理解汇编语言。
2.5 操作系统概述
- Windows
- Linux
- Mac OS(苹果电脑内置系统)
- Android(最主流的系统)--> 基于Linux演化出来的
- IOS(苹果手机/iPad)和Mac OS是两套系统
其他就是一些小众的系统,比如一些特定领域的系统,VxWorks-->工业设备 航空航天 OpenWrt-->路由器
每个系统运行的程序都是不同的(不能兼容的),因此我们希望一套程序就能兼容不同的操作系统,Java所谓的“跨平台”也就是这么来的(Windows有Windows的JVM,Linux有Linux的JVM,虽然是不同的系统,但都兼容同样的字节码,Java程序员不必考虑系统的差异)。实际上,Java的应用场景主要还是 安卓 & 服务器后端,很少会写一个跨不同平台的程序。
一个操作系统要做很多事情,其中最重要的是“管理”:1)管理不同的硬件设备 2)给软件提供稳定的运行环境——这些事情都是由操作系统的内核 即操作系统核心功能的集合 提供。
操作系统 = 内核 + 配套的应用程序
操作系统会管理各种的硬件设备,同时给应用程序提供一个运行环境(操作系统会给应用程序提供API 让调用完成不同的功能)
例:println("Hello World!") 是Java 标准库提供的函数,JVM 中 为了实现 println,就会调用操作系统提供的 API 执行 (Linux对应的系统 API 叫做 write) ,程序就会进入到系统内核执行,此时系统就会操作对应的 硬件设备 来完成打印操作。
操作系统管理的硬件设备很多,但不是系统直接操作硬件, 而是 硬件厂商 会提供对应的"驱动程序”,通过驱动程序,间接操作硬件设备的 。
例: 鼠标按钮非常多,如果把鼠标直接插到电脑上,上面很多按钮都是用不了的,必须要安装对应的驱动程序,电脑才能识别出鼠标的具体型号,以及每个按钮提供的对应功能。
更形象的理解:
标签:...,初阶,Java,--,JavaEE,常识,指令,内存,cpu From: https://blog.csdn.net/2301_80243321/article/details/140538695