python(2)-flask+gunicorn+supervisor的python服务部署

过程

部署一个 Python 服务可以通过 Flask 框架、Gunicorn 服务器和 Supervisor 进程管理工具来完成。

1.安装 Flask、Gunicorn 和 Supervisor:

1
pip install flask gunicorn supervisor

  1. 创建一个 Python 脚本,例如 app.py,并添加一个简单的 Flask 应用。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from flask import Flask

    app = Flask(__name__)

    @app.route('/')
    def hello():
    return "Hello, World!"

    if __name__ == '__main__':
    app.run()

3.创建 Gunicorn 配置文件:创建一个名为 gunicorn_config.py 的文件,配置 Gunicorn 服务器:

1
2
bind = '0.0.0.0:8000'
workers = 4

4.运行 Gunicorn 服务器:使用 Gunicorn 运行 Flask 应用:

1
gunicorn -c gunicorn_config.py app:app

5.创建 Supervisor 配置文件:创建一个名为 flask_app.conf 的配置文件,配置 Supervisor:

1
2
3
4
5
6
7
[program:flask_app]
directory=/path/to/your/app
command=/path/to/gunicorn -c /path/to/gunicorn_config.py app:app
autostart=true
autorestart=true
stderr_logfile=/var/log/flask_app.err.log
stdout_logfile=/var/log/flask_app.out.log

6.启动 Supervisor:启动 Supervisor 并加载配置文件:

1
sudo supervisord -c /etc/supervisor/supervisord.conf

7.检查应用程序状态:使用 Supervisorctl 命令检查应用程序的状态:

1
sudo supervisorctl status

SQL(1)-基本用法

SQL(Structured Query Language)是用于管理和操作关系型数据库的标准语言。以下是SQL的一些常用知识点,涵盖了基本的查询、数据操作、数据定义和数据控制等方面:

1. 基本查询

  • SELECT语句:用于从数据库中检索数据。

    1
    2
    SELECT column1, column2, ...
    FROM table_name;
  • WHERE子句:用于过滤记录。

    1
    2
    3
    SELECT column1, column2, ...
    FROM table_name
    WHERE condition;
  • AND / OR:用于组合多个条件。

    1
    2
    3
    SELECT column1, column2, ...
    FROM table_name
    WHERE condition1 AND condition2;
  • IN子句:用于指定多个可能的值。

    1
    2
    3
    SELECT column1, column2, ...
    FROM table_name
    WHERE column_name IN (value1, value2, ...);
  • BETWEEN子句:用于选取介于两个值之间的数据。

    1
    2
    3
    SELECT column1, column2, ...
    FROM table_name
    WHERE column_name BETWEEN value1 AND value2;
  • LIKE子句:用于模式匹配。

    1
    2
    3
    SELECT column1, column2, ...
    FROM table_name
    WHERE column_name LIKE pattern;

2. 排序和分组

  • ORDER BY子句:用于对结果集进行排序。

    1
    2
    3
    SELECT column1, column2, ...
    FROM table_name
    ORDER BY column1 ASC/DESC;
  • GROUP BY子句:用于将数据分组。

    1
    2
    3
    SELECT column1, column2, AGGREGATE_FUNCTION(column3)
    FROM table_name
    GROUP BY column1, column2;
  • HAVING子句:用于过滤分组后的结果。

    1
    2
    3
    4
    SELECT column1, AGGREGATE_FUNCTION(column2)
    FROM table_name
    GROUP BY column1
    HAVING AGGREGATE_FUNCTION(column2) condition;

3. 聚合函数

  • COUNT:用于计数。

    1
    2
    SELECT COUNT(column_name)
    FROM table_name;
  • SUM:用于求和。

    1
    2
    SELECT SUM(column_name)
    FROM table_name;
  • AVG:用于求平均值。

    1
    2
    SELECT AVG(column_name)
    FROM table_name;
  • MAX:用于求最大值。

    1
    2
    SELECT MAX(column_name)
    FROM table_name;
  • MIN:用于求最小值。

    1
    2
    SELECT MIN(column_name)
    FROM table_name;

4. 数据操作

  • INSERT语句:用于插入新记录。

    1
    2
    INSERT INTO table_name (column1, column2, ...)
    VALUES (value1, value2, ...);
  • UPDATE语句:用于更新现有记录。

    1
    2
    3
    UPDATE table_name
    SET column1 = value1, column2 = value2, ...
    WHERE condition;
  • DELETE语句:用于删除记录。

    1
    2
    DELETE FROM table_name
    WHERE condition;

5. 数据定义

  • CREATE TABLE语句:用于创建新表。

    1
    2
    3
    4
    5
    CREATE TABLE table_name (
    column1 datatype constraints,
    column2 datatype constraints,
    ...
    );
  • ALTER TABLE语句:用于修改表结构。

    1
    2
    ALTER TABLE table_name
    ADD column_name datatype;
  • DROP TABLE语句:用于删除表。

    1
    DROP TABLE table_name;

6. 约束

  • PRIMARY KEY:用于唯一标识表中的每条记录。

    1
    2
    3
    4
    5
    CREATE TABLE table_name (
    column1 datatype PRIMARY KEY,
    column2 datatype,
    ...
    );
  • FOREIGN KEY:用于建立表之间的关系。

    1
    2
    3
    4
    5
    CREATE TABLE table_name (
    column1 datatype,
    column2 datatype,
    FOREIGN KEY (column1) REFERENCES other_table_name(column1)
    );
  • UNIQUE:用于确保列中的所有值都是唯一的。

    1
    2
    3
    4
    5
    CREATE TABLE table_name (
    column1 datatype UNIQUE,
    column2 datatype,
    ...
    );
  • NOT NULL:用于确保列中的值不能为空。

    1
    2
    3
    4
    5
    CREATE TABLE table_name (
    column1 datatype NOT NULL,
    column2 datatype,
    ...
    );

7. 子查询

  • 子查询:在一个查询中嵌套另一个查询。
    1
    2
    3
    SELECT column1, column2, ...
    FROM table_name
    WHERE column1 = (SELECT column1 FROM another_table WHERE condition);

8. 联接(JOIN)

  • INNER JOIN:返回两个表中匹配的记录。

    1
    2
    3
    4
    SELECT table1.column1, table2.column2, ...
    FROM table1
    INNER JOIN table2
    ON table1.common_column = table2.common_column;
  • LEFT JOIN:返回左表中的所有记录,以及右表中匹配的记录。

    1
    2
    3
    4
    SELECT table1.column1, table2.column2, ...
    FROM table1
    LEFT JOIN table2
    ON table1.common_column = table2.common_column;
  • RIGHT JOIN:返回右表中的所有记录,以及左表中匹配的记录。

    1
    2
    3
    4
    SELECT table1.column1, table2.column2, ...
    FROM table1
    RIGHT JOIN table2
    ON table1.common_column = table2.common_column;
  • FULL OUTER JOIN:返回两个表中的所有记录,如果没有匹配,则返回 NULL。

    1
    2
    3
    4
    SELECT table1.column1, table2.column2, ...
    FROM table1
    FULL OUTER JOIN table2
    ON table1.common_column = table2.common_column;

9. 事务控制

  • BEGIN TRANSACTION:开始一个事务。

    1
    BEGIN TRANSACTION;
  • COMMIT:提交事务。

    1
    COMMIT;
  • ROLLBACK:回滚事务。

    1
    ROLLBACK;

10. 视图

  • CREATE VIEW:创建视图。

    1
    2
    3
    4
    CREATE VIEW view_name AS
    SELECT column1, column2, ...
    FROM table_name
    WHERE condition;
  • DROP VIEW:删除视图。

    1
    DROP VIEW view_name;

11. 索引

  • CREATE INDEX:创建索引。

    1
    2
    CREATE INDEX index_name
    ON table_name (column1, column2, ...);
  • DROP INDEX:删除索引。

    1
    DROP INDEX index_name;

12. 存储过程和函数

  • 存储过程:预编译的SQL代码块,可以多次调用。

    1
    2
    3
    4
    5
    CREATE PROCEDURE procedure_name
    AS
    BEGIN
    -- SQL statements
    END;
  • 函数:返回一个值的预编译的SQL代码块。

    1
    2
    3
    4
    5
    6
    7
    CREATE FUNCTION function_name (parameters)
    RETURNS datatype
    AS
    BEGIN
    -- SQL statements
    RETURN result;
    END;

python(1)-语法进阶

yield

yield可以暂停一个函数的运行,返回值给函数调用者,并使得函数可以从上次离开的地方接着运行。通常我们可以借助yield来实现一个生成器。

生成器

生成器是一个可以产生一个序列的函数,调用生成器函数会产生一个生成器对象,并不会开始启动函数,只有当执行__next__()时函数才会执行。生成器时一个一次性操作,和我们常见的列表、字典等可以迭代的对象不同,列表等是可以无限次迭代的。

装饰器

python中函数是一等对象,所以函数可以像普通变量一样当作参数传给另一个函数的,装饰器可以在不改变另一个函数的情况下用来封装另一个函数以拓展这个被封装函数的功能,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码到装饰器中并继续重用。

装饰器不仅可以是函数,也可以是类。使用类装饰器主要依靠类的__call__方法。我们可以直接定义一个装饰器函数或者装饰器类,但是有个缺点是原函数的元信息不见了,比如函数的docstring__name__都会发生改变,此时我们可以使用functools.wrapswraps本身也是一个装饰器,它能把原函数的元信息拷贝到装饰器里面的函数中。

java(1)-面向对象

类与对象

类就是用户定义好的原型,可以通过类创建对象,类中定义好了一系列的属性或者是函数。对象是真正的实体。当为一个类创建了对象,也可以说是实例化了这个类,java中有几种创建类的方式。

当只是简单地声明一个类变量时,如Object a,不同于原始变量int、double等声明变量时就分配好了内存,这样的声明方式并没有创建好一个对象,需要通过new关键字来触发类构造器,并为这个对象分配好内存。所有类都至少有一个构造函数,如果没有定义,Java编译器会自动创建一个无参构造函数。这个构造器会调用其父类的无参构造函数。

封装、继承与多态

修饰符

在介绍封装、继承与多态之前,需要先了解java中的修饰符,修饰符有两类:

一类是控制访问权限的,一类是实现其他功能的。控制访问权限的修饰符有

1
2
3
4
5
6
7
8
// 以下为类修饰符
public --任何类均可访问。
default --没有指定修饰符时的默认修饰符,只有同一个包中的类可以访问。
// 以下为属性、方法修饰符
public --任何类均可访问。
private --只有声明的类中可以访问。
protected --只有同一个包中的类和其子类可以访问。
default --没有指定修饰符时的默认修饰符,只有同一个包中的类可以访问。

实现其他功能的修饰符有:

1
2
3
4
5
6
7
8
9
10
// 以下为类修饰符
final --此类不能被其他类继承。
abstract --抽象类,此类不能用来创建对象。
// 以下为属性、方法修饰符
final --属性、方法不能被重载。
static --属性、方法属于类而不是对象。
abstract -- 只能用在抽象类中的方法上。
transient -- 序列化对象时跳过此属性和方法。
synchronized -- 此方法一次只能被一个线程访问。
volatile --此属性的值不是线程内部缓存,而是从主内存中读取。

封装

封装可以将实现细节隐藏起来,其最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。

继承

在继承中,先了解两个概念:父类和子类,父类就是被继承的类,子类就是继承其他类的类,在jva中,继承使用extends关键字或implements关键字。java中类的继承是单一继承,一个子类只能拥有一个父类。所有 Java 的类均是由java.lang.Object 类继承而来的。通过使用关键字 extends ,子类可以继承父类的除 private 属性外所有的属性。Implements 关键字在类继承接口的情况下使用,可以多继承接口。

重写(Override)与重载(Overload)

重写(Override)

重写是子类对父类的允许访问的方法的实现过程进行重新编写!返回值和形参都不能改变。

子类在声明变量时,可以使用父类类型,这是因为在编译阶段,只是检查参数的引用类型,然而在运行时,Java 虚拟机 (JVM) 指定对象的类型并且运行该对象的方法。需要注意的是构造方法不能被重写。需要在子类中调用父类的被重写方法时,要使用 super 关键字。

重载(Overload)

重载 (overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。构造函数是可以重载的。

多态

通过继承、重写、重载可以以多种不同的方式实现某个操作,便可以实现多态。除此之外,java中还有接口和抽象类以实现多态。

接口

接口通常以interface来声明。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。

Linux相关(2)-进程管理与性能分析

进程管理相关命令

进程启动

1
2
nohup --用于在系统后台不挂断地运行命令
& --放在命令后,表示后台执行

进程查看

1
2
3
4
5
6
7
ps -aux --显示进程状态
top --实时显示进程状态
pstree --树状图展示进程关系
nice --调整进程优先级
pidof --查询进程PID
kill --终止进程
killall --终止某服务名称对应的所有进程

历史命令

1
2
history --显示执行过的命令历史
!编码数字 --重复执行某一次的命令

性能分析

系统状态

1
2
3
4
uname --查看系统内核版本与系统架构,详细系统版本使用cat /etc/redhat-release
uptime --查看系统的负载信息
free --显示当前系统中内存的使用量信息
who --查看当前登入主机的用户终端信息

网络状态

1
2
3
ifconfig --查看网卡配置和网络状态ifconfig
ping --测试主机之间的网络连通性
netstat --显示如网络连接、路由表、接口状态等的网络相关信息

时间

1
2
3
date -- 显示当前日期
date "+%Y-%m-%d %H:%M:%S" --以给定格式显示日期
date "+%j" --今年第几天

git相关(3)-分支与合并

git分支

git分支是git的一大特性,git 的分支本质上仅仅是指向提交对象的可变指针,是包含所指对象校验和(长度为 40 的 SHA-1 值字符串)的文件,这也是为什么git分支的创建和销毁都异常高效的原因,创建新分支时,就是在当前所在的提交对象上创建一个指针,而git是通过一个名为HEAD的特殊指针来记录自己的当前位置的。

与git分支相关的命令有:

1
2
3
4
5
6
7
git branch -- 查看本地分支
git branch -v -- 查看本地分支每个分支的最后一次提交
git branch -vv -- 查看本地分支每个分支跟踪的远程分支
git checkout -b dev -- 新建dev分支,并切换到dev分支(此后HEAD会指向dev分支,工作目录也会变为dev分支指向的快照内容)
git checkout master -- 切换到master分支(此后HEAD会指向master分支,工作目录也会变为master分支指向的快照内容)
git merge dev -- 合并dev分支到当前分支
git branch -d dev -- 删除dev分支

分支切换

注意在切换分支时,git会重置工作目录,自动添加、删除、修改文件以确保此时你的工作目录和这个分支最后一次提交时的样子一模一样,因此在切换分支前,要注意暂存当前的工作进度,可以使用git stash命令暂存当前工作。

分支合并

在合并时,可能会看到fast-forward这个词,这是指当前分支是合并分支的直接上游,两者合并不会产生冲突,而只是指针向前移动了,所以叫做fast-forward。

如果两个分支已经分叉开来,进行合并时,git会根据两个分支的共同祖先来做一个三方合并,此时的合并就不是简单的指针向前移动了,而是将三方合并的结果生成一个新的快照并创建一个新的提交指向它。

有时候合并会发生冲突,靠git自动合并已经无法解决,就需要人工去解决冲突,git会在有冲突的文件中加入标记,使用<<<<<<<>>>>>>>=======标识了冲突的位置,=======将两个分支的冲突位置内容分隔开来,为了解决冲突,只能选择其中一个,手动地将标识的片段改为你选择的内容即可,修改完冲突之后,还要使用git add来表示冲突已经解决,git commit来完成合并提交。

远程分支

远程分支以 (remote)/(branch) 形式命名,本地分支与远程分支交互相关的命令如下:

1
2
3
4
git push (remote) (branch):(remote branch) --推从到远程分支
git fetch (remote) --拉取远程仓库的内容,不会修改工作目录
git pull (remote) --拉取并合并远程仓库的内容到本地
git push (remote) --delete (branch) --删除远程分支

算法(1)--排序

排序

排序方法

选择排序

选择排序的思路是找到数组中最小的数和第一个元素交换位置,然后在剩下的元素中找到最小的元素和第二个元素交换位置,
直到最后只剩一个元素,这样就是一个从小到大排好序的数组。选择排序的复杂度为O(n^2)。

插入排序

插入排序的思路是将元素插入一个已经排好序的子列表中,直到整个列表都排序完成。插入排序的复杂度为O(n^2)。

冒泡排序

冒泡排序的思路是每次对连续的邻居元素进行比较,两个元素是逆序排序就交换位置,否则保持不变,直到所有元素都被排序好。每次进行完一轮比较,就能将最大或者最小的元素移到其最终的位置上,当不再发生交换的时候,就说明元素已经被排好序了,冒泡排序的复杂度是O(n^2)。

归并排序

归并排序的思路是利用递归的方法,将数组分为两半,各自进行归并排序的过程。其关键是如何将排好序的两个子数组也排好序,鉴于两个子数组是已经排好序了的,只需要将两个子数组依次比较。归并排序的复杂度是O(nlogn)。

快速排序

快速排序的思路是挑出一个中心点,把数组分为两半,其中一半所有元素都小于这个中心点,另一半大于这个中心点,再对这两半进行递归处理,所以快速排序的关键在于这个中心点的选择了。快速排序的复杂度是O(nlogn)。

堆排序

堆排序用了二叉堆,将一个数组中的所有元素添加到堆中,然后将堆中最大的元素连续移除以获得一个排好序的数组。一个二叉堆具有如下性质:是一个完全二叉树;每个节点都大于或等于它的子节点,二叉堆通常是用数组实现的,父母节点和子节点的位置满足一定的关系,假如一个在位置i的节点,它的左子节点就在位置2i+1上,右子节点在位置2i+2上。所以堆排序的关键在于二叉堆的建立和维护。堆排序的复杂度是O(nlogn)。

桶排序和基数排序

桶排序和基数排序用于排序整数非常有效。

  • 桶排序

​ 桶排序的思路是加入数组中的元素在0到t的范围内,则把这些元素放入对应的标记上0到t的桶当中,每个桶中的元素值都是相同的。

  • 基数排序

    在桶排序中,如果元素范围过大的话,就会需要很多桶,此时就可以用基数排序。基数排序基于桶排序,只是基数排序只会用到十个桶,基于基数位置进行桶排序。

外排序

当数据量大到无法一次性载入内存时,使用外排序。外排序的思路就是将大量数据拆分成小块数据,小块数据进行内排序之后,再分别合并排序。

相关java基础

数组

数组一旦创建了,大小就是固定的。
java中声明数组变量的语法是’elementType[] arrayRefVar;’,声明数组只是创造了一个数组引用的存储位置,并没有为这个数组分配内存,创建一个数组可以使用new操作符,
例如’array RefVar = new elementType[arraySize];’。

  • 数组的拷贝
    数组变量是一个数组的引用,直接使用赋值语句只是让两个变量去指向同一个数组(同一片存储空间),要想真正地拷贝数组有几种方式:
    使用循环对数组中的元素一个一个地拷贝;使用System类中的静态方法arraycopy;使用clone方法。
    arraycopy的语法是’arraycopy(sourceArray,srcPos,targetArray,tarPos,length);’。

git相关(2)-git&github

远程仓库

远程仓库是指托管在因特网或其他网络中的你的项目的版本库。

github

GitHub是一个面向开源及私有软件项目的托管平台,因为只支持git作为唯一的版本库格式进行托管,故名GitHub。

一次练习

最近在学java,也想巩固一下之前学习过的算法和学习新的算法,就打算用java实现,就用这个项目来加强git的使用练习。

首先在IDEA下java学习的项目里,新建了一个algorithms module,在此文件下,进入Git Bash,新建本地仓库,此时只有一个用来测试排序算法的java文件和一个iml项目配置文件。

image-20200322125951038

目前java文件的内容还是空的,

image-20200322130352882

编辑一下,加入main函数,文件被编辑之后,再次使用git status查看文件状态,会发现文件状态已经变成了modified,再次add,然后开始commit。

image-20200322130657131

commit之后,会显示此次提交的一些信息。

image-20200322131655585

前面展示了一些Git本地的基本操作,现在假如本地文件修改好了,或者工作暂停了,准备放到github上,那么先去github上Create a new repository,最初创建的时候只有一个readme文件,下面将本地仓库同步到远程仓库上。

image-20200322132218647

image-20200322133650342

建立完之后,在本地仓库,将远程仓库的URL复制下来,添加远程仓库。

image-20200322133352132

现在本地仓库里是没有readme文件的,如果此时想要直接push,将本地仓库推送到远程仓库的话,看看会发生什么。

image-20200322134210602

跟随这个报错信息的指示,使用pull,看又会发生什么。这个原因是因为目前本地仓库和远程仓库没有任何相同的文件,根本不相干,所以会被告知无法合并,更加方便的流程是先从远程仓库拉取下来,再把本地文件加入到远程仓库下载到本地的库,然后再提交。

image-20200322135255020

那就没有解决办法了嘛?不是的,可以使用一个强制的方法,添加一个可选项—allow-unrelated-histories,问题终于得以解决。

image-20200322140334095

现在再去github上看看,就会发现提交成功而且push成功啦,开森,撒花~之后就要坚持练习写代码啦,刚把得勒~

image-20200322140554220

git相关(1)-git基础原理与命令

什么是git

Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.

使用Git

假设已经在电脑上安装好了Git,并配好了环境,在windows下,文件夹下右击出现了

Git Bash Here,就说明已经安装好了。

使用git需要首先建立一个仓库,之后就可以在这个仓库中对代码进行各种操作,过程中会使用到各种git命令,下面就介绍一下每个git命令的具体作用。

Git 基础命令

git init用于初始化一个仓库。在某个文件夹下打开Git Bash,运行完这个命令,文件夹下会生成一个.git文件夹,这个文件夹会记录以后的变更行为,但想要真正地追踪这些变更,还需要更多的操作,只有处于tracked状态下的文件,git才会追踪,后面会具体介绍。

git status用于查看仓库中所有文件的状态。Git中文件有4种状态:untracked, unmodified ,

modified, staged,后三种状态属于tracked,这几个状态体现了git的原理。

新建一个文件的时候,这个文件处于untracked状态,对这个文件使用了 git add之后,这个文件进入staged状态,也就是暂存区,使用了git commit之后,这个文件进入unmodified状态,这才是实际提交了改动,如果编辑了这个文件,对这个文件进行了更改,便进入了modified状态。

文件状态图

git add在上部分有介绍过,但是这个命令并不是添加文件到某个项目中的意思,准确地说这个命令是把想要提交的内容添加到准备提交的集合里,可以用这个命令来追踪新文件(add the file),暂存文件(stage the file),或者其它在commit之前的操作。如果在运行了git add之后又修改了文件,没有再次运行git add,就运行了commit,commit的是修改之前的内容。那么是不是每一次都要反复操作git add呢,其实还有别的方法可以跳过暂存区这一步,下面会说明。

git commit是提交变化到仓库里,提交到仓库里的几乎总是可以恢复的,后面会介绍如何恢复。git commit -a就可以跳过暂存区这一步,因为-a包含了所有改动过的文件。git commit -m可以加上这次提交的描述,

git rm用于删除文件,这里的删除有两种含义,从Git中删除和从工作目录中删除,如果只是想要Git不在追踪这个文件,需要使用git rm --cached

git log用于回顾提交历史,运行这个命令可以看到提交的SHA-1 校验和,作者,提交时间和具体提交的内容。如果想要复原到某次提交时候的版本,这个命令是非常重要的,通过拿到每次提交的SHA-1 校验和,可以追踪到对应的版本。

git reset HEAD 用于取消暂存文件。

git checkout --用于撤销所作的修改。

Git 分支

分支就是与主线相对的,每个人都可以使用各自的分支进行工作,而不影响主线。在许多版本控制系统中,是需要创建一个完整的源项目副本来创建分支的,而Git不是这样的,Git处理分支的方式非常轻量,分支之间的操作非常迅速。

要理解Git是如何处理分支的,就要理解Git是如何实现对文件的追踪的。Git保存的是不同时刻的快照(Snapshot),进行提交操作时,Git会保存一个提交对象,这个对象包含了一个指向暂存内容快照的指针,还包含了作者、邮箱等内容以及指向它的父对象的指针,如果是第一次提交,是没有父对象的,而之后的提交,其父对象就是上一次提交。Git的分支,本质上就是指向提交对象的可变指针,所以不同的分支可以指向不同的内容,从而互不影响,而且Git的分支实质上就是一个包含所致对象校验和的文件,所以其创建和销毁都非常高效。

git branch就是创建分支的命令,这个命令会在当前的提交快照上创建一个指针。Git通过一个HEAD的特殊指针指向当前所在的本地分支,从而可以知道自己当前在哪一个分支上。

git branch -d用于删除分支。

git checkout是切换分支的命令。

git merge用于合并分支。当合并分支产生冲突时,Git会停下来,这时候需要手动解决这些冲突,解决完冲突之后,使用git add命令将冲突文件标记为冲突已解决。

远程仓库

之前所述的内容,都是基于本地的操作,而如果想要在Git项目上进行协作,就需要一个公共的空间供项目参与者进行共同编辑,这就是远程仓库。远程仓库是指托管在因特网或其他网络中的你的项目的版本库,使用命令新建远程仓库的操作与本地是一致的,在github上create repository就可以新建一个远程仓库,本地和远程仓库之间通过SSH连接,完成SSH的公钥设置之后, 想要实现本地与远程仓库的内容交换,使用以下介绍的命令。

git remote add <shortname> <url>用于添加一个新的远程仓库。

git fetch用于从远程仓库中获取本地没有的数据,但是这个命令指挥把数据下载到本地仓库,并不会与本地仓库自动合并,想要实现自动合并,需要使用git pull命令。git clone可以把远程仓库的内容克隆到本地,并将远程仓库默认命名为”origin”。

git push <remote> <branch>命令用于将本地内容推送到远程仓库上,只有具备远程仓库的写入权限,并且没有人推送过之前,这条命令才会生效,如果别人先推送了,需要先抓取别人的工作并合并到自己的工作中之后才能推送。

git remote show <remote>用于查看某一个远程仓库的具体新息。

git 别名

上述说了很多命令,有些命令也比较长,命令很多也比较难记下来,git提供了将这些命令起个别名的功能方便使用。

git config --global alias.co checkout就将checkout起了别名co,现在使用git co就相当于git checkout

Linux相关(1)-文件管理与文本编辑

文件操作相关命令

查看目录和文件

1
2
3
4
5
6
7
8
ls -- 当前目录下文件展示
ll -- 当前目录下文件展示 详细
tree --树状图形式展示
pwd --显示当前工作目录
find --按照指定条件来查找文件所对应的位置
cd -- 打开目录,.表示当前目录,..表示上一级目录,-表示回到刚才所在的路径下。
which 命令 --查看命令所在路径
file 文件名 --查看文件类型

查看文件内容

1
2
3
4
5
6
7
8
9
10
11
cat 文件名 -- 从第一行开始显示文件内容
head [-n number] 文件名 -- 只看头几行
tail [-n number] 文件名 -- 只看尾巴几行,tail -f 可以实时查看文件更新内容
more 文件名 -- 一页一页显示内容
less 文件名 -- 一页一页显示内容,相比less可以向上翻页
nl 文件名 -- 显示行号
stat 文件名 --查看文件的具体存储细节和时间等信息
wc 文件名 --统计指定文本文件的行数、字数或字节数
grep 文件名 --按行提取文本内容
cut 文件名 --按列提取文本内容
diff [参数] 文件名称A 文件名称B --比较多个文件之间内容的差异

处理目录和文件

1
2
3
4
5
6
7
8
mkdir -- 创建目录
rmdir -- 删除空目录
cp source dest --复制source到dest
mv source dest -- 移动source到dest/重命名
rm -- 删除
touch --创建空白文件
tar -czvf 压缩包名称.tar.gz 要打包的目录 -- 把指定的文件进行打包压缩
tar -xzvf 压缩包名称.tar.gz -C 解压到的路径 --解压到指定路径

磁盘管理

1
2
3
4
5
df -- 列出文件系统的整体磁盘使用量
du -- 检查磁盘空间使用量
du -ah --max-depth=1 查看当前目录下的第一级使用量
mount --磁盘挂载
umount --磁盘卸载

文本编辑器vi/vim

命令模式(:)

1
2
3
4
5
6
7
8
9
10
11
12
13
:i   -- 进入编辑模式
:wq -- 保存并退出
:q -- 退出
:q! --强制退出
:w [filename] --另存为
:set nu --显示行号
:set nonu --取消行号
:1,$s/word1/word2/g -- 从第一行到最后一行寻找 word1 字符串,并将该字符串取代为 word2
:n1,n2s/word1/word2/g -- 在第 n1 与 n2 行之间寻找 word1 这个字符串,并将该字符串取代为 word2
:10,20s#^#//#g -- 在 10 - 20 行添加 // 注释
:10,20s#^//##g -- 在 10 - 20 行删除 // 注释
:10,20s/^/#/g -- 在 10 - 20 行添加 # 注释
::10,20s/#//g -- 在 10 - 20 行删除 # 注释

操作键:

1
2
3
4
5
6
7
8
9
10
11
gg -- 转到第一行
G -- 转到最后一行
nG -- 转到第n行
dd -- 删除光标所在行
yy -- 复制光标所在行
[Ctrl] + [f] -- 往上翻页
[Ctrl] + [b] -- 往下翻页
/ -- 搜索,如/word就是搜索word
u -- 撤销上一步
[Ctrl]+r -- 重复上一步
p,P -- 粘贴复制内容,p是复制到光标所在下一行,P是复制到光标所在上一行。