luffy学习-05
一、协同开发
在公司中,都是多人共同开发同一个项目
- 组长本地创建出空项目,底层代码写完——>提交到远程仓库
- 和同事们张三李四王麻子都要共同开发这个项目
- 我们要把代码clone到本地
- 在pycharm中打开
- 找一个位置:
git bash here(cmd)
git clone 远程地址
然后使用pycharm打开- 本地如果不能够运行项目 1、依赖没装好(有些是公司自己封装的包没下 pip install -i 公司私有地址) 2、数据库链接不对(本地
- 在pycharm中打开
4.编写代码,提交到本地版本库,推到远端即可(推之前 pull
一下)没事就拉一下
多人协同开发一个项目
- 作为项目创建者:本地整好,远程整好,推上去。把别人添加为开发者
- 作为协同开发者:远程账号、密码——>登录进去就能看到这个项目
二、冲突解决
一、多人同一分支开发出现冲突
出现冲突的原因
- 别人跟你改了同样的代码,但是他先提交到远程仓库了
- 你要提交,因为版本不一样你提交不上。先拉取,拉取下来。因为改了同样代码,会发生冲突
- 冲突的样子如下:
<<<<<<< HEAD
print('lqz')
======= # 上面是你的代码
print('lqz is handsome')
>>>>>>> f67f73948d175b186cd5f1319d7602fe004e285c # 别人的代码(版本号)
- 修改代码到不报错
- 重新提交到本地版本库,推到远端
二、分支合并出现冲突
1、新建 dev分支,切换过去
- git branch dev
- git branch master
2、dev分支修改dev.py第一行,提交到版本库
- 在第一行加了print
git add .
git commit -m ‘修改了dev.py’
3、修改dev分支的home/views.py
最后一行
- 在views.py最后一行加入注释
git add .
git commit -m '最后一行加入注释'
4、切回到master分支,修改dev.py第一行和home/views.py
最后一行,提交到版本库
git checkout master
- 在第一行加入print
- 在views.py最后一行加入注释
git add .
git commit -m 'master修改内容'
5、当合并代码,会出现冲突、解决、提交
git merge dev
- 有冲突 解决
git add .
git commit -m '解决冲突'
小总结:就是dev改两行数据,master也改同样的两行数据,然后在master上合并devgit merge dev
,冲突了,然后解决冲突之后,就是add和commit命令就可以。
知识点补充
在pycharm和git的cmd窗口敲命令是一样的,差距是在git里能敲linux命令,pycharm里只能敲windows和git命令。
三、线上分支合并(pr(pull request)、mr(merge request))
之前全是线下分支操作,在本地增删改查分支
1、远程建立分支:gitee上点击操作
2、把远程分支拉回本地
git pull origin dev
注意的是:此时已经拉下来了,但是看不到,需要切换一下分支就好git checkout dev
来到了本地dev分支
3、本地dev分支增加代码
git add .
git commit -m '本地dev提交'
4、本地dev提交到远端
git push origin dev
5、远程分支合并:把dev合并到master(看好了谁要合并谁)
- 你提交
pull request(pr的简写)
的申请(pr、mr)——>跟你没关系了——>最后等着看是【合进去了,还是没有合进去】 - 你老大能看到这个pr——>审批通过——>点合并
- 到此 dev分支就合并进master分支
补充点:
- gitee叫pr,全称 pull request
- github叫mr,全称是merge request
四、pycharm操作git
命令操作git,编辑器pycharm也可以操作git,图形化界面操作
- 以前使用的所有命令。都可以在pycharm中“点点点”实现
命令
- clone
- add
- git commit -m ‘注释’
- git push
- git branch(pycharm右下角)
- 查看git操作记录git log
- 本地代码跟版本库比较
五、为开源项目贡献代码
- 开到开源项目,点
fork
,你的仓库就有这个开源项目了 - 在本地拉取到【你的仓库】fork的代码
- 你继续写,提交到自己远程仓库
- 提交pr合并,如果作者同意,你就可以合并进去了
六、git面试题
1、你们公司分支方案是什么样的?
- master、dev、bug三条分支
- master主要用来发布版本,写好了某个版本的代码合并进去,不直接在master上开发
- dev:开发分支,项目的开发者,都在dev分支上开发
- bug:bug分支,用来修改bug,发布小版本
2、使用git开发,遇到过冲突吗?
- 遇到过
- 多人在dev分支开发,出现的冲突
- 多分支合并出现的冲突
- 把代码拉下来,直接解决冲突,保留我的代码,保留同事的代码
3、你知道git 变基?
- 分支合并:dev分支合并到master分支
- merge或rebase合并
- 把多次提交合并成一个
4、git pull 和git fetch的区别
- pull 和 fetch都是拉取代码
- pull=fetch+合并
5、你知道git flow吗?git工作流,他是一个别人提出的分支方案
- 我们用的是master+div+bug分支方案
6、使用git的操作流程
- 如果是普通开发者:git clone下来,写代码,执行git add . git commit -m ‘’ git pull git push
7、什么是gitee,github:pr,gitlab:mr?
- 不同叫法:提交分支合并的请求
七、前台首页组件编写
- HomeView.vue 页面组件
- Header.vue 头部组件
- Banner.vue 轮播图组件
- Footer.vue 尾部组件
代码展示
HomeView.vue
<template>
<div class="home">
<Header></Header>
<Banner></Banner>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<Footer></Footer>
</div>
</template>
<script>
import Header from '@/components/Header'
import Banner from '@/components/Banner'
import Footer from '@/components/Footer'
export default {
name: 'HomeView',
data() {
return {}
},
components: {
Header, Banner, Footer
}
}
</script>
Header.vue
<template>
<div class="header">
<div class="slogan">
<p>人终向前走 花自向阳开</p>
</div>
<div class="nav">
<ul class="left-part">
<li class="logo">
<router-link to="/">
<img src="../assets/img/head-logo.svg" alt="">
</router-link>
</li>
<li class="ele">
<span @click="goPage('/free-course')" :class="{active: url_path === '/free-course'}">三毛流浪记</span>
</li>
<li class="ele">
<span @click="goPage('/actual-course')" :class="{active: url_path === '/actual-course'}">鲁滨逊漂流记</span>
</li>
<li class="ele">
<span @click="goPage('/light-course')" :class="{active: url_path === '/light-course'}">狼图腾</span>
</li>
</ul>
<div class="right-part">
<div>
<span>登录</span>
<span class="line">|</span>
<span>注册</span>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Header",
data() {
return {
url_path: sessionStorage.url_path || '/',
}
},
methods: {
goPage(url_path) {
// 已经是当前路由就没有必要重新跳转
if (this.url_path !== url_path) {
// 传入的参数,如果不等于当前路径,就跳转
this.$router.push(url_path)
}
sessionStorage.url_path = url_path;
},
},
created() {
sessionStorage.url_path = this.$route.path
this.url_path = this.$route.path
}
}
</script>
<style scoped>
.header {
background-color: white;
box-shadow: 0 0 5px 0 #aaa;
}
.header:after {
content: "";
display: block;
clear: both;
}
.slogan {
background-color: #eee;
height: 40px;
}
.slogan p {
width: 1200px;
margin: 0 auto;
color: #aaa;
font-size: 13px;
line-height: 40px;
}
.nav {
background-color: white;
user-select: none;
width: 1200px;
margin: 0 auto;
}
.nav ul {
padding: 15px 0;
float: left;
}
.nav ul:after {
clear: both;
content: '';
display: block;
}
.nav ul li {
float: left;
}
.logo {
margin-right: 20px;
}
.ele {
margin: 0 20px;
}
.ele span {
display: block;
font: 15px/36px '微软雅黑';
border-bottom: 2px solid transparent;
cursor: pointer;
}
.ele span:hover {
border-bottom-color: orange;
}
.ele span.active {
color: orange;
border-bottom-color: orange;
}
.right-part {
float: right;
}
.right-part .line {
margin: 0 10px;
}
.right-part span {
line-height: 68px;
cursor: pointer;
}
</style>
Banner.vue
<template>
<div class="banner">
<el-carousel :interval="5000" arrow="always" height="400px">
<el-carousel-item v-for="item in bannerList" :key="item.title">
<div v-if="item.image.indexOf('http')==-1">
<router-link :to="item.link"><img :src="item.image" alt=""></router-link>
</div>
<div v-else>
<a :href="item.link"><img :src="item.image" alt=""></a>
</div>
</el-carousel-item>
</el-carousel>
</div>
</template>
<script>
export default {
name: "Banner",
data() {
return {
bannerList: []
}
},
created() {
this.$axios.get(this.$settings.BASE_URL + 'home/banner/').then(res => {
this.bannerList = res.data.result
})
}
}
</script>
<style scoped>
.el-carousel__item {
height: 400px;
min-width: 1200px;
}
.el-carousel__item img {
height: 400px;
margin-left: calc(50% - 1920px / 2);
}
.el-carousel__item h3 {
color: #475669;
font-size: 18px;
opacity: 0.75;
line-height: 300px;
margin: 0;
}
.el-carousel__item:nth-child(2n) {
background-color: #99a9bf;
}
.el-carousel__item:nth-child(2n+1) {
background-color: #d3dce6;
}
</style>
Footer.vue
<template>
<div class="footer">
<ul>
<li>关于我们</li>
<li>联系我们</li>
<li>商务合作</li>
<li>帮助中心</li>
<li>意见反馈</li>
<li>新手指南</li>
</ul>
<p>Copyright © luffycity.com版权所有 | 京ICP备17072161号-1</p>
</div>
</template>
<script>
export default {
name: "Footer"
}
</script>
<style scoped>
.footer {
width: 100%;
height: 128px;
background: #25292e;
color: #fff;
}
.footer ul {
margin: 0 auto 16px;
padding-top: 38px;
width: 810px;
}
.footer ul li {
float: left;
width: 112px;
margin: 0 10px;
text-align: center;
font-size: 14px;
}
.footer ul::after {
content: "";
display: block;
clear: both;
}
.footer p {
text-align: center;
font-size: 12px;
}
</style>
八、首页轮播图功能前后端打通
Banner.vue
<template>
<div class="banner">
<el-carousel :interval="5000" arrow="always" height="400px">
<el-carousel-item v-for="item in bannerList" :key="item.title">
<div v-if="item.image.indexOf('http')==-1">
<router-link :to="item.link"><img :src="item.image" alt=""></router-link>
</div>
<div v-else>
<a :href="item.link"><img :src="item.image" alt=""></a>
</div>
</el-carousel-item>
</el-carousel>
</div>
</template>
<script>
export default {
name: "Banner",
data() {
return {
bannerList: []
}
},
created() {
this.$axios.get(this.$settings.BASE_URL + 'home/banner/').then(res => {
this.bannerList = res.data.result
})
}
}
</script>
<style scoped>
.el-carousel__item {
height: 400px;
min-width: 1200px;
}
.el-carousel__item img {
height: 400px;
margin-left: calc(50% - 1920px / 2);
}
.el-carousel__item h3 {
color: #475669;
font-size: 18px;
opacity: 0.75;
line-height: 300px;
margin: 0;
}
.el-carousel__item:nth-child(2n) {
background-color: #99a9bf;
}
.el-carousel__item:nth-child(2n+1) {
background-color: #d3dce6;
}
</style>
九、登录注册功能设计
后端接口
- 账号/手机号/邮箱+密码登录接口
- 手机号+验证码登录接口
- 发送手机验证码接口 (第三方发送短信)
- 注册接口--》手机号,验证码,密码
- 判断手机号是否存在接口
十、cgi fastcig WSGI uwsgi uWSGI
1、cgi fastcgi WSGI uwsgi uWSGI
cgi:通用网关接口(Common Gateway Interface/CGI)是一种重要的互联网技术,可以让一个客户端,从网页浏览器向执行在网络服务器上的程序请求数据。CGI描述了服务器和请求处理程序之间传输数据的一种标准。
一句话总结: 一个标准,定义了客户端服务器之间如何传数据
fastcgi:快速通用网关接口(Fast Common Gateway Interface/FastCGI)是一种让交互程序与Web服务器通信的协议。FastCGI是早期通用网关接口(CGI)的增强版本
一句话总结: CGI的升级版
常用的fastcgi软件:
Apache HTTP Server (部分) :LAMP LNMP
Nginx(主流):nginx是一个符合fastcgi协议的软件,处于浏览器和web程序之间,主要做请求转发和负载均衡,也可以称之为服务器中间件
Microsoft IIS:windows server
WSGI:Web服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)是为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。自从WSGI被开发出来以后,许多其它语言中也出现了类似接口
一句话总结: 为Python定义的web服务器和web框架之间的接口标准
wsgiref:性能很低,python实现的,django内置了,测试阶段用,上线不用
uWSIG:性能高,c实现的
gunicorn:python实现的
uWSGI: 符合wsgi协议的web服务器,上面标准的具体实现
uwsgi:uWSGI服务器,自有协议
2、Apache
-Apache 公司
-Apache web服务器
-Apache 开源协议
-Kafka :apache顶级开源项目
-echars:原来是百度开发的,交给了apache孵化
小总结:
- 从浏览器发出去的请求到后端遵循的就是
cgi
,定义了客户端和服务端传递的标准 - fastcgi是cgi的增强版,更快了 常用的三个软件
Apache Nginx Microsoft ISS
- wsgi:python程序规定我们之间的协议,http请求来了进wsgi拆成一个字典,进入程序包装成request对象,后面可以接django、flask框架。为Python定义的web服务器和web框架之间的接口标准
- 符合wsgi协议的有
wsgiref uWSIG gunicorn
- 符合wsgi协议的有
- uWSGI: 符合wsgi协议的web服务器,上面标准的具体实现
- uwsgi:uWSGI服务器,自有协议
十一、浏览器输入一个地址到请求返回,经历的过程
一共7个大步骤
一、解析域名
1、在浏览器输入URL
2、查浏览器缓存
3、查本机host文件
4、查路由器缓存
5、客户端向本地域名服务器递归查询
6、本地域名服务器向根域名服务器迭代查询
7、根域名服务器告诉本地域名服务器
8、本地域名服务器向顶级域名服务器dns.com进行查询
9、顶级域名服务器dns.com告诉本地域名服务器
10、权威域名服务器dns.baidu.com告诉本地域名服务器
二、三次握手
11、TCP的建立连接
三、发送请求
12、浏览器通过http协议向主机发送请求
四、响应请求
13、服务器给出响应
五、释放连接
14、TCP释放连接
六、返回响应
七、解析渲染
15、浏览器渲染页面
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)