利他才能利己


  • 首页

  • 标签

  • 归档

  • 搜索

生而为人,我很欢喜

发表于 2020-09-26 | 分类于 随笔 |

记得第一次读挪威的森林,还是上高一的时候。

这本书是一个同班同学借给我看的,这位同学是被大家公认的博览群书的翩翩才子。现在看来,他和《挪威的森林》这本书中的永泽还真是有得一拼。他告诉我说书里面写的很刺激,值得一看。我当时以为这是一本植物学家写的关于人与自然、探索世界的书籍,但从他猥琐的笑容里我逐渐感觉到我可能猜错了。

当时粗略的读完了这本书,内心满是草泥马,觉得渡边就一混蛋、渣男。在那个时候,渣男这个词并不奉行但世界上早已经有了这样的一群人🤢。

前段时间在偶然的机会下,我在书店又看到了这本书,难掩心中的迷惑又从容的读了一遍,发现根本不是自己原来看到和想到的那样。结合当时的日本社会背景和文化,这本书更多的是在写人精神层面的东西,生活给我们的是九十九件不如意和一件无奈,所有的不开心 、抑郁、困惑都在于本心,只要心态好,雨后便是晴天。人需要学会自我救赎。

日本很多作家的书籍,读来都比较压抑,像太宰治的《人间失格》,这本书我很早之前就买了但迟迟没有想好什么时候去看,直到我读完东野圭吾的大部分小说后才鼓起勇气读完了《人间失格》,读完我才知道,像我这种心态像花一样的人根本不畏惧什么。在出社会之前,我自己也是个经常愁眉苦脸的家伙,很多朋友都告诉我包括我的大学老师(良师益友),说我眉头就好像是被一把无孔的锁死死的锁住一样,笑容在我的脸上显得很吝啬。在那个时候,我对大学毕业其实是很恐惧的,家庭没有任何背景,自己对未来也很迷茫,大脑里乱糟糟的。不过我内心很知道这一切需要靠自己去改变,只有努力奋斗才能摆脱内心的束缚。慢慢的,我自己把很多事情想明白了,做事情也很有主见了,心态调整的相当好。

当生活以痛吻我,我要报之以歌!

前段时间,听到一位老师讲解书籍,里面提到【生而为人,我很抱歉】这句话,他说这是太宰治写的。文章下面的评论很多人都在喷他,说他没有文化,这句话根本不是太宰治写的。人就是这样,挑毛病最拿手。我默默的去查了一下,这句话最早是出自诗人 寺内寿太郎 之手但确实是因为太宰治让这句话发扬光大的。

诗人寺内寿太郎原创于《遗书》的一组诗歌,大致意思是:生而为人,深感歉意;

然后,在日本作家太宰治所写的短小说《二十世纪旗手》中,作者把这句话作为了一个副标题,1937年首次在《改造》杂志上发表,收录在《人间失格》作者集中。

寺内寿太郎和太宰治是认识的。

据说是一个名不见经传的文学青年寺内寿太郎,他的表兄弟是太宰的朋友。这个青年相当命途多舛,年轻时失去了双亲,靠亲戚抚养,上了庆应大学。曾经多次感到人生的无奈,离家出走。一颗追求文学的诗心,让他写下了题为《遗书》的一组诗歌。其中有一首就是“一句诗”:生而为人深感歉意。然后这个倒霉蛋儿式文学青年的大嘴表哥就在一次跟太宰溜达聊天的时候谈到了这个表弟的诗句。当时太宰他们认为有了好点子,谁先用,算谁的。于是太宰就出其不意地在《二十世纪旗手》的开头,用了这么一句话。这个可怜的文学青年,怀着一颗赤诚的文学之心阅读他崇拜的作家太宰大作的时候,第一句话就被噎成重伤,据说脸气得发青去找他表哥算账,他表哥找到太宰算账,太宰装傻,哎呀,我以为是你的主意呢,真是深感歉意啊。于是这个可怜的青年大哭着,一切都完啦,患上严重的忧郁症。多次离家出走,最后一次被人目击是战后在一个车站。之后就不知所终了。

然鹅在2006年的电影《被嫌弃的松子的一生》中,这句话也被说了一次。川尻松子在自杀前,抄写日本小说家太宰治短篇小说《二十一世纪旗手》的开篇语「生まれて、すみません。」(中文意思:生而为人,我很抱歉)作为遗言。

然后我在那篇文章的下面写了自己的评论:

所有批评老师讲解错误的人,你们真的知道这句话的来源吗?有这个撕逼的时间,不如去读读我的文章😄

生活中,美好的事物往往都是短暂的甚至是临时的,不如意的事情十之八九,只有调整好自己的心态才能迎接更美好的明天。情绪是可以感染的,热爱生活是我们不被坏情绪侵没和迷失的太阳。生活中需要正能量,很多事情只要你换个思路来想可能它的发生并不是一件坏事。不要把自己锁在那口暗无天日的井中,奋力前行才有美好的明天。

生而为人,我很欢喜!

C++中用char数组构造string

发表于 2020-09-05 | 分类于 C/C++ |

在 C++ 中如何使用用 char 数组 构造 string,确实是一个老掉牙的话题,但是稍加不注意你就会出错。

最近在写一个可以跨平台打印的日志程序,遇到了这个问题,故记之,共勉!

用 char 数组初始化 string 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <string>

using std::string;
using std::cout;

int main(int argc, const char * argv[])
{
char chArray[] = {'h', 'e', 'l', 'l'};
cout << "array size = " << sizeof(chArray)/sizeof(char) << endl;
cout << chArray << endl;
string str(chArray);
cout << "str = " << str << " and str's size = " << str.length() << endl;
}

针对上面的代码,不同的编译器输出结果不一致,具有一定的随机性。

在 macos 系统下,输出结果

1
2
3
array size = 4
hell\310\367\277_\377
str = hell\310\367\277_\377 and str's size = 10

得到这种结果,简直要法克…

但是有时候输出结果又是下面那样的

1
2
3
array size = 4
hell
str = hell and str's size = 5

很明显,string 的 size 不对.

思考一下,原来是少了 ‘\0’,修改上面代码,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <string>

using std::string;
using std::cout;

int main(int argc, const char * argv[])
{
char chArray[] = {'h', 'e', 'l', 'l', '\0'};
cout << "array size = " << sizeof(chArray)/sizeof(char) << endl;
cout << chArray << endl;
string str(chArray);
cout << "str = " << str << " and str's size = " << str.length() << endl;
}

修改之后,代码的结果输出正常了。

1
2
3
array size = 5
hell
str = hell and str's size = 4

也就是说,char 数组初始化 string 对象,数组的结束符 ‘\0’ 不要忘记了。

另外,要注意 string 的 size 要比 char 数组 的 size 小。

不知道上面的东西,你有没有看明白?

那么下面的代码输出,你觉得会达到自己的预期吗?

1
2
3
4
5
6
7
8
9
10
const char * cp = str.c_str();
unsigned long size = str.length();
char chArray2[size];
for (int i=0; i<size; i++) {
chArray2[i] = cp[i];
cout << chArray2[i] << endl;
}

string str2(chArray2);
cout << "str2 = " << str2 << " and str2's size = " << str2.length() << endl;

这里很显然是错误的,至少两处是不对的。

1、chArray2 的大小;

2、chArray2 的结束符没有添加 ‘\0’;

修改一下,给出完整示例

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
#include <string>

using std::string;
using std::cout;

int main(int argc, const char * argv[])
{
// char[] ---> string
char chArray[] = {'h', 'e', 'l', 'l', '\0'};
cout << "array size = " << sizeof(chArray)/sizeof(char) << endl;
cout << chArray << endl;
string str(chArray);
cout << "str = " << str << " and str's size = " << str.length() << endl;

// string --> char[]
const char * cp = str.c_str();
unsigned long size = str.length();
char chArray2[size + 1];
for (int i=0; i<size; i++) {
chArray2[i] = cp[i];
cout << chArray2[i] << endl;
}
chArray2[size] = '\0';

string str2(chArray2);
cout << "str2 = " << str2 << " and str2's size = " << str2.length() << endl;
}

也许有人会说,为什么要用 char 数组 去构造 string 对象,用 char *(指针)不是更好吗?

的确是这样,但是有时候需要 char 数组来操作,我也是把自己遇到的问题,加以总结跟大家分享一下。

把示例代码中的

1
char chArray[] = {'h', 'e', 'l', 'l', '\0'};

修改为

1
char chArray[] = "hell";

或者

1
const char *chArray = "hell";

代码也可以正常正确的输出。

如果你有兴趣,可以看我之前总结的一篇文章 不见得你会计算C字符串长度, 🙇‍!


心若相知,无言也默契。

微服务: 多 Module 管理工程

发表于 2020-08-29 | 分类于 Server |

简介

在 微服务-想办法让项目运行起来 这篇文章中,介绍了如何使用 IDEA 开发工具搭建本地的微服务开发环境,通常我们会把一个微服务项目分解成多个服务,那么为了更好的管理该项目,大家一般都会在 IDE 里面通过多 Module 来进行管理。这里的多 Module 可以理解为多个 SpringBoot 项目。

近期收到一些小伙伴的反馈,在使用 IDEA 搭建多 Module 的时候总会遇到一些莫名其妙的问题,甚是让人烦恼。趁此机会给大家介绍一下。

下面的实践,使用的是 IntelliJ IDEA 2020.2 版本,2019.x 版本也是同样的创建方法。

说干就干

一些在你看来并不起眼的工作,对于别人来说可能是难以逾越的鸿沟。

不废话,直接实践开干!

1、打开 IDEA,File/New Project

选择 Spring Initializr,工程类型选择 Maven。

在接下来的步骤中,不需要选择任何依赖。填写完成后,点击 Finish 即可。

删除工程的 src、.mvn、mvnw 、mvnw.cmd 这几个目录。

删除后,工程目录如下

修改 pom.xml 文件,增加如下内容:

1
<packaging>pom</packaging>

在 Maven 项目中,packaging 给出了项目的打包类型,即作为项目的发布形式,其可能的类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 继承说明:这里继承SpringBoot提供的父工程 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<!-- 项目说明:这里作为聚合工程的父工程,修改打包为pom聚合工程 -->
<groupId>com.veryitman.main</groupId>
<artifactId>blog-main-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>blog-main-server</name>
<description>Blog of main project for Spring Boot</description>

在 Maven 3 中,其可用的打包类型如下:

  • jar,默认类型
  • war
  • ejb
  • ear
  • rar
  • par
  • pom
  • maven-plugin

如下图所示:

2、创建 Module

在工程名称上面右键新建 module,如下图

这里以创建 SpringBoot Module 为例,使用 Spring Initializr 创建 Module

按照你自己的需求填写对应的信息即可进入到下一步直至 Finish.

此时,修改该 module 的 pom 文件,如下(将从工程继承而不是从spring boot继承)所示:

1
2
3
4
5
6
<parent>
<groupId>com.veryitman.main</groupId>
<artifactId>project-xxx-server</artifactId> <!-- 工程名称 -->
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

同理,再新建一个 mz-payment-inone 的 Module,最后工程目录如下:

同理, mz-payment-inone 建立好之后也修改一下它的 pom 文件中的 <parent> 标签内容。

所有的 module 建立完成之后,在 工程的 pom 中增加 module 的说明即增加 <module> 标签 ,如下:

1
2
3
4
5
<!-- 模块说明:这里声明多个子模块 -->
<modules>
<module>ms-login-inone</module>
<module>mz-payment-inone</module>
</modules>

至此,工程中多 Module 已经创建完成👏,接下来再给大家介绍一下 Module 之间如何相互调用。

Module 之间的调用

按照上面的方法,我再次创建了一个 mz-core 的 Module,该 Module 为 上面两个 SpringBoot Module 提供基础的方法。

在 mz-core 中增加了一个 MZDateUtil 类和对应的方法

在 mz-login-inone 中使用该类的方法。

为 mz-login-inone 添加依赖 ms-core,如图

在 mz-login-inone 的 pom.xml 文件中添加如下代码

编写 API 进行测试,在 mz-login-inone 的 MZLoginInoneController 中增加如下代码

1
2
3
4
5
6
7
8
9
10
@RestController
@RequestMapping("login")
public class MZLoginInoneController {

@GetMapping(value = "inone")
public String loginInone() {

return "Current date: " + MZDateUtil.currentDate();
}
}

运行 mz-login-inone,在浏览器访问该接口,显示如下:


如果你在使用过程中还有遇到奇葩的问题,欢迎留言评论,感谢阅读!


詹姆斯·高斯林 (James Gosling)是一名软件专家,1955年5月19日出生于加拿大,Java 编程语言的共同创始人之一,一般公认他为“Java之父”。

瘦身秘笈: 饮食运动相得益彰

发表于 2020-08-15 | 分类于 随笔 |

简介

在 瘦身秘笈: 养成好习惯 这篇文章中给大家介绍了一些保护自己健康的好习惯,希望您在看下面内容之前,可以先看看之前的文章。

今天跟大家分享关于饮食和运动结合如何让自己更加健康起来,我不是专业的瘦身专家😅,只能根据自己的亲身经历抛砖引玉,希望每个为家庭付出的IT工作者都能健康。

你可能经常会听到有人说“我喝口凉水都能胖”,也看到很多吃得再多也长不胖的人,轮到自己想瘦一点的时候感觉怎么那么难,经常陷入下面的死循环中。

个人觉得只要自己不是胖的太过离谱(BMI大于30了)即使胖一点也没有关系,身体健康就好。你非要极致的身材,只能进行自我毁灭式的减肥了。

上次去爬山,听到有一哥们喘着气说长肥肉容易,掉肥肉难。感同身受,必须将 饮食+运动 结合好,你才能在与肥肉搏斗中立于不败之地。

我相信只要你能坚持下来,奇迹一定会在你身上发生。

了解概念

热量单位


我们经常看到诸如 卡、千卡、焦、千焦、大卡 之类的热量单位,让人傻傻分不清。

一般描述食物的热量单位是卡路里(Calorie), 1卡路里简称1卡,但是由于用 卡 来表示热量又太小了,所以人们总是用 千卡 (KCal)来表示食物的热量。1千卡热量有多少?就是把1升水升高1摄氏度需要的热量。例如每100g米饭大概是116千卡的热量,我们平时用小碗盛一碗米饭目测有200多克。

那么既然 千卡 已经能很好的表示食物热量了,为何还需要 大卡 呢?

其实呢 大卡 就是 千卡 😄,只不过有些人对其的叫法不同而已,这就好比有些人把西红柿叫做番柿是一样的道理。

热量的单位还可以用 千焦(KJ)和 焦 (J,也称之为焦耳)作单位,但这个单位一般用作学术上面,没有 千卡 那么接地气。

焦耳(简称焦,符号为J),是国际单位能量和做功的单位。1焦耳能量相等于1牛顿力的作用点在力的方向上移动1米距离所做的功 。

符号J为纪念英国物理学家焦耳而命名。1焦=1牛·米,也等于1瓦的功率在1秒内所做的功,1焦=1瓦·秒。

千焦和千卡换算如下:

1
1千卡 = 4.184千焦 = 1大卡 = 1000卡 = 4184焦

以后你只需要记住,千卡和大卡都是一样的就可以了,在评估食物的热量上面暂时忘记焦耳这个单位吧,算起来脑壳会bulinbulin的痛。

脂肪和热量


1 克脂肪含有 9 大卡热量,1 斤脂肪为 500 克,那么 1 斤脂肪含有的热量为:

1
500×9 = 4500千卡

根据这样来计算,1 千克(KG,即1公斤)脂肪含有 9000 千卡热量。人体内每克纯脂肪的热量是 9 千卡,但人体脂肪内还有一些非脂肪物质,比如约 10% 的水分,所以 1 公斤的脂肪储存着大概 7000~7700 千卡 的热量。

换句话来说,你消耗掉大概 **7000~7700 千卡 **的热量才能瘦 1 公斤左右。饮食相当于摄入热量,运动可以消耗热量,这个道理很好懂吧?所以,控制饮食和适当的运动才能更好的控制热量的摄入和消耗。

饮食

早睡早起

很多小伙伴睡得晚早晨起来的也晚,尤其是周末这种现象更加严重。

如果你像上图中那样日复一日,迟早会不健康起来的🙁,也非常容易让你胖起来。正确的循环应该是下面那样:

正常饮食从早睡早起开始。

尽量每天早上8点左右吃完早餐,早餐不要过于油腻。

鸡蛋🥚+红薯(普通)+高钙牛奶;

鸡蛋🥚+高钙牛奶+玉米;

鸡蛋🥚+全麦面包+坚果;

鸡蛋🥚+蒸饺(瘦肉/蔬菜馅儿);

鸡蛋🥚+红薯(紫薯)+青瓜;

蛋白粉(冲水)+全麦面包+坚果;

西红柿鸡蛋面🥚+柠檬水+蔬菜;

上面是我每周的早餐搭配,没有固定哪天早上吃什么,都是轮着来。你会发现我基本会保证每早都有个水煮鸡蛋,并且没有任何一种油炸的食物。

早上起来后,记得先喝一杯热开水,睡了一夜后身体水分会流失很多,所以需要早上起床后补充一定的水分(300ml~500ml左右即可)。每次早上喝热开水的时候,仿佛能听到细胞在身体里的欢呼声😄,你对身体的任何好,它都能感觉得到,不信的话你可以坚持几天试试。

少吃多餐

我之前总喜欢把吃不完的饭菜全部包揽,直接倒进碗里拌饭吃那种,嗝!总觉得扔掉挺可惜的。殊不知,盘子里面剩下的菜下面全部是厚厚的油,伴着米饭吃起来是很爽但是也会让热量乘虚而入。

后面发现自己逐渐壮大的肚子,就开始慢慢戒掉 吃锅底 的习惯了。

午餐可以适当的油腻一点,但是不要太过分哟。可以给减肥的自己加个卤鸡腿,记得扔掉鸡皮(热量有点高),午餐后可以吃点青瓜。

每天中午午餐,尽量多吃蔬菜,蔬菜里面的膳食纤维可以适当的阻止脂肪的成长,帮你阻挡一部分热量肆虐滋长。

晚餐尽量在 18 点之前吃,不要吃太多,同样不要吃的过于油腻。如果晚上尤其是下班比较晚的小伙伴,可以给自己补充一片全麦面包或者一杯高钙脱脂牛奶。

晚餐可以相对清淡一点,如果你不小心吃多了,那你晚上尽量多运动一会,哪怕散步也好。

晚上临睡前2小时内就不要吃东西了,对!不吃 anything。

午餐和晚餐,我现在都是吃个7成饱,如果你是刚开始减肥,建议从9成饱开始逐步递减到半饱。下午如果饿了就给自己补充点水果或者面包,切记在这两餐当中吃的太多,这样不仅会加大热量的摄入,还会让你的胃不堪重负。

至于什么是几成饱,我也没有实际测量过。不过,有个简单的办法,把你平时吃的米饭或者其他主食适当的减少一些分量。

有很多人说不吃晚餐,可以很快的瘦下来,这个我承认。2018年我坚持了一个半月没有吃晚餐,确实瘦了不少,但是每天晚上肚子凄惨的叫声着实让人难受。一个半月后,我实在是坚持不下来了,自己的内心就感觉住着另外一个自己总是说:”算了吧,太辛苦了,放弃吧!“,这种声音会持续到你毫无反抗之力为止。然后我就开始回归到正常的晚餐生活,胃口就像决堤的大坝,体重又如日中天的上来了😳。抛开经常不吃晚餐对身体有无坏处来说,你要是能坚持下来我觉得你不去创业当 CEO 就对不起你这颗坚强的心。

运动

上面简单说了一下瘦身期间如何调节自己的饮食,下面我们说说结合运动,让你的瘦身计划如虎添翼。

根据美国的运动协会所做的研讨表明,在人初步运动 10 分钟之后,脂肪组织中的血流量会增加,表明脂肪的进行初步的燃烧,在运动 30 分钟后,脂肪组织内的血流量达到最高,如果间断运动,其脂肪组织血流量最高浓度仍可持续6小时。

如果你能坚持,最好趁热打铁,连续运动 30 分钟,这样可以烧脂肪长达 6 小时。但是运动时长也并不需要太长,研究表明,运动时长即使超过 30 分钟,脂肪也只能燃烧 6 小时。

另外运动最好是每天都能坚持做,不要三天打鱼两天晒网。

我推荐给大家两种运动,成本比较低的那种。即步行、跑步。

步行

我之前一直怀疑步行到底能否让人瘦身,后面坚持了三个月,发现步行只要坚持下来对瘦身是大有脾益的。

下面是我对步行的心路历程。

每天坚持最少 30 分钟的步行,利用午餐或者晚餐后散步,下班回家走一段等时间段来步行。每走1公里,大概消耗掉50千卡的热量。

我着重说一下调整部分。

刚开始,走路没有注意自己的走姿,后面通过朋友和书籍的指导,我做出了几个改变。

1、尽量大步走,但是注意量力而行;

2、后脚跟先着地,不要让脚掌先着地;

3、收腹,正常呼吸不要憋气;

4、尽量摆动自己的双臂,主要不要打着路人;

5、腰直起来,提臀,目视前方;

6、每次至少要走 30 分钟或者以上才有效,这个时候脂肪才会慢慢开始燃烧;

对了,抬头看红绿灯🚦,不要只忙着走路,安全第一!

跑步

如果你现在比较胖,还是建议不要跑步,对膝盖的伤害有点大。

我这里说的瘦身跑步指的是慢跑,比如你步行一公里需要12分钟,那么跑步一公里用7~8分钟就可以了。

慢跑更有助于瘦身减脂,快跑可以让你增肌。

我现在一周一般跑2~3次步,每次2公里左右,等体重再下来一点后再增大跑步的强度。每慢跑1公里的步,大概消耗掉80千卡的热量。

可以找个公园跑步,空气和氛围会好点更能让你坚持下来,如果有条件可以带上入耳式的蓝牙耳机,听着音乐放飞自我。

运动时体内水丢失加快,如果不及时补充会引起水不足。在运动强度较大时,要注意运动中水和矿物质的同时补充,运动后,应根据需要及时补充足量的饮水。

登山也是一项很不错的运动,根据自己的情况可以每个月可以进行一次登山运动,走进大自然呼吸新鲜空气,还能锻炼自己的意志。

切记每次运动前后,一定要进行适量的拉伸运动,防止肌肉过后酸痛影响接下来的运动。

减肥不仅仅是控制卡路里,更重要的是从根本上解决肥胖问题,改变易胖体质,别让脂肪缠上你。减肥的真理就是管住嘴迈开腿,通过减少摄入、增加能耗两方面实现,也就是说开源节流才能实现足够多的热量亏空。

肥肉不是一天突然长起来的,切记不要妄想一天就把肥肉给减下去,循序渐进的减肥才是王道,找到适合自己的减肥方法才能事半功倍!


真正自律的人,是不会把自律挂嘴边的~

微服务: ConfigurationProperties配置

发表于 2020-08-02 | 分类于 Server |

简介

我们在开发的时候,可能会遇到这样的场景:

变量希望能够被在配置文件中动态配置,只要修改这些配置,对应的 Java 类对象的变量值就可以改变,从而改变代码的行为。这样我们通过修改配置就可以满足业务诉求,而不需要修改一行代码。

在 SpringBoot 中,可以通过 @ConfigurationProperties 和 @Values 两个注解配合 properties 文件达到上述目的。

比如我的 application.properties 文件配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# ------------------------
# Swagger config
# ------------------------
msconfig.swagger.enableSwagger=true

# ------------------------
# Security config
# ------------------------

msconfig.security.enableCSRF=false
msconfig.security.defToken="token-xx-yy-kk-token-end"

msconfig.security.testList[0]="list0"
msconfig.security.testList[1]="list1"
msconfig.security.testList[2]="list2"

msconfig.security.testMap.KeyTest="map-key"
msconfig.security.testMap.ValueTest="map-value"

接下来,通过 @ConfigurationProperties 和 @Values 来分别读取对应的配置。

本文涉及的代码都已经更新到 Github 工程 中了,大家可以下载查看。

关于微服务的相关文章目录,可以☞ 点我 查看更多内容。

ConfigurationProperties

对应的,新建两个实体类,如下图所示:

实体类 MSSecurityPropertyConfigModel 的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

@Component
@Setter
@Getter
@ConfigurationProperties(prefix = "msconfig.security")
public class MSSecurityPropertyConfigModel {
private boolean enableCSRF;

private String defToken;

// List的配置
private List testList;

// Map的配置
private Map testMap;
}

这里需要注意以下几个问题:

1、必须提供 setter 方法,这里我使用了 lombok;

2、必须使用 @Component 注解,标注在实体类上面;

3、在 @ConfigurationProperties 的 prefix 中必须和配置文件命名保持一致;

4、需要在类上加上 @Component 注解;

关于 MSSwaggerPropertyConfigModel 大家可以自行查看代码,这里不再赘述。

写个测试类,验证一下配置。

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
@RunWith(SpringRunner.class)
@SpringBootTest
public class MSPropertyConfigTests {

@Autowired
MSSwaggerPropertyConfigModel swaggerPropertyConfigModel;

@Autowired
MSSecurityPropertyConfigModel securityPropertyConfigModel;

private Logger logger = LoggerFactory.getLogger(MSPropertyConfigTests.class);

@Test
public void primitiveDataConfig() {

boolean enableSwagger = swaggerPropertyConfigModel.isEnableSwagger();
boolean enableCSRF = securityPropertyConfigModel.isEnableCSRF();

logger.info("primitiveDataConfig-enableSwagger: " + enableSwagger + ", enableCSRF: " + enableCSRF);

String defToken = securityPropertyConfigModel.getDefToken();
logger.info("securityPropertyConfigModel deftoken: " + defToken);

List list = securityPropertyConfigModel.getTestList();
for (Object v : list) {
logger.info("securityPropertyConfigModel value: " + v);
}

Map map = securityPropertyConfigModel.getTestMap();
logger.info("securityPropertyConfigModel map: " + map);
}
}

执行该测试方法,得到如下的输出内容:

1
2
3
4
5
6
primitiveDataConfig-enableSwagger: true, enableCSRF: false
securityPropertyConfigModel deftoken: "token-xx-yy-kk-token-end"
securityPropertyConfigModel value: "list0"
securityPropertyConfigModel value: "list1"
securityPropertyConfigModel value: "list2"
securityPropertyConfigModel map: {KeyTest="map-key", ValueTest="map-value"}

如果您在使用 @ConfigurationProperties 注解过程中,提示如下错误:

1
“Spring Boot Configuration Annotation Processor not found in classpath ”

此时需要在你的 pom.xml 文件中引进 configuration-processor 依赖即可解决。

1
2
3
4
5
6
<!--ConfigurationProperties-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

Value

使用 @Values 注解可以直接作用到某个类的某个字段上面,使用上面比较方便。

对于读取集合的方法跟 @ConfigurationProperties 注解有点不同。

在 application.properties 文件中增加 testList1 和 testMap1 配置如下:

1
2
3
4
5
6
7
8
9
# ------------------------
# Security config
# ------------------------

msconfig.security.enableCSRF=false
msconfig.security.defToken="token-xx-yy-kk-token-end"

msconfig.security.testList1=list0,list1,list2
msconfig.security.testMap1={name:"map-key", age:20}

注意:在配置文件中的 testList1 和 testMap1 配置格式和之前的不一样,否则解析会报错。

测试类中验证,示例代码如下,注意 @Values 注解对集合的书写格式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Value("${msconfig.security.enableCSRF}")
private boolean geEnableCSRF;

@Value("${msconfig.security.defToken}")
private String defUserToken;

@Value("#{'${msconfig.security.testList1}'.split(',')}")
private List list1;

@Value("#{${msconfig.security.testMap1}}")
private Map map1;

@Test
public void primitiveDataConfig() {
logger.info("annotation value. geEnableCSRF: " + geEnableCSRF);
logger.info("annotation value. defUserToken: " + defUserToken);

for (Object v : list1) {
logger.info("annotation value. list: " + v);
}

logger.info("annotation value. map: " + map1);
}

读取结果如下:

1
2
3
4
5
6
annotation value. geEnableCSRF: false
annotation value. defUserToken: "token-xx-yy-kk-token-end"
annotation value. list: list0
annotation value. list: list1
annotation value. list: list2
annotation value. map: {name=map-key, age=20}

我们也可以将 @ConfigurationProperties 和 @Values 这两个注解配合使用。

1
msconfig.security.alias="play-game"

在代码中重新定义变量名称为 aliasPlayGame,可以使用 @Values 定位实际配置的变量名称。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Component
@Setter
@Getter
@ConfigurationProperties(prefix = "msconfig.security")
public class MSSecurityPropertyConfigModel {
private boolean enableCSRF;

private String defToken;

private List testList;

private Map testMap;

// 和 ConfigurationProperties 一起使用
@Value("msconfig.security.alias")
private String aliasPlayGame;
}

你以为的不一定是你以为的

ngrok让服务近在咫尺

发表于 2020-07-16 | 分类于 Server , Tools |

简介

最近在和一个第三方服务做联调,即我方服务调用第三方的服务 API-A,然后第三方把结果回调给我方服务 API-B,因为我是在本地搭建的 SpringBoot 服务,又涉及到频繁的改动,所以就没有部署到远程服务器上面。

API-A 回调到 API-B 需要我方服务能被外网访问,如是我就使用了 ngrok 这个工具进行了内网穿透,让第三方服务很容易的就访问到我的本地服务。

所谓的内网穿透,也即 NAT 穿透,进行 NAT 穿透是为了使具有某一个特定源 IP 地址和源端口号的数据包不被 NAT 设备屏蔽而正确路由到内网主机。

下面具体讲一讲该工具的安装、配置和使用。

配置

Step1:下载工具

点击 这里 可以进入下载页面根据自己所在的平台选择下载 ngrok。

目前 ngrok 支持 Mac OS X、Linux Mac (32-bit) 、Windows (32-bit)、Windows (64-bit)、 Linux (ARM)、 Linux (ARM64) 、Linux (32-bit) 、FreeBSD (64-Bit) 、FreeBSD (32-bit) 等操作系统。

我使用的是 Windows 系统,下面我以此系统安装配置做一个说明。

下载完成后,解压到你的磁盘任意目录,如我的放到了下面目录中:

Step2:配置 ngrok

配置 ngrok 需要在其官网注册一个账号,点击 Sign UP 完成注册即可。

注册完成之后进入 控制台,获取你的 Your Authtoken,复制一下即可后面有用。

打开 Windows 自带的命令行工具(CMD,曹孟德),执行下面

1
./ngrok.exe authtoken 'your-authtoken'

完成后,会在 C:\Users\your-name\.ngrok2\ngrok.yml 文件中注册成功。

Step3:启动 ngrok

我的服务端口号是 8080, 执行下面命令:

1
./ngrok.exe http 8080

可以在命令行看到如下输出:

1
2
3
4
5
6
7
Session Status                online
Account name (Plan: Free)
Version 2.3.35
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding http://1a9d2e7e1e2d.ngrok.io -> http://localhost:8080
Forwarding https://1a9d2e7e1e2d.ngrok.io -> http://localhost:8080

接下来,我们访问 SpringBoot 的服务 API,如下:

1
http://1a9d2e7e1e2d.ngrok.io/pay/callback

或者访问 HTTPS 也可以的。

1
https://1a9d2e7e1e2d.ngrok.io/pay/callback

在外网访问这个接口也是没有问题的。

场景

内网穿透工具 ngrok 还有其他使用场景。

  • 外网连接自己的内网服务器,在外网演示内网 WEB 站点;

  • 无需部署开发的服务到外网服务器,快速调试本地程序,比如微信公众号的开发等;

  • ngrok 支持 HTTP、HTTPS 协议站点,HTTP 协议站点直接升级为 HTTPS 站点;

  • ngrok 支持 TCP,UDP 协议端口转发。

  • ngrok 支持数据库、SSH、远程桌面、网络摄像头等等开放到外网可以访问;

还有其他的内网穿透工具,大家可以自行搜索。


你以为的不一定是你以为的

微服务-Android客户端: 实现注册和登录

发表于 2020-06-20 | 分类于 Server , Android |

简介

在 微服务项目系列文章 中跟大家一起学习了如何搭建、部署(本机和远程部署、热部署、Nginx等)、运行一个 SpringBoot 服务以及 MySQL 数据库的操作、文档(Swagger)的生成等操作,客户端采用浏览器的方式实现了用户注册、登录的流程。根据 微服务-立志做个伟大的项目 立下的【誓言】可以循序渐进的实现我们伟大的理想了,今天我们正式进入 Android 客户端的学习,希望对微服务、Android 开发感兴趣的同学有点帮助。

如果你对 Android 不了解,建议先学习 Google 官网关于 Android 开发的入门知识,最起码你能用 Android Studio 跑起一个工程。如果你对 Java 也不了解或者压根都没有学习过 Java,那么你可能要加油了争取用一周的时间搞懂 Java 语法了,然后在 Android 学习的过程中再去深入 Java 语言的学习。当然了你会 Kotlin 编程语言也可以。这里想告诉大家,任何一门编程语言想精通需要比较长的时间,但是初级入门能写简单的代码只要用心不应该超过一周。你只需要克服内心的恐惧笃定自己一定行,那么很快你就入门了。

阅读下面的内容需要你:

  • 看过 微服务项目系列文章 中的文章,不要求都看过至少关于如何使用 SpringBoot 的部分看过;
  • 会 Java 编程或者 Kotlin 编程,入门的知识即可;
  • 了解 Android 开发,知道如何使用 Android Studio 这个 IDE;

本篇主要内容:

  • 搭建 Android 工程的基本框架;
  • 实现 Android 端的用户注册和登录功能;

工程源码在 Github 上面,大家可以去下载一起学习,工程相关目标如下:

项目目前只实现了注册、登录的功能,后续会丰富其内容。

搭建 Android 工程

该工程名称为 MSBlog,我的本机环境安装了:

  • JDK 1.8;
  • Android Studio 4.0;
  • Android SDK ;

首先,打开 Android Studio,选择 File/New/New Project...,打开下面视图

紧接着,点击 Next,填写相关的项目名称和包名等信息即可。

工程大致结构如下:

在 com.veryitman.msblog.http、com.veryitman.msblog.model 这两个包中是网络请求、数据模型等的 Java 实现,MZOkHTTPWrapper 是对 okhttp 的封装。

该工程中,使用了两个第三方库分别是 gson(json解析等)、okhttp(HTTP请求),详细配置在 app/build.gradle 文件中。

1
2
implementation("com.squareup.okhttp3:okhttp:4.7.2")
implementation 'com.google.code.gson:gson:2.8.6'

实现 Android 注册

用户注册效果图

启动 SpringBoot 服务,注意在 MZHttpUrlModel 中修改一下连接该服务的 IP 地址(用你自己本机的IP)。

点击 Signup,根据用户输入的信息请求服务端的API去注册,点击 Had Account 去登录页面,点击 Guest 直接进入应用。

具体的代码是在 MZSigninActivity 中实现的,有兴趣的朋友可以看看源码,这里不再赘述。

在进行网络请求之前,注意需要在 AndroidManifest.xml 文件中添加访问网络的权限。

1
<uses-permission android:name="android.permission.INTERNET"></uses-permission>

实现 Android 登录

用户登录效果图

具体的代码是在 MZSignupActivity 中实现的,有兴趣的朋友可以看看源码,这里不再赘述。

点击 Signup,根据用户输入的信息请求服务端的API去登录。

进入主界面后,就可以看到四个Tab页面,分别是主页、分类、好友、个人中心。

目前这几个页面尚未实现,后续会陆续完成。

总结

新建一个 Android 工程还算是蛮简单的一个过程,希望大家能把工程跑起来,如果有任何问题可以留言给我。

今天的分享就这么多,简单的做个小结:

  • 从搭建完成 SpringBoot 再到使用 Android 实现一个简单的客户端,需要初学者付出较多的努力,最关键的是我们一起迈出了第一步;
  • 在代码中尽量不要使用魔术数字,把通用的常量放到对应的类中进行管理,减少后续的维护成本;
  • 尽量多的输出 Log,并且使用 Tag 对 Log 进行分类,方便后续排查问题,提高解决问题的效率;

不要抱怨自己没有天赋,如果你能坚持做好一件事情,本身就是天赋。

简谈亲子教育

发表于 2020-06-06 | 分类于 随笔 |

简介

网上流传着这样一句话:“没有一个教孩子学习的家长不是心梗的”。

当然了,这句玩笑话显然是夸张了一些,但它足以表明家长和孩子之间在学习这个话题上存在着不可调和的矛盾。

今天想跟大家分享一下在学习这件事情上,怎么做到更好的与自己的孩子相处才能不伤害彼此。

看到本篇文章的时候,或许你还是未婚者,或者是准父母者,抑或是已为人父母了,但我建议你看下去,说不定有些收获呢。

不可逆的伤害

今年是个特别年,冠状病毒让全国家长增加了陪伴孩子的时间。别人都说:”陪伴是最好的教育“,而我却发现自己在陪伴的日子里并没有那么理性,动辄为了教孩子写作业变得勃然大怒,俨然就是一头失去理性的野兽,后想起来挺好笑的。

我小的时候经常挨父亲的揍,经常因为没有做好一些小事情,就会被突如其来的鞭子收拾的服服帖帖。直到自己上了初中,挨揍的迹象才逐渐消失,取而代之的是我对父亲的冷漠和敷衍以及对家的失望。你对孩子无缘无故的大骂,换来的并不是望子成龙而是不可逆的伤害,会让孩子对你失去信任,它会让你们彼此的交流变得屈指可数,到那个时候就后悔莫及了。

孩子来到这个世界上,不会的东西实在太多了,我们活了这麽多年不还仍旧在学习嘛?上学只是孩子在未来的道路上的一个阶段而已,而我们应该尽自己最大的努力让他在这个道路上走得更稳更安全才是正确的做法。只凭拳脚或者大吼大叫是无法让孩子信服的,三字经说”子不教父之过“,但是”教“得太”过“了就不好了。推荐大家读读 看《银河补习班》有感 这篇文章,鼓励和相信自己的孩子,才是给他前进的道路上最大的动力。每个孩子都是聪明的,他们会用自己的心灵感受你对他的点点滴滴。

知识的诅咒

大家应该考过驾照被教练带着练过车吧,我相信有很多学员都被教练骂哭过甚至还不止一次。若不是自己交了钱付出了那么多,应该早就拔方向盘走人了吧。我也听过身边很多同事抱怨过对教练的各种不满,年轻气盛点的学员也有当面怼教练的。

我自己亲身经历的一件事情,说起来也挺逗。那天去考科目三(路考),凌晨天不亮就出发到考试地了,如果当天科目三能考试通过就可以接着考科目四了,拿驾照就指日可待。在练车的过程中,教练对着我们几个学员分别痛斥了一顿,这个都说了几百遍了那个已经讲了上千遍了怎么还是不注意,我看你们考试挂了也是活该。这种感觉就像你清晨刚一起床就被人用冰水浇灌了一番。我确实是没有忍住就怼了教练一番,我用相对文明的成语胡乱说了他一通,还好大家都没有动起手来😄,那天考试还算顺利大家都考试通过了。

在回来的路上,我问一个学员你现在最想做的一件事是什么?他说删了教练的微信老死不相往来,我举起了左手,他举起了右手,我们不约而同的击了一掌,那响声响彻云霄,感觉那是练车以来最爽的一次就好比报了一个大仇一样。

教练开车多年俨然是一个老司机,而作为从来没有接触过汽车的学员,练车和考试对于他们来说除了不熟悉更可怕的是内心的那份对车的恐惧。再加上教练的咆哮就会更加乱了方寸。这就是知识的诅咒。

那什么是知识的诅咒呢?英文称之为The Curse of Knowledge`,我们一旦知道了某事,就无法想象这件事在未知者眼中的样子。当我们把自己知道的知识解释给别人的时候,因为信息的不对等,我们很难把自己知道的完完全全给对方解释清楚。总是,我们的知识“诅咒”了我们。

简单的用一句话来说,知识的诅咒 就是你自己知道的东西很难通过简单的交流或者教育让对方全部get到。

生活中有很多这样的例子,对于孩子的学习,同样存在知识的诅咒。我们总是认为这些作业太简单,应该讲一两遍孩子都会了,他们为何总是反复的在错呢?为了防止知识的诅咒对我们的影响,我们更应该多一些耐心,或者换个思路想一想是不是自己的教育和表达方式有问题?换个思路和做法,孩子是不是就能学的更轻松呢?

瓦拉赫效应

在了解了 知识的诅咒 这个知识点后,我们再来聊聊什么是 瓦拉赫效应。

在说 瓦拉赫效应 之前,我们还是先看看身边的真实事件。

我有个同学,初中成绩很一般,父母花钱求领导让他上了一个县高中。在高中的文理科分班之前,他整体成绩也很一般,没有人会相信他最后居然可以考上985的大学。后来同学聚会,他跟我们讲其实自己很喜欢理科尤其是数学和物理,对文科没有任何兴趣考试也是瞎蒙的。他非常感谢文理分科让自己有了更好的选择,否则自己的一生可能是另外一番景象。

学生的智能发展都是不均衡的,都有智能的强点和弱点,他们一旦找到自己最佳点,使潜力得到充分的发挥,便可取得惊人的成绩。这一现象人们称之为“瓦拉赫效应”。

奥托·瓦拉赫是诺贝尔化学奖获得者,他的成才过程极富传奇色彩。瓦拉赫在开始读中学时,父母为他选择的是一条文学之路,不料一个学期下来,教师为他写下了这样的评语:“瓦拉赫很用功,但过分拘泥。这样的人即使有着完美的品德,也决不可能在文字上发挥出来。”此后,他改学油画。可瓦拉赫既不善于构图,又不会调色,对艺术的理解力也不强,成绩在班上是倒数第一,学校的评语更是难以令人接受:“你是绘画艺术方面的不可造就之才。”面对如此“笨拙”的学生,绝大多数老师认为他已成才无望,只有化学老师认为他做事一丝不苟,具备做好化学实验应有的品格,建议他试学化学,父母接受了化学老师的建议。这下,瓦拉赫智慧的火花一下被点着了,文学艺术的“不可造之才”一下子变成公认的化学方面的“前程远大 的高才生”。

如果你还在强迫自己的孩子去上所谓的兴趣班的父母,是时候考虑一下继续这样下去会不会对孩子造成更大的伤害?

在这个年代,每个人都有很大的压力包括孩子自己,即使你在班级里考了80分也可能是倒数第一,培养孩子的兴趣是很重要但前提是你让他把最基本的学习搞好。强迫他去上兴趣班是没有任何意义的。


自己乱七八糟的说了许多,总结一下吧!

  • 孩子在学习方面不懂的有很多,家长要更加有耐心的教导他们,别被知识诅咒了;
  • 每个孩子的智能发展是不均衡的,当他们遇到问题后,试着换个方式去引导和教育他们,帮助他们找到那个平衡点;
  • 拳打脚踢、声嘶力竭只能让家长和孩子之间的关系变得更加矛盾,造成的伤害不可逆;
  • 不要私自给孩子下决定,尽量彼此进行商量,适当的时候可以进行适度的“骗”;

对孩子的歇斯底里,换来的只不过是两败俱伤。

微服务: 配置Nginx反向代理

发表于 2020-05-23 | 分类于 Server |

简介

本来是一件很小的事情,但我觉得还是很有必要跟大家分享一下,勿以善小而不为。

事情是这样的…

有个小伙伴告诉我说自己想学习一下 SpringBoot 结合 Nginx,毕竟用了 Tomcat 那么久(启动 SpringBoot 项目会自动启动 Tomcat)也是时候玩玩 Nginx 了。这个想法很赞,去探索和了解自己没有学过的东西本来就是一种进步。

他说按照网上教程配置了一下 Nginx,但是通过配置的方式访问 Nginx 死活都不能访问到 SpringBoot Web 项目提供的接口中去。

今天我们一起来看看这个问题,我也把实践的内容分享给大家,希望能帮助到有需要的人。

关于微服务相关的文章,有兴趣的可以参阅 微服务项目系列 这篇文章。

大写的 404

经过一番的沟通,他给我大致描述了一下经过,我就开始了复现之路。

这个小伙伴是想通过 Nginx 的反向代理能力访问所有 SpringBoot Web 项目的接口,关于什么是反向代理、正向代理,可以参考我之前名为 反向代理 的一篇文章。

我所用依旧是 SpringBoot 项目源代码 中的代码,代码托管在 Github 上面了,有需要的朋友可以 clone 下来。

报错如下图所示:

我在本机(Windows 10系统)安装的 Nginx 版本是 1.15.12,上图可以看出访问对应的 url 出现了 404 错误,关于 404 这个错误码,百度百科是这样解释的:

404,是一种HTTP状态码,指网页或文件未找到。

HTTP 404或Not Found错误信息是HTTP的其中一种“标准回应信息”(HTTP状态码),此信息代表客户端在浏览网页时,服务器无法正常提供信息,或是服务器无法回应且不知原因。

直白来讲,就是找不到资源。首先我们来看一下我是如何配置 Nginx 反向代理的。

配置文件 nginx.conf (在Nginx安装目录conf目录下),内容如下:

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
worker_processes  1;

events {
worker_connections 1024;
}

http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;

# 自定义虚拟主机1
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
}

# 自定义虚拟主机2:配置转发给ms-user服务(springboot)
server {
listen 80;
server_name user.com;
location / {
proxy_pass http://localhost:8080;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
}
}
}

从配置可以看到,配置了两个虚拟主机,问题就出现在这里。

让 404 消失

我们再来看一下刚才报 404 的访问地址 http://localhost/signin/name?username=fooboy&userpwd=123,其中 http://localhost 本质是 http://localhost:80,再结合看一下 Nginx 的配置文件,其实是访问到了 自定义虚拟主机1 上面了。

有两个比较简单的解决方案,下面的两种方案无需修改 SpringBoot 项目的任何配置,你只需要启动你的 SpringBoot 项目即可。

方案一:配置主机 host

修改系统主机 C:\Windows\System32\drivers\etc 目录下面的 HOSTS 文件,记得要用管理员身份打开才有权限去写。

在 HOSTS 文件中,增加如下配置:

1
127.0.0.1 user.com

在浏览器访问 http://user.com/signin/name?username=fooboy&userpwd=123 就可以成功了(注意访问的域名是 user.com),如下图所示(该API需要输入登录账号和密码):

方案二:修改虚拟主机的端口

这个需要修改 Nginx 的配置文件,将 自定义虚拟主机2 中的端口改为非 80 端口号,修改如下:

1
2
3
4
5
6
7
8
9
10
11
# 自定义虚拟主机2:配置转发给ms-user服务(springboot)
server {
listen 8085;
server_name user.com;
location / {
proxy_pass http://localhost:8080;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
}
}

修改完成后,保存文件。

需要重新加载 Nginx 的配置,可以在终端输入如下命令:

1
nginx.exe -s reload

重新加载成功后,在浏览器访问 http://localhost:8085/signin/name?username=fooboy&userpwd=123 就可以成功了(注意访问的端口改为了 8085),如下图所示:

至此问题解决。


只要你愿意,一切都来得及~

瘦身秘笈: 养成好习惯

发表于 2020-05-10 | 分类于 随笔 |

习惯的力量

得此秘笈者终生受益,练此秘笈无须自宫。


过年因疫情肆虐,大家基本都是待在家中。老婆跟我说,你能不能写点非技术的东西呀,技术文章我们都看不懂,你可以写点程序员平常是怎么生活的文章呀?面对她恨铁不成钢的“愤怒”,我也hinhin的反思了一把,除了代码之外,确实有很多东西值得说值得写。毕竟人不能总是陷入能力的陷阱中,要不断的打破知识的诅咒,不断的去探索和表达自己。

于是,今天分享的话题与技术基本没有关系,我们聊聊关于健康管理的话题。

不知道大家有没有这样一种感觉,每当别人给你分享关于他自己一些经验的时候,尤其这些经验我们还没有体验过,就觉得对方说的东西距离自己很遥远,哪怕对方是苦口婆心的谆谆教导,自己可能也只是心不在焉的听听而已。

今天要分享的是关于如何调整自己的生活习惯的话题,为了能让大家“欣然接受”(奢求🙁),我用实际行动确实让自己有所改变,才敢发文。希望对大家有益。

对于 程序员保养秘笈 这个话题,我准备分为几篇文章跟大家分享,本篇算是一个导读。无论你现在是处于程序开发的初级阶段(小白🤝),还是高级(脱发😜)阶段,都希望你能坚持看完。减肥的前提是你能养成好习惯并且坚持下来,千万不要轻易相信网上所谓的减肥机构以及一些虚假宣传。

我始终认为只要自己的身体各项指标正常(比如没有脂肪肝,没有高血压等),生活习惯良好,即使胖一点也无所谓。一旦你能养成良好的习惯,想不瘦都难并且可以受益终生。

下面正式进入吹🐂🍺的时间。

BMI 靠谱不?

在2019年10月份,我体重达到了 86.5kg,我的身高175cm,这个体重对我来说已经超标了。当时的BMI(身体质量指数,简称体质指数)指数值为 28.2,下图是BMI相关的标准。

从上面的图中就可以看出,我已经属于过度肥胖了。

自从我改变了的生活方式后,现在的BMI指数值为23.4,虽然达标了但还有很大的缩减空间,还需要继续努力。

这里我要普及一下关于BMI的相关知识,请各位搬好小板凳认真听。

BMI就是所谓的“体质指数”,计算公式如下:
$$
BMI = 体重kg / (身高m)^2
$$
即体重除以身高的平方得到的值就是 BMI 值。看到这个公式,调皮的小伙伴可能会说你是不是长高了所以BMI值才变低的🤭,我都几十岁的人了,长高已经是可望不可及了。

下面是引用自作者 仰望尾迹云 的 《我的最后一本减肥书》里面的内容。

从公式上看,BMI就相当于把人均匀地剁成几段,称一称单位身高里人的体重。所以,体重越重,身高越低,BMI也就越高。BMI反映了人“横向发展”的程度,越胖的 人,BMI自然越高。BMI自20世纪五六十年代就开始用。但BMI多少算肥胖,多少算正常,不同国家和组织,规定都不一样。西方的标准一般略低。我国的标准,BMI值18.5~24算体重正常,24~28算超重,但还不算肥胖,超过28算肥胖。

但BMI也不是绝对标准。对大多数普通人来说,BMI有相对较好的指导意义,但BMI也有两个重要缺陷。

首先,BMI不区分脂肪和肌肉,有些人超重,是脂肪太多;但也有些人超重,是肌肉比例大,比如力量型运动员。他们体重大是因为肌肉发达,所以不能叫“胖”。用BMI衡量这些人的健康或者胖瘦,他们就很冤枉。有数据称,美国2004—2005赛季的1124名橄榄球运动员中,BMI超过30的有43%,超过35的有14%。看起来很可怕,但其实这些运动员身体健康得不得了,一个个也都不胖。

其次,BMI不区分脂肪的分布位置,这也是个大问题。从健康的角度讲,内脏脂肪和皮下脂肪,前者要比后者危险得多,但BMI可分不出脂肪长在哪儿。两个身高体重一样的人,一个胖得很均匀,一个脂肪都集中在内脏处,从健康和审美的角度讲,这两个人完全不同,但BMI却是一样的。所以,BMI高,不一定就是胖,也不一定就不健康;BMI低,不一定就不胖,也不一定绝对健康。BMI太粗略,所以有些问题还要具体来看。那为什么BMI在全世界被广泛使用了半个世纪?实际上这也是没办法的办法。准确地测量人的脂肪含量,并且明确脂肪的分布位置,难度很大,只有在实验室或者医院才能测出来。绝大多数人,不可能有条件经常去做体成分测试。

BMI最大的好处就是简单,知道身高体重就能算出来。虽然有误判,但相对来说,效用价格比还是很高的,适合大范围人群使用。不用BMI的话,也确实没有更好的办法来衡量人的身高体重和健康的关系了。

总之,如果你没有经常运动或者去健身(低头看看自己肚子上面的肉吧)用BMI来看自己是否偏胖,算是比较靠谱的衡量标准了。如果你偏瘦的话,就需要稍微补充一下营养了,毕竟太瘦了对身体也不好还影响加班的效率!

算是好习惯吧

说实话,我也不知道怎么来定义什么是好习惯,凡是让你受益的习惯我觉得都算是好习惯。我把自己受益的那些习惯分享给正在看此文的你。

下面这些习惯暂时不展开说,后续的文章会详细的介绍。

1、早睡早起

对于绝大部分生活在大城市的年轻人,尤其这些年轻人是程序员的话,早睡简直是让人望尘莫及了,996甚至997的日子习以为常,每晚回到家基本都是22点后了,洗个澡刷个d音聊个w信再给自己远方的女朋友打个电话,估计都凌晨了,猛一点的可能要到凌晨2、3点才开始睡觉,早起就变得更难了。

晚睡的坏处自然不用我多说,大家心里都跟明镜似的。我个人觉得在大城市奋斗的年轻人,能在24点前一点点睡觉,放下手机也算是‘立地成佛’了。不过慢慢养成习惯吧,坚持一段时间后再把早睡时间往前调整一点,循序渐进的去调整自己。早上尽量在8前起床,有条件的朋友可以自制早餐,一杯热牛奶,一个新鲜鸡蛋,一个苹果或者香蕉就搞定了。

2、规律饮食

早餐尽量在9点前搞定,根据自己的喜好,早上可以多吃一点,尤其是疫情期间蛋白质的补充千万不能少。

午餐以蔬菜为主,加点玉米或者红薯之类的粗粮,也可以适当的吃点肉但千万不要太油腻,像猪肘子呀别人吃一个,你最好吃一半甚至更少一点。有人说了万一要是没忍住吃多了呢,那怎么办?酒肉穿肠过,佛祖心中留😄。嗯,偶尔几下也没有关系了,你只要在接下来的一两天内通过运动把他消耗掉就可以了。

晚餐最好在19点前就吃完,主食适当的少一点,主食还是以大米为主吧,同等质量的面食要比大米的热量高,多吃点菜。如果晚上你能忍住不吃肉那就更好了,晚餐尽量保证低盐低油饮食,遇到晚上加班或者开会肚子饿了可以适当补充一点高纤维面包和牛奶,睡觉前2个小时内就不要吃东西了。

总之,一日三餐按时吃饭,蔬菜为主,主食为辅,8分饱就可以了,适当的给胃和肠道留点运动的空间,只有它们舒服了你才能高枕无忧。

PS:我之前使用过不吃晚餐的方法来减肥,苦苦的坚持了40多天,结果一个朋友的晚宴让我彻底突破了自己的防线,我承认那一晚我撑到了。最后可想而知,体重还是反弹回来了并且比之前更能吃了。所以,不吃饭减肥对于绝大多数的人来说是行不通的,只有吃饱了才能有力气减肥嘛!

3、经常喝水

这里的水指的不是可乐,雪碧之类的饮料,而是白开水(适当的加点料也可以,比如柠檬片,枸杞,茶叶)。

经常喝水有助于身体的新陈代谢,特别是像瘦下来的朋友们,多喝水可以促进脂肪的燃烧。还有如果你有肾结石之类的疾病更应该多喝水,水喝的量够了上厕所也会频繁,还可以促进运动,一举两得。

喝水可以保持每15分钟喝2~3口的样子,不要豪饮,慢慢养成习惯就好了,最好不要等着自己渴了再来喝水,让喝水变成肌肉记忆。早起一杯温开水可以清肠道,用餐前一杯水有利于增强饱腹感减少用餐量,间接地可以减少热量的摄入。

4、适当运动

你是否经常坐在位置上点外卖吃?如果是我建议你改变一下自己这个习惯,可以选择去楼下跟同事一起用餐,既可以增加运动又可以促进与同事之间的交流,饭前饭后走一走,有助于消化和吸收,减少脂肪的堆积。

一提到运动,大家心里面想到的一般都是那种大汗淋漓的场面才算是运动。其实运动有很多种,如果你不能跑步就选择快走,如果你觉得快走还是很累那就慢走,反正动起来比坐下来要好一些。特别是比较胖的人,跑步要特别注意自己的膝盖,体重偏胖对膝盖的伤害是很大的。

可以使用 NEAT(Non-Exercise Activity Thermogenesis,即非运动性热消耗)法来增加自己的热量消耗,我总结了一下自己使用的 NEAT 小习惯,如下图:

这里我着重提一下收腹这个小动作,经常保持收腹的动作可以增强腹部的练习,有利于瘦肚子。当然了这个过程很慢,一旦你习惯了这个动作,我敢保证要不了多久肯定有同事说你瘦了许多。

5、戒烟限酒

之前有很多朋友都戒烟了,有的戒了半年,有的戒了几年,最后还是抽上了,戒烟是一个值得研究和探讨的课题。所以,我并没有期望你读到这里就立即戒烟了。

戒烟最难的是如何消除内心的那种失落的恐惧感,一烟在手,天下我有的感觉让人难以割舍。

我自己本身也是一个烟民,正在戒烟的苦难中苦苦挣扎着,等我哪一天真正戒掉了再来分享这个心路历程。

戒酒,对于有酒瘾的朋友也是很难的一件事情,但是限酒我觉得还是要去尝试一下的,少喝点不至于那么伤肝吧。本人对酒不感兴趣,也基本不喝,因为一喝就醉,实在没有这个天赋。

还有很多好的习惯没有一一列举出来,比如早晚刷牙(如果你喜欢甚至可以早中晚刷牙😜)、还有降低吃饭速度、午休等等,总之你有多自律就有多自由!


勿以恶小而为之,勿以善小而不为~

<1…345…20>

193 日志
16 分类
163 标签
© 2024 veryitman