idea git push 引起的血案

操作不当导致一天内写的代码丢失,最后依靠 idea 的本地历史(local history)找回。

过程:

  1. 使用 idea 的 VSC 工具进行 git commit (用这个主要是这个带有自动整理代码,优化导入的功能,还会分析代码)
  2. 想了想应该只有我有最新的版本了,别人不会有更新的。于是直接点开 git push (以前都是先使用 git pull 的,这次脑残了)
  3. 提示有冲突,是否进行合并,选择是,自动合并完毕后。编译代码失败。一看,我一天写的写的定时消息通知不见了。
  4. 我的妈啊,怎么直接没了,赶紧打开 bash 用 git reflog 结果如下:(有两处的 commit 信息是 add: 加入各处通知)
  5. ee2fa85 直接变成了 merge 节点,而且我的提交直接就没有了,恢复不了。git reset --hard 只能回到原来的版本,但是记录里面根本没有我提交的版本
  6. 救命稻草:idea 本地历史,idea 提供了磁盘上所有文件的修改记录,并且标注了时间,after push 、build 的操作就记录了下来,(这么吃内存也是有好处)于是我凭记忆恢复了我一天写的代码。
  7. 最后再提交、推送到远程库
  • 从 gitea 上面的提交图来看,也说明了这次血案的原因

    由提交图可以看到,我提交了一个 merge 节点,用于自动合并与其他人的代码版本。这个节点应该是 git 自动生成的,提交信息里面应该有 merge branch 字样,但是这个提交直接用我的 commit 信息了。

其实还有点疑惑的地方,有时间复现一下,看一看到底是怎么回事。


升级到 spring boot 2.0

spring boot 2.0 版本出了有一段时间了,当然是要用一用了,把现在在写的项目升级一波。当然升级前是看了一下别人的博客 http://tengj.top/2018/07/23/springboot2to1/ 。(怎么感觉有质量的博客越来越少,剩下的就是在互相“引用”,搜出来基本一模一样,国内某搜索引擎更加差劲,还是自己抽时间看文档比较好)本篇持续更新(随缘)


  • 首先在 pom.xml 中修改 1.5.10 为 2.0.4 (项目要求稳定一点,也不能太激进。)
  • idea 下载依赖的时候,手动运行 mvn clean 等命令下载依赖,不然会出现 idea 依赖下完,还是不能构建,至今不知道为什么,是什么 bug

2.0 中的更改:

  1. 删除 repository 的 findOne ,导致以前使用的 findOne 不能使用,直接替换为 getOne 会出现以下问题:
    getOne 返回代理类HibernateProxy,进行序列化时出错,提示添加适配器。

简单解决:
用 findById 回避代理类,但是这个接口又被改成返回 Optional<S> 必须使用 get() 来获取 实体。Optional 要求内容非空,否则使用 get() 方法会抛出异常 NoSuchElementException ,优雅了解决空指针异常。

  1. new PageRequest 不推荐使用 @Depreacted ,直接更换为静态方法 PageRequest.of,点进去看是返回 new PageRequest 。(之前在 1.5 好像就是不推荐用 of 静态方法,现在又改回来了)

重装系统后要做的事情
  • 前一阵子参加信息院的安全竞赛,竟然获得了一个固态硬盘。马上装上 win10 体验一波。原来买电脑的时候就是装的 win10,后面各种卡顿(年少无知,非要去电脑城买),直接换成 win7。最近 win7爆出使用数量下降,肯定是电脑更新换代,都是预装 win10。ok,不多说了,进入主题。
  • 进入 win10 后,要求登录 Microsoft 账号,BABALA填完后,进入等待桌面加载。动画效果确实好,比 win7 更加炫酷。但是开始菜单多了很多用不到的东西和用不了到的东西比如 OneNote、天气、新闻、联系人…所以第一步:卸载这些无用的东西。
  • 由于我以前将用户数据和系统分离,为了少安装一些常用的软件,通常把用户文档、桌面移动到其他盘,在新系统上设置一下就恢复了快捷访问。
  • 其他的不多说了,就是安装一些非绿色版,要修改注册表的软件,杀毒软件、 office 等等,调整系统设置
    (ok,这是一个月之前的事情了,我很多都忘了。win10游戏时输入法无法打字,以及 windows defender 一直偷cpu,一气之下格式化C盘。下面才是我现在在用的重装过后的win7)
  • 详细列一下开发要设置的东西,便于以后查阅
  1. 安装运行库。这些都没有自带,给差评。visual c redistributable ,DirectX,.net framework 等等。推荐一个软件All in One Runtimes可以直接安装以上的运行库。
  2. 可绿色运行的开发软件添加一下系统路径。如 python3 (python2出现并发数设置不对的错误,估计是配置文件放在了系统盘上),jetbrain(导入以前的设置,还有登录账号激活),nodejs(包括.\node_modules\.bin)
  3. listary 效率工具设置自启动(有了它桌面都可以不要,只要你知道要用什么软件,直接键入名称即可启动),bandizip 添加文件关联,sublime vscode notepad
  4. 重新安装一下git,虽然可以是绿色版本,但是使用系统自带的cmd真的好丑。使用 git-bash 就好一点了
  5. 复制一下服务器私钥到用户主目录下,这样 ssh 就不用输密码了。
  6. 安装 chrome,有时候 google 打不开,只能去各软件广告商下载。再手动导入科学插件,最后登录账号,基本就结束了。
    现在做的事情基本就这么多,过几天有新东西再更新。

更新:

  1. 安装 Office 2016 使用 https://github.com/officetoolplus/OTool 服务器上安装 docker 版本的 vlmcsd 授权激活,但是在 office 上无法登陆账号,朋友的 Office 2019 可以用。一直没找到原因。
  2. finallshell 可以加速海外服务器的访问,看了一下 last 命令,是有两个账号同时登陆,查 ip 是阿里云香港,进行了转发,效果好了很多。
  3. MobaXterm 分屏同时多个终端输入,管理服务器真的不要太爽,比 putty 好用多了。

Spring boot 笔记

JPA

  • 中文乱码

    1. 检查数据库编码
      • show variables like 'character_set_database';–查看该数据库使用的编码
      • alter database <数据库名> CHARACTER SET utf8;–修改编码为utf8
      • show create table <表名>;–查询表的编码,默认为:latin1
      • alter table <表名> character set utf8;–修改表的编码
    2. 检查JPA连接配置
      • spring.datasource.url后面加上characterEncoding=utf-8参数

    ps:后面才知道mysql的utf8是假的,只支持三字节的编码,utf8mb4才是现在称的真正utf8

View Object

因为前端要的字段可能跟数据库里的不同,或者要其他的数据,都在一个接口处返回,或者嵌套对象返回。
解决方法是使用一大片 getter setter for 语句来处理,代码极其不好看。于是花半天时间查阅 jpa 文档,发现可以用到 VO 来解决这些问题。
这里直接就贴上代码看一下就ok了。

1
2
3
4
5
6
7
8
9
10
11
public interface CompreGradeItem {
Integer getCompreRank();
// more...与数据库字段相同的直接写 get 方法
// 使用Value注解,获取到对象内的成员
@Value("#{target.student.major}")
String getMajor();
// 新建的键值对,可以利用 spel 实现简单的处理
// 要实现高级自定义,则编写自己的 bean 可以实现任意逻辑(下面一个)
@Value("#{@compreGradeBean.getAddGroup(target)}")
List<Object> getAddGroup();
}
1
2
3
4
5
6
7
8
9
10
11
12
@Component
public class CompreGradeBean {
private final CompreAddGradeRepository compreAddGradeRepository;
private final AwardBean awardBean;
@Autowired
public CompreGradeBean(CompreAddGradeRepository compreAddGradeRepository, AwardBean awardBean) {
this.compreAddGradeRepository = compreAddGradeRepository;
this.awardBean = awardBean;
}
public List<Object> getAddGroup(CompreGradeEntity compreGradeEntity) {
// 在这里编写自定义的方法,可以再进行查询。
}
1
2
3
public interface CompreGradeRepository extends JpaRepository<CompreGradeEntity, String> {
Page<CompreGradeItem> findAllByStudentMajorLikeAndStudentStuClassLikeAndYearTerm(String major,String stuClass,String yearTerm,Pageable pageable);
}

更新:
用这种方法,由于 jpa 无法预知程序员想要留下的字段,所以直接全部字段都查询出来,数据量少应该无所谓,但是最好还是写 nativeQuery 这样数据库压力会小点,但是返回的是 List<Object[]> 映射字段名就麻烦了。用 setter ?不存在的。尽量避免写出无意义,而且容易出错的代码
下面说一下我正在使用的方法:
配合 java 8 的特性 stream 实现字段映射:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 要映射的类
class ClassForm {
private String A;
private String B;
// 这里是一个需要调用 bean 的一个参数
private String C;
// getter setter
public static ClassForm map(Object[] i){
ClassForm tmp = new ClassForm();
tmp.setA(i[0]);
tmp.setB(i[1]);
return tmp;
}
// 模仿流式 api
public ClassForm setC(String c){
this.C = c;
return this;
}
}
1
2
3
4
// 在外层调用的时候
List<Object[]> x = repository.findAllByXXX(xxx);
List<ClassForm> r = x.stream().map(s->ClassForm.map(s).setC(myBean.getC(s[2]))).Collect(Collector.toList());
// 随后 r 就可以通过反射 API,自动生成 JSON 数据了

数据结构实验——全栈的体验

#全栈开发感想

##摘要

以前一直是学习后端开发,使用简单的 flask 框架进行开发,前端的网页要不就是没有,要不就是抄别人现成的网页,只是把ajax请求地址改成自己的。开发一些玩具类似的东西还是挺快的。

##背景

现在突然有个课设项目,大佬要跟我组队,不过他也不会前端的东西,我知道也是浅尝辄止。见过许多华丽的网页,自己却写不出来。我让他先去看一看网页相关的库,上上w3school 先入入门。过了几天,结果他就直接用上bootstrap写出页面的布局了。还把要使用到的图形库,及其插件给找到了。以前我是没有弄过页面布局,我后面又去看栅格布局,bootstrap是如何进行布局,以及响应式布局的(虽然这个项目用不上)

自己学习过Python相关的Web开发框架,写起来就不是很吃力,基本查查文档就行了。他拿着我的代码却无从下手。数据库方面我也是直接 sql 语句写的,使用零配置的sqlite3 加快进度。他开始可能也没懂相关的地方,结果到他的电脑就出问题了,找不到我建立的数据库表。他弄了很久,后面查到是Pycharm的路径没有设置,由于sqlite打开不存在的数据文件时不会报错,直接新建了一个新的文件。应该就直接访问用户的目录去了,但是由于是没有建立表,查询就会出错。

###总结

关于团队协作,以前写一点玩具都是自己在写,没有用团队协作的东西(最多也就用Git 来同步我在服务器写的代码了)。项目开始前,是我写前端和后端比较多,队友写算法(他还研究了C 与Python连接的问题,开始用boost ,后面直接就ctypes)

1. 代码同步问题:

一开始,每个人写的功能不一样,代码几乎不需要同步。到后面对接才发现没有代码同步,TIM传文件真的很烦人,以为项目快结束了,然而后面的bug修复,文件传输就越来越多。不得已在最后使用了Git,前面费的时间要早用git 就不会白白费在传文件上。

2. 整体项目的架构:

由于还是缺乏对团队项目的整体规划缺少实战的经验,一开始就没有认真考虑出完整的构思,只有大概的想象,放在后面对接时就费了不少的功夫,要是稍有一点整体的构想,就不会到后面的改了又改,后端数据库和前端对接不上,又要去调试代码。功能到后面想添加就得重写代码

3. 调试工具的使用:

学会看输出。调试工具方便了测试,找bug。客户端网络请求,和后台数据匹配就清晰可见。由于使用了很多的前端相关库,一旦有错误就会抛出错误。就可以在相关的代码行数查看,动态修改执行的语句,和页面上的DOM,JQuery还是一如既往的强大,封装的方法很全,写起来很快。JS语言的强大,与灵活,赋予了编码很大的自由度,当然需要极高的操作才可以把握这个度。

4. 软件工程方面的理论支撑:

写玩具简单,但是真正做出能实际运用的东西就要思考了。编码也是写文章,写思想的,只不过表达形式不一样,文章用文字,用修辞手法,写作手法。而代码则是用计算机能够识别的文字,做一件事有不同的方法,用户看到的输出可能是一样的。但是代码放在哪里,何时执行却是编码时应该想清楚的。以前C 编写过程中,一个功能性类即有cin 又有cout这合适吗,执行功能就不应该和用户进行交互,交互应该交给合适的类去做。功能性的类应该只有接口,由外部调用,可抛出错误,返回值作为输出,或者由交互相关类处理后输出。这样做到系统的低耦合、高内聚。鲁棒性高。

5. 前端技术熟悉:

在项目中学习,能够加深理解。很多的技术都没接触过。这次让我知道页面的交互确实不简单,在命令行,对有技术的使用者会很熟悉。对无基础的则还是需要和谐的界面。和后端的交互使用ajax,http协议的熟悉,请求到后端的api地址,返回内容都是要考虑的,整个网页程序的统一,分工要明确。


Git记录

#Git 使用笔记

克隆本分支,深度为1

1
2
git clone -b deploy_online --depth=1 git@github.com:whllhw/whllhw.github.io 
git push #提交代码直接push

当已经存在.git文件夹时可以使用

1
2
3
git branch -r # 显示远程分支
git branch -a # 显示所有分支
git checkout -b dev origin/deploy_online # 建立本地分支dev并切换为远程的deploy_online?待验证

推送到远程其他分支时

1
2
3
4
5
6
git remote add origin git@github.com:whllhw/whllhw.github.io #添加远程仓库
git push --set-upstream origin master:passage #将本地的master分支提交到远程的passage
# 以后每次提交都要使用 git push origin HEAD:passage 有点麻烦!
# 或者使用上面切换分支的方法 git checkout -b ...
# 或者使用本地分支与远程分支相同(master 作为变量,为分支名)
git push --set-upstream origin master #默认将本地master分支提交到远程的master

我的云上CentOS记录

#使用CentOS笔记

在云上使用Centos,很多常用的命令不能直接用。软件仓库轻量化,也有导致使用不便。安装nginx 要添加源,才能直接安装,不然就是自己编译源代码。
将持续更新。。。

##使用常用命令

Centos 安装编译工具包,很多在其他系统上直接安装的程序,都被包含进去,保证软件包仓库的纯净。

1
yum groupinstall "Development Tools"

nginx 配置重载
nginx -s reload
nginx 配置测试
nginx -t

查看本地端口使用情况

netstat -ntlp

结束进程

pkill {pidname}


Selenium 自动化测试框架

比较快速的爬取一些网站,最快就是用这个框架,记录遇到的坑。

查阅的中文文档基本用法简单,但是高级的用法就是英文的,或者没有。这里记录一下。

Read more
使用Flask 中遇到的Python2 编码问题

使用Flask 中遇到的Python2 编码问题

python2 的编码问题一直被开发者诟病,进行一些字符工作是确实会有点麻烦,而且新手不熟悉编码,更会踩坑里。

开始前建议阅读 Python2.x 字符编码终极指南,或者搜索一下就有很多文章。

Python2 中的 str 类型可以看做是 byte 类型的数组,即是字节流。早期设计中并没有这么多的编码,后来版本提供一个 unicode类型来修复了这一类型。有如下关系

1
2
unicode.encode('utf-8') = str
str.decode('utf-8') = unicode

Flask 中提交的表单 + MySQLdb + Mysql

  1. 源文件中指明编码 #coding=utf-8
  2. Mysql设置编码为utf8
  3. MySQLdb 连接指定charset=‘utf8’,插入的代码如下
1
g.db.execute('insert into entries (title, text) values ({}, {})'.format(request.form['title'].encode('utf-8'), request.form['text'].encode('utf-8')))

request.form[‘title’] 的类型是Unicode,encode后应该就可以变成str了,可是
提示OperationalError: (1054, "Unknown column 'abc' in 'field list'")英文都插入不了,然后经Stack Overflow启发,改动 { } => “{ }”,然后就可以运行了。。坑死了。

还有一个坑:OperationalError: (2002, "Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)")

默认MySQLdb会在/var/lib/mysql 寻找sock,由于服务器的安装位置不是这里,查找mysql.sock发现在/tmp 目录下,创建MySQLdb连接时,指定unix_sock = /tmp/mysql.sock就可以连接了


腾讯云主机相关的iptables使用端口转发

腾讯云主机相关的iptables使用端口转发

阿里云、腾讯云的主机都是只有内网IP网卡,用户不能使用公网IP网卡,因此直接在iptables上进行开放端口是不行的。

Read more