Long Luo's Life Notes

每一天都是奇迹

By Long Luo

最近在部门内部做了一次知识分享,关于Java反射,因此有了这篇文章:《5分钟学会Java反射》。这篇文章篇幅不长,用了大量示例,力求在很短的时间里让大家明白Java反射知识。

关于 Java 反射,我们需要弄懂以下几个问题:

  1. 反射是什么?
  2. 反射有什么用?
  3. 怎么用反射?

下面我们来一一进行讲解:

一、反射是什么?

Reflection 的意思是“反射、映象、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。

Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性及方法;对于任何一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象的方法的功能称为Java的反射机制。

1. 自省(Introspection) vs. 反射(Reflection)

反射经常和自省弄混,为了区别,我们先看看两者的详细定义:

自省(Introspection):

Introspection is the ability of a program to examine the type or properties of an object at runtime.

反射(Reflection):

Reflection is the ability of a program to examine and modify the structure and behavior of an object at runtime.

从上述定义,我们可以看出,自省是反射的子集。部分语言支持自省,但是不支持反射,比如C++。

2. 自省示例 vs. 反射示例

自省示例: instanceof操作符用于判断一个对象是否属于一个特定的类。

1
2
3
4
if(obj instanceof Dog) {
Dog d = (Dog)obj;
d.bark();
}

反射实例: Class.forName()方法返回了一个具体类/接口的对象,当然参数需要指定为特定的类名。

1
2
3
4
5
6
// with reflection
Class <?> c = Class.forName("classpath.and.classname");
Object dog = c.newInstance();

Method m = c.getDeclaredMethod("bark", new Class<?>[0]);
m.invoke(dog);

二、 为什么需要反射?

Java反射在框架开发中尤为重要。有些情况下,我们要使用的类在运行时才会确定,这个时候我们不能在编译期就使用它,因此只能通过反射的形式来使用在运行时才存在的类(该类符合某种特定的规范,例如JDBC),这是反射用得比较多的场景。

编译时我们对于类的内部信息不可知,必须得到运行时才能获取类的具体信息。比如ORM框架,在运行时才能够获取类中的各个属性,然后通过反射的形式获取其属性名和值,存入数据库。

反射机制提供的功能:

  1. 在运行时判断任意一个对象所属的类;
  2. 在运行时构造任意一个类的对象;
  3. 在运行时判断任意一个类所具有的成员变量和方法;
  4. 在运行时调用任意一个对象的方法。通过反射甚至可以调用到private的方法;
  5. 在运行时修改构造函数,变量和方法的访问权限。

解耦

假如我们有两个程序员,一个程序员在写程序的时候,需要使用第二个程序员所写的类,但第二个程序员并没完成他所写的类。那么第一个程序员的代码能否通过编译呢?这是不能通过编译的。利用Java反射的机制,就可以让第一个程序员在没有得到第二个程序员所写的类的时候,来完成自身代码的编译

在对类的调用和实例化的时候,通过在配置文件中配置相应的类名,在程序中读取类名,然后通过反射技术在程序中加载和实例化,如常见的数据库驱动程序类,为了达到不依赖特定数据库驱动类,将用到的数据库驱动类名放到配置文件中(常用的有XML文件、Properties文件和文本文件),然后在程序中加载驱动,来实现对数据库的解耦,也就是说只要修改配置文件,就可以方便地更改数据库类型。

例如, Spring使用如下的bean配置:

1
2
3
<bean id="someID" class="com.programcreek.Foo">
<property name="someField" value="someValue"/>
</bean>

Spring在处理<bean>时,会使用Class.forName(String),同时参数为"com.xxx.Foo"用于实例化这个Class。同时,使用反射设置<property>去用于设置特定的值。

这种机制同样也用于Servlet的web应用:

1
2
3
4
<servlet>
<servlet name>someServlet </s e rvl e t􀀀name>
<servlet class>com.programcreek.WhyReflectionServlet</servlet class>
<servlet>
阅读全文 »

By Long Luo

Linux环境变量问题汇总

测试好的脚本放到 crontab 里就报错: 找不到命令

写好一个脚本,测试没有问题,然后放到crontab 想要定时执行,但是总是报错,去看日志的话显示某些命令找不到,这种一般都是因为PATH环境变量变了导致的

自己在shell命令行下测试的时候当前环境变量就是这个用户的环境变量,可以通过命令:env 看到,脚本放到crontab 里面后一般都加了sudo 这个时候 env 变了。比如你可以在命令行下执行 env 和 sudo env 比较一下就发现他们很不一样

sudo有一个参数 -E (–preserver-env)就是为了解决这个问题的。

这个时候再比较一下

  • env
  • sudo env
  • sudo -E env

大概就能理解这里的区别了。

本文后面的回复中有同学提到了:

第一个问题,sudo -E在集团的容器中貌似是不行的,没有特别好的解,我们最后是通过在要执行的脚本中手动source “/etc/profile.d/dockerenv.sh”才行

我也特意去测试了一下官方的Docker容器,也有同样的问题,/etc/profile.d/dockerenv.sh 中的脚本没有生效,然后debug看了看,主要是因为bashrc中的 . 和 source 不同导致的,不能说没有生效,而是加载 /etc/profile.d/dockerenv.sh 是在一个独立的bash 进程中,加载完毕进程结束,所有加载过的变量都完成了生命周期释放了,类似我文章中的export部分提到的。我尝试把 ~/.bashrc 中的 . /etc/bashrc 改成 source /etc/bashrc , 同时也把 /etc/bashrc 中的 . 改成 source,就可以了,再次进到容器不需要任何操作就能看到所有:/etc/profile.d/dockerenv.sh 中的变量了,所以我们制作镜像的时候考虑改改这里

crontab

docker 容器中admin取不到env参数

docker run的时候带入一堆参数,用root能env中能看到这些参数,admin用户也能看见这些参数,但是通过crond用admin就没法启动应用了,因为读不到这些env。

同样一个命令ssh执行不了, 报找不到命令

比如:

ssh user@ip ” ip a ” 报错: bash: ip: command not found

但是你要是先执行 ssh user@ip 连上服务器后,再执行 ip a 就可以,这里是同一个命令通过两种不同的方式使用,但是环境变量也不一样了。

同样想要解决这个问题的话可以先 ssh 连上服务器,再执行 which ip ; env | grep PATH

$ which ip
/usr/sbin/ip
$ env | grep PATH
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin

很明显这里因为 ip在/usr/sbin下,而/usr/sbin又在PATH变量中,所以可以找到。

那么接下来我们看看

$ssh user@ip "env | grep PATH"
PATH=/usr/local/bin:/usr/bin

很明显这里的PATH比上面的PATH短了一截,/usr/sbin也没有在里面,所以/usr/sbin 下的ip命令自然也找不到了,这里虽然都是同一个用户,但是他们的环境变量还不一样,有点出乎我的意料之外。

主要原因是我们的shell 分为login shell 和 no-login shell , 先ssh 登陆上去再执行命令就是一个login shell,Linux要为这个终端分配资源。

而下面的直接在ssh 里面放执行命令实际上就不需要login,所以这是一个no-login shell.

login shell 和 no-login shell又有什么区别呢?

  • login shell加载环境变量的顺序是:① /etc/profile ② ~/.bash_profile ③ ~/.bashrc ④ /etc/bashrc
  • 而non-login shell加载环境变量的顺序是: ① ~/.bashrc ② /etc/bashrc

也就是nog-login少了前面两步,我们先看后面两步。

下面是一个 .bashrc 的内容:

$ cat .bashrc 
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi

基本没有什么内容,它主要是去加载 /etc/bashrc 而他里面也没有看到sbin相关的东西

那我们再看non-login少的两步: ① /etc/profile ② ~/.bash_profile

cat /etc/profile : if [ “$EUID” = “0” ]; then pathmunge /usr/sbin pathmunge /usr/local/sbin else pathmunge /usr/local/sbin after pathmunge /usr/sbin after fi

这几行代码就是把 /usr/sbin 添加到 PATH 变量中,正是他们的区别决定了这里的环境变量不一样。

用一张图来表述他们的结构,箭头代表加载顺序,红框代表不同的shell的初始入口image.png

像 ansible 这种自动化工具,或者我们自己写的自动化脚本,底层通过ssh这种non-login的方式来执行的话,那么都有可能碰到这个问题,如何修复呢?

在 /etc/profile.d/ 下创建一个文件:/etc/profile.d/my_bashenv.sh 内容如下:

$cat /etc/profile.d/my_bashenv.sh 

pathmunge () {
if ! echo $PATH | /bin/egrep -q "(^|:)$1($|:)" ; then
   if [ "$2" = "after" ] ; then
  PATH=$PATH:$1
   else
  PATH=$1:$PATH
   fi
fi
}
 
pathmunge /sbin
pathmunge /usr/sbin
pathmunge /usr/local/sbin
pathmunge /usr/local/bin
pathmunge /usr/X11R6/bin after
 
unset pathmunge

complete -cf sudo
 
    alias chgrp='chgrp --preserve-root'
    alias chown='chown --preserve-root'
    alias chmod='chmod --preserve-root'
    alias rm='rm -i --preserve-root'
    
HISTTIMEFORMAT='[%F %T] '
HISTSIZE=1000
export EDITOR=vim    
export PS1='\n\e[1;37m[\e[m\e[1;32m\u\e[m\e[1;33m@\e[m\e[1;35m\H\e[m \e[4m`pwd`\e[m\e[1;37m]\e[m\e[1;36m\e[m\n\$'

通过前面我们可以看到 /etc/bashrc 总是会去加载 /etc/profile.d/ 下的所有 *.sh 文件,同时我们还可以在这个文件中修改我们喜欢的 shell 配色方案和环境变量等等

脚本前增加如下一行是好习惯

1
#!/bin/bash --login
image-20220505213833017

BASH

1、交互式的登录shell (bash –il xxx.sh) 载入的信息: /etc/profile ~/.bash_profile( -> ~/.bashrc -> /etc/bashrc) ~/.bash_login ~/.profile

2、非交互式的登录shell (bash –l xxx.sh) 载入的信息: /etc/profile ~/.bash_profile ( -> ~/.bashrc -> /etc/bashrc) ~/.bash_login ~/.profile $BASH_ENV

3、交互式的非登录shell (bash –i xxx.sh) 载入的信息: ~/.bashrc ( -> /etc/bashrc)

4、非交互式的非登录shell (bash xxx.sh) 载入的信息: $BASH_ENV

SH

1、交互式的登录shell 载入的信息:

/etc/profile ~/.profile

2、非交互式的登录shell 载入的信息:

/etc/profile ~/.profile

3、交互式的非登录shell 载入的信息:

$ENV

练习验证一下bash、sh和login、non-login

  • sudo ll 或者 sudo cd 是不是都报找不到命令
  • 先sudo bash 然后执行 ll或者cd就可以了
  • 先sudo sh 然后执行 ll或者cd还是报找不到命令
  • sudo env | grep PATH 然后 sudo bash 后再执行 env | grep PATH 看到的PATH环境变量不一样了

找不到ll、cd命令不是因为login/non-login而是因为这两个命令是bash内部定义的,所以sh找不到,通过type -a cd 可以看到一个命令到底是哪里来的

4、非交互式的非登录shell 载入的信息:

nothing

export命令的作用

Linux 中export是一种命令工具通过export命令把shell变量中包含的用户变量导入给子程序.默认情况下子程序仅会继承父程序的环境变量,子程序不会继承父程序的自定义变量,所以需要export让父程序中的自定义变量变成环境变量,然后子程序就能继承过来了。

我们来看一个例子, 有一个变量,名字 abc 内容123 如果没有export ,那么通过bash创建一个新的shell(新shell是之前bash的子程序),在新的shell里面就没有abc这个变量, export之后在新的 shell 里面才可以看到这个变量,但是退出重新login后(产生了一个新的bash,只会加载env)abc变量都不在了

$echo $abc
$abc="123"
$echo $abc
123
$bash
$echo $abc

$exit
exit

$export abc

$echo $abc
123

$bash

$echo $abc
123

一些常见问题

执行好好地shell 脚本换台服务器就:source: not found

source 是bash的一个内建命令(所以你找不到一个/bin/source 这样的可执行文件),也就是他是bash自带的,如果我们执行脚本是这样: sh shell.sh 而shell.sh中用到了source命令的话就会报 source: not found

这是因为bash 和 sh是两个东西,sh是 POSIX shell,你可以把它看成是一个兼容某个规范的shell,而bash是 Bourne-Again shell script, bash是 POSIX shell的扩展,就是bash支持所有符合POSIX shell的规范,但是反过来就不一定了,而这里的 source 恰好就是 bash内建的,不符合 POSIX shell的规范(POSIX shell 中用 . 来代替source)

. (a period)

. filename [arguments]

Read and execute commands from the filename argument in the current shell context. If filename does not contain a slash, the PATH variable is used to find filename. When Bash is not in POSIX mode, the current directory is searched if filename is not found in $PATH. If any arguments are supplied, they become the positional parameters when filename is executed. Otherwise the positional parameters are unchanged. If the -T option is enabled, source inherits any trap on DEBUG; if it is not, any DEBUG trap string is saved and restored around the call to source, and source unsets the DEBUG trap while it executes. If -T is not set, and the sourced file changes the DEBUG trap, the new value is retained when source completes. The return status is the exit status of the last command executed, or zero if no commands are executed. If filename is not found, or cannot be read, the return status is non-zero. This builtin is equivalent to source.

在centos执行好好的脚本放到Ubuntu上就不行了,报语法错误

同上,如果到ubuntu上用 bash shell.sh是可以的,但是sh shell.sh就报语法错误,但是在centos上执行:sh或者bash shell.sh 都可以通过。 在centos上执行 ls -lh /usr/bin/sh 可以看到 /usr/bin/sh link到了 /usr/bin/bash 也就是sh等同于bash,所以都可以通过不足为奇。

但是在ubuntu上执行 ls -lh /usr/bin/sh 可以看到 /usr/bin/sh link到了 /usr/bin/dash , 这就是为什么ubuntu上会报错

source shell.sh 和 bash shell.sh以及 ./shell.sh的区别

source shell.sh就在本shell中展开执行 bash shell.sh表示在本shell启动一个子程序(bash),在子程序中执行 shell.sh (shell.sh中产生的一些环境变量就没法带回父shell进程了), 只需要有读 shell.sh 权限就可以执行 ./shell.sh 跟bash shell.sh类似,但是必须要求shell.sh有rx权限,然后根据shell.sh前面的 #! 后面的指示来确定用bash还是sh

$cat test.sh 
echo $$

$echo $$
2299

$source test.sh 
2299

$bash test.sh 
4037

$./test.sh 
4040

如上实例,只有source的时候进程ID和bash进程ID一样,其它方式都创建了一个新的bash进程,所以ID也变了。

bash test.sh 产生一个新的bash,但是这个新的bash中不会加载 .bashrc 需要加载的话必须 bash -l test.sh.

通过ssh 执行命令(命令前有sudo)的时候报错:sudo: sorry, you must have a tty to run sudo

这是因为 /etc/sudoers (Linux控制sudo行为、权限的配置文件)中指定了 requiretty(Redhat、Fedora默认行为),但是 通过ssh远程执行命令是没有tty的(不需要交互)。 解决办法可以试试 ssh -t or -tt (强制分配tty)或者先修改 /etc/sudoers把 requiretty 删掉或者改成 !requiretty

cp 命令即使使用了 -f force参数,overwrite的时候还是弹出交互信息,必须手工输入Y、yes等

Google搜索一下别人给出的方案是这样 echo yes | cp -rf xxx yyy 算是笨办法,但是没有找到这里为什么-f 不管用。 type -a cp 先确认一下 cp到底是个什么东西:

    #type -a cp
    cp is aliased to `cp -i'
    cp is /usr/bin/cp

这下算是有点清楚了,原来默认cp 都是-i了(-i, –interactive prompt before overwrite (overrides a previous -n option)),看起来就是默认情况下为了保护我们的目录不经意间被修改了。所以真的确认要overwrite的话直接用 /usr/bin/cp -f 就不需要每次yes确认了

重定向

sudo docker logs swarm-agent-master >master.log 2>&1 输出重定向http://www.kissyu.org/2016/12/25/shell%E4%B8%AD%3E%20:dev:null%202%20%3E%20&1%E6%98%AF%E4%BB%80%E4%B9%88%E9%AC%BC%EF%BC%9F/

>/dev/null 2>&1 标准输出丢弃 错误输出丢弃
2>&1 >/dev/null 标准输出丢弃 错误输出屏幕

http://kodango.com/bash-one-liners-explained-part-three

umask

创建文件的默认权限是 666 文件夹是777 但是都要跟 umask做运算(按位减法) 一般umask是002 所以创建出来文件最终是664,文件夹是775,如果umask 是027的话最终文件是 640 文件夹是750 『尽量不要以数字相加减啦!』你应该要这样想(-rw-rw- rw-) – (——–wx)=-rw-rw-r–这样就对啦!不要用十进制的数字喔!够能力的话,用二进制来算,不晓得的话,用 rwx 来算喔!

其它

echo $-   // himBH 

“$-” 中含有“i”代表“交互式shell” “$0”的显示结果为“-bash”,bash前面多个“-”,代表“登录shell”. 没有“i“和“-”的,是“非交互式的非登录shell”

set +o histexpand (! 是history展开符号, histexpand 可以打开或者关闭这个展开符) alias 之后,想要用原来的命令:+alias (命令前加)

bash程序执行,当“$0”是“sh”的时候,则要求下面的代码遵循一定的规范,当不符合规范的语法存在时,则会报错,所以可以这样理解,“sh”并不是一个程序,而是一种标准(POSIX),这种标准,在一定程度上(具体区别见下面的“Things bash has that sh does not”)保证了脚本的跨系统性(跨UNIX系统)

Linux 分 shell变量(set),用户变量(env), shell变量包含用户变量,export是一种命令工具,是显式那些通过export命令把shell变量中包含的用户变量导入给用户变量的那些变量.

set -euxo pipefail //-u unset -e 异常退出 http://www.ruanyifeng.com/blog/2017/11/bash-set.html

引号

shell 中:单引号的处理是比较简单的,被单引号包括的所有字符都保留原有的意思,例如’$a’不会被展开, ’cmd’也不会执行命令;而双引号,则相对比较松,在双引号中,以下几个字符 \(, \`, \ 依然有其特殊的含义,比如\)可以用于变量展开, 反引号`可以执行命令,反斜杠。但是,在双引号包围的字符串里,反斜杠的转义也是有限的,它只能转义$, `, “, (回车)这几个字符,后面如果跟着的不是这几个字符,只不会被黑底,反斜杠会被保留 http://kodango.com/simple-bash-programming-skills-2

su 和 su - 的区别

su命令和su -命令最大的本质区别就是:前者只是切换了root身份,但Shell环境仍然是普通用户的Shell;而后者连用户和Shell环境一起切换成root身份了。只有切换了Shell环境才不会出现PATH环境变量错误。su切换成root用户以后,pwd一下,发现工作目录仍然是普通用户的工作目录;而用su -命令切换以后,工作目录变成root的工作目录了。用echo $PATH命令看一下su和su -以后的环境变量有何不同。以此类推,要从当前用户切换到其它用户也一样,应该使用su -命令。

比如: su admin 会重新加载 ~/.bashrc ,但是不会切换到admin 的home目录。 但是 su - admin 不会重新加载 ~/.bashrc ,但是会切换admin的home目录。

The su command is used to become another user during a login session. Invoked without a username, su defaults to becoming the superuser. The optional argument - may be used to provide an environment similar to what the user would expect had the user logged in directly.

后台任务执行

将任务放到后台,断开ssh后还能运行: “ctrl-Z”将当前任务挂起(实际是发送 SIGTSTP 信号),父进程ssh退出时会给所有子进程发送 SIGHUP;

jobs -l 查看所有job

“disown -h %序号” 让该任务忽略SIGHUP信号(不会因为掉线而终止执行),序号为 Jobs -l 看到的顺序号; “bg”让该任务在后台恢复运行。

shell 调试与参数

为了方便 Debug,有时在启动 Bash 的时候,可以加上启动参数。

  • -n:不运行脚本,只检查是否有语法错误。
  • -v:输出每一行语句运行结果前,会先输出该行语句。
  • -x:每一个命令处理完以后,先输出该命令,再进行下一个命令的处理。
1
2
3
$ bash -n scriptname
$ bash -v scriptname
$ bash -x scriptname

shell 数值运算

bash中数值运算要这样 $(( \(a+\)b )) // declare -i 才是定义一个整型变量

  • 在中括号 [] 内的每个组件都需要有空白键来分隔;
  • 在中括号内的变量,最好都以双引号括号起来;
  • 在中括号内的常数,最好都以单或双引号括号起来。

在bash中为变量赋值的语法是foo=bar,访问变量中存储的数值,其语法为 $foo。 需要注意的是,foo = bar (使用空格隔开)是不能正确工作的,因为解释器会调用程序foo 并将 =bar作为参数。 总的来说,在shell脚本中使用空格会起到分割参数的作用,有时候可能会造成混淆,请务必多加检查。

其它

  • 系统合法的 shell 均写在 /etc/shells 文件中;
  • 用户默认登陆取得的 shell 记录于 /etc/passwd 的最后一个字段;
  • type 可以用来找到运行命令为何种类型,亦可用于与 which 相同的功能 [type -a];
  • 变量主要有环境变量与自定义变量,或称为全局变量与局部变量
  • 使用 env 与 export 可观察环境变量,其中 export 可以将自定义变量转成环境变量;
  • set 可以观察目前 bash 环境下的所有变量;
  • stty -a
  • $? 亦为变量,是前一个命令运行完毕后的回传值。在 Linux 回传值为 0 代表运行成功;
  • bash 的配置文件主要分为 login shell 与 non-login shell。login shell 主要读取 /etc/profile 与 ~/.bash_profile, non-login shell 则仅读取 ~/.bashrc

在bash中进行比较时,尽量使用双方括号 [[ ]] 而不是单方括号 [ ]这样会降低犯错的几率,尽管这样并不能兼容 sh

type

执行顺序(type -a ls 可以查看到顺序):

  1. 以相对/绝对路径运行命令,例如『 /bin/ls 』或『 ./ls 』;
  2. 由 alias 找到该命令来运行;
  3. 由 bash 内建的 (builtin) 命令来运行;
  4. 透过 $PATH 这个变量的顺序搜寻到的第一个命令来运行。

tldr 可以用来查询命令的常用语法,比man简短些,偏case型

参考文章:

关于ansible远程执行的环境变量问题

Bash和Sh的区别

什么是交互式登录 Shell what-is-interactive-and-login-shell

Shell 默认选项 himBH 的解释

useful-documents-about-shell

linux cp实现强制覆盖

https://wangdoc.com/bash/startup.html

编写一个最小的 64 位 Hello World

计算机教育中缺失的一课

MacOS设置环境变量path/paths的完全总结 很详细

最近由于要获取几台Linux服务器的硬件配置信息,就写了一个获取硬件配置信息的脚本代码,可以获取CPU、内存、硬盘等硬件信息。

使用这个脚本文件,就可以一次性输出代码如下所示:

阅读全文 »

By Long Luo

一、

码字和编程都是我的个人爱好

相比小学学了语文之后就开始码字,我真正接触编程还是要等到上了大学之后。

当然作为一名程序员,编程是我至关重要的技能,毕竟,“Talk is cheap, show me the code.”。

码字,换个高大上的说法,也叫写作。不过对于我来说,还是叫码字比较好,毕竟和码代码都差不多,充其量不过是生活工作上的随手记录而已。巴尔扎克不无自豪地说自己是法国社会的书记员,我们只能说是自己苟活一生的书记员。

写作和编程,其实内在是相通的,都是一个创作的过程,都需要事先在大脑中构建一个骨架。然后根据这个骨架,在其中逐渐添加皮和肉,最后形成一个完整丰满的人体。

不过,相比编程需要的绝对严密的逻辑,写作在逻辑上要求就太宽松了,毕竟程序要是出bug了,造成的损失可就大了。

面对一个问题,程序员需要对问题进行透彻的分析,理清其涉及的所有细节,预测可能发生的所有意外与非意外的情况,列出解决方案的所有步骤,以及对解决方案进行尽量全面的测试。

程序员最开心的莫过于程序按照自己设想的方案运行,所有中间分支及数据均按照预定的思路运行,最后得出符合预期的正确的结果。

二、

写作并不神秘,也不高尚,不过是一种倾诉方式,好比有人找朋友聊天,或自言自语,都是抒发内心感受。而写作,不过是将这个过程纯粹化,加以提炼,倾诉成具体的文字罢了。

许多爱好当中,写作最容易被人误会,会特别让人觉得高大上、矫情或伪文艺

其实主要还是理解写作的人知识水平不一致。比如一个人喜欢跑步,他的目标绝对不是跑进奥运会;一个人喜欢唱歌,他也八成没想唱进中国大剧院。平凡人的爱好之所以可贵,在于怡情养性,并通过特定的爱好结识朋友,形成自己稳定的交际生活圈,寻得共同话题和快乐。

和许多其它的爱好一样,无非是消遣、自娱,说得深沉点,叫自我救赎。它与跳广场舞、看电视剧、种花养狗在给予当事人慰藉和快乐上并无二致。

微博上看到一些小学生写的诗歌作文,笔划稚嫩,语言有趣。如果他不饰雕琢,写出本真,比拿腔拿调者更容易成为写作高手。

当今之世,手机人手一部,天下大小事情心里眼中随时过,发表感慨,写点东西已成为抒发内心感受的重要渠道。

比如,心里憋得慌,又找不到对等的倾诉对象,而又非说不可,觉得只有记下来才对得起生活的每一天,慢慢的就会喜欢上写作。

总的来说,写作能够成文,一是对语言文字的把握能力,二是对生活的感受程度。二者缺一不可。

回想写作的意义,对于普通人,就像跳广场舞一样,纯粹是自娱自乐,并以此为信号,向其他人发出真诚邀请。

时间无垠的荒野,有这么几个人,几位志同道不合的朋友,也是一乐。

阅读全文 »

By Long Luo

一、

好多年以前,经历了一次不大不小的挫折。说不大,因为相对来说,失去的东西并不算很多;说不小,是因为这次经历极大程度地改变了我的人生态度,影响了我今后的生活。

由于种种原因,在这里不方便细说,反正很突然家里出了点意外,然后我又无能为力。常言道,祸不单行。工作,感情,生活等方面烦恼接踵而至,整个工作生活搞的一团糟,反正最后失去了工作,还有其他一些东西。 有那么一段时间,整个人颓废之极,每天负能量缠身,用现在流行的一个词就是:丧。

成为无业游民之后,一下子失去了经济来源,这个当然是不能告诉家人的,毕竟家里事情还挺多,只能报喜不报忧。

这个时候,住的地方开了一家大排档,这下好了,夜夜笙歌,油烟直往上冲。于是呢,加上心情不好,造成晚上整夜整夜睡不着,白天倒是可以睡几个小时,但整天无精打采,一想东西,脑子就头痛。

这样昼夜颠倒的生活持续了半个月之后,某天傍晚,和往常一样,走着走着,我知道我再这样下去就要废了。

于是,制定了改变计划:

第一,换个好点安静的地方住。于是搬到了有个大阳台的房子,阳光很充足,很安静。每天都能看到暖暖的阳光,心情一下子变的好了起来。

第二,每天坚持运动。每周坚持去游泳3次,游够6km。在游泳池那种孤独的环境里,可以一边慢慢的游,一边静静的想一些事情。因为运动导致精疲力尽,晚上睡觉时很容易睡着。通过前面2项努力,把昼夜颠倒的作息习惯纠正了过来。直到现在,游泳都是我最喜欢同时也是坚持了最长时间的运动。

第三,努力找工作。每天看各种试题,认真准备面试,每天都有面试,花了不到2周找到了一份还可以的工作,经济危机解除。于此同时,坚持无论多晚,都写日记,哪怕只写几句话。

不管在任何时候,永远别卖惨,因为永远有比你更惨的人。而且绝对,绝对不会有人帮你,一切问题一定要自己解决,你才配说你是个活着的人。 社交平台上,给别人带来负能量的人,除了成为别人的笑柄,或者留下一个很差的印象,对这个世界是没有正面意义的。

人在失意时也不可以失态,不把脆弱展示给别人

阅读全文 »

  1. 日日 你赚了那么多钱是怎么理财的?能说说你的投资理财方式和各自比例么?你说过没有500万现金不生孩子,你觉得还有多久能实现?

日日 你赚了那么多钱是怎么理财的?能说说你的投资理财方式和各自比例么?你说过没有500万现金不生孩子,你觉得还有多久能实现?

fhjj200312,你好​ 感谢提问​。

说实话,这个问题本来是不准备回答的​ 因为我感觉我没什么可分享的​,毕竟我自己做得不怎么样 但后来一想,​可以把我做得比较差的地方说出来,供大家参考呀 那就正好可以说一下​。

一、我没赚到什么钱​

我从毕业到工作的时间不长,年薪百万之后很快就离职了,因为发自内心不喜欢工作​。

赚的钱也没攒下来,都花了,因为一方面觉得小钱并没有什么好的投资渠道,还不如花掉对抗通胀,另一方面觉得自己还是趁年轻的时候四处出去转转吧,总好过将来身体不行了很多地方去不了,而且照片里也全是自己中年谢顶​的样子,想想蛮悲伤的。

现在付费阅读、分答、小讲、问答,虽然说看起来好像收入渠道不少,但其实扣分成、缴税之后,一个月到手和之前工作时没差太多,一年仍然是百万的样子,并没有实现向 8 位数的质变。

可能会有人觉得这话有点装,但事实上真的是这样的:当你月收入是 10W 时,每个月再多赚 1W,没有什么实质性的变化。 从  1000 到 1W,这是质变,从 10W 到 11W,这没变化。

这也是我觉得所谓「理财」里最重要的第一点:心态。

要永远保持对物质收益的饥渴,才更好形成正向反馈去提升自我。但同时不要被物质欲望吞没,变成了金钱的奴隶。

找到中间合适的「度」,我觉得最好的办法就是:别把钱当钱,哪怕你现在还没钱。

懂的人懂,心穷是永远不会有钱的,因为钱根本不值钱,你自己才值钱。

看重自己,看轻钱,你就会有机会变得越来越值钱。

二、关于理财

我觉得主要是 4 个方面吧:

1、不要赌,不要指望暴富。

这个道理我最早是在 A 股里体会到的,当时我用几万本金赚了几万,但并没有什么快乐的感觉,整天还是提心吊胆。后来利润全赔了,本金也赔了几万,却异常痛苦。

然后我就想起自己上学时学过的 丹尼尔.卡尼曼 的「损失厌恶」理论:人们对于一定金额的损失带来的痛苦,要远大于同等金额的收益带来的快乐。而股市说白了就是赌,这个过程是「零和博弈」,即便你是大概率赢,你最后收获的快乐都要少于痛苦。

更何况,散户在 A 股里,怎么可能是大概率赢呢?估计赢面还没赌场大吧。

后来我去澳门赌了一次,就彻底看明白赌博是什么了:

当时我在澳门威尼斯人,换了 1000 块的筹码,玩理论上赌徒的赢面最大的游戏,21 点,大概有 49%以上的概率可以赢钱,不过整体上肯定还是赔钱。

玩了大概 15 分钟吧,我就从 1000 赢到了将近 10000,当我低头看到自己有这么多筹码时,真心很慌。这来钱太快了,就跟你吸过毒之后,绝对连爱都不想做了。

但输起来也快,很快就只剩下 4000 了,我就离场了。带着这 4000,在接下来的 3 天里,每天 1000 都输完了。

所以赌博是什么?是「娱乐」,是「提醒自己人性有多脆弱」。 ​ 我在《为什么我那么喜欢骂人?》里说过,正因为知道自己在诱惑面前有多脆弱,才要建立起强大的防御措施,让自己尽量远离诱惑。 .

2、把精力放在大方向的判断上

这个就不展开说了,因为逻辑是不变的,但时机是可遇不可求的。 具体可以看一下我之前写的关于买房的文章,《我为什么要买房?》 在小事上,很多人喜欢斤斤计较,甚至乐在其中。比如买个泡面,还要来回比价格。 唉,都已经要吃泡面了,还把时间浪费在这种屁事上…… 把这些心思都省下来,好好学点经济学知识,最起码「供需关系」理顺了,现实生活中到处都是钱。

阅读全文 »
0%