开篇 最近迷上了 Emacs 的 org-mode, 所以想以后通过 org-mode 来写博客, 经过一番研究, 就有了现在的这个博客(虽然一年多没有更新了), 下面就来说说这篇博客的搭建历程, 包括一些实用的技巧和踩过的坑. 环境搭建 hugo Install Hugo hugo 主题 Hugo theme Stack ox-hugo pandoc (用于博客迁移, 将 markdown 转为 org 文件) 搭建步骤 通过 hugo 初始化一个目录 # blog 为你的博客目录名称 hugo new site blog 将刚生成的目录发布到 github 上, 至于如何将该目录发布到 github 上有很多种方法, 这里就不展开了 挑选博客主题我这里选用的是: Hugo theme Stack 根据各自的主题文档配置修改配置文件, 这里因为情况不一样, 我就以 Stack 主题举例了 进入到博客根目录下的 themes 文件夹下, 运行以下命令, 将主题仓库作为博客仓库的一个子模块 git submodule add https://github.com/CaiJimmy/hugo-theme-stack/ themes/hugo-theme-stack 进入到主题目录下的 exampleSite 文件夹下 /blog/themes/hugo-theme-stack/exampleSite/ 将其中的 content 文件夹和 config.yaml 文件覆盖到博客根目录下. ...
常用 Git 命令清单
本文转载自阮一峰的网络日志—常用 Git 命令清单 开篇 我每天使用 Git ,但是很多命令记不住。 一般来说,日常使用只要记住下图 6 个命令,就可以了。但是熟练使用,恐怕要记住 60~100 个命令。 下面是我整理的常用 Git 命令清单。几个专用名词的译名如下。 Workspace:工作区 Index / Stage:暂存区 Repository:仓库区(或本地仓库) Remote:远程仓库 一、新建代码库 # 在当前目录新建一个Git代码库 $ git init # 新建一个目录,将其初始化为Git代码库 $ git init [project-name] # 下载一个项目和它的整个代码历史 $ git clone [url] 二、配置 Git 的设置文件为.gitconfig,它可以在用户主目录下(全局配置),也可以在项目目录下(项目配置)。 # 显示当前的Git配置 $ git config --list # 编辑Git配置文件 $ git config -e [--global] # 设置提交代码时的用户信息 $ git config [--global] user.name "[name]" $ git config [--global] user.email "[email address]" 三、增加/删除文件 # 添加指定文件到暂存区 $ git add [file1] [file2] ... # 添加指定目录到暂存区,包括子目录 $ git add [dir] # 添加当前目录的所有文件到暂存区 $ git add . # 添加每个变化前,都会要求确认 # 对于同一个文件的多处变化,可以实现分次提交 $ git add -p # 删除工作区文件,并且将这次删除放入暂存区 $ git rm [file1] [file2] ... # 停止追踪指定文件,但该文件会保留在工作区 $ git rm --cached [file] # 改名文件,并且将这个改名放入暂存区 $ git mv [file-original] [file-renamed] 四、代码提交 # 提交暂存区到仓库区 $ git commit -m [message] # 提交暂存区的指定文件到仓库区 $ git commit [file1] [file2] ... -m [message] # 提交工作区自上次commit之后的变化,直接到仓库区 $ git commit -a # 提交时显示所有diff信息 $ git commit -v # 使用一次新的commit,替代上一次提交 # 如果代码没有任何新变化,则用来改写上一次commit的提交信息 $ git commit --amend -m [message] # 重做上一次commit,并包括指定文件的新变化 $ git commit --amend [file1] [file2] ... 五、分支 #列出所有本地分支 $ git branch # 列出所有远程分支 $ git branch -r # 列出所有本地分支和远程分支 $ git branch -a # 新建一个分支,但依然停留在当前分支 $ git branch [branch-name] # 新建一个分支,并切换到该分支 $ git checkout -b [branch] # 新建一个分支,指向指定commit $ git branch [branch] [commit] # 新建一个分支,与指定的远程分支建立追踪关系 $ git branch --track [branch] [remote-branch] # 切换到指定分支,并更新工作区 $ git checkout [branch-name] # 切换到上一个分支 $ git checkout - # 建立追踪关系,在现有分支与指定的远程分支之间 $ git branch --set-upstream [branch] [remote-branch] # 合并指定分支到当前分支 $ git merge [branch] # 选择一个commit,合并进当前分支 $ git cherry-pick [commit] # 删除分支 $ git branch -d [branch-name] # 删除远程分支 $ git push origin --delete [branch-name] $ git branch -dr [remote/branch] 六、标签 # 列出所有tag $ git tag # 新建一个tag在当前commit $ git tag [tag] # 新建一个tag在指定commit $ git tag [tag] [commit] # 删除本地tag $ git tag -d [tag] # 删除远程tag $ git push origin :refs/tags/[tagName] # 查看tag信息 $ git show [tag] # 提交指定tag $ git push [remote] [tag] # 提交所有tag $ git push [remote] --tags # 新建一个分支,指向某个tag $ git checkout -b [branch] [tag] 七、查看信息 # 显示有变更的文件 $ git status # 显示当前分支的版本历史 $ git log # 显示commit历史,以及每次commit发生变更的文件 $ git log --stat # 搜索提交历史,根据关键词 $ git log -S [keyword] # 显示某个commit之后的所有变动,每个commit占据一行 $ git log [tag] HEAD --pretty=format:%s # 显示某个commit之后的所有变动,其"提交说明"必须符合搜索条件 $ git log [tag] HEAD --grep feature # 显示某个文件的版本历史,包括文件改名 $ git log --follow [file] $ git whatchanged [file] # 显示指定文件相关的每一次diff $ git log -p [file] # 显示过去5次提交 $ git log -5 --pretty --oneline # 显示所有提交过的用户,按提交次数排序 $ git shortlog -sn # 显示指定文件是什么人在什么时间修改过 $ git blame [file] # 显示暂存区和工作区的差异 $ git diff # 显示暂存区和上一个commit的差异 $ git diff --cached [file] # 显示工作区与当前分支最新commit之间的差异 $ git diff HEAD # 显示两次提交之间的差异 $ git diff [first-branch]...[second-branch] # 显示今天你写了多少行代码 $ git diff --shortstat "@{0 day ago}" # 显示某次提交的元数据和内容变化 $ git show [commit] # 显示某次提交发生变化的文件 $ git show --name-only [commit] # 显示某次提交时,某个文件的内容 $ git show [commit]:[filename] # 显示当前分支的最近几次提交 $ git reflog 八、远程同步 # 下载远程仓库的所有变动 $ git fetch [remote] # 显示所有远程仓库 $ git remote -v # 显示某个远程仓库的信息 $ git remote show [remote] # 增加一个新的远程仓库,并命名 $ git remote add [shortname] [url] # 取回远程仓库的变化,并与本地分支合并 $ git pull [remote] [branch] # 上传本地指定分支到远程仓库 $ git push [remote] [branch] # 强行推送当前分支到远程仓库,即使有冲突 $ git push [remote] --force # 推送所有分支到远程仓库 $ git push [remote] --all 九、撤销 # 恢复暂存区的指定文件到工作区 $ git checkout [file] # 恢复某个commit的指定文件到暂存区和工作区 $ git checkout [commit] [file] # 恢复暂存区的所有文件到工作区 $ git checkout . # 重置暂存区的指定文件,与上一次commit保持一致,但工作区不变 $ git reset [file] # 重置暂存区与工作区,与上一次commit保持一致 $ git reset --hard # 重置当前分支的指针为指定commit,同时重置暂存区,但工作区不变 $ git reset [commit] # 重置当前分支的HEAD为指定commit,同时重置暂存区和工作区,与指定commit一致 $ git reset --hard [commit] # 重置当前HEAD为指定commit,但保持暂存区和工作区不变 $ git reset --keep [commit] # 新建一个commit,用来撤销指定commit # 后者的所有变化都将被前者抵消,并且应用到当前分支 $ git revert [commit] # 暂时将未提交的变化移除,稍后再移入 $ git stash $ git stash pop 十、其他 # 生成一个可供发布的压缩包 $ git archive
Nginx 搭建图片服务器及緩存設置
Nginx 搭建图片服务器及緩存設置 2019-08-09 23:13:04 准备工作 安装 Nginx 依赖 yum -y install pcre-devel openssl openssl-devel 如果不安装在执行=./configure=时会出现=./configure: error: the HTTP rewrite module requires the PCRE library.=错误 安装 Nginx 下载 Nginx 安装包 Nginx 官网下载地址 解压 Nginx tar -zxvf nginx-1.14.2.tar.gz cd nginx-1.14.2 ./configure make && make install 在配置/编译/安装过程中可能会出现缺少依赖的问题, 这个根据个人遇到的问题自行 Google 吧,这里就不一一介绍了 修改配置 修改工作进程数配置 一般根据 CPU 核心数设置, CPU 有几个核心就设置成几, 比如我的服务器有 8 个核心就设置为 8 worker_processes 8; 修改 events 模块中包含 nginx 中所有处理连接的设置 常用配置项如下: events{ use epoll; worker_connections 20000; } 详细说明 use epoll; 使用 epoll 的 I/O 模型(值得注意的是如果你不知道 Nginx 该使用哪种轮询方法的话,它会选择一个最适合你操作系统的) ...
volatile关键字详解(转)
volatile 关键字详解(转) {#volatile 关键字详解转} 2019-08-09 23:13:04 本文转自Ruheng的简书–你真的了解volatile关键字吗? volatile 关键字经常在并发编程中使用,其特性是保证可见性以及有序性,但是关于 volatile 的使用仍然要小心,这需要明白 volatile 关键字的特性及实现的原理,这也是本篇文章的主要内容。 Java 内存模型 {#java 内存模型} 想要理解 volatile 为什么能确保可见性,就要先理解 Java 中的内存模型是什么样的。 Java 内存模型规定了所有的变量都存储在主内存中。每条线程中还有自己的工作内存,线程的工作内存中保存了被该线程所使用到的变量(这些变量是从主内存中拷贝而来)。线程对变量的所有操作(读取,赋值)都必须在工作内存中进行。不同线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存来完成。 基于此种内存模型,便产生了多线程编程中的数据“脏读”等问题。 举个简单的例子:在 java 中,执行下面这个语句: i = 10; 执行线程必须先在自己的工作线程中对变量 i 所在的缓存行进行赋值操作,然后再写入主存当中。而不是直接将数值 10 写入主存当中。 比如同时有 2 个线程执行这段代码,假如初始时 i 的值为 10,那么我们希望两个线程执行完之后 i 的值变为 12。但是事实会是这样吗? 可能存在下面一种情况:初始时,两个线程分别读取 i 的值存入各自所在的工作内存当中,然后线程 1 进行加 1 操作,然后把 i 的最新值 11 写入到内存。此时线程 2 的工作内存当中 i 的值还是 10,进行加 1 操作之后,i的值为 11,然后线程 2 把 i 的值写入内存。 最终结果 i 的值是 11,而不是 12。这就是著名的缓存一致性问题。通常称这种被多个线程访问的变量为共享变量。 ...
禁用Gnome桌面Ctrl+Alt+S调整桌面快捷键
禁用 Gnome 桌面 Ctrl+Alt+S 调整桌面快捷键 {#禁用 gnome 桌面 ctrlalts 调整桌面快捷键} 2019-08-09 23:13:04 正文 久仰 Manjaro 大名很久,所以最近搞了个 Manjaro, 为了平滑过度, 所以选择了 Gnome 版的, 本来以为可以开开心心的撸代码了, 但是当我在 IDEA 中按下快捷键 备打开设置配置一下字体的时候, 我的 IDEA 竟然变小了??? 想都不用想, 快捷键冲突, 改 IDEA 的快捷键是不可能的了, 毕竟我已经和 JetBarins 开展了深度合作,这要改了,岂不是什么 WebStorm PyCharm CLion GoLand(虽然不经常用,但是据说多写几个显得牛逼:) )啥的全都得改? 然后…… 我特么把快捷键列表翻了个遍也没找到一个对应的! Fuck!!! 但是,作为 Google(养大的)程序员怎么可能妥协, 然后在 Ubuntu 论坛上找到了这篇帖子,但是我就啥都没找到…… 最后在 SuperUser 找到了以下结果 然后 嗯??? Gnome 扩展??? 特么要把这个叫 Screen Window sizer 的扩展禁用, 就解决了!!!也不知到是不是自己手贱装上的, 就当不是吧. 又水了一篇博客,开心 -_- 参考链接 SuperUser Ask Ubuntu
Navicat Data Modeler 破解
Navicat Data Modeler 破解 2018-09-23 16:02:47 起因 最近发现 Navicat Data Modeler 设计起数据库来特别顺手, 但是, 它和其他 Navicat 家的工具一样, 只有 14 天的试用期 激活工具下载地址 [[https://waver.me/resource/Files/resource/Navicat_Keygen_Patch_v3.7_By_DFoX_URET.rar][]] 破解工具 虽然知道破解软件是不对的, 但奈何作为无产阶级的我又家境贫寒, 无钱购买, 终于在我的坚持下发现了一款神奇的破解工具, 那下面就说说我的励志故事吧! 破解步骤 工具解压后的样子如下: 具体步骤 打开 Navicat_Keygen_Patch_v3.7_By_DFoX_URET.exe 按照图中标出的选, 点击 patch 按钮, 选择自己的 Navicat Data Modeler 后, 提示如下 然后点击 Generate, 会在 Navicat Data Modeler 生成 Serial Keygen 3. 后点击激活工具最下方的 Generate (图上忘标了), 然后选择 Modeler 的安装目录,选择后将会在安装目录下生成 license_file 文件 4. 在激活之前, 先确保你的电脑是离线的, 否则将会激活失败 5. 然后打开 Navicat Data Modeler 依次点击 帮助 > 注册 将刚刚复制的 Serial Keygen 粘上去 6. 注意! 不要直接点击激活按钮, 要按住 Ctrl + Shift 然后点击激活, 然后会让你选择 license_file, 选择第三步生成的文件, 然后….. 7. 大功告成 ...
通过一次IDEA Spring Boot 启动报错深入理解maven scope标签
起因 昨天同事突然告诉我项目无法启动了, 但是神奇的是我也在用一样的代码, 但是在我的机器上并没有出现这个问题, 所以我就开始 fuck bug 了,报错信息大概是下面这个样子 Caused by: java.lang.IllegalStateException: Failed to introspect annotated methods on class org.springframework.boot.web.support.SpringBootServletInitializer at org.springframework.core.type.StandardAnnotationMetadata. getAnnotatedMethods(StandardAnnotationMetadata.java:163) ~[spring-core-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.context.annotation.ConfigurationClassParser. retrieveBeanMethodMetadata(ConfigurationClassParser.java:380) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.context.annotation.ConfigurationClassParser. doProcessConfigurationClass(ConfigurationClassParser.java:314) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.context.annotation.ConfigurationClassParser. processConfigurationClass(ConfigurationClassParser.java:245) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.context.annotation.ConfigurationClassParser. parse(ConfigurationClassParser.java:198) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.context.annotation.ConfigurationClassParser. parse(ConfigurationClassParser.java:167) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE] ... 17 common frames omitted Caused by: java.lang.NoClassDefFoundError: javax/servlet/ServletContext at java.lang.Class.getDeclaredMethods0(Native Method) ~[na:1.8.0_111] at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) ~[na:1.8.0_111] at java.lang.Class.getDeclaredMethods(Class.java:1975) ~[na:1.8.0_111] at org.springframework.core.type.StandardAnnotationMetadata.getAnnotatedMethods (StandardAnnotationMetadata.java:152) ~[spring-core-4.3.10.RELEASE.jar:4.3.10.RELEASE] ... 22 common frames omitted Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletContext at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_111] at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_111] at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[na:1.8.0_111] at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_111] ... 26 common frames omitted 解决方法 通过网上一番 Goolge, 答案如下 ...
Jrebel激活服务器及使用方法
ckey.run https://helper.idejihuo.com/#home
Java中的代码点和代码单元
本文转自Java中的代码点和代码单元,原出处没找到,对不起原作者了 摘要 本文介绍 Java 平台支持增补字符的方式。增补字符是 Unicode 标准中代码点超出 U+FFFF 的字符,因此它们无法在 Java 编程语言中描述为单个的 16 位实体(例如 char 数据类型)。这些字符一般极少用,但是,有些会在诸如中文或日文人名中用到,因此,在东亚国家,政府应用程序通常会要求支持这些字符。 Java 平台目前正在改进,以便支持对增补字符的处理,这种改进对现有的应用程序影响微乎其微。新的低层 API 在需要时能够使用单个的字符运行。不过,大多数文本处理 API 均使用字符序列,例如 String 类或字符数组。现在,这些均解释为 UTF-16 序列,而且,这些 API 实现已转变为正确地处理增补字符。这些改进已融入 Java 2 平台 5.0 版,标准版 (J2SE)。 除详细解释这些改进之外,本文同时为应用程序开发人员确定和实现必要的更改提供指导,以支持整个 Unicode 字符集的使用。 背景 Unicode 最初设计是作为一种固定宽度的 16 位字符编码。在 Java 编程语言中,基本数据类型 char 初衷是通过提供一种简单的、能够包含任何字符的数据类型来充分利用这种设计的优点。不过,现在看来,16 位编码的所有 65,536 个字符并不能完全表示全世界所有正在使用或曾经使用的字符。于是,Unicode 标准已扩展到包含多达 1,112,064 个字符。那些超出原来的 16 位限制的字符被称作增补字符。Unicode 标准 2.0 版是第一个包含启用增补字符设计的版本,但是,直到 3.1 版才收入第一批增补字符集。由于 J2SE 的 5.0 版必须支持 Unicode 标准 4.0 版,因此它必须支持增补字符。 对增补字符的支持也可能会成为东亚市场的一个普遍商业要求。政府应用程序会需要这些增补字符,以正确表示一些包含罕见中文字符的姓名。出版应用程序可能会需要这些增补字符,以表示所有的古代字符和变体字符。中国政府要求支持 GB18030(一种对整个 Unicode 字符集进行编码的字符编码标准),因此,如果是 Unicode 3.1 版或更新版本,则将包括增补字符。台湾标准 CNS-11643 包含的许多字符在 Unicode 3.1 中列为增补字符。香港政府定义了一种针对粤语的字符集,其中的一些字符是 Unicode 中的增补字符。最后,日本的一些供应商正计划利用增补字符空间中大量的专用空间收入 50,000 多个日文汉字字符变体,以便从其专有系统迁移至基于 Java 平台的解决方案。 ...
RandomAccess接口理解
RandomAccess 接口理解 本文转自 Stick2It — RandomAccess接口理解 根据 javadoc 上面的的解释是: RandomAccess 是一个标记接口,用于标明实现该接口的 List 支持快速随机访问,主要目的是使算法能够在随机和顺序访问的 list 中表现的更加高效。 我们可以简单的看下 Collections 下的 binarySearch 方法的源码: view plain copy public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) { if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD) return Collections.indexedBinarySearch(list, key); else return Collections.iteratorBinarySearch(list, key); } 从源码中我们可以看到,在进行二分查找的时候,list 会先判断是否是 RandomAccess 也即是否实现了 RandomAccess 接口,接着在调用想用的二分查找算法来进行,(其中: BINARYSEARCH_THRESHOLD Collections 的一个常量(5000),它是二分查找的阀值。)如果实现了 RandomAccess 接口的 List,执行 indexedBinarySearch 方法,否则执行 iteratorBinarySearch 方法。 分别看下这两个方法的实现: indexedBinarySearch 方法 view plain copy private static <T> int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) { int low = 0; int high = list.size()-1; while (low <= high) { int mid = (low + high) >>> 1; Comparable<? super T> midVal = list.get(mid); int cmp = midVal.compareTo(key); if (cmp < 0) low = mid + 1; else if (cmp > 0) high = mid - 1; else return mid; // key found } return -(low + 1); // key not found } indexedBinarySearch 方法是直接通过 get 来访问元素 ...