Java的编程逻辑(Java基础)(SE传)【一】(执行语句 跳转实现原理 栈 内存分配)

Java的编程逻辑(Java基础)(SE传)


前言

作者是大一学生:
由于学习Java的路上出现了很多资料和视频还有很多的书籍,
作者本人很喜欢纸质书籍和手写笔记,
所以就将部分手写笔记,纸质书籍很适合的例子,
部分自己的理解,和直面面经问题的需要,
以上元素综合作此系列,
我更倾向于叫>手账,写在博客里,
如果有需要可以看看,或许有些收获。如果喜欢可以收藏,
有任何意见或者建议可以私信或者留言

一、第一部分 编程基础

这章节更倾向于编程语言基础薄弱的同学观看如果
如果有一定的编程基础可以自选跳过,
或者可以看一遍疏通一下基础的编程逻辑
希望能帮到您!

>编程基础

开头的开头我们可以了解一下什么是编程
计算机是个机器,主要由CPU,内存,硬盘,输入/输出设备组成。
计算机上跑着操作系统,现在有两类大家比较熟知,分别是WindowsLinux
基本上,所有的数据都需要放在内存里去进行处理,而程序很大一部分工作就是操作在内存的数据。如何表示和操作数据,底层都是二进制表示,所以高级语言引用了数据类型和变量的概念。

1.1数据类型和变量

Java中基本数据类型(primitive type)包括:
数值类型:整数类型(byte,short, int, long)
浮点类型(float,double)
字符类型(char)
布尔类型:(boolead)
(看看就好)

  • byte:Java中最小的数据类型,在内存中占1个字节(8 bit),取值范围-128~127即-2^7 ~ 2 ^7-1,默认值0

  • short:短整型,2个字节(16 bit),取值范围-32768~32717即-2^15 ~ 2 ^15-1,默认值0

  • int:整型,用于存储整数,在内存中占4个字节,取值范围-2147483648~2147483647即-2^31 ~ 2 ^31-1,默认值0

  • long:长整型,在内存中占8个字节即-2^15 ~ 2 ^15-1,默认值0L(不加L默认为int类型)

  • float:浮点型,在内存中占4个字节,用于存储带小数点的数字(与double的区别在于float类型有效小数点只有6~7位),默认值0f

  • double:双精度浮点型,用于存储带有小数点的数字,在内存中占8个字节,默认值0

  • char:字符型,用于存储单个字符,内存中占2个字节,取值范围0~65535,默认值为NULL

  • boolean:布尔类型,占1个字节,用于判断真或假(仅有两个值,即true、false),默认值false

注:每种基本数据类型都有对应的数组类型
数组表示固定长度的同种数据类型的多条记录;这些数据在内存中连续存放
Java是面向对象的语言,除开基本数据类型,其他都是对象类型。
在这里插入图片描述
为了操作数据,需要把数据放在内存中。
内存就是在程序看来是一块有地址编号的连续的空间
数据放在内存中的某个位置后,为了方便地找到和操作这个数据,需要给这个位置起个名字。编程语言通过变量这个概念来表示这个过程。
——变量诞生了!!
声明一个变量:
int a;
其实就是在内存中分配了一块空间,这个空间存放着int数据类型,
a指向这块内存空间所在的位置(如果指针有不理解的可以先理解为房间门牌号),通过对a的操作即可以操作a指向的内存空间,
比如通过
a = 2;
这个操作即可以将a指向的内存空间的值改为2(也就是房间里存放的值改为2);
变量就是给数据起名字,方便找操作和使用不同的数据,它的值是可以改变的
是不是觉得简单,当然只是开头,此系列重点在于Java的编程逻辑而展开的。

1.2 条件执行

流程控制中最基本的就是条件执行,也就是说,一些操作只能在某些特殊条件满足的情况下才能执行,在另外一些条件下执行另外的操作。我们来看看语法和相对应的原理。
if (条件语句){ // 代码块 };或者if (条件语句) 代码块;
原理很简单就是在表达式为真的情况下才能执行后面的代码,,具体来说条件语句必须是为布尔变量,是一个直接的布尔变量,或者一个数运算后的结果。比较运算下面展示一些 内联代码片

int a = 10;
if(a%2 == 0){
System.out.println("偶数");
}
或者
int a = 10;
if(a%2 == 0) System.out.println("偶数");

if/else也很简单就是判断条件的一个布尔值,为真执行if语句内容,为假执行else里的代码。

int a = 10;
if(a%2 == 0){
System.out.println("偶数");
}else {
System.out.println("奇数");
}

是不是感觉很累赘,如果你只想表达一个简单的语句,或者就想一句话说出是不是真的?如果是真的…… :如果是假的……;这时候就来介绍三目运算符;
判断条件 ? 表达式 1 : 表达式 2;
你可以用它来对变量赋值

int max = x > y? x : y;

就这样很简便,但如果想执行多种判断条件组合 还是使用 if/else if/else 的方法。
如果只是根据变量值而言有多种可能,那就不妨试试关键字 switch;

switch () {
case1:
        代码1;break;
case2:
        代码2;break;
case3:
        代码3;break;
default :代码n;
}

很简单这就不赘述了,那么这些跳转是如何实现的呢?

1.3 跳转实现原理

条件语句具体是怎么实现的呢?程序都是一条条的指令,CPU有一个指令指示器,指向下一条要执行的指令,CPU根据指示器的指示加载指令并执行。指令大部分都是具体的操作和运算,在执行这些操作的时候,执行完一个操作后,指令指示器就会自动指向挨着的下一条指令。
但有一些特殊的指令,称为跳转指令,这些指令会修改指令指示器的值,让CPU跳到一个指定的地方执行。跳转由两种方式: 一种是条件跳转;另外一种是无条件跳转。条件跳转检查某个条件,满足则进行跳转,无条件跳转则是直接进行跳转。if、if/else、if/esle if/else、三元运算符都可以转换为条件跳转和无条件跳转,switch不太一样。
switch 的转换具体和具体的操作系统有关。如果分支比较少,可能会转换为跳转指令。如果分支比较多,使用条件跳转就会产生很多次比较运算,效率低,这时候就出现了一种效率高一些的方式,跳转表。跳转表是一个映射表,存储了可能的值及其要跳转的地址。
在这里插入图片描述
跳转表之所以高效是因为,其中的值必须是整数,且按顺序大小排列。按顺序大小排列的整数可以使用高效的二分法查找。如果值是连续的,则跳转表还会进一步进行特殊的优化,优化为一个数组,值就是下标的索引,直接根据值就可以找到跳转的地址。
程序代码源中,case的值不是按照顺序排列来的,编译器会自动排序。switch值的类型可以是byte、short、int、char、枚举、String。String用于switc时也会转换为整数处理。long容纳不下。
循环条件没什么可以写的有一个 foreach 可以注意一下(foreach 不是关键字)。通常我们可以利用foreach进行数组的遍历操作。:冒号后面跟着的是数组或者集合,每次循环index都会自己更新 。

int[] arr = {1,2,3,4};
for( int index : arr }{
System.out.println(index);
}

1.4 函数调用的基本原理

如果要清楚函数调用的实现机制,首先要了解一个概念:

1.4.1 栈的概念

我们之前谈论过程序执行的基本原理:CPU有一个指令指示器,指向下一条要执行的指令,要么顺序执行,要么跳转执行(条件跳转或无条件跳转)
程序从主函数main函数开始顺序执行,函数调用可以看作一个无条件跳转,跳转到对应的函数指令处开始执行,碰到return语句或者函数结尾的时候,在执行一次无条件跳转,跳转回调用方法处,执行调用函数的下一调指令。
这里会有几个问题:
(1)参数如何传递?
(2)函数如何知道返回到什么地方?
(3)函数结果如何传递给调用方法处的?
解决思路就是使用内存来存放这些数据,栈!
是一块内存,它有一个特殊的性质,一般的是先进后出,类似于一个桶,往栈里放数据叫做入栈,最下面的叫做栈底,最上面的叫做栈顶,从栈顶拿出数据叫做出栈
栈一般是从高位地址往地位地址存储的,所以栈底的内存地址是最高的,栈顶的是最低的。
计算机主要通过栈来存放函数调用过程中的数据,包括参数,返回地址,以及函数内部自定义局部变量。
返回值不太一样,它可能存放在栈中,但它使用的栈和局部变量不完全一样,有的系统的CPU内的相关数据放在栈的最底下,没调用一次就会将相关的函数的数据入栈,调用结束后就会出栈。
函数中的参数和函数内定义的变量,都分配在栈中,这些变量只有在函数被调用的时候才分配,而且在调用结束后就释放,但这个说法e指针对与基本数据类型,下面来看数组和对象。

1.4.2 数组和对象的内存分配

对于数组和对象类型,它们都有两块内存,一块放着实际数据内容,另外一块放着存放实际内容的地址,实际的内容空间一般是不分配在栈上的,而是分配在中(堆别急),但存放地址的空间就是分配在栈上的。
在这里插入图片描述程序结束main函数后,存放地址的栈空间会随着入栈分配,出栈释放,但存放在实际内容的空间不受影响,空间没有变量指向它的时候,Java系统会自动的回收垃圾,释放这片区域,堆中分配的空间,会被Java的GC(垃圾回收)机制回收。

1.4.3 函数调用小结

函数调用主要是通过来存储相关的数据,系统就函数调用者和函数如何使用栈做约定,返回值可以简单的认为是通过一个专门的返回值存储器存储的。
从函数调用的过程中可以得出,调用函数是由成本的,每一次的调用都需要分配额外的栈空间用于存储参数、局部变量以及返回地址,需要进行额外的入栈和出栈的操作。
其中栈的空间不是无限的,如果栈的空间过深,系统就会抛出异常java.lang.StackoverflowError,即栈溢出

总结

以上就是第一小节的全部内容
还是比较基础,下一部分面向对象

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
在一个库存管理系统中,库存增减的情景是十分常见的。比如说,当产品出售时库存会减少,当新库存到货时库存会增加。为了实现这一过程,我们可以使用Java编程语言和SQL语句来完成。 首先,我们需要建立一个数据库表来存储我们的产品信息,其中包括产品ID,名称,库存数量等字段。我们可以使用如下的SQL语句来创建一个产品表: ```sql CREATE TABLE Product ( id INT PRIMARY KEY, name VARCHAR(50), stock INT ); ``` 接着,我们可以使用Java编程语言来实现库存增减的逻辑。比如说,当有产品出售时,我们可以编写一个方法来更新数据库中对应产品的库存数量,如下所示: ```java public void sellProduct(int productId, int quantity) { // 查询当前库存数量 int currentStock = 0; String query = "SELECT stock FROM Product WHERE id = ?"; // 执行SQL查询 // 更新currentStock的值 // 检查库存是否充足 if (currentStock < quantity) { System.out.println("库存不足!"); } else { // 更新库存数量 int newStock = currentStock - quantity; String updateQuery = "UPDATE Product SET stock = ? WHERE id = ?"; // 执行SQL更新操作 } } ``` 类似地,当有新的库存到货时,我们也可以编写一个方法来更新数据库中对应产品的库存数量。通过这样的方式,我们可以实现库存增减的逻辑,并且确保数据库中的库存数量是准确的。 通过以上的SQL语句Java逻辑,我们可以很好地实现库存增减的情景。这样的方法不仅能够确保产品信息的准确性,也能够提高系统的可靠性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Duacker

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值