文章目录
  1. 1. 问题排查
    1. 1.1. CPU异常飙高排查思路
  2. 2. JavaCore相关
    1. 2.1. bigdecimal四舍五入
    2. 2.2. bigDecimal转换为百分比,保留若干小数
    3. 2.3. bigDecimal精确度
    4. 2.4. bigDecimal除法
    5. 2.5. bigdecimal详解
    6. 2.6. java8的optionnal
  3. 3. 并发框架
  4. 4. 集合框架
    1. 4.1. 如何对一个list进行subList操作
    2. 4.2. 集合如何进行排序操作?(如:如何对一个list中的元素进行排序)
  5. 5. 数据库相关(包含Dao相关组件)
    1. 5.1. mybatis update自动追加逗号 “,”
    2. 5.2. mybatis使用truncate语句
    3. 5.3. mybatis使用@Param传参以及批量插入
    4. 5.4. MySQL建表时设置timestamp精度到毫秒
    5. 5.5. mybatis批量插入
    6. 5.6. MySQL的case when语法
  6. 6. 前端相关
    1. 6.1. vue页面间传参
    2. 6.2. vue element获取一行数据
    3. 6.3. vue element视频播放组件
  7. 7. 工具技巧
    1. 7.1. 跨主机进行文件复制
    2. 7.2. idea自动导包
  8. 8. 打包运行相关
    1. 8.1. 如何通过命令行传递带空格的参数?
    2. 8.2. Linux下找出进程正在侦听的端口号
    3. 8.3. nohup的作用
  9. 9. git 相关
    1. 9.1. git更新带子module的工程
    2. 9.2. git更新子工程终极方案
    3. 9.3. git 强制使用远程覆盖本地
    4. 9.4. git去除某个历史提交
  10. 10. 方法2–递归方式
  11. 11. Spring相关
    1. 11.1. Spring中通过 @Value 设置默认值
    2. 11.2. Spring中HttpServletRequest的线程安全性
    3. 11.3. SpringBoot 类加载机制
    4. 11.4. Spring Bean生命周期
    5. 11.5. Spring强化
  12. 12. Jersey相关
    1. 12.1. Jersey常用方法
    2. 12.2. 查看Jersey REST服务的WADL服务定义
  13. 13. Json解析相关
    1. 13.1. Jackson整理
  14. 14. ffmpeg
  15. 15. 维护多个sshkey
    1. 15.1. 具体步骤
  16. 16. vim临时显示行号
  17. 17. python相关
    1. 17.1. 1. init.py的作用

本文将主要记录在日常开发中遇到的各种问题。以技术类别进行章节划分,作为个人的编码备忘录随时进行查阅,并长期进行置顶。

问题排查

CPU异常飙高排查思路

cpu占用高如何排查

  • 查看占用cpu高的进程: 通过 top 命令找到 CPU 消耗最高的进程,并记住进程 ID {pid}。

    top -M -n 2 -d 3 >{pid}/top.txt 查看top

  • 再次通过 top -Hp {pid} 找到 CPU 消耗最高的线程 ID,并记住线程 ID(十进制).
  • 通过 JDK 提供的 jstack 工具 dump 线程堆栈信息到指定文件中。

    jstack {pid} >{pid}/jstack_1.txt 一次堆栈快照 备用

    jstack {pid} >{pid}/jstack_2.txt 两次堆栈快照 备用

  • 由于刚刚的线程 ID 是十进制的,而堆栈信息中的线程 ID 是16进制的,因此我们需要将10进制的转换成16进制的,并用这个线程 ID 在堆栈中查找。

    使用 printf “%x\n” [十进制数字] ,可以将10进制转换成16进制。

  • 通过刚刚转换的16进制数字从堆栈信息里找到对应的线程堆栈。就可以从该堆栈中看出端倪。

  • 通过top查看当前进程cpu占用情况,找到cpu使用最高的进程PID
  • 查看子进程情况

    top -p 4606 -H

  • 将 子进程id 转换成16进制

    printf “%x \n” 4648 结果为1228

  • 使用jstack查询具体出现问题的代码位置

    jstack 4606|grep 1228 -C 30

  • 根据打印结果定位到具体代码位置

JavaCore相关

该模块主要记录JavaCore相关的技术点

bigdecimal四舍五入

BigDecimal.ROUND_HALF_UP: 遇到.5的情况时往上近似,例: 1.5 ->;2
BigDecimal.ROUND_HALF_DOWN : 遇到.5的情况时往下近似,例: 1.5 ->;1

bigDecimal转换为百分比,保留若干小数

DecimalFormat decimalFormat = new DecimalFormat("0.00%");
BigDecimal decimal = new BigDecimal(count.intValue()).divide(new BigDecimal(allCount), 5, ROUND_HALF_UP);
String formatted = decimalFormat.format(sdPercent);

bigDecimal精确度

BigDecimal.setScale(5,  BigDecimal.ROUND_HALF_UP)  -->保留五位小数,最后一位遇到.5的情况时往上近似

bigDecimal除法

  1. Java的BigDecimal在使用除法(divide方法)时,应该手动指定精度和舍入的方式。
  2. 如果不指定精度和舍入方式,在除不尽的时候会报异常。

bigdecimal详解

这里直接参考别人的文章:

(BigDecimal的用法详解)[https://www.cnblogs.com/jpfss/p/8072379.html]

java8的optionnal

理解、学习与使用 JAVA 中的 OPTIONAL

举个例子:

public static void main(String[] args) {
    Double d = 2.2;
    Optional.ofNullable(d).ifPresent(a -> {
        System.out.println(a);
    });
    Double a = null;
    System.out.println(Optional.ofNullable(a).orElse(2.2));
}

ofNullable:如果对象即可能是 null 也可能是非 null,你就应该使用 ofNullable() 方法:不会抛出NullPointerException

ifPresent:检查是否有值的。该方法除了执行检查,还接受一个Consumer(消费者) 参数,如果对象不是空的,就对执行传入的 Lambda 表达式:

orElse:如果有值则返回该值,否则返回传递给它的参数值

并发框架

这部分主要讲并发框架相关

  1. CompletableFuture用法

CompletableFuture需要单独总结,这里直接放一个参考链接。 CompletableFuture 使用详解

  1. Java线程池拒绝策略

Java线程池的拒绝策略

Java ThreadPoolExecutor的拒绝策略

  1. SimpleDateFormat为何线程不安全?

SimpleDateFormat线程不安全问题与ThreadLocal原理

集合框架

本模块主要记录集合相关的问题

如何对一个list进行subList操作

1
2
3
List<Object> list = new Arraylist<>();
List<Object> subList = list.subList(0, 5);
其中subList(0, 5)取得的是下标为0到4的元素,不包含下标为5的元素.

注意:subList看起来好像是取出了原list的子list,实际上仅仅是取到原list的引用。

subList方法的返回值,只是ArrayList的一个映像而已。

也就是说,当我们使用子集合subList进行元素的修改操作时,会影响原有的list集合。

如果要生成原有list的子集合,还是采用硬复制的方式比较好,也就是新建一个新的list,对原list集合进行解析后装载到新的list中。

集合如何进行排序操作?(如:如何对一个list中的元素进行排序)

集合排序,一般有三种方法。

利用集合框架提供的Collections.sort实现排序,待进行排序的实体需要实现比较器Comparable接口的compareTo方法。

返回当前入参的实体和this对象的属性差(该属性为排序依据),

属性差如果为负数表示当前入参比本身小,

属性差如果为0表示当前入参与本身相等,

属性差如果为正数表示当前入参比本身大,

最后调用Collections.sort(temp);返回的集合排序方式为自然排序。

通过调用 Collections.sort(List list, Comparator<? super T> c) 方法,传入Comparator实现,这种方式下,实体不需要实现Comparable接口。

对于JDK1.8,可以通过stream流实现排序,对象本身不需要实现Comparable接口,示例代码如下

//3.利用Java8的stream流和Comparator实现集合排序
list = list.stream().sorted(Comparator.comparing(Person::getAge)).collect(Collectors.toList());

数据库相关(包含Dao相关组件)

本章节主要记录数据库相关的技术点,包含Dao相关组件的使用,如JPA、Mybatis等

mybatis update自动追加逗号 “,”

一个推荐的SQL如下:

<update id="updateOne"  parameterType="com.inspur.search.data.EntityRelation">
    UPDATE ENTITY_RELATION
        <trim prefix="set" suffixOverrides=",">
        <if test="srcId!=null">SRC_ID=#{srcId},</if>
        <if test="srcType!=null">SRC_TYPE=#{srcType},</if>
        <if test="destId!=null">DEST_ID=#{destId},</if>
        <if test="destType!=null">DEST_TYPE=#{destType},</if>
        <if test="relType!=null">REL_TYPE=#{relType},</if>
        <if test="status!=null">STATUS=#{status},</if>
        <if test="snId!=null">SN_ID=#{snId},</if>
        </trim>
    WHERE id=#{id}
</update>

这种方式是动态SQL拼接,使用trim是为了删掉最后字段的“,”

不用单独写SET了,因为set被包含在trim中了

mybatis使用truncate语句

在mybatis中使用truncate语句刷新表。

<update id="truncateTable">
    truncate table [表名]
</update>

mybatis使用@Param传参以及批量插入

@Param Parameter N/A 如果你的映射器的方法需要多个参数, 这个注解可以被应用于映射器的方法参数来给每个参数一个名字。否则,多参数将会以它们的顺序位置来被命名 (不包括任何 RowBounds 参数) 比如。 #{param1} , #{param2} 等 , 这是默认的。

如果使用 @Param(“person”), 则参数应该被命名为 #{person}。

这里重点总结一个场景,批量insert。对应sql如下:

<insert id="batchInsertIdList" parameterType="java.util.List">
    insert into idlist_tmp (id, record_date) values
    <foreach collection="tmpInfos" item="tmpInfo" separator=",">
        (#{tmpInfo.id}, #{tmpInfo.recordDate})
    </foreach>
</insert>

这里通过#{tmpInfo.id}指定insert参数为对象tmpInfo的某个属性

int batchInsert(@Param(value = "tmpInfos") List<TmpInfo> tmpInfos);

这里通过@Param指定insert的sql中的参数引用。

MySQL建表时设置timestamp精度到毫秒

CREATE TABLE `table1` (
`tab1_id` VARCHAR(11) DEFAULT NULL,
`create` TIMESTAMP(3) NULL DEFAULT NULL,
`create2` DATETIME(3) DEFAULT NULL
) ENGINE=INNODB DEFAULT CHARSET=utf8

设置精度的方式为:

TIMESTAMP(3)与 DATETIME(3)意思是保留3位毫秒数

TIMESTAMP(6)与 DATETIME(6)意思是保留6位毫秒数

修改字段精度的方式为:

ALTER TABLE tb_financial MODIFY CREATE_TIME DATETIME(3) DEFAULT NULL COMMENT '录入时间';

插入日期可以用NOW(3)来控制精确的毫秒数,如:SELECT CURRENT_TIMESTAMP(3);也是可以的

mybatis批量插入

mybatis 批量插入数据

mybatis批量保存的两种方式(高效插入)

MySQL的case when语法

语法如下:

select 字段1, 字段2,       
    case 字段3     
    when 值1 then 新值       
    when 值2 then 新值      
    end as 重新命名字段3的名字       
from table      
where ……      
order by ……  

如:

SELECT
    m.id AS id0,
    v.id AS id1,
    v.user_id AS userId,
    v.app_id AS appId
    (
    CASE
            WHEN v.label = 0 THEN
            '清晰' 
            WHEN v.label = 1 THEN
            '模糊' 
            WHEN v.label = 2 THEN
            '超清晰' ELSE '其他' 
        END 
        ) AS '清晰度'
    FROM
        video_info v,
        media_info m 
    WHERE
        v.id = m.id 
        AND m.id IN (
            '123123',
            '123124',
            '123125'
        )

参考资料: MySQL 的CASE WHEN 语句使用说明

前端相关

人生苦短,不会点儿前端都没法儿混了。不喜欢也得会写点儿啊…

vue页面间传参

来自:https://blog.csdn.net/qq_29918313/article/details/82862548

A页面带着参数传给B页面,B页面带着该参数请求接口或者有其他用途

A页面:

/* 编辑 */
handleEdit (aa) {
let params = {
    aaId: aa.aaId
}
this.$router.push({
    path: '/bb/edit',
    name: 'Edit',
    params: params
})
},

B页面:

首先要接收A页面传递过来的参数:

let aaId = this.$route.params.aaId

接收方式就是代码中使用的this.$route.params.aaId。B页面中需要带着aaId请求数据,则直接使用即可。另外,跳转页面使用this.$router.push({})。

vue element获取一行数据

来自: https://blog.csdn.net/qq_33616027/article/details/90411872

使用slot-scope获取数据

在操作列,对操作按钮先用带有slot-scope属性的dom进行包装,即可获取当前行的数据,
具体的代码,除了操作列不同外,还需要删除el-table标签中绑定的*@row-click*方法,
剩下的都一样:

<el-table-column label="操作尝试2">
    <template slot-scope="scope">
        <el-button type="text" @click="checkDetail(scope.row)">查看详情</el-button>
    </template>
</el-table-column>
<script>
export default {
        name: "dengmiQuery",
        data() {
            return {
                modifyForm:{
                    formLabelWidth:'120px',
                    mimian:'',
                    mimu:''
                },
                dengmiQueryForm: {
                    dialogVisible: false,
                    list: [],
                }
            };
        },
        methods: {
            checkDetail(val){
                console.log(val)
            }

        }
    }
</script>

通过template slot-scope=“scope”来定义当前行的数据对象,然后通过scope.row来获取当前行的数据。

vue element视频播放组件

来自:https://blog.csdn.net/abelethan/article/details/89016678

搞视频相关业务的一定会接触播放组件

使用 vue-vedio-player

  • 首先我们先安装这个插件

    npm install vue-video-player -s
    
  • 我们需要在main.js里面导入并引用

    import VideoPlayer from 'vue-video-player'
    import 'vue-video-player/src/custom-theme.css'
    import 'video.js/dist/video-js.css'
    
    Vue.use(VideoPlayer)
    
  • html部分

    <template>
        <div class='demo'>
            <video-player class="video-player vjs-custom-skin"
                        ref="videoPlayer"
                        :playsinline="true"
                        :options="playerOptions">
            </video-player>
        </div>
    </template>
    
  • js部分

    <script>
        export default {
            data() {
                return {
                    playerOptions: {
                        //播放速度
                        playbackRates: [0.5, 1.0, 1.5, 2.0], 
                        //如果true,浏览器准备好时开始回放。
                        autoplay: false, 
                        // 默认情况下将会消除任何音频。
                        muted: false, 
                        // 导致视频一结束就重新开始。
                        loop: false, 
                        // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
                        preload: 'auto', 
                        language: 'zh-CN',
                        // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
                        aspectRatio: '16:9',
                        // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
                        fluid: true,
                        sources: [{
                            //类型
                            type: "video/mp4",
                            //url地址
                            src: '' 
                        }],
                        //你的封面地址
                        poster: '', 
                        //允许覆盖Video.js无法播放媒体源时显示的默认信息。
                        notSupportedMessage: '此视频暂无法播放,请稍后再试',
                        controlBar: {
                            timeDivider: true,
                            durationDisplay: true,
                            remainingTimeDisplay: false,
                            //全屏按钮
                            fullscreenToggle: true  
                        }
                    }
    
                }
            }
        }
    </script>
    
  • style部分

    <style scoped>
    .demo{
        display: inline-block;
        width: 600px;
        height: 338px;
        text-align: center;
        line-height: 100px;
        border: 1px solid transparent;
        border-radius: 4px;
        overflow: hidden;
        background: #fff;
        position: relative;
        box-shadow: 0 1px 1px rgba(0, 0, 0, .2);
        margin-right: 4px;
    }
    
    .demo:hover{
        display: block;
    }
    </style>
    

工具技巧

本章节主要记录各种工具使用的技巧,如IDEA GIT等

跨主机进行文件复制

参考链接

从本地服务器复制到远程服务器

复制文件:

$scp local_file remote_username@remote_ip:remote_folder
$scp local_file remote_username@remote_ip:remote_file
$scp local_file remote_ip:remote_folder
$scp local_file remote_ip:remote_file
指定了用户名,命令执行后需要输入用户密码;如果不指定用户名,命令执行后需要输入用户名和密码;

复制目录:

$scp -r local_folder remote_username@remote_ip:remote_folder
$scp -r local_folder remote_ip:remote_folder
第1个指定了用户名,命令执行后需要输入用户密码; 第2个没有指定用户名,命令执行后需要输入用户名和密码;

注解

从远程复制到本地的scp命令与上面的命令一样,只要将从本地复制到远程的命令后面2个参数互换顺序就行了。

使用示例

实例1:从远处复制文件到本地目录

$scp root@10.6.159.147:/opt/soft/demo.tar /opt/soft/
说明: 从10.6.159.147机器上的/opt/soft/的目录中下载demo.tar 文件到本地/opt/soft/目录中

实例2:从远处复制到本地

$scp -r root@10.6.159.147:/opt/soft/test /opt/soft/
说明: 从10.6.159.147机器上的/opt/soft/中下载test目录到本地的/opt/soft/目录来。

实例3:上传本地文件到远程机器指定目录

$scp /opt/soft/demo.tar root@10.6.159.147:/opt/soft/scptest
说明: 复制本地opt/soft/目录下的文件demo.tar 到远程机器10.6.159.147的opt/soft/scptest目录

实例4:上传本地目录到远程机器指定目录

$scp -r /opt/soft/test root@10.6.159.147:/opt/soft/scptest
说明: 上传本地目录 /opt/soft/test到远程机器10.6.159.147上/opt/soft/scptest的目录中

idea自动导包

IDEA自动导包配置方式如下:

在菜单中选择如下选项:
 Settings→
    Editor→
        General→
            Auto Import 
然后勾选Add unambiguous imports on the fly以及Optimize imports on the fly

解释一下含义:

Add unambiguous imports on the fly:        快速添加明确的导入。
Optimize imports on the fly:               快速优化导入,优化的意思即自动帮助删除无用的导入。

打包运行相关

本章节主要记录打包相关的问题

如何通过命令行传递带空格的参数?

通过参数引用即可解决该问题,在UNIX环境下,通过引号将带空格的参数括起来即可,如:

$ java PrintFileSizes "/home/steve/Test File.txt"

Linux下找出进程正在侦听的端口号

在Linux下快速查到正在侦听的端口号,命令如下:

# 安装工具包,默认已安装,centos下为yum install
sudo apt install net-tools
# 查看侦听中的端口
sudo netstat -ltnp

nohup的作用

举个例子,有启动命令如下

nohup java -jar XXX.jar > /dev/null 2>&1 & 

nohup表示:不挂断运行命令,当账户退出或终端关闭时,程序仍然运行。

/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;这里表示”禁止输出”。我们应当在程序内配置日志打印。

其他用法:linux环境下nohup的执行jar

git 相关

本模块主要整理git相关操作

git更新带子module的工程

  1. 首先克隆父工程

    git clone ssh://xxxxxx.git
    
    查看子模块
    
    git submodule
    
    子模块前面有一个-,说明子模块文件还未检入(空文件夹)。
    
  2. 然后在父工程根路径下初始化子工程

    git submodule init
    
    初始化模块只需在克隆父项目后运行一次。
    
  3. 更新子工程

    git submodule update
    

git更新子工程终极方案

cd  project (自己工程目录根目录)
cd  submodule-project (依赖的子工程根路径)
git pull origin branch  (拉取子工程最新提交)
cd  “your-project-root-path”  (进入你自己工程的根目录)
git commit -m 'upgrade model' && git push -u origin your-branch (生成一个提交并push)

这样服务端的子工程也就随之发生更新

git 强制使用远程覆盖本地

git fetch --all && git reset --hard dev&& git pull

git去除某个历史提交

首先获取git提交记录的commitId

git rebase -i 20624e607934da393719a0a046c27a4be32944f1

skip更新为drop或者删除掉

git push origin master --force

方法2–递归方式

递归克隆整个项目

git clone ssh://xxxx.git assets --recursive 

递归克隆整个项目,子模块已经同时更新了,一步到位。

Spring相关

这部分主要整理Spring框架相关的问题,包括SpringBoot

Spring中通过 @Value 设置默认值

1.1 字符串类型的属性设置默认值

    @Value("${some.key:my default value}")
    private String stringWithDefaultValue;

    如果默认值设为空,也将会被设置成默认值。

    @Value("${some.key:}")
    private String stringWithBlankDefaultValue;

1.2 基本类型设置默认值

    布尔类型
    @Value("${some.key:true}")
    private boolean booleanWithDefaultValue;

    数字类型
    @Value("${some.key:42}")
    private int intWithDefaultValue;

1.3 包装类型设置默认值

    布尔类型
    @Value("${some.key:true}")
    private Boolean booleanWithDefaultValue;

    数字类型
    @Value("${some.key:42}")
    private Integer intWithDefaultValue;

1.4 数组的默认值使用逗号分割

    @Value("${some.key:one,two,three}")
    private String[] stringArrayWithDefaults;

    @Value("${some.key:1,2,3}")
    private int[] intArrayWithDefaults;

1.5 使用 Spring Expression Language (SpEL) 设置默认值

    @Value("#{systemProperties['some.key'] ?: 'my default system property value'}")
    private String spelWithDefaultValue;

    这表示:在systemProperties属性文件中,如果没有设置 some.key 的值,my default system property value 会被设置成默认值。

Spring中HttpServletRequest的线程安全性

Spring中获取request的几种方法,及其线程安全性分析

SpringBoot 类加载机制

springboot应用启动原理(二) 扩展URLClassLoader实现嵌套jar加载

Spring Boot ClassLoader

Spring Bean生命周期

一个对象具备完整的Spring生命周期才可以称之为一个Spring的bean,否则就只是个Java对象

参考文章:

Spring Bean的生命周期(非常详细)

Spring Bean的生命周期

spring Bean的完整生命周期

w3cschool—Spring Bean 生命周期

Spring钩子方法和钩子接口的使用详解

剑指Spring源码(一)

剑指Spring源码(二)

剑指Spring源码(三)俯瞰Spring的Bean的生命周期(大众版)

Spring点滴四:Spring Bean生命周期

Spring的BeanPostProcessor和BeanFactoryPostProcessor区别

BeanPostProcessor和BeanFactoryProcessor浅析

Spring强化

那些年,我们一起追的Spring

BeanPostProcessor —— 连接Spring IOC和AOP的桥梁

Jersey相关

这里记录Jersey相关的内容

Jersey常用方法

jersey获取各个参数的总结

查看Jersey REST服务的WADL服务定义

查看WADL服务定义通过下方URL即可访问到。

http://ip:port/应用根路径/application.wadl

Json解析相关

这里主要解析Json解析相关的技术点。

Jackson整理

  1. 在Jackson中将JsonNode转换为Object

    mapper.convertValue(jsonNode, MyPojo.class)

  2. Jackson中的TypeReference

    一般情况下如果没有TypeReference的话,JsonNode转换过来的是LinkedHashMap而不是对象本身,因此
    需要使用TypeReference来进行Json的解析

    如:

    List<TableColumns> columns = mapper.convertValue(params.get("columns"), new TypeReference<List<TableColumns>>() {});
    
    对于复杂Json的转换,需要通过TypeReference解析,TypeReference可以正确反序列化嵌套多层的List或Map,例如List<Map<String,String>>
    

    举个实际的例子,

    Map<String, MarkDetail> markDetailMap = objectMapper.convertValue(haveMarkDetails, new TypeReference<Map<String,MarkDetail>>() {});
    
    Map<String, String> dataDetailMap = objectMapper.convertValue(dataDetailJsonNode, new TypeReference<Map<String, String>>() {});
    

    可以看到,convertValue的第二个参数是一个TypeReference实例。通过这种方式能够将复杂json类型进行正确解析。

ffmpeg

ffmpeg的几个工具基本用法

ffmpeg是用于转码的应用程序。

一个简单的转码命令可以这样写:

将input.avi转码成output.ts,并设置视频的码率为640kbps

ffmpeg -i videoplayback.mp4 -b:v 640k output.ts

用于播放的应用程序。

一个简单的播放命令可以这样写:

播放test.avi

ffplay test.avi

ffprobe是用于查看文件格式的应用程序。

这个就不多介绍了。

ffprobe videoplayback.mp4

维护多个sshkey

在公司与开源社区之间切换,有多个git账户,因此需要一个策略用于维护多个sshkey

由于有两个账号,生成密钥时通常都是三个回车一撸到底,那么后执行的会覆盖先执行的。

三个回车中,第一个回车的意思是保存地址,那我们不直接回车,而是输入保存地址就可以。

具体步骤

  1. 生成第一个密钥

    ssh-keygen -t rsa -C "myoschina@qq.com"
    

连续三个回车,将oschina的密钥默认保存

  1. 生成第二个密钥

在C盘/Users/用户名/.ssh下建立一个新的目录,如:github

接着运行命令生成第二个sshkey

ssh-keygen -t rsa -C "github@gmail.com"

出现Enter file in which to save the key时输入

/c/Users/用户名/.ssh/github/id_rsa

表示将本次生成的key保存在建立的github目录下

  1. 创建config文件

C盘/Users/用户名/.ssh下新建config文件,该文件没有后缀名的,用途是配置映射功能,填入下面代码:

#github配置
Host github.com
    HostName github.com
    IdentityFile c:\\Users\\xxxxx\\github\\.ssh\\id_rsa
    PreferredAuthentications publickey
    User usernameOfGithub

#gitoschina的配置
Host git.oschina.net
    HostName git.oschina.net
    IdentityFile c:\\Users\\xxxxx\\.ssh\\id_rsa
    PreferredAuthentications publickey
    User usernameOfOsChina

HostName是服务器域名,IdentityFile 是密钥的地址.

vim临时显示行号

如果只是临时显示vim的行号,只须按ESC键退出编辑内容模式,输入

:set number  后按回车键显示行号

行号显示只是暂时的,退出vim后再次打开vim就不显示行号了。

python相关

此模块主要整理python相关内容

1. init.py的作用

1、__init__.py是Python中package的标识

__init__.py 文件的一个主要作用是将文件夹变为一个Python模块,
Python 中的每个模块的包中,都有__init__.py 文件

2、批量引入(定义__all__用来模糊导入)

我们在python中导入一个包时,实际上是导入了它的__init__.py文件,
这样我们可以在__init__.py文件中批量导入我们所需要的模块,而不再需要一个一个的导入。

3、配置模块的初始化操作,这个文件也是一个正常的python代码文件,因此可以将初始化代码放入该文件中。

python中init.py文件的作用实例:

python的每个模块的包中,都有一个__init__.py文件,有了这个文件,
我们才能导入这个目录下的module。

__init__.py里面还是可以有内容的,我们在导入一个包时,
实际上导入了它的__init__.py文件。我们可以再__init__.py文件中再导入其他的包,或者模块。

这样,当我们导入这个包的时候,__init__.py文件自动运行。
帮我们导入了这么多个模块,我们就不需要将所有的import语句写在一个文件里了,
也可以减少代码量。不需要一个个去导入module了。



版权声明:

原创不易,洗文可耻。除非注明,本博文章均为原创,转载请以链接形式标明本文地址。

文章目录
  1. 1. 问题排查
    1. 1.1. CPU异常飙高排查思路
  2. 2. JavaCore相关
    1. 2.1. bigdecimal四舍五入
    2. 2.2. bigDecimal转换为百分比,保留若干小数
    3. 2.3. bigDecimal精确度
    4. 2.4. bigDecimal除法
    5. 2.5. bigdecimal详解
    6. 2.6. java8的optionnal
  3. 3. 并发框架
  4. 4. 集合框架
    1. 4.1. 如何对一个list进行subList操作
    2. 4.2. 集合如何进行排序操作?(如:如何对一个list中的元素进行排序)
  5. 5. 数据库相关(包含Dao相关组件)
    1. 5.1. mybatis update自动追加逗号 “,”
    2. 5.2. mybatis使用truncate语句
    3. 5.3. mybatis使用@Param传参以及批量插入
    4. 5.4. MySQL建表时设置timestamp精度到毫秒
    5. 5.5. mybatis批量插入
    6. 5.6. MySQL的case when语法
  6. 6. 前端相关
    1. 6.1. vue页面间传参
    2. 6.2. vue element获取一行数据
    3. 6.3. vue element视频播放组件
  7. 7. 工具技巧
    1. 7.1. 跨主机进行文件复制
    2. 7.2. idea自动导包
  8. 8. 打包运行相关
    1. 8.1. 如何通过命令行传递带空格的参数?
    2. 8.2. Linux下找出进程正在侦听的端口号
    3. 8.3. nohup的作用
  9. 9. git 相关
    1. 9.1. git更新带子module的工程
    2. 9.2. git更新子工程终极方案
    3. 9.3. git 强制使用远程覆盖本地
    4. 9.4. git去除某个历史提交
  10. 10. 方法2–递归方式
  11. 11. Spring相关
    1. 11.1. Spring中通过 @Value 设置默认值
    2. 11.2. Spring中HttpServletRequest的线程安全性
    3. 11.3. SpringBoot 类加载机制
    4. 11.4. Spring Bean生命周期
    5. 11.5. Spring强化
  12. 12. Jersey相关
    1. 12.1. Jersey常用方法
    2. 12.2. 查看Jersey REST服务的WADL服务定义
  13. 13. Json解析相关
    1. 13.1. Jackson整理
  14. 14. ffmpeg
  15. 15. 维护多个sshkey
    1. 15.1. 具体步骤
  16. 16. vim临时显示行号
  17. 17. python相关
    1. 17.1. 1. init.py的作用
Fork me on GitHub