今天开始努力学习

面向谷歌编程选手许若芃


  • Home

  • Categories58

  • Archives85

  • Search

Unity之旋转,欧拉角

Posted on 2019-12-24 | Edited on 2019-12-25 | In Unity , 基础

参考资料

  • 如何通俗地解释欧拉角?之后为何要引入四元数?
  • Quaternion

gimbal lock 欧拉角的死锁问题

欧拉角

  • 欧拉角的思想就是,在旋转物体的时候,不是完全使用坐标,而是使用相对每个轴的旋转角度
  • 比如在旋转的时候,先绕世界的z轴转一定角度(和世界产生联系),然后再绕自己的坐标轴转两次

欧拉角的三个角度

  • pitch:俯仰
  • yaw:偏航
  • roll:翻滚

在发生着三种旋转的情况下,万向节可以通过自己的调节让中间的物体保持不变

万向节死锁

万向节就是一个让物体以单一轴旋转的装置,由彼此垂直的三个平衡环组成,可以让架子里面的物体保持角度不变
万向节

  • 在上面的三种旋转情况下,如果有两个方向的转轴重合了,就会失去一个自由度,产生死锁

Quaternion

也就是中文里面的四元数(x,y,z,w)

  • 在unity里面,一般使用quaternion来表示物体的旋转,因为使用quaternion不容易产生死锁问题
  • 数学推导挺复杂的,一般在unity里面实际用的时候不一定用得到
  • 注意,在unity里面,四元数的类型是Quaternion,欧拉角的类型是Vector3,注意类型的转换

常用函数

性质

  • eulerAngles:返回这个四元数本身代表的欧拉角。从transform.ratotion里面读取出来四元数之后,可以直接这样转换成欧拉角
  • x,y,z,w:可以直接返回四元数的数值,但是实际用的时候作用不大

静态方法

  • public static float Angle(Quaternion a, Quaternion b);
    • 如果有两个东西a和b同时绕着c转,a和c以及b和c之间都会产生角度
    • 返回两个旋转a和b之间的角度(直接返回角度,不用访问四元数)
  • public static Quaternion Euler(float x, float y, float z);
    • 从绕三个周的角度,得到这个旋转的四元数
  • public static Quaternion Slerp(Quaternion a, Quaternion b, float t);
    • 在a和b的两个旋转里面插入一个新的旋转
    • t的range是[0,1],如果是0的话就是和a重合,是1的话就和b重合
    • 这个可以用来作为,从开始到结束,随着时间转动
  • public static Quaternion FromToRotation(Vector3 fromDirection, Vector3 toDirection);
    • 创建一个rotation,从一个vector3的方向(世界)转到另一个方向
  • public static Quaternion identity;
    • identity rotation (Read Only).
    • 也就是意味着不转!!!

四元数的理解

和我们在二次坐标系表示复数一样,四元数是一个四次元来表示complex number的概念

Python的request库

Posted on 2019-12-18 | In 编程语言 , Python , Lib

之前做了个日本的网测题,题目的内容是call一个web上面的api并且返回结果。之前一直不知道这道题是在干什么,这两天终于搞明白了

参考资料

  • 快速上手request文档
  • GET 和 POST 到底有什么区别?
  • 关于HTTP协议,一篇就够了

关于request

一个Python的第三方库,用于访问网络资源
需要导入模块import requests

小知识:http协议(居然现在才发现我连这个都不知道)

  • http是超文本传输协议的缩写,是从www服务器传输超文本到本地浏览器的传输协议
  • http协议作用于客户端-服务器架构上,浏览器作为http的客户端,通过url向http服务器端(web服务器)发送所有请求,web服务器在接到请求后,向客户端发送响应

特点

  • 简单快捷。客户端请求的时候,只需要request method(包括GET,HEAD,POST等)和url。每种方法规定的客户和服务器的连接类型不同。因为协议简单,所以服务器的程序规模小,反应快速
  • 灵活:允许传输任意类型的对象
  • 无连接:限制每次连接只处理一个请求,收到客户端的应答后断开连接
  • 无状态:对于事物的处理没有记忆能力,所以如果处理的时候需要先前的信息就需要全部重新传输
  • B/S(浏览器,服务器-广域网),C/S(客户端,服务器-局域网)模式

URL(Uniform Resource Locator)

http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name
一个URL包括几部分:

  • 协议部分:http:,表示用的这个协议(https是加密的协议)
  • 域名部分:www.aspxfans.com,也可以用IP地址作为域名
  • 端口,用冒号分割,不是必须的
  • 虚拟目录(endpoint),从第一个/到最后一个/,也不是必须的
  • 文件名,从最后一个/到?为止。如果没有?就是到#。如果都没有就是到最后。如果省略的话就是默认文件名
  • 参数部分:从?到#,不是必须的。用来搜索和查询。可以有多个参数,参数之间&相隔
  • 锚部分,从#开始到最后,不是必须的

客户端发送的request

当客户端向服务器发送请求的时候,包括以下的四个部分:
request line,header,empty line, request data

  • 请求行,会说明method(比如GET),要访问的资源,http版本
  • 请求头部:说明服务器要使用的附加信息(多行)
  • 空行:请求头部后面需要有空行
  • 请求数据(主体),可以为空

服务器响应的response

分为状态行,消息报头,空行,和响应正文

  • 状态行:http的版本号,状态码(200),状态消息(ok)
  • 消息报头:客户端需要使用的附加信息
  • 空行
  • html部分为响应正文

关于状态码

  • 200 ok 成功
  • 3xx 重定向,必须完成更进一步的操作
  • 4xx 客户端错误,请求有语法错误或者无法实现
  • 5xx 服务端错误,服务器未能实现
1
2
3
4
5
6
7
200 OK                        //客户端请求成功
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常

工作原理

  • 客户端(浏览器)连接到服务器,和服务器的http端口简历TCP连接(TCP:一种传输协议)
  • 发送http请求
  • 服务器接收并返回响应
  • 释放连接TCP,可能会由服务器断线,可能会保持一段时间
  • 客户端解析html的内容,显示

小知识:关于post和get

  • GET请求,请求数据会附在URL后面,用?分割(比如传入参数的时候)
    • 如果是英语或数字,原样
    • 如果是空格换成+
    • 如果是中文或者其他字符,直接把字符串加密得到16进制ASCII
  • 所以GET提交的数据会在地址栏显示出来,但是POST会把结果放在包体里面,不改变
  • 传输数据大小:
    • URL对数据的大小没有限制,但是有些浏览器可能会限制URL的字符长度,导致GET不行
  • 安全性:
    • POST的安全性更高。
    • 但是http本身就是明文协议,所以其实哪个都安全性不高。最主要的方法是https

回到request本身

发送请求

我们可以使用get命令获取某个网页的信息,然后从名字为r的对象里面得到后续需要的信息
我们可以用r.url来打印现在的url等

1
r = requests.get('https://api.github.com/events')

传递参数

requests支持用params关键字来传输参数,参数设置在dict里面

1
2
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.get("http://httpbin.org/get", params=payload)

响应内容

响应的内容可以用r.text来限时,request会根据http头部的编码对文本进行解码,可以用r.encoding来查看解码类型并且改变

二进制响应内容

可以用字节的方式来访问响应体r.content,会自动解码

Json响应内容

内置json解码器,可以处理json数据。r.json()
如果解码失败,会抛出异常401

原始响应内容

r.raw

实际应用

所以在一道例题中,需要调用某个网站的api,得到输入数字的hash值

  • http方法:GET
  • 参数:”q”,生成hash的文字列
  • 响应:两个key的json,分别是’n’和’hash’
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import requests

    # the input data
    param = 'n'
    url = 'http://challenge-server.code-check.io'
    endpoint = '/api/hash'

    param = {'q': param}
    r = requests.get(url + endpoint, params=param)

    # r = requests.get(url)
    print(r.json())

关于链表

Posted on 2019-11-18 | Edited on 2019-12-02 | In 基础 , 数据结构

虽然链表是一种比较基础的数据结构,但是在实际应用的时候用处没有那么多

  • 链表是一种线性的表,但是不会线性的存储数据
  • 数组存储的时候需要连续存储

单向链表

有一个头结点head,指向链表内存的首地址。
链表里面的每个节点有两个成员

  • 需要保存的数据val
  • 指向下一个结构的指针next

特点:

  • 查找
    • 对各个点的查找必须从头找起,后续的地址是前节点给出来的。无论访问哪个点都必须从头来
    • 时间复杂度n,和数组相同
  • 插入和删除(优势)
    • 由于链表是不连续的存储,所以在插入和删除的时候,链表不需要大量成员的位移
    • 复杂度1
  • 读取(劣势)
    • 数组因为连续存储,所以可以通过寻址迅速的定位。但是链表不连续,所以必须依据指针持续的遍历

应用

  • 由于有双向链表,单向链表的应用比较少
  • 撤销功能:文本,图形编辑器。用到了链表的删除特性
  • 实现图或者hashMap等高级数据结构

双向链表

增加了一个prev节点,相当于多了一个指针,所以用双向链表占的内存更多
比如编辑器的undo/redo操作,用双向链表就更好一点。如果是单向的话时间会是n

循环链表

链表的末尾指针指向了链表开头
比如分时装置

  • CPU处理多个用户的请求时产生抢占资源的情况,需要分时策略
  • 每个用户代表一个节点,会给每个节点分配一定的处理时间,然后进入下一个节点。

Leetcode链表练习题

141 判断单链表是否有cycle

思路:

  • in-place的方法,如果两个人一起跑步,一个快一个慢,那么总有一个时刻快的会把慢的套圈
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Solution:
    def hasCycle(self, head: ListNode) -> bool:
    fast = head
    slow = head
    while slow and fast and fast.next:
    slow = slow.next
    fast = fast.next.next
    if fast == slow:
    return True
    return False

24 交换两个相邻的node

思路:

  • 注意这个node的交换,不单和目前的部分(目前操作的两个)有关系,还和前面一个点有关系,因为前面一个点的next需要是交换之前的后一个点
  • 注意while时候的条件判断,必须两个点都在的时候才能进行交换
  • 注意d这个附加的点,用这个点可以快速的定位head点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution:
def swapPairs(self, head: ListNode) -> ListNode:
counter = 0
d = ListNode(-1)
d.next = head
prev_node = d
while head and head.next:
curr = head
to_swap = head.next

prev_node.next = to_swap
curr.next = to_swap.next
to_swap.next = curr

prev_node = curr
head = curr.next

return d.next

328 把链表的odd位都交换到前面去

思路:

  • 判断这个点如果是odd,那么上一个odd的next是现在的点,这个点的下一个指向even的开始点
  • 如果这个点是even,那么上一个even的next是现在的点,这个点的下一个是null
  • 死磕了一个小时的原因:
    • 注意深拷贝和浅拷贝的问题,浅拷贝的时候,改变这个东西的同时,之前的也会改变
    • 注意形成环的问题,一定要注意每个点的input和output的方向都确定了,该赋值0的时候赋值0
    • 注意每次的odd点都应该指向even的起始点
    • 在下一个点会变化的时候,记得及时保存
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      class Solution:
      def oddEvenList(self, head: ListNode) -> ListNode:
      start = ListNode(-1)
      even_start = ListNode(-1)
      start.next = head

      if (not head) or (not head.next): return head

      prev_odd = head
      prev_even = head.next
      even_start.next = prev_even


      counter = 1
      while head:
      curr = head
      if counter >=3:
      temp = curr.next
      if counter % 2 != 0: #odd
      prev_odd.next = curr
      curr.next = even_start.next
      if counter == 3:
      even_start.next.next = None
      prev_odd = curr
      elif counter % 2 == 0:#even
      prev_even.next = curr
      prev_even = curr
      curr.next = None
      head = temp
      else:
      head = curr.next
      counter += 1


      return start.next

计算机网络

Posted on 2019-11-05 | In 基础 , 计算机网络

概述

网线把主机连接起来
互联网把不同的网络连接起来

ISP

“互联网服务供应商”
从互联网管理机构获得IP地址,拥有通信线路以及路由器等联网设备,个人或机构缴纳一定的费用就可以连入互联网

主机间的通信方式

  • client-server:客户是服务的请求方,服务器是供应方
  • P2P:不区分客户和服务器

电路交换和分组交换

  • 电路交换:电话通信系统,需要建立物理链
  • 分组交换:每个分组有首部和尾部,包含了源地址和目的地址等。同一个传输路径上互相不受影响

时延

  • 排队时延:路由器输入和输出队列间的等待时间,取决于通信量
  • 处理时延:主机或路由器受到分组时的处理时间(分析首部,提取数据,进行差错检验等)
  • 传输时延:传输所用的时间
  • 传播时延:在信道中传播用的时间

计算机网络体系结构

五层

  • 应用层:为特定应用提供数据传输,HTTP,DNS等协议(报文)
  • 传输层:为进程提供通用数据传输服务。由于应用层协议很多,定义通用的传输层协议就可以支持不断增多的应用层协议。运输层包括两种协议:传输控制协议 TCP,提供面向连接、可靠的数据传输服务,数据单位为报文段;用户数据报协议 UDP,提供无连接、尽最大努力的数据传输服务,数据单位为用户数据报。TCP 主要提供完整性服务,UDP 主要提供及时性服务。
  • 网络层:为主机提供数据传输服务,网络层把传输层传递下来的报文段或者用户数据报封装成分组。
  • 数据链路层:网络层针对的还是主机之间的数据传输服务,而主机之间可以有很多链路,链路层协议就是为同一链路的主机提供数据传输服务。数据链路层把网络层传下来的分组封装成帧。
  • 物理层

OSI

  • 表示层:数据压缩,加密,描述。不必关心各台主机数据内部格式不同的问题
  • 会话层:建立和管理会话

TCP/IP

数据链路层和物理层合并为网络接口层

计算机操作系统

Posted on 2019-11-05 | Edited on 2019-11-06 | In 基础 , OS

概述

大纲:中断,系统调用,内存管理,进程线程,调度,同步,文件系统,I/O

什么是操作系统

  • 功能上
    • 对用户来说,OS是控制
    • 管理应用程序的运行
    • 为应用程序提供服务
    • 杀死应用程序
  • 对下
    • 资源分配,管理,外设管理(多个资源的协调)

抽象

承上启下的作用:层次架构

  • 硬件之上
  • 应用程序(比如办公软件,视频播放软件等等)之下
    • OS为应用软件提供服务支撑
    • 分为两部分:shell部分,对外的接口。kernel部分,也就是OS的本身

kernel部分

  • CPU管理,进程线程
  • 内存管理(物理内存,虚拟内存)
    • 虚拟内存:给上层应用提供尽可能大的内存空间
  • 文件系统管理
  • (底层相关)中断处理和设备驱动 -> 直接和硬件打交道

操作系统的特征

  • 并发concurrency:同时存在多个运行的程序,需要OS管理和调度
    • 一段时间内,多个程序
    • 并行parallelism:一个时间点上多个程序。一般并行的需要有多个CPU
  • 共享:有效让资源共享给需要的应用程序
    • 对于一个内存单元:一个时间点上只有一个程序访问一个资源
    • 同时访问?互斥共享?
  • 虚拟:让每个用户都觉得有一个计算机专门为他服务
    • 把一台机器虚拟成多台机器
  • 异步(虽然执行的步骤不同,但是结果也相同)
    • 不是一贯到底的,是走走停停的,向前推荐的速度不可知
    • 但是运行环境相同,OS要保证运行的结果也相同

为什么学习OS

  • 效率,可靠 -> 算法
  • 硬件
    • 良好的硬件管理,合理的资源分配
  • 硬件可以完成很多OS以前关注的问题
  • 需要权衡
    • 时间空间
    • 性能和可预测
    • 公平和性能

经典OS

  • UNIX
  • Linux:移动终端的占有量非常大
  • Windows

历史

剑指offer

Posted on 2019-11-05 | In 就职

面试的流程

  • 能写单元测试,加分
  • 答非所问,不懂装懂,大忌
  • 准备几个问题

面试的三个环节

行为面试 5-10分钟

  • 性格特点
  • 深入了解项目经历
    • 项目介绍方法
      • 简短的项目背景
      • 自己完成的任务(参与 != 负责)
      • 为了完成任务自己是怎么做的
      • 自己的贡献,最好能用数字加以说明
    • 追问问题:
      • 遇到最大的问题是什么,怎么解决
      • 学到了什么
      • 和其他团队成员有什么冲突,怎么解决的
  • 简短的介绍
  • 对技能的分级
    • 了解:只是学过,但是没有做过实际的项目
    • 熟悉:
      • 大部分的技能
    • 精通
      • 不要随便用
      • 如果有人请教这个方面的问题有信心解决,才能用精通
  • 为什么跳槽
    • NG答案
      • 老板刻薄
      • 同事难相处
      • 加班频繁
      • 工资太低
    • 可以尝试的
      • 对现在的工作失去了激情,需要寻找一份有挑战

技术面试 40-50分钟

  • 基础知识
    • 数据结构,算法,编程语言等
  • 能写出清晰,完整的代码
  • 能思路清晰的解决问题
    • 简单问题-> 清晰代码
    • 复杂问题-> 画图,举例等分析
  • 能从时间空间方面优化代码
    • 主动提问,弄清要求
  • 沟通能力,学习能力,发散思维能力

基础

  • 对一门编程语言的掌握
  • 数据结构
    • 链表,树,栈,队列,哈希表
    • 尤其是链表和二叉树
  • 查找,排序算法等

高质量代码

  • 边界条件,特殊输入
  • 简单的问题需要完整的考虑问题,考虑特殊条件
  • 代码是不是够鲁棒

清晰的思路

  • 举几个简单的例子让自己理解问题
  • 图形抽象数据结构
  • 把复杂的问题分成简单的子问题

优化效率的能力

  • 不能放弃思考
  • 需要知道怎么计算效率
    • 比如斐波那契数列,用top-down就比bottom-up的重复计算多出很多
  • 知道各种数据结构的优缺点

学习能力

  • 最近在看什么书,学习到了什么新技术
  • 抛出一个新概念,理解并解决相关的问题

提问环节 5-10分钟

  • 不要问和自己职位没关系的问题
  • 不要问薪水(指技术面试)
  • 不要立即打听面试的结果
  • 与应聘的职位和项目相关的问题
    • 提前了解公司信息
    • 注意面试时对方介绍的内容

第二章 面试的基础知识

编程语言

驱动C,linuxCpp,windowsC#,跨平台Java,苹果O-C,小型应用Perl,Python

C++

  • sizeof(也就是拿着准备好的概念题)
    • 空类型的sizeof,instance需要占据一定空间,占用多少编译器决定
  • 给一段代码,看是否能够运行等
  • 定义一个类型或实现类型中的成员函数

相关书籍

  • Effective C++(面试之前突击)
  • C++ Primer(语法的全面了解)
  • 深度搜索C++对象模型(了解对象内部)
  • The C++ Programming Language(深入了解)

C\

  • 主要会问C++和C#的区别

相关书籍

  • Professional C#(写给已经有其他经验的程序员)
  • CLR Via C#

数据结构

关于docker

Posted on 2019-11-05 | In 基础 , 工具
  • Docker
  • Docker入门教程
  • 通俗解释Docker是什么

解决的问题

不同的机器有不同的操作系统,库和组件。把一个应用部署到多台机器上需要大量环境配置的操作

  • 主要就是实现隔离性。但是比虚拟机的隔离性好很多
  • 主要解决的问题
    • 硬件性能过剩。在很多时候硬件处于闲置状态
    • 软件冲突
  • 但是在上面的情况下,如果使用多台电脑成本很高,所以在硬件机能过剩的情况下,硬件虚拟化的普及就提出来了
1
2
绝大部分应用,开发者都可以通过docker build创建镜像,通过docker push上传镜像,用户通过docker pull下载镜像,用docker run运行应用。
用户不需要再去关心如何搭建环境,如何安装,如何解决不同发行版的库冲突——而且通常不会需要消耗更多的硬件资源,不会明显降低性能。这就是其他答主所说的标准化、集装箱的原因所在。

Docker是对Linux容器(Linux Containers)的一种封装

docker解决的就是环境配置的问题。

  • 对进程隔离,被隔离的进程独立于宿主系统或者其他隔离进程
  • 可以不修改程序代码,不需要学习特定环境的技术,就能实现应用程序部署在机器上

用途

  • 提供一次性的环境。
    • 本地测试他人软件
    • 持续集成时,提供单元测试和构建环境
      • 持续集成指不断的将代码集成到主干上,这样能更快的发现错误
      • 因为使用的时候可以隔离,随意不会对其他的产生影响
  • 提供弹性的云服务:因为可以随开随关
  • 组件微服务架构:
    • 可以在本机模拟出服务器架构

与虚拟机的比较

虚拟机是通过模拟硬件,在硬件上安装操作系统从而实现的

启动速度

  • 虚拟机需要先启动虚拟机的操作系统,再启动应用
  • docker相当于直接启动一个进程,速度快

占用资源

  • 一台机器只能开十几个虚拟机,是一个完整的操作系统,需要占用大量的磁盘,内存和CPU
  • docker只需要相关应用和组件,一台机器可以开成千上万个

优势

  • 容易迁移:打包好的应用在不同的机器上迁移
  • 容易维护:分层和镜像,可以容易复用重复的部分。
  • 容易扩展:可以使用基础镜像扩展得到新的镜像

镜像(imgae)和容器

镜像是一种静态的结构,可以看成OOP里面的类。容器是镜像的一个instance
镜像包含容器运行时候需要的代码以及组件,是一个分层结构,每一层都是只读的。构建镜像的时候会一层一层的创建,前一层是后一层的基础
构建容器的时候,可以在镜像里增加writeable layer,从而保存容器在运行过程中的修改

容器文件

  • 生成容器后,会存在容器文件和image文件。关闭容器不会删除容器文件
  • 如果要完全终止,可以删除容器文件

image文件

  • docker把应用程序以及他的依赖,打包在image文件里。经过这个文件才能生成docker容器,docker根据这个文件生成容器的实例。
  • image是二进制文件,实际开发中,image文件一般都会继承另一个image文件,再加上一些个性化设置(image文件是通用的)
  • 制作完成后,文件可以上传网上仓库,比如DockerHub

Python在遍历时删除元素

Posted on 2019-10-30 | In 编程语言 , Python , list
  • Python语法糖——遍历列表时删除元素
  • Filter

之前在leetcode刷题的时候,如果用for循环删除list的元素时总会发生问题。由此来总结一下遍历删除元素的各个方法

我比较常用的——建立新的list

简单直接的方法可以挺好的解决这个问题,建立一个新的list。如果结果不符合,则跳过这个元素,符合的时候把这个元素加入list。
虽然这样显得比较蠢,但是遇到问题的时候比较容易想起来

延伸:遍历拷贝的list。操作原始的list

1
2
3
for i in lst[:]:
if i == 0:
lst.remove(i)
  • 在这里,lst[:]已经是拷贝之后的结果了,也就是说对原来的lst操作不会对拷贝的结果产生影响

filter

  • 显得比较聪明的一种方法
  • filter是python里面的一个函数,包括两个参数
    • function:用于条件判断。这个function可以是之前已经用def定义好的function,也可以是用lamnda简写的function
    • lst:用于输入需要修改的list,参数是一个可迭代的对象
      1
      lst = filter(lambda x: x != 0, lst)

也就是说,会先判断x是否不等于0,如果返回值是true,那么保留这个元素。如果返回值是false,则删除这个元素。

列表解析

也就是在1行里面写list的方法

1
lst  = [x for x in lst if x != 0]

while判断

1
2
while 0 in lst:
lst.remove(0)

倒序循环

  • 这个方法占用的空间最少
  • 但是可读性比较差
1
2
3
for i in range(len(lst)-1,-1,-1):
if lst[i] == 0:
del lst[i]

关于Git

Posted on 2019-10-27 | In 基础 , 工具
  • Git
  • 什么是分支
  • Git常用命令

集中式系统和分布式系统

Git属于分布式,SVN(subversion)是集中式的系统

  • 集中式只有在中心服务器有一份代码,分布式在每个人的电脑上都有一份代码
  • 集中式版本控制有安全性问题(中心服务器挂了)
  • 集中式需要联网才能工作。
  • 分布式新建分支,合并分支的操作比较快。集中式新建分支相当于复制一份完整代码

中心服务器

Github作为中心服务器用于交换每个用户的修改,没有中心服务器也能工作,倒是中心服务器24小时开启方便交流。

工作流

  • 新建仓库之后,目前的目录就成为了工作区。工作区有一个隐藏目录.git,属于Git的版本库
  • 在版本库里面,有一个Stage的暂存区,以及History版本库。在History里面会储存所有的分支,然后会使用HEAD指针来指向目前分区
    区域
  • 使用 git add 会把文件添加到暂存区,也就是Stage
  • 使用 git commit 会把暂存区的修改提交到当前的分支里面。提交之后暂存区就清空了
  • 使用 git reset – 会使用现在的分支内容覆盖暂存区,也就是撤销最后一次add的操作
  • 使用 git checkout – 会用Stage的内容覆盖本地内容,撤销最后一次本地修改
    也可以用复合命令来跳过Stage的部分
  • 如果使用 git commit -a可以直接把文件的修改先加到暂存区,然后再提交
  • 如果使用 git checkout HEAD – 可以取出最后一次修改,也就是对本地文件进行回滚操作

分支的实现

在Git里面,使用了指针把每次的提交都连成一条线,HEAD会指向当前的指针
branch-1

新建分支会在时间线上最后一个节点新建分支,并且HEAD会指向新的分支。而对新的分支的每次提交只会让当前的指针移动,其他的指针不会移动

branch-2

合并的时候改变的也是Master的指针

关于Git的分支(branch)

什么是分支

  • 分支的意义:把现在的工作从主线上分离开,以免影响开发主线(这也是Git最大的优势,因为SVN开发新的分支相当于复制代码,速度非常慢)
  • 为了不影响其他人的开发,可以在主线上建立自己的分支,工作完成后合并到主分支。每一次的提交会被保存,这样发生问题时候的定位就更加容易了

分支的应用

  • merge分支,为了可以随时发布release而创建的分支。通常大家会把master当成merge分支来使用
  • Topic分支:为了开发新功能或者修复Bug的分支,从merge里面创建,完成之后需要合并到merge里面去

分支的合并

  • merge(历史记录会非常复杂)
    • 如果以前的master没有改变,可以直接合并(fast forward)
      • 可以在合并时加上–no-ff来进行Fast forward,加上-m生成一个新的commit
      • 如果直接fast forward可能会丢失分支信息
    • 如果以前的有了新的更新,需要把两个分支修改的内容结合,生成一个新的提交
      merge
  • rebase(历史记录简单,但是可能会导致原来的内容无法正常运行)
    • 如果使用这个方法合并,最后得到的结果会是一条线性的。如果在提交的时候X和Y发生冲突,需要修改冲突的部分
      rebase

分支的冲突

如果两个分支对同一个文件都进行了修改,合并的时候就会产生冲突。把不同分支的内容修改成一样的就可以解决
在Git里面会用 <<<<< ===== >>>>>来表示

储藏 Stashing

在一个分支上操作之后,如果没有提交这个分支就进行切换,那么在另一个分支上也能看到修改。因为所有的分支都公用一个工作区域。

  • 可以使用 git stash把当前的分支修改储藏起来,这样就可以安全的切换到其他分支
  • 比如,如果正在dev分支上开发,此时有master上面的bug需要修改,但是dev的开发还没有完成。这时候可以新建一个bug分支,并且切换到bug之前先用stash把目前dev的开发进度储存起来

SSH传输设置

Git的仓库和Github的中心仓库是通过SSH进行加密的

.gitignore

这个文件可以忽略以下的文件:

  • 操作系统自动生成的文件,比如缩略图
  • 编译生成的中间文件
  • 自己的敏感信息。比如存放口令的配置文件

gitignore

正则表达式

Posted on 2019-10-24 | Edited on 2019-10-27 | In 基础 , 工具

参考资料:

  • 读懂正则表达式就是这么简单
  • 正则表达式
  • 正则表达式网站

基本概念

正規表現(せいきひょうげん、英: regular expression)形式言語分野
用于文本内容的查找和替换(差し替える)
用于其他语言或者产品软件里面
在使用的时候一定要注意转义符号\,不使用这个符号的时候代表的是真实的内容,使用了才有相应的意思

正则字符

元符号

  • 被匹配的字符第一个必须和^之后的一样,最后一个必须和$之前的一样
  • “^”:
    • 匹配行或字符串的起始位置
    • 整个文档的起始位置
  • $:行或者字符串的结尾

  • \b:用于匹配边界,不消耗字符(Boundary)

    • \bis\b 用来识别is的两边是否是边界
  • \d:匹配数字(digit)
    • 比如0开头,五位数-> ^0\d\d\d\d\d$
  • \w:匹配字母,数字,下划线(基本可以理解为注册用户名的要求)
  • \s:匹配空格,\s+可以让空格重复
  • .:匹配除了转行符号以外的任何字符。\w的加强版,相当于w加上空格
  • []:匹配在空号内元素的字符,只匹配存在于括号里面的。可以写成[a-z]

反义

上面的表达写成大写,如果是[]的话变成[^],表达的意思是不包括这些的字符

量词

有关量词的三个概念:

  • 贪心 * 会首先匹配整个字符串,会选择尽可能多的内容,失败的话就backtracking(消耗最大)
  • 懒惰 ?从起始位置开始尝试匹配,每次检查一个内容,直到检查完所有的内容(相当于遍历)
  • 占有 + 覆盖整个字符串,然后寻找。但是就试一次

相关量词:

  • 贪心* 会重复0次或者更多
    • ”aaaaa“里面匹配a* ,那么得到的是所有的字符a
    • 重复一次或多次:
      • ”aaaaa“,a+会取字符中所有a值,但是* 可以是0次,+不行
  • ? 重复零次或一次
    • ”aaaaa“,a?只会匹配一次,结果也是单个字符a
  • {n},重复n次,比如a{3}会匹配aaa
  • {n,m} 重复n-m次,比如a{3,4}可以匹配到aaa或者aaaa
  • {n,} 重复n次或更多次,也就是至少重复n次

懒惰限定符(大家和?的排列组合)

  • *? 重复任意次,但是尽可能少重复
    • 比如 acbacb,正则 a.*?b,只会匹配acb,因为需要.重复的数量尽可能少
  • +?重复1次或者更多次,但是尽可能少重复
  • ?? 重复0次或一次,但是尽可能少重复
  • {n,m}重复n-m次,但是尽可能少重复。比如a{0,m}?取到的是空
  • {n,}?至少重复n次,尽可能少重复

进阶

捕获分组

如果给一部分的内容加上了括号,这部分的内容就被抓住了。然后如果后面用到了相同内容的表达式,就可以直接用一个符号代替,而不用继续写一个了。
不考虑重复使用的时候,也可以单独只用于分组,分组之后的内容可以加上+ * ?等内容进行重复。但是注意嵌套层数过多会引起歧义
常用写法

  • (exp):匹配exp。捕获到自动命名的组里面,\1这样的
  • (?exp)匹配exp,捕获内容并自己命名,后面引用的时候需要 “\k“
  • (?:exp):匹配exp,但是不捕获,也不给这个组分配编号
  • (?=exp):匹配exp前面的位置
    • how are you doing,正则(?.+(?=ing)),去ing前面的字符,匹配出来的是how are you do(匹配ing之前的.+)
  • (?<=exp):匹配后面的位置。比如(?(?<=how).+),匹配后面的位置,也就是匹配how之后的.+
  • (?!exp):匹配后面不跟着exp的位置。比如\d{3}(?!\d)匹配三个数字,然后后面不再跟数字了
  • (?<!exp):匹配前面不是exp的位置。(?!<[0-9])123,匹配123,并且123前面不能是数字

例子:

分组使用

比如匹配IP地址,IP地址由四部分组成,每一部分是0-255的数字。则可以分为以下的部分表示

  • 一位数字
  • 不以0开头的两位数
  • 2开头,第二位是0-4的三位数
  • 25开头,第三位是0-5的三位数
    1
    ((25[0-5]|(2[0-4]\d)|(1\d{2})|([1-9]\d)|(\d))\.){3}(25[0-5]|(2[0-4]\d)|(1\d{2})|([1-9]\d)|(\d))

回溯引用

比如匹配HTML里面的标题元素

1
<(h[1-6])>\w*?<\/\1>

其中,h[1-6]被分为一组,这一组的名字叫做\1,也就是说前后的两部分需要一样。h1对h1,h2对h2才能匹配上

替换(需要两个regexp)

比如修改电话号码格式
313-555-1234

  • 查找的正则式(\d{3})(-)(\d{3})(-)(\d{4})
  • 需要替换成为的格式($1)$3-$5。也就是说把第一个正则式中的第1,3,5个括号直接代入了后面替换的格式里面
  • 替换之后的内容 (313)555-1234

大小写转变

  • \l 把后面跟随的单独的字符改成小写
  • \u 把单独的字符改成大写
  • \L 把L之后,E之前的全都变成小写
  • \U 把U之后,E之前的全都变成大写
  • \E 结束符号

如,abcd,查找(\w)(\w{2})(\w),然后改为$1\U$2\E$3

前后查找

订好了应该匹配的内容的首尾内容,但是不包括这个首尾内容。也就是前面说到的向前匹配?=和向后匹配?<=.(但是js不支持向后匹配)。如果要找非的条件的时候,需要把=换成!

  • 比如匹配邮箱的@前面的部分 (\w+|.)+(?=@)(这里加上了.,因为我的学校邮箱@前面也是有. 的)
  • 匹配结果: **xu.r.aa**@m.titech.ac.jp

嵌入条件

回溯引用

判断某个表达式是否匹配,如果匹配的话继续匹配后面的条件

1
(\()?abc(?(1)\))

  • 先匹配左括号((),?来判断左括号有0个或者1个
  • ?(1)是判断的表达式,也就是说能匹配到左括号的时候,再匹配右括号。
  • 匹配结果:
    abc
    (abc)
    (abc

前后查找

条件为首尾是否匹配,如果匹配的话继续(注意首尾不包括在匹配内容里面)

1
\d{5}(?(?=-)-\d{4})

  • 首先匹配五位数字
  • (?=-)表示向前查找-,也就是对-向前查找,作为条件。如果向前查找成功了,那么继续进行后面的操作,也就是匹配一个-,然后匹配一个4位数字
    44444-4444
    44444-
    66666
123…9
RUOPENG XU

RUOPENG XU

85 posts
58 categories
92 tags
© 2022 RUOPENG XU
Powered by Hexo v3.8.0
|
Theme – NexT.Gemini v7.0.1