我的第一个项目的收获

作者分享毕业设计管理系统项目经历。项目要求用Jsp和Javabean实现,作者负责建模和Javabean,后兼做数据库。在需求分析、建模、数据库设计、Javabean设计等方面遇到诸多问题,如对象模型向关系模型妥协、O/R Mapping痛苦等。后来接触主流技术,解决了之前的困惑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

孔子说:“学而不思则罔,思而不学则殆。”从我做项目的经历,我深深感叹古人的智慧。

 

去年我毕业设计时候做的一个项目是毕业设计管理系统。当时老师给我们的要求是用Jsp Javabean来实现。我主要负责项目建模和Javabean部分,后来负责数据库的同学被SARS困在家不能返校,所以数据库部分也由我来完成了。当时对java的知识是非常贫乏的,只有简单的语法基础,连jsp javabean都是第一次听到过。不知道从哪里开始,于是就研究老师给的一个非常简单的演示项目,首先觉得javabean是个比较简单的东西,于是就先开始分析用户需求。

 

需求怎么来描述呢?由于学校教育的局限,加上自己研究了很长时间高数,政治,英语(干什么用大家都明白吧),造成了知识的严重匮乏。我就以参加毕业设计人员为中心,建立他们的需求列表。但是这样的需求描述是非常片面的,几乎都是静态的需求,而且很难设计几个用户的交互过程,和某些状态的改变。而且这种需求是否有真正符合需要是个问题,所以我立刻和同学一起设计web界面,目的很简单,因为用户的需求都是通过界面来实现的,对界面的设计能涵盖最终提交用户的功能,而且还能发掘很多非用户的需求。这样我在实现这些功能的时候会有数。在一年后当我仔细看过用例分析,uml后感觉是如获至宝。心头的结全部打开。

 

建模该怎么建?当时真是什么概念都没有,虽然知道uml,但是仅仅知道皮毛。于是我就很简单的从对象的角度考虑问题,首先找毕业设计管理系统中涉及的人员,这个是很明显找出来的,涉及到学生,教师,管理员,进一步提取出项目对象,各个人员之间通讯的消息对象,毕业设计文档对象,等等。接下来设计数据库表,由于学校教数据库的时候只有讲述了ER图到关系模式的转化,而根本没有讲ODL到关系模式的转化(现在看来,ODL应该更好,对理解O/R Mapping有更多的帮助。)于是就画ER图,建立各种表,设定主键,外键,等等。

 

我遇到的首要问题就是学生,教师,管理员该怎么办,每一个对象建一个表,似乎也没有什么问题。但是在建立消息对象的时候就有问题了,因为消息是要在学生,教师,管理员任意两者都能传送的,我建消息表的时候是这样设计的:一个消息的内容,消息的发送人,消息的接收人(消息内容和发送人一个表,为解决冗余接收人单独一个表),这样这个消息就有很大的灵活程度了,消息发送人可以是三种角色间的随便一种,更进一步,这样的消息可以是系统生成的消息,而且接收者可以是随便哪种角色。但随之带来的问题是:消息发送人、接收者该去参照谁呢?显然填一个发送者、接收者的id是不够的,必须连发送者的角色也填上。第二种方法,每个角色有一个收到消息的列表,让它去参照单一的消息表id,这样也能解决问题。第三种方法,把学生,教师,管理员合并成一个用户表,那么消息发送人,接收人只要简单的参照一个通用的用户id了。这种合并子类的方法会造成教师,管理员的行有些null值,但是考虑到教师和管理员的数目远远小于学生的数目,所以这样的冗余是忽略不计的。最后我还是选择了最后一种方法。不过我还是觉的是对象模型向关系模型的一种妥协。

 

接着我着手设计javabean,访问数据库用的是单纯的JDBC。因为我对前台界面要访问一个对象的哪些属性是不了解的,事实上也不该了解。所以我只能从数据库取出一个完整的对象,让他来决定究竟要访问哪些属性。而且对对象的修改也是这样,前台修改好新的对象的属性,我来进行更数据库的同步。于是我的javabean就出现了这样的方法:load()、 store()、 update()、delete()这样的对象和数据库表同步的方法。这在一年后的今天看来,实际上我已经自己做了一个O/R Mapping的工作了。当时自己做这样的O/R Mapping是相当痛苦的事情,而且用的方法也是最粗浅的,就是整个对象更数据库同步,即使没有修改的属性也同步,所以要同步的话,必须要先把对象从数据库取出来,修改后再写回。而且要求所有属性必须是nullablenon-primitive类型。第二个问题,对表中的外键怎么反应到bean中?比如每个学生有一个辅导教师,在数据库中很明显学生表需要一个外键参照教师id,但是在StudentBean中教师属性是写Teacher对象呢,还是Teacher id值呢,按照面向对象,很明显应该Teacher对象,但是我就觉得这是个多么heavy的事情呀!再想想教师情况,一个教师有一个CollectionStudent对象是多么“重”!意味着load一个教师要load所有的students。于是我采用的方法是:还是用对象,比如teacher 的学生属性,还是一个collection  Student对象,同时提供了一个loadStudents()的方法,load teacher对象的时候并不load 学生属性,只有bean的用户显式调用loadStudents()的时候才会加载一组student对象,这在现在看来似乎我自觉不自觉的实现了lazy loading

 

现在审视当时编写的javabean,犯的最大最大的错误就是把data access objectbusiness workflow混在一起了。比如把教师所有要调用的功能都放在教师对象里面,而有些功能有时是要涉及几个bean的。现在看了简直是惨不忍睹的设计,虽然当时也困惑过,但是却没有动动脑筋来解决,我现在看了session bean 的思路时,觉得是那么的舒畅、自然。

 

当时困惑的还有关于jsp的处理,jsp只是负责显示的,但是为什么一个jsp提交的数据要给另外一个jsp去处理呢?这是很不舒畅的做法,于是有了最初的servlet做控制器的想法,但是当时顾不了研究那么多,也没有最终实现,毕竟前台不是我负责的。当我现在知道了StructsMVC Model2的时候,我以前的困惑都随之解决。又一次感觉非常舒畅。

 

以上是我一个新手的第一个项目的一些情况,是在非常闭塞的环境里面做的,上网都是电话卡拨号,根本没有接触到主流技术,但是正是这种环境下积累的无数困惑,使我遇到EJBHibernateStructs的时候如饮甘露,迅速的吸收了他们的营养。否则我想学习这些技术无疑是很耗时间的,因为根本没有更这种技术产生共鸣,不知道他们搞那么多框框究竟想干什么,而我产生了一种共鸣,他们这些框框,正是开我心头疑惑的锁。

 

又回到开头孔子的话,事实上我在做项目中,一直都是按自己的思考方式在“思”而没有去“学”,所以常常感到疲倦而无所得,即“殆”。但是如果不实际自己去动手做,而光光学j2ee,必然会很迷惑,即“罔”。我感觉先有困惑再有解决,是掌握技术的十分有效的而且巩固的方法,而且很有创造性,是属于归纳的思考方式。所以碰到问题,首先需要想想按常理该怎么去解决,再去寻找别人怎么解决的,这样自己提高会十分迅速。
<think>我们正在寻找C语言项目创意或实践任务。根据引用[1],C语言是许多其他语言的基础,深入掌握C语言有助于理解其他语言的底层实现。因此,一个好的C语言项目应该能够帮助理解计算机底层原理、内存管理、算法实现等。以下是一些适合不同水平的C语言项目创意:1.**基础项目**(适合初学者):-**通讯录管理系统**:实现一个命令行下的通讯录管理程序,支持添加、删除、修改、查询联系人信息(如姓名、电话、地址等),并将数据保存到文件中。-**计算器**:实现一个支持加减乘除、括号、指数等运算的科学计算器,可以解析表达式并计算。2.**中级项目**(需要一定的数据结构和算法知识):-**文件压缩工具**:使用哈夫曼编码(HuffmanCoding)实现一个简单的文件压缩和解压工具。-**简单数据库**:实现一个基于文件的小型数据库,支持创建表、插入、删除、查询等基本操作,可以使用B树索引。3.**高级项目**(涉及系统编程、并发、网络等):-**多线程Web服务器**:实现一个支持多线程的简单HTTP服务器,能够处理静态文件请求。-**操作系统相关**:实现一个简单的命令行解释器(Shell),支持管道、重定向等基本功能;或者实现一个简单的内存分配器(malloc/free)。4.**算法与数据结构项目**:-**实现常用数据结构**:如链表、栈、队列、哈希表、二叉树、图等,并实现相关操作。-**算法可视化**:使用图形库(如SDL)可视化排序算法(快速排序、归并排序等)或路径查找算法(A*算法、Dijkstra算法)。5.**硬件相关项目**(需要硬件支持):-**嵌入式系统开发**:使用C语言控制Arduino或树莓派,实现LED灯控制、温度监控等。-**驱动程序开发**:在Linux环境下编写简单的字符设备驱动程序。6.**游戏开发**:-**控制台小游戏**:如贪吃蛇、俄罗斯方块、扫雷等,使用控制台字符界面实现。7.**网络应用**:-**聊天程序**:实现一个基于TCP/UDP的简单聊天程序,支持多个客户端。这些项目可以帮助巩固C语言知识,同时提升编程能力。请根据自身水平选择合适的项目。§§相关问题§§1.如何开始一个C语言项目?2.在C语言项目中如何管理内存?3.有哪些调试C语言程序的技巧?4.C语言项目如何实现文件操作?5.如何用C语言实现一个简单的HTTP服务器?</think>### C语言项目创意与实践任务 以下项目创意兼顾实用性与学习价值,涵盖不同难度层次,适合巩固C语言核心能力(内存管理、指针、数据结构、算法等)。每个项目均提供核心实现思路及学习目标: --- #### **1. 简易文件压缩工具**(中级) **目标**:实现基于哈夫曼编码(Huffman Coding)的文件压缩/解压程序。 **核心任务**: - 读取文件二进制数据,统计字符频率,构建哈夫曼树。 - 生成字符编码表,将原文件转换为压缩后的二进制文件。 - 实现解压功能,通过哈夫曼树还原原始文件。 **关键技术点**: ```c // 哈夫曼树节点结构 typedef struct Node { char data; int freq; struct Node *left, *right; } Node; // 优先队列实现(最小堆) Node** create_min_heap(int capacity); void heapify(Node** heap, int size, int i); ``` **学习收获**: - 深入理解树结构、堆操作 - 掌握二进制文件读写(`fread`/`fwrite`) - 实践内存动态管理(`malloc`/`free`) --- #### **2. 命令行数据库系统**(中高级) **目标**:构建支持增删改查(CRUD)的简易数据库,数据持久化到文件。 **核心功能**: - 创建表结构(如学生信息表:学号、姓名、成绩)。 - 支持SQL-like命令: ```sql INSERT INTO students VALUES (101, "Alice", 85.5); SELECT * WHERE score > 80; ``` - 数据以二进制格式存储,支持索引加速查询(可选B+树)。 **关键技术点**: ```c // 数据记录结构 typedef struct { int id; char name[50]; float score; } Record; // 文件分块读写 void write_block(FILE *fp, Record *block, int count); ``` **学习收获**: - 文件I/O高级操作 - 数据结构优化实践(哈希表/B+树) - 命令行参数解析(`argc`, `argv`) --- #### **3. 多线程网络聊天室**(高级) **目标**:实现服务端-客户端架构的实时聊天室,支持多用户并发。 **核心组件**: - **服务端**: - 使用`socket()`创建TCP监听 - 为每个客户端创建线程(`pthread`) - 消息广播:将客户端消息转发给所有在线用户 - **客户端**: - 独立线程接收消息并实时显示 **关键技术点**: ```c // 服务端核心逻辑 void *handle_client(void *arg) { int client_fd = *((int*)arg); char buffer[1024]; while (recv(client_fd, buffer, sizeof(buffer), 0) > 0) { broadcast(buffer); // 向所有客户端发送 } } ``` **学习收获**: - Linux网络编程(`socket`, `bind`, `listen`) - 多线程同步(互斥锁`pthread_mutex`) - 实战并发编程模型 --- #### **4. 嵌入式温度监控系统**(硬件交互) **目标**:通过树莓派/Raspberry Pi读取传感器数据,实现温度异常报警。 **硬件需求**:DS18B20温度传感器、LED/蜂鸣器。 **核心逻辑**: 1. 读取`/sys/bus/w1/devices/28-*/temperature`文件获取温度值。 2. 若温度超过阈值,触发GPIO输出控制LED闪烁: ```c // GPIO控制示例 #define GPIO_PIN 17 void set_gpio_high(int pin) { FILE *fp = fopen("/sys/class/gpio/export", "w"); fprintf(fp, "%d", pin); fclose(fp); // ... 设置方向为输出并写入值 } ``` **学习收获**: - Linux系统文件操作 - 硬件交互原理 - 实时系统设计思想 --- #### **5. 算法可视化工具**(图形库结合) **目标**:使用SDL库可视化排序算法(如快速排序、归并排序)。 **核心实现**: - 生成随机数组,用柱状图表示数据。 - 每一步排序后刷新画面,高亮比较/交换的元素。 ```c // SDL绘图示例(绘制柱状图) void draw_bars(SDL_Renderer *renderer, int arr[], int size) { for (int i = 0; i < size; i++) { SDL_Rect rect = {i * 10, 400 - arr[i], 8, arr[i]}; SDL_RenderFillRect(renderer, &rect); } } ``` **学习收获**: - 第三方库集成(SDL/OpenGL) - 算法过程直观化 - 事件驱动编程 --- ### 项目选择建议 - **初学者**:从文件压缩工具开始,强化指针与数据结构。 - **进阶者**:尝试数据库系统或聊天室,掌握系统级编程。 - **硬件爱好者**:嵌入式项目提供物理交互体验。 > 提示:所有项目务必注重**内存安全**(避免泄漏/越界)和**错误处理**(检查函数返回值)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值