博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

课程内容总结

 

课程:《程序设计与数据结构》
班级: 2023
姓名:何锐
学号:20202304
实验教师:王志强
总结日期:2022年1月1日
必修/选修: 必修

 

首先,在开始总结之前,我们要明确,无论什么课程,没有能完全教你方方面面的,作为一名编程学习者,相对与很多科目来说,更重要的是要不断练习,自学,并且不断纠错成长。

在学这门课程之前,我一直以为,这只是我在第二学习学习过的c语言的另一个样子,面向对象的概念也不了解。后来,在跟着王老师学习了一段时间后,逐渐明白,其实编程的思想才是共通的,各种语言有各种语言的长短处,用它看似在解决数学或者习题,但其实是用它解决实际问题的练习与积累,很感谢这门课程,极大地激发了我学习编程的兴趣,以下我会从三个方面去展开我本学期的学习总结。

 首先,老生常谈,从根本上来讲,这些都是程序开发的基础。要学好基础,才能在以后进行更多的、更难的软件、管理系统开发。

 

 

一、关于Linux

严格上来说,linux并不是操作系统,而是一个操作系统的内核,严谨一些可以说:linux 一般指 GNU 套件加上 linux 内核。

 在这学期一开始的时候,王老师就带我们进行了linux内核系统ubuntu的安装,并且在ubuntu上进行了简单的程序开发。起初我并不能理解为何这么做,后来,在逐渐自学了很多linux系统的相关知识后,发现linux有很多优点,开源仅仅是第一部分,使用者可以直观地获取linux的实现机制,并且高度自由的自定义。而且,linux系统性能稳定,核心防火墙组件性能高效、简单。

并且,使用linux学习java,更容易让初学者理解java的特性与编程思想,更容易加快java学习进度,和从根本上理解java的运行方式。

再者,从现实意义的角度上说,我们都是未来某一个事业里的后备人员,如今国产化趋势明显,要求高,如今众多pc端国产化平台的操作系统都是基于linux内核制作的,所以,尽早学习liunx只有好处。

但是从目前的了解来看,linux还存在好多待解决的事。比如他的产品生态确实不行,游戏啊应用啊啥也没有。还有就是在使用过程中,那个应用市场好难用,我每次都得用命令行下载。而且,虽然用linux的命令行去做java程序设计会更容易理解其运作方式,但是很多冗杂的简单重复性的操作比起集成开发系统,vim还是稍有逊色。

其中,学习最多的应该是命令行sudo,允许系统管理员让普通用户执行一些或者全部的root命令的一个工具,如halt,reboot,su等等。这样不仅减少了root用户的登录 和管理时间,同样也提高了安全性。

(一)

1.基本命令

ls 列出当前目录下的文件(ls -a可以显示当前目录中的所有内容,包括隐藏文件和目录)

cd 目录名称 = 进入某目录  (cd ..便是退回上一目录)

mkdir 创建文件夹

rm 删除当前目录下某个文件  

mv 将某文件转移或重命名

cp 复制某文件至某地

2.帮助类命令

info

命令是Linux下info格式的帮助指令。阅读 info 格式的文档。

man命令:可以通过一些参数,快速查询linux帮助手册,并且格式化显示。

cheat

cheat命令是在GNU通用公共许可证下,为Linux命令行用户发行的交互式备忘单应用程序。

3.更多

还有很多命令,使用率不高,但可以便利很多操作。

find查找一个文件在系统中的什么位置,locate是神速版本的find。可以通过cheat find学习find命令。

grep 可以对文件全文检索

whereis,which告诉你使用的命令工具装在什么地方。

apt-cache可以在使用apt-get install安装一个程序时先找找软件源的库里有没有这个程序,有才可以安装。

(二)

用sudo进行程序编写:

(1)编辑

对于java程序的编辑,在linux系统中主要通过vim实现。Vim是一个非常好的文本编辑器。

首先,vim可以直接通过在终端中使用   vim 文件名   或者    vi 文件名    来创建文本文件,通过不同的文件后缀也可创建不同类型的文件。

(2)编译

在完成一个java文件的编辑后,即写完一个完整的.java文件后,通过命令  javac 文件名   来对该java文件进行编译。

(3)运行

这里的hello文件是最基础的helloworld。

运行该程序,即hello.class文件,通过命令  java 文件名(此时不需要扩展名)  即可运行程序,如图:

(4)调试

调试可以通过JDB和GDB调试工具对java代码进行调试,jdb 文件名 对其进行调试。

设置断点:方法断点、行断点、条件断点、临时断点。

stop in xxx 设置断点

 run 使程序运行

 next 使程序运行下一行

以上便是关于linux的学习总结。

 

 

二、关于java

java是一个面向对象程序设计的高级语言,相比与大一第二学期学习的c语言而言,编程的思路和方法不一样,但是编程的总思想还是相近的。不过,java还有一个独有的jvm核心技术,这个东西能帮助java在所有的平台使用java,保证了通用性和跨平台功能。java有很多特性,还有,他是大小写敏感的语言,还有很多预装的程序包,能大大提高java编程的方便性。

再者,学习java对我还有很大帮助的一点是,Android是基于java进行开发的,于是在学习java的同时能够学习安卓的开发。

java开发就和所有其他程序开发一样。

首先,我们要用java语法进行程序的编写,然后通过java字节码和jvm编程所有平台(一般是pc)能够执行的形式,这是java的特点,这表明java是中立结构,也就保证了java跨平台的高效性。如果是开发过程的话,我们还要注意查找bug和优化程序。

在java开发中,一个程序由类组成,类又包含方法,但是主程序要包含一个main方法,他是程序的入口。这里呢,有一个潜规则(非必须但是建议),主类名的单词首字母大写。不过有个必须的事:文件名和主类名要一致。对于在java中使用的标识符来说,它由字母、数字、下划线和美元符号组成(注意:数字不能在开头用)。并且,本来的程序包中的选定词(如String,System等)和保留字自己就别用了。

以下是保留字:

 

 对于java来说,空格、回车和Tab在计算机处理的过程中会自动忽略掉。(但是你别写程序的时候啥也不用)。

最后,来了解一下java的调试程序JDB。(一般来说,如果你写的程序是有语法错误的话它是无法运行的,但是Java程序中有逻辑错误,就需要使用JDB来进行调试了。)

调试程序先要学会设置断点,这样才能让程序停在你感觉有问题的代码处进行排查。学习调试我们要学会设置四种断点:

  • 方法断点
  • 行断点
  • 条件断点
  • 临时断点

stop in 用来设置方法断点,stop at 设置行断点,stepi和next都是单步执行命令。run运行至断点。quit和exit可以退出JDB。

在之后我们使用idea是,我更推荐另一种更好用的方法,使用JUnit(java单元测试工具)

它是指对软件中的最小可测试单元进行检查和验证。对于单元测试中单元的含义,要根据实际情况去判定其具体含义,也就是你要根据其伪代码进行理解后去用JUnit去测试。

软件开发(区别于程序开发)

软件设计—软件实现—软件测试(代码过程:伪代码-产品代码-测试代码)

在上面都理解后,你同时也可以去学习TDD开发模式,就是测试驱动开发,是一种逆向逻辑思维,先写测试代码,然后再写产品代码。

在开发程序的过程中,你还需要了解面向对象程序的原则:

S.O.L.I.D原则,

  • SRP(Single Responsibility Principle,单一职责原则)
  • OCP(Open-Closed Principle,开放-封闭原则)
  • LSP(Liskov Substitusion Principle,Liskov替换原则)
  • ISP(Interface Segregation Principle,接口分离原则)
  • DIP(Dependency Inversion Principle,依赖倒置原则)

接着就是到软件设计到软件实现步骤之中最重要的一部分,及代码的编写。

首先,在写java时要明白如何写类,要先了解类间关系。

1.继承,继承指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力。在Java中继承关系通过关键字extends明确标识,在设计时一般没有争议性。在UML类图设计中,继承用一条带空心三角箭头的实线表示,从子类指向父类,或者子接口指向父接口。

2.实现,实现指的是一个class类实现interface接口(可以是多个)的功能,实现是类与接口之间最常见的关系。在Java中此类关系通过关键字implements明确标识,在设计时一般没有争议性。在UML类图设计中,实现用一条带空心三角箭头的虚线表示,从类指向实现的接口。

3.依赖,简单的理解,依赖就是一个类A使用到了另一个类B,而这种使用关系是具有偶然性的、临时性的、非常弱的,但是类B的变化会影响到类A。比如某人要过河,需要借用一条船,此时人与船之间的关系就是依赖。表现在代码层面,为类B作为参数被类A在某个method方法中使用。在UML类图设计中,依赖关系用由类A指向类B的带箭头虚线表示。

4.关联,关联体现的是两个类之间语义级别的一种强依赖关系,比如我和我的朋友,这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的。关联可以是单向、双向的。表现在代码层面,为被关联类B以类的属性形式出现在关联类A中,也可能是关联类A引用了一个类型为被关联类B的全局变量。在UML类图设计中,关联关系用由关联类A指向被关联类B的带箭头实线表示,在关联的两端可以标注关联双方的角色和多重性标记。

5.聚合,聚合是关联关系的一种特例,它体现的是整体与部分的关系,即has-a的关系。此时整体与部分之间是可分离的,它们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享。比如计算机与CPU、公司与员工的关系等,比如一个航母编队包括海空母舰、驱护舰艇、舰载飞机及核动力攻击潜艇等。表现在代码层面,和关联关系是一致的,只能从语义级别来区分。在UML类图设计中,聚合关系以空心菱形加实线箭头表示。

6.组合,组合也是关联关系的一种特例,它体现的是一种contains-a的关系,这种关系比聚合更强,也称为强聚合。它同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束,比如人和人的大脑。表现在代码层面,和关联关系是一致的,只能从语义级别来区分。在UML类图设计中,组合关系以实心菱形加实线箭头表示。

在对以上的类间关系进行合理运用后便能积少成多地编写多功能高集成的程序了。

同时,在整体的程序学习与理解外,我们还学习了很多细节。

1.三大特性:封装、继承、多态,

封装是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。可以防止该类的代码和数据被外部类定义的代码随机访问。要访问该类的代码和数据,必须通过严格的接口控制,最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。可以让程式码更容易理解与维护,也加强了程式码的安全性。

继承则如上面所讲的继承关系。

多态是同一个行为具有多个不同表现形式或形态的能力。就是同一个接口,使用不同的实例而执行不同操作。

2.文件读写与输入,在程序中获取外界输入:直接输入的string和文件读取的io流。

3.服务器和客户端的开发与构建

4.安卓开发

(由于篇幅问题,牵扯到细节的部分有所取舍,如有获取更多内容的需要可以私下来交流 :)  )。

 

三、关于数据结构

这是整个这节课中内容最多、最杂也最难的内容,相比与数据结构,前面的内容更偏向于基础与能力,而数据结构则是对前面的比如java的应用去解决数学等实际问题。

计算机是一门研究用计算机进行信息表示和处理的科学。这里面涉及到两个问题:

  • 信息的表示
  • 信息的处理

信息的表示和组织又直接关系到处理信息的程序的效率。随着应用问题的不断复杂,导致信息量剧增与信息范围的拓宽,使许多系统程序和应用程序的规模很大,结构又相当复杂。日常生活中,人们习惯以松散的方式处理信息:比如板子上的钉子,笔记本中的便条,或者文件夹中的图片。然而,用计算机处理信息需要将数据规则地组织起来。

数据结构是指相互之间具有(存在)一定联系(关系)的数据元素的集合。由于我们追求数据的效率和重用性以及在计算机上的抽象原因。

首先,我们先来了解数据。

在java中,我们将其分为常量与变量。变量可直接定义,常量在定义符号前加一个final。

以下是8种基本数据类型和定义:

整形与浮点型(数值型):byte、short、int、long、float、double

字符型:char(字节)、String

布尔型:bollean

在计算机的数据计算力,由于计算器进行读取的方式是后缀表达式,所以运算符的优先级十分重要,如下:

 

 

数据结构的三个组成部分:

  • 逻辑结构: 数据元素之间逻辑关系的描述
  • 存储结构: 数据元素在计算机中的存储及其逻辑关系的表现称为数据的存储结构或物理结构。
  • 数据操作: 对数据要进行的运算

 1.逻辑结构:

元素之间的相互联系(关系)称为逻辑结构。数据元素之间的逻辑结构有四种基本类型:

  集合:结构中的数据元素除了“同属于一个集合”外,没有其它关系。

  线性结构(1:1):结构中的数据元素之间存在一对一的关系。

  树型结构(1:M):结构中的数据元素之间存在一对多的关系。

  图状结构或网状结构(M:N):结构中的数据元素之间存在多对多的关系。

2.储存结构:

元素之间的关系在计算机中有两种不同的表示方法:顺序表示和非顺序表示。由此得出两种不同的存储结构:顺序存储结构和链式存储结构。

  顺序存储结构:用数据元素在存储器中的相对位置来表示数据元素之间的逻辑结构(关系)。

  链式存储结构:在每一个数据元素中增加一个存放另一个元素地址的指针(pointer )或引用(reference),用该指针或引用来表示数据元素之间的逻辑结构(关系)。

java的开发者和之前的前辈用自己的力量与经验构建了java强大的工具包,其中就包含了极多的数据结构。主要包括:枚举、位集合、向量、栈、字典、哈希表、属性。

在其中,我们详细学过了数组、链表、栈、堆、队、树、图等一系列表示数据、处理数据的结构,并对之加以利用。

下面是我们自定义过(自己编写过自己的)的数据结构(代码在码云中,以下的内容均有)

1.ArrayList(顺序结构的线性表)

属于是java中的集合框架,是非常常用的数据结构。实现了 List 接口。底层基于数组实现容量大小动态变化。允许 null 的存在。同时还支持快速访问、复制、序列化。

2.LinkedList(链式结构的线性表)

可以被当作堆栈、队列进行操作,支持序列化,是非同步的。

对比链表和顺序表,我们可以得到一些简单的结论;
(1)若线性表需要频繁查找,很少进行插入和删除操作时,宜采用顺序存储结构;
(2)若线性表需要频繁的插入和删除时,宜采用链表结构;
(3)当线性表中的元素个数变化较大或者根本不知道有多大时,最好用链表结构,这样可以不需要考虑存储空间的大小问题;
(4)而如果事先知道线性表的大致长度,比如一年12个月,那么这种情况下可以考虑用顺序结构;
(5)当然还要考虑实际情况,来综合平衡采用哪种数据结构更能满足和达到需求和性能;
3.栈(是限定仅在表尾进行插入和删除操作的线性表)

(1)把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈,栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构;
(2)首先,栈是一个线性表,也就是说,栈具有线性关系,即前驱后继关系,只不过它是一种特殊的线性表而已;而定义中说的在线性表的表尾进行插入和删除操作,这里的表尾是指栈顶,而不是栈底;
(3)栈的应用:平衡符号,后缀表达式,中缀到后缀的转换,栈与递归;
栈的实现:由于栈属于线性表,所以栈的实现方式也有顺序实现方式和链式实现方式;并且实现时,可以直接调用前面两种线性表;

作array和linked时调用arraylist和linkedlist进行定义。

4.队列(queue):只允许在一端进行插入操作,而在另一端进行删除操作的线性表;
(1)队列是一种先进先出的线性表(First In First Out),简称FIFO,允许插入的一端为队尾,允许删除的一端为队头;
(2)队列的链表实现是很简单的,但队列的数组实现或许有些问题,因此就出现了循环数组来实现队列;
5.二叉树:(二叉树是一棵树,其中每个结点都不能有多于两个的子结点)

(1) 每个结点最多有两棵子树,没有子树或者只有一棵子树也是可以的;
(2)左子树和右子树是有顺序的,次序不能任意颠倒;
(3)即使树中只有一棵子树,也要区分它是左子树还是右子树;
(同样,二叉树也可以通过顺序存储和链式存储来实现,二叉树的顺序存储就是用一维数组存储二叉树中的结点,并且结点的存储位置,也就是数组的下标要能体现结点之间的逻辑关系,比如父结点与子结点的逻辑关系,子结点 与子结点之间的关系;但顺序存储的实用性不强,所以一般采用链式存储)
二叉树存储后,由于在程序中不好直接读出,还需要遍历:

(1)前序遍历:先访问子结点,然后前序遍历左子树,再前序遍历右子树。

(2)中序遍历:从根结点开始(但并不是先访问根结点),中序遍历根结点的左子树,然后方式根结点,最后中序遍历右树。

(3)后序遍历:从左到右先叶子后结点的方式遍历访问左右子树,最后是访问根结点。

6.图:一个图就是一些顶点的集合,这些顶点通过一系列结对(连接)。(对于图,我们使用了两种在java中储存的方法)

(1)邻接矩阵

建立一个顶点表(记录各个顶点信息)和一个邻接矩阵(表示各个顶点之间关系)。

特点:无向图的邻接矩阵是对称的;顶点i 的度=第 i 行 (列) 中1 的个数;

(2)邻接表

对每个顶点vi 建立一个单链表,把与vi有关联的边的信息(即度或出度边)链接起来

 

以上基本就是这学期学习过程的收获啦,很多地方还有更多的细节,同时还有很多不足,还要继续努力学习啊。

下面是这学期,作业和自学的代码统计。