luffy项目(五)

今日内容概要

  • 协同开发
  • 冲突解决
  • 线上分支合并
  • pycharm操作git
  • 为开源项目贡献代码
  • git面试题
  • 前台首页组件编写
  • 首页轮播图功能前后端打通
  • 登录注册功能设计

今日内容详细

协同开发

# 在公司中,都是多人共同开发同一个项目
    -1 组长本地创建出空项目,底层代码写完---》提交到远程仓库
    -2 张三,李四,王五都要共同开发这个项目
    -3 我们要把代码clone到本地
        -pycharm中:
        -找一个位置:git bash here(cmd)
        git clone 远程地址
        使用pychrm打开
        本地能够运行起项目来(依赖没装好),数据库链接不对(本地)

   -4 写代码,提交到本地版本库,推到远端即可(推之前先pull一下)

# 多人协同开发一个项目
    -作为项目创建者:本地搞好,远程搞好,推上去,把别人加为开发者
    -作为协同开发者:远程账号,密码---》登录进去就能看到这个项目了

冲突解决

多人同一分支开发出现冲突

# 出现冲突的原因
    -别人跟你改了同样的代码,但是他先提交到远程仓库了
    -你要提交,提交不上,先拉取,拉取下来,因为改了同样代码,冲突
    -冲突的样子
    <<<<<<< HEAD
    print('asdmq')
    =======    # 上面是你的代码,下面是别人的代码
    print('xxxyyy')
    >>>>>>> e32561dc36f739a0a3c0b3f5a7cde62b689665ec
    -修改代码到不报错  #  先把冲突的地方删除,剩下的代码分析,需要留哪些,到底是留我的代码,还是留同事的代码(删同事的,跟同事说一声),如果删自己的,不用说
    -重新提交到本地版本库,推到远端

分支合并出现冲突

1. 新建要给dev分支,切换过去
    git branch dev
    git checkout dev

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 '解决冲突'

线上分支合并

# 之前全是线下分支操作,本地增删查改分支
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,mr)---》跟你没关系了--->[合进去了,没有合进去]
    -你领导就能看到这个pr,审核通过,点合并
    -到此 dev分支就合并进master分支了

pycharm操作git

命令操作git,编辑器pycharm,可以操作git,图形化界面操作
以前使用的所有命令,都可以在pycharm中点点点实现

为开源项目贡献代码

# 为开源项目贡献代码
    1 看到开源项目,点fork,你的仓库就有这个开源项目了
    2 在本地拉去【你仓库】fork的代码
    3 你继续写,提交到自己远程仓库
    4 提交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+dev+bug分支方案
 
6 使用git 的操作流程
    - 如果是普通开发者:git clone下来,写代码,git add ., git commit, git pull, git push

7 什么是gitee,github:pr,gitlab:mr?
    -不同叫法:提交分支合并的请求

前台首页组件编写

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>老男孩IT教育 | 帮助有志向的年轻人通过努力学习获得体面的工作和生活</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">
         <a :href="item.link"><img :src="item.image" alt=""></a>
      </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>

登录注册功能设计

# 后端接口
    1 账号/手机号/邮箱+密码登录接口
    2 手机号+验证码登录接口
    3 发送手机验证码接口  (第三方发送短信)
    4 注册接口--》手机号,验证码,密码
    5 判断手机号是否存在接口

补充

1. cgi fastcig WSGI uwsgi uWSGI  
# cgi:通用网关接口(Common Gateway Interface/CGI)是一种重要的互联网技术,可以让一个客户端,从网页浏览器向执行在网络服务器上的程序请求数据。CGI描述了服务器和请求处理程序之间传输数据的一种标准。
     一句话总结: 一个标准,定义了客户端服务器之间如何传数据

# fastcig:快速通用网关接口(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孵化

浏览器输入一个地址到请求返回,经历的过程

1 输入URL并回车确认
    在这过程中,浏览器可能会做一些预处理,甚至已经在智能匹配所有可能的URL了,他会从历史记录,书签等地方,找到已经输入的字符串可能对应的URL,来预估所输入字符对应的网站
2 URL解析/DNS解析查找域名IP地址
    1)浏览器对 URL 进行检查时首先判断协议,如果是 http/https 就按照 Web 来处理,另外还会对 URL 进行安全检查,然后直接调用浏览器内核中的对应方法,接下来是对网络地址进行处理,如果地址不是一个IP地址而是域名则通过DNS(域名系统)将该地址解析成IP地址。
    2)递归查询和迭代查询
3 网络连接发起HTTP请求
    1)互联网内各网络设备间的通信都遵循TCP/IP协议,利用TCP/IP协议族进行网络通信时,会通过分层顺序与对方进行通信。分层由高到低分别为:应用层、传输层、网络层、数据链路层。发送端从应用层往下走,接收端从数据链路层网上走。
    2)从上面的步骤中得到 IP 地址后,浏览器会开始构造一个 HTTP 请求,应用层客户端向服务器端发送的HTTP请求包括:请求报头和请求主体两个部分,其中请求报头(request header)包含了至关重要的信息,包括请求的方法(GET / POST和不常用的PUT / DELETE以及更不常用的HEAD / OPTION / TRACE,一般的浏览器只能发起 GET 或者 POST 请求)、目标url、遵循的协议(HTTP / HTTPS / FTP…),返回的信息是否需要缓存,以及客户端是否发送Cookie等信息。需要注意的是,因为 HTTP 请求是纯文本格式的,所以在 TCP 的数据段中可以直接分析 HTTP 文本的。
4 HTTP报文传输过程
    当应用层的 HTTP 请求准备好后,浏览器会在传输层发起一条到达服务器的 TCP 连接,位于传输层的TCP协议为传输报文提供可靠的字节流服务。它为了方便传输,将大块的数据分割成以报文段为单位的数据包进行管理,并为它们编号,方便服务器接收时能准确地还原报文信息。TCP协议通过“三次握手”等方法保证传输的安全可靠。“三次握手”的过程是,发送端先发送一个带有SYN(synchronize)标志的数据包给接收端,在一定的延迟时间内等待接收的回复。接收端收到数据包后,传回一个带有SYN/ACK标志的数据包以示传达确认信息。接收方收到后再发送一个带有ACK标志的数据包给接收端以示握手成功。在这个过程中,如果发送端在规定延迟时间内没有收到回复则默认接收方没有收到请求,而再次发送,直到收到回复为止。
5 服务器接收数据
    IP协议的作用是把TCP分割好的各种数据包封装到IP包里面传送给接收方。而要保证确实能传到接收方还需要接收方的MAC地址,也就是物理地址才可以。IP地址和MAC地址是一一对应的关系,一个网络设备的IP地址可以更换,但是MAC地址一般是固定不变的。ARP协议可以将IP地址解析成对应的MAC地址。当通信的双方不在同一个局域网时,需要多次中转才能到达最终的目标,在中转的过程中需要通过下一个中转站的MAC地址来搜索下一个中转目标。
6 服务器响应请求/MVC
    在找到对方的MAC地址后,已被封装好的IP包再被封装到数据链路层的数据帧结构中,将数据发送到数据链路层传输,再通过物理层的比特流送出去。这时,客户端发送请求的阶段结束。
7 服务器返回数据
    接收端的服务器在链路层接收到数据包,再层层向上直到应用层。这过程中包括在传输层通过TCP协议将分段的数据包重新组成原来的HTTP请求报文。
8 客户端接收数据
    服务接收到客户端发送的HTTP请求后,服务器上的的 http 监听进程会得到这个请求,然后一般情况下会启动一个新的子进程去处理这个请求,同时父进程继续监听。
9 浏览器加载/渲染页面
10 打印绘制输出

image

posted @   空白o  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示