项目管理套路:看这一篇绝对够用❤️

news2024/9/27 15:22:37

在这里插入图片描述

写论文必不可少的,就是创建代码并进行实验。好的项目管理可以让实验进行得更加顺利。本篇博客以一次项目实践为例,介绍项目管理的方法,以及可能遇到的问题,并提供一些可行的解决方案。

目录

  • 项目管理工具
  • 开始第一步
  • 版本管理十分关键
  • 如何进行版本管理
    • 创建分支
    • 进行改动
    • 添加改动与上传
    • 分支带来的新问题
    • 常用的git使用命令
  • 一些技巧让项目管理更简单
    • 项目结构构建
    • Commit规范
    • 文档与注释
  • 总结

项目管理工具

项目管理困难的主要原因在于,项目并非一个人构建的。许多人同时写代码,就容易出现:A改了代码的同时,B也改了代码,二人改了同一块代码,导致项目版本出现分歧的情况。这个时候,采用一个好用的项目管理工具,则可以很好地解决版本冲突的情况。Github则是一款以解决版本冲突为目标的项目管理工具,该工具跨平台皆可使用,并且简单易用,因而成为广大程序员经常使用的项目管理工具。本篇博客也就以此为工具展开对项目管理方法的经验介绍。

开始第一步

在注册完github账号之后,你就可以开始项目管理了。一般而言,项目开始之初,我们并没有一个程序项目,因而我们需要先构建一个程序项目。进入个人主页后可以在左侧个人拥有的项目库(Repositories)中找到新建(New)的按钮,点击进去后会看到这样的画面。
请添加图片描述
新建一个项目之前,需要先给项目起一个名字并填在Repository name那里,在Description那里可以填写对项目的介绍(ps: 对项目的理解越深刻,就可以用越简短的话介绍清楚这个项目到底要做什么。写Description有助于后续进行比对,并检查是否按照计划完成项目),同时还可以选择该项目是否公众可见(Public or Private),在初始化的时候可以选择添加一个README文件(ps: 建议初始化的时候就带上README文件,可以在里面写一些需要项目参与者提前知道的先验知识)。
请添加图片描述
除此之外,还可以添加.gitignore文件来指定每次git add以及git push的时候是否需要忽略一些文件(ps:每次进行实验都会产生许多中间文件,如果都把它们git push到repo里,显然会浪费很多网络资源,不利于项目开发);license这个功能限制了他人对你开源代码库的程度,不同license有不同的规则,具体请见官方文档(ps: 这个不需要在最开始就决定下来,初始化一个项目的时候并不一定要确认此项,不过为了后期开源代码能得到更多的关注,可以随着项目进展再思考license如何选择)。
请添加图片描述
建好一个代码项目,应该会有一个这样的结果。可以发现,初始化README里面的内容就是我们最开始在Description栏里写的东西。个人认为这个界面十分简洁美观,github为项目开发提供的功能其实都已经集成在这一个界面上了。菜单栏里可以看到有以下功能:

  • Code: 项目代码在这个界面里,做出的改动也会都体现在这里面
  • Issue: 这里类似于一个论坛,项目参与者可以在这里提出问题,其他参与者可以在这里进行讨论与解答问题(ps: 项目进行的过程中总会遇到许多奇奇怪怪的问题,这些问题大家共同商量出一个结果会比一个人自己闷头解决更靠谱一些,这里可以帮助项目参与者达成共识,可以有效提升项目的质量)。
  • Pull Request: 把其他分支上的代码拉到master分支上,并进行版本的融合。每个项目参与者会提供一部分功能代码,这些代码规范的写法是在不同的分支上,在各自分支上测试无误后,再由管理者将其merge到master主分支上。这一过程被称为pull request,其功能实现则可以在这个界面里实现。
  • Action: 创建工作流以自动化测试以及其他关键操作(比如pull request)。
  • Projects: 将其他相关的github repo列举在这里,方便后来的项目参与者了解情况。
  • Wiki:对与项目更加详细的介绍,好多东西无法在项目的注释里、README文档里讲清楚,这部分信息可以都放在Wiki里进行详细介绍。(ps: 文档管理做的越好,项目质量越高,但是这部分在我看了众多项目后发现,得到的关注并不是很充足)。
  • Security: 安全设置。
  • Insights: 项目流量监督。
  • Settings: 项目其他关键设置。
    请添加图片描述

以上就是在项目创建之初,我们要在远端(也就是网站)上进行的操作,下面我们要将远端的repo与本地进行联系。
请添加图片描述
本地打开终端,并输入指令git clone [url]就可以从远端拉取刚刚初始化的项目代码,从而使得本地与远端形成一个联系。

⚠️这里可能会遇到一些坑:

  1. 网络失败:是指loss connection这种错,一般错因在于本地机器的网络太过拉胯,重启网络服务、重启机器、更改网络设置等一些操作往往可以解决(ps:不过有时候就算真的这么处理了,网络该连不上还是连不上,我实验室机器的网络太过拉胯,一把辛酸泪)
  2. 没有权限:这要在本地设置ssh key 然后上传到远端,具体操作详见官方文档。

例如,对于How2Code这个例子,我需要输入指令git clone https://github.com/Doris404/How2Code.git 然后就可以看到本地机器就有一个名为How2Code的文件夹,里面含有一个README文档,和远端的设定一样。

接下来我们就可以进行项目开发了 ❤️

版本管理十分关键

Github解决的最核心的问题就是版本管理。我们先来了解一下这个问题究竟有多复杂。我将用一个例子来解释此问题的复杂程度。

一个三人团队要构建项目实现网上订餐功能,三人在项目初始阶段约定,一人实现一个功能,并且初步商定的功能包括:查询可点餐馆及可点菜品、下单与付款、评价与点评、纠纷处理等。

A作为项目主要负责人实现了下单与付款这个最复杂的功能,B实现查询可点餐馆及可点菜品,C实现评价与点评、纠纷处理这两个功能。

划分功能时大家一致认为,这些代码互相独立性比较强,所以三人分别在不同的机器上各自实现各自代码即可以做到版本管理。然而在项目进行过程中,出现了意想不到的情况。A下单与付款的功能实现依赖于B显示出来的界面。因此B最初实现的界面一旦发生改动,则A的代码实现也要跟着变更。在项目进行过程中则出现了以下情况:

  1. B 实现了一个初始界面
  2. A 基于初始界面进行功能实现,但于此同时B改动了一些初始界面,并形成了一个新版界面
  3. A 和 B都上传代码,此时A的代码不能在新版界面上测试通过,只能在初始界面上通过,但由于缺乏版本管理工具,此时的代码无法通过,并且我们遗失了初始界面。

Github提供了分支用于解决这个问题,同样是上述情况,如果我们使用branch,则是另一番景象:

  1. B实现了一个初始界面,并给它放在branch 1上
  2. A实现了基于初始界面的功能,传到branch 1上
  3. B改动初始界面,并形成新版界面,传到branch 2上

这样branch1的代码就是可以正常跑通的,而branch 2上则缺少A的代码,A则可以依据branch 1上自己实现的代码进行改动,并且提交到branch 2上。

相信从上述例子中,你已经明白了版本管理有多么关键。

如何进行版本管理

创建分支

Github提供了branch功能可以用于版本管理,这一部分我将介绍如何使用branch进行版本管理。在本地终端进入项目文件夹,输入git branch即查看当前分支名称。默认分支是master分支。
请添加图片描述
使用branch进行版本管理的第一步就是创建新的分支,运行git branch checkout -b [your branch name]即可以创建一个新的分支,并切换到这个新的分支上。
请添加图片描述

进行改动

此时你已经转到这个新的分支上了,就可以在这个新的分支上进行项目开发。例如,我改动了README文档,添加了一些文本。
请添加图片描述
则可以通过git status查看到我们哪些更改,然后决定是否要接受这些改动。

git add [your file name]则可以将对指定文档的改动添加到改动之中,如果在添加之后后悔了,可以使用git restore --staged [your file name]来撤销git add操作。执行结束后,你会发现刚才提交到改动中的改动被移除改动。

另一个git restore指令与刚才使用的git restore --staged [your file name]不一样,对没在改动中的改动git restore将撤销你在文件中做出的改动,执行结束后,在文档中的改动将消失。
请添加图片描述

添加改动与上传

git add .可以将所有的改动都添加到缓存之中,接着调用git commit -m "[your commit info]" 来添加改动的介绍,最后调用git push —-force-with-lease origin [your branch name]来将改动push到远端的指定分支。
请添加图片描述
远端可以看到,新分支创建成功,并且也有我们添加的改动请添加图片描述
请添加图片描述
可以发现,new_branch比master领先1个commit,我们可以对new_branch的改动进行比较,并决定是否merge到master分支。点击Compare & pull request则可以申请一个pull request对new_branch的改动进行融合。
请添加图片描述
填写new_branch具体做了什么改动,然后点击Create pull request即可以创建一个pull request。
请添加图片描述
创建成功后,其他参与者可以提交comment来发表对改动的建议。

值得注意的是该分支上还可以push 更多的改动。只要该分支上的改动没merge到master,在此之前该分支上的所有改动,都会集成到之前提交到pull request之中。
请添加图片描述
分支融合有3种可选方案,新手不建议选择Rebase and merge方案,建议从前2个方案中进行选择。前两个方案本质都是将改动以merge的形式加到master中,区别在于选Create a merge commit则将这两次改动分别merge进去,选Squash and merge则可以将2此commit 合并成一次commit。考虑到简洁性,建议选择Squash进行融合。

Rebase这个方法是三个方法中最为简洁的一种,它将以线性来融合改动,这同时也带来了风险。例如,如果new_branch改动和master改动出现冲突,则可能出现改动覆盖的情况,这意味着有一支的改动因为代码融合消失了。因而不建议初学者使用这个融合方式。

更多解释可以查看博客的介绍。
请添加图片描述
merge得到通过后,可以在master分支上看到之前的2次commit融合成1次commit提交到master分支上,并且commit info是第2次commit info。

至此,我们完成了一次基于分支的改动提交。

分支带来的新问题

分支提供了一个版本融合的方案,但是总会有一些菜鸟在初次使用的时候不太熟练,然后误把改动添加到master分支上,我们如何保护master分支呢?
请添加图片描述
Github提供一些规则来实现对主要分支的保护,点击Protect this branch,则可以添加规则来约束对master分支的改动(ps:这些改动也可以在setting-Branches里进行)。添加的规则种类繁多,包括每个分支的起名规则,分支提交的约束等等。
请添加图片描述
这里我选了在分支融合之前,必须要请求pull request至少1次(ps:其他的选项可以根据个人需求进行勾选)以及分支要符合标准的命名规则:name_file 分支所用者以及改动主文件名。

常用的git使用命令

git clone [url]
git branch # see which branch we are in
git checkout -b [branch name] # create a new branch and turn to this branch
git checkout [branch name] # turn to a exist branh
git add [your file name] # add your update into cache
git commit -m "[update info]" # add commit info
git push --force-with-lease origin [branch name] # push your update into [branch name]

⚠️ master分支代码就是最权威的,改动的时候一定要基于master分支,另开一个分支,然后再在这个新开的分支上改动代码,将改动push到这个新分支上,然后将此分支merge到master分支上。

一些技巧让项目管理更简单

除了上述基于Github功能的项目管理,我们也可以发动主观能动性来使得项目管理更加顺滑。

项目结构构建

在项目创建之初就应该对项目有一个明确的定位,这个项目到底实现什么功能,具体如何构建项目代码结构,才能有利于后续的代码书写,都是在项目之初有明确的定位的。这件事情非常重要!!!

至于如何获得明确的定位,是超出本篇博客的内容(ps:以我浅显的经验,明确的定位并不是一次讨论就能决定的,需要需求方和实现方多交流沟通确定)。

Commit规范

首先,就是commit info的书写规范,一般来说commit info是要做到提示参与者这次提交具体进行了哪些改动的功能,对于一个不了解情况的人而言,其能阅读的文本数量实在有限,因此需要提交者用最短的话描述出代码改动的核心。建议项目之初就总结一下commit info的书写规范,并强制要求所有参与者遵守。一个可选的例子是:

<type> (scope): describe
  • type:commit的类型说明,允许7种标识

feat: 添加新功能
fix: 修补bug
docs: 增加文档
style: 修改格式
refactor: 重构
test: 添加测试
chore: 构建过程或辅助工具的变动

  • scope:改动范围,比如某个包,某个文件
  • describe: 改动的描述,以动词开头,例如: update README.md

一个可能的例子就是:feat(train.py): add train.py表示这次改动添加了train.py文件实现了train的功能。

文档与注释

文档和注释对项目实现十分重要是所有程序员的共识,然而现实却是大家写文档和注释的意愿并不强烈。一方面是因为代码书写占据了大部分程序员的大部分时间,结束了一天辛劳工作的程序员实在没用动力去完成文档注释的书写;另一方面,文档与注释的确让项目实现变得更加简单易行,但是写文档的好处主要是体现在除去文档书写者的所有人身上,除非所有人都写文档和注释,否则文档和注释的坚持者将遗憾地发现自己做了最多的工作,而受益却是别人的。基于上述原因,文档与注释的书写情况总是不容乐观。

这篇博客不想对不写文档与注释的人进行道德上的谴责,毕竟偷懒是人之常情。本篇博客希望提供一个写文档的思路,来减少善良的程序员在写文档与注释时所承担的时间开销 ❤️

如何写文档才能提升写文档的效率呢?我的经验是,先确定文档的结构,通过子标题的形式来将文档结构简明地总结出来,然后填充每个子标题的具体内容。这样做有一个好处,可以极大地调动其他参与者的文档书写积极性。

例如,对于网上订餐项目,三人实现4个功能包括:查询可点餐馆及可点菜品、下单与付款、评价与点评、纠纷处理。A作为项目管理者,对于这个项目的结构有个非常明确的认识(至少要比B和C这两个参与者明确),因而它非常清楚本项目的代码包含从数据库获取信息模块,显示信息模块,交易模块,评价和售后模块。因而项目的文档结构也应符合项目代码结构,对这些模块进行各自的介绍。

对代码介绍的文档中则应包含这4个子标题,并且对这些模块的具体实现进行展开解释。代码实现上A对显示信息模块等非主写模块并不了解,因此他会将这部分文档书写交给给自负责的人。

上述介绍只是写文档的最基本介绍,更深入的技巧,建议读者阅读一些提升写作能力的工具书。

好消息是,文档的书写不止有手工书写这一种方法(ps:这好像是废话),一些项目文档生成工具可以帮助我们从注释生成文档。对于python代码而言,可以使用Sphinx包来轻松实现项目注释文档生成。具体使用参考博客。

注释对于我们理解函数功能有极大的作用,在写注释时可以参考一些优秀项目的注释书写规范,这里给出一个实例供读者参考。

class People(object):
	""" __init__
	Args:
		name(str): name of a person
		father_name(str): father name of this person
		mother_name(str): mother name of this person
		gender(str): can only be male or female
		config(json): config file that may contain name, father_name, mother_name, gender
	Returns:
		a person from People
	Notes:
		Some description of People
	Examples:
		person = People(
			name = 'Doris404',
			father_name = 'Xiaoming',
			mother_name = 'Xiaohong',
			gender = 'female'
		)
	"""
	def __init__(
		self, 
		name, 
		father_name, 
		mother_name,
		gender,
		config):
		try:
			self.name = config['name']
		except:
			self.name = name
		try:
			self.father_name = config['father_name']
		except:
			self.father_name = father_name
		try:
			self.mother_name = config['mother_name']
		except:
			self.mother_name = mother_name
		try:
			self.gender = config['gender']
		except:
			self.gender = gender
		try:
			self.config = config
		except:
		 	pass

总结

以上是我在项目管理方面的经验,更多内容可以参考我的github repo,上述教程中的例子可以在How2Code repo中得到体现。

如果本篇博客可以帮到你的话,请给我一个赞吧,感谢 ❤️

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1243203.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微信小程序:This Mini Program cannot be opened as your Weixin version is out-of-date.

项目场景&#xff1a; 问题描述 升级基础库3.2.0&#xff0c;然后PC端整个小程序都打不开了&#xff0c;点击小程序提示”This Mini Program cannot be opened as your Weixin version is out-of-date. Update Weixin to the latest version.“&#xff0c;并且点击Update Wei…

成为AI产品经理——模型构建流程(下)

目录 1.模型训练 2.模型验证 3.模型融合 4.模型部署 上节课我们讲了模型设计、特征工程&#xff0c;这节课我们来讲模型构建剩下的三个部分&#xff1a;模型训练、模型验证和模型融合。 1.模型训练 模型训练就是要不断地训练、验证、调优直至让模型达到最优。 那么怎么达…

Linux系统装宝塔面板提示磁盘空间不足如何清理,检测到当前磁盘超过80%,空间不足如何清理

Linux系统装宝塔面板提示磁盘空间不足如何清理&#xff0c;检测到当前磁盘超过80%&#xff0c;空间不足如何清理 今天登陆服务器查看到磁盘空间满&#xff0c;如题这部分属于运维问题&#xff0c;如果直接点击 如何直接点立即清理会跳转企业版购买&#xff0c;1599CNY对普通用…

如何做一个简单的深度集成学习框架

使用同一个框架&#xff0c;独立在一个数据集上面&#xff0c;分别训练多次&#xff0c;每个单独模型训练超参数可以一样&#xff0c;也可以不一样&#xff0c;最后若干个训练好的独立模型在测试集数据上面做最后集中决策。 实例代码如下&#xff1a; class MyEnsemble(nn.Modu…

CVE-2023-6099:优卡特脸爱云一脸通智慧管理平台SystemMng.ashx接口未授权漏洞复现

文章目录 优卡特脸爱云一脸通智慧管理平台未授权SystemMng.ashx接口漏洞复现&#xff08;CVE-2023-6099&#xff09; [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 优卡特脸爱云一脸通智慧管理平台未授权…

eNSP-远程登陆实验

实验拓扑&#xff1a; 实验需求&#xff1a; 1. 如图所示&#xff0c;配置设备名称和IP地址 2. 配置R2的远程登录vty接口0-4&#xff0c;完成以下需求&#xff1a; 1&#xff09;采用接口password的验证方式&#xff0c;口令为"spoto"&#xff08;不含引号&#xf…

为何越来越多的程序员纷纷转行网络安全?

目前&#xff0c;我国IT行业的人才结构不断升级&#xff0c;公司对程序员的要求越来越高&#xff0c;出现了大量的裁员现象&#xff0c;导致很多的程序员纷纷想转行的想法。 可能对于早期的程序员而言&#xff0c;学好编程语言就能找到比较好的工作。而现在伴随着互联网的不断发…

美国大学陪读签证申请条件是什么?

美国大学陪读签证是留学生的家庭成员在美国陪同留学生就读期间的签证类型。申请该签证需要满足一定的条件&#xff0c;这些条件通常包括&#xff1a; 1.申请人身份关系证明&#xff1a;申请人必须是留学生的家庭成员&#xff0c;如配偶或子女&#xff0c;需要提供证明文件&…

Lua脚本解决redis实现的分布式锁多条命令原子性问题

线程1现在持有锁之后&#xff0c;在执行业务逻辑过程中&#xff0c;他正准备删除锁&#xff0c;而且已经走到了条件判断的过程中&#xff0c;比如他已经拿到了当前这把锁确实是属于他自己的&#xff0c;正准备删除锁&#xff0c;但是此时他的锁到期了&#xff0c;那么此时线程2…

【深度学习实验】图像处理(一):Python Imaging Library(PIL)库:图像读取、写入、复制、粘贴、几何变换、图像增强、图像滤波

文章目录 一、实验介绍二、实验环境1. 配置虚拟环境2. 库版本介绍 三、实验内容0. 安装 PIL 库1. 图像读取和写入a. 图像读取b. 图像写入c. 构建新图像 2. 图像复制粘贴a. 图像复制b. 图像局部复制c. 图像粘贴 3. 几何变换a. 图像调整大小b. 图像旋转c. 图像翻转 4. 图像增强a.…

QGIS之二十五两个面图层数据中选择图形完全一致的数据

效果 步骤 1、准备数据 2、按位置选择 在Qgis工具箱中搜索"按位置选择"工具 选择要素和比较要素根据实际选择 运行 3、结果

FreeRTOS学习之路,以STM32F103C8T6为实验MCU(2-3:任务切换)

学习之路主要为FreeRTOS操作系统在STM32F103&#xff08;STM32F103C8T6&#xff09;上的运用&#xff0c;采用的是标准库编程的方式&#xff0c;使用的IDE为KEIL5。 注意&#xff01;&#xff01;&#xff01;本学习之路可以通过购买STM32最小系统板以及部分配件的方式进行学习…

WorkPlus解放企业应用开发,实现跨平台无缝切换

在移动应用的快速发展时代&#xff0c;企业对于自主开发和应用平台替换的需求日益增长。WorkPlus作为一个完整的移动数字化APP底座&#xff0c;为企业提供了独立自主的应用开发环境&#xff0c;实现了平台无关性和应用解耦。今天&#xff0c;我们将深入探讨WorkPlus在企业应用开…

基于 Flink SQL 和 Paimon 构建流式湖仓新方案

本文整理自阿里云智能开源表存储负责人&#xff0c;Founder of Paimon&#xff0c;Flink PMC 成员李劲松在云栖大会开源大数据专场的分享。本篇内容主要分为四部分&#xff1a; 数据分析架构演进介绍 Apache PaimonFlink Paimon 流式湖仓流式湖仓Demo演示 数据分析架构演进 …

【C语言:深入理解指针二】

文章目录 1. 二级指针2. 指针数组3. 字符指针变量4. 数组指针变量5. 二维数组传参的本质6. 函数指针变量7. 函数指针数组8. 转移表9. 回调函数10. qsort函数的使用与模拟实现 1. 二级指针 我们知道&#xff0c;指针变量也是变量&#xff0c;它也有自己的地址&#xff0c;使用什…

TypeError: Cannot read property ‘sendpost‘ of undefined

箭头函数指向问题&#xff0c;定义let that this 解决

【外贸商机篇】黑色星期五来啦,跨境电商必备手册!

黑色星期五是每年11月的第四个星期五&#xff0c;三天后是网络星期一。这两个购物日是美国一年中最繁忙的购物日之一&#xff0c;仅在2021年的感恩节周末&#xff0c;电子商务收入估计就达到196亿美元。 在一项Statista调查中&#xff0c;美国消费者被问及他们计划购买哪些商品…

自由飞翔之小鸟

一、创建文件、包、类、插入图片文件 二、app包 1、Gameapp类&#xff08;运行游戏&#xff09; package app;import main.GameFrame;public class Gameapp {public static void main(String[] args) {//游戏的入口new GameFrame();} } 三、main包 1、Barrier&#xff08;障…

Python基础:生成器(Generators)和生成器表达式(Generator Expressions)详解

生成器&#xff08;Generators&#xff09;和 生成器表达式&#xff08;Generator Expressions&#xff09;是 Python 中用于处理迭代器和序列数据的强大工具。它们允许你按需生成值&#xff0c;而不是一次性生成所有值&#xff0c;从而节省内存和提高性能。 1. 生成器&#x…

前缀和——724. 寻找数组的中心下标

文章目录 &#x1f353;1. 题目&#x1fad2;2. 算法原理&#x1f984;解法一&#xff1a;暴力枚举&#x1f984;解法二&#xff1a;前缀和 &#x1f954;3. 代码实现 &#x1f353;1. 题目 题目链接&#xff1a;724. 寻找数组的中心下标 - 力扣&#xff08;LeetCode&#xff0…