Spring事务简介

2019-11-20 00:00:00 +0000

事务

事务的概念:

事务是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。

事务的四个基本要素(ACID):

  1. 原子性(Atomicity):事务开始后,所有操作要么全部做完,要么全部不做。事务是一个不可分割的整体。
  2. 一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏。从一种一致状态,达到另一种一致状态。A给B转账,A扣了钱,B加了钱。总钱数在事务前后是一致的。
  3. 隔离性(Isolation):不同事务之间的操作,互不干扰。A给B转账100,C给A转账200,这两件事是互不干扰的。
  4. 持久性(Durability):事务完成之后,就对数据库进行了修改,不能取消。

    注:我一开始学习的时候,不明白持久性这一特性,比如转账完成,转账转错了,就不能回滚吗?这时候,事务已经COMMIT,结束了,当然不能回滚。但是能重新提交另外一个事务来“抵消”错误的转账。持久性是针对一个事务的概念。要想撤回这个事务对数据库产生的影响,只能用另一个事务来抵消

事务并发的问题:

  1. 丢失更新:两个事务T1和T2读入同一个数据并修改,T2提交的结果覆盖了T1提交的结果,导致T1的修改被丢失。
  2. 脏读:事务A读取了事务B更新的数据,如果B回滚,那么A读到的数据就是脏数据。事务A的两次读操作分别在事务B的修改之后和回滚之后。
  3. 不可重复读:事务A多次读取同一数据,事务B在A多次读取期间,对数据进行了更改并提交,导致A多次读取到的结果不一致。事务B写操作,在事务A的两个读操作之间完成(侧重于修改和删除,通过行锁就能解决)。
  4. 幻读:事务A将所有人的年龄置空,事务B同时插入一条数据。事务A执行结束,发现还有一条数据年龄不为空(侧重新增,需要锁住表才能解决)。但是Innodb对于幻读有解决方案,对于在默认”可重复读”的隔离级别下,普通查询是“快照读”,是看不到别的事务插入数据的,只有在“当前读”的情况下才会出现幻读。

事务的隔离级别:

用不同的隔离级别会解决不同的事务并发问题:

隔离级别 丢失更新 脏读 不可重复读 幻读
读未提交(read uncommited) 不允许 允许 允许 允许
读已提交(read commited) 不允许 不允许 允许 允许
可重复读(repeatable read) 不允许 不允许 不允许 允许
可串行化(serializable) 不允许 不允许 不允许 不允许

用户通过 设置隔离级别 这个入口,来控制大多数的锁。比较少的用显示调用。通过设置合适的隔离级别,数据库会自动使用合适的锁。

读未提交:通过 排他写锁 来实现。两个事务不可同时写同一条数据。
读已提交:大多数数据库的默认级别就是这个,比如Sql Server,Oracle
可重复读:可以通过“共享读锁”和“排他写锁”实现。这是MYSQL默认的隔离级别。

数据库的锁:

  • 加锁方式:两阶段协议锁(2PL:Two-Phase Locking) 具体含义是相对于“一次性锁协议”而言的,所谓“一次性锁协议”指的是事务开始时,一次性申请所有锁,之后不再申请任何锁,如果某个锁不可用,则申请不成功,事务不执行,在事务尾端,一次性释放所有锁。这样不会产生死锁问题。两阶段锁协议指的是,整个事务分为两个阶段,前一个阶段是加锁,后一个阶段是解锁。在加锁阶段,事务只能加锁,也可以操作数据,但是不能解锁。直到事务释放第一个锁,就进入解锁阶段,这时候事务只能解锁,也可以操作数据,但是不能加锁。这么做,让解锁不必发生在事务尾端,提高了事务并发度。但是可能会造成死锁。
  • 锁的类型:共享锁(S Lock)、排它锁(X Lock)

  • 根据锁的粒度 分为 页级锁 行级锁 和 表级锁;
  • 根据锁的模式 分为 共享锁(S锁)、排他锁(X锁)、意向共享锁(IS锁)、意向排它锁(IX锁)
  • 表级锁:表锁(分S锁、X锁)、MDL锁、意向锁(分S锁、X锁)
  • 行级锁:记录锁(record-lock 分S锁、X锁)、间隙锁(Gap lock)、临键锁(Next-key lock)、插入意向锁

共享锁 会防止 排他锁 来加锁,但是允许其他 共享锁 来加锁。
排他锁 会防止其他 排他锁 和 共享锁 来加锁。

简单记忆:意向锁之间不冲突、排它锁与其他锁都冲突、S锁与 IS锁/S锁 不冲突)

表级锁

  1. MDL锁: 全称metadata lock,又叫元数据锁。不需要显示使用,方为一个表时,会被自动加上。对一个表进行增删改查时,会加上MDL读锁;修改一个表时,会加上MDL写锁。

  2. 表锁: 语法示例

-- 锁定student表
lock tables student read; -- 可以执行,此时其他会话,可以读,会被阻塞;不能写,报错
select * from student where id = 1; -- 可以执行
select * from teacher where id = 1; -- 不能执行,只能读锁定的表
insert into student (id, name) values (10, 'studentName'); -- 不能执行,只能读,不能添删改
unlock tables; -- 可以执行,解锁

lock tables student write; -- 可以执行,此时其他会话,可以读写,会被阻塞
unlock tables; -- 可以执行,解锁
  1. 意向锁: 表锁与行锁冲突,如果加表锁时,要遍历每行是否加了行锁,效率很低,因此首先加意向锁,就简单了。

行级锁:

  1. 记录锁(Record Lock):单行记录的锁,锁加在索引上。
  2. 间隙锁(Gap Lock):范围锁,锁定一个范围,不包含记录本身。RR级别下才会有这个锁。
  3. 临键锁(Next-Key Lock):锁定一个范围,也锁定记录本身。RR级别下才会有这个锁。
  4. 插入意向锁(Insert Intention Lock):特殊的间隙锁,简称II Gap,代表有插入意向,只有insert才会有这个锁。

快照读 与 当前读:

一致性非锁定读(快照读):普通的select,不包含如下sql:

select * from student where id = 1 lock in share mode;
select * from student where id = 1 for update;

一致性锁定读(当前读):除了上述sql之外的,还有insert、update、delete。 RC级别下,快照读是 读取 被锁定行数据 最新已提交的快照。
RR级别下,快照读是 读取 事务开始时的快照。

加锁机制

RC级别:

只有记录锁

RR级别:

原则1:加锁单位都是next-key lock,锁定的是前开后闭的区间 原则2:访问到的对象才会加锁; 优化1:索引上的等值查询,给唯一索引加锁的时候,next-key lock会退化成行锁。 优化2:索引上的等值查询,向右遍历 且 最后一个值不满足等值条件的时候,next-key lock会退化成间隙锁。

Spring的事务

所有的数据库访问技术都有事务处理机制,这些技术提供了API用来开启事务、提交事务来完成数据操作,或发生错误时回滚数据。

Spring的事务机制是用统一的机制来处理不同数据访问技术的事务处理。它提供了一个PlatformTransactionManager接口,不同的数据库访问技术提供不同的实现。

数据访问技术 实现
JDBC DataSourceTransactionManager
JPA JpaTransactionManager
Hibernate HibernateTransactionManager
JDO JdoTransactionManager
分布式事务 JtaTransactionManager

声明式事务

@Transactional注解的方式选择需要使用事务的方法就是声明式事务,这是AOP的另外一个应用。当此方法被调用时,Spring开启一个新的事务,无异常运行结束时,提交这个事务。

这个注解来自于org.springframework.transaction.annotation包,而不是javax.transaction包。

@Transactional的属性说明

属性 含义 默认值
propagation Propagation.REQUIRED,方法A被调用时,如果没有事务则新建一个事务。当方法A调用方法B时,方法B使用和A相同的事务。方法B有异常需要回滚时,整个事务回滚。 Propagation.REQUIRED
Propagation.REQUIRES_NEW,当方法A调用方法B时,无论是否当前有事务都去新建。这样,方法B有异常需要回滚时,A不回滚。
Propagation.NESTED,跟REQUIRES_NEW类似,但是只支持JDBC,不支持JPA和Hibernate。
Propagation.SUPPORTS,方法调用时,有事务就用事务,没有就不用。
Propagation.NOT_SUPPORTED,强制不在事务中执行,若有事务,则在方法调用到结束的阶段,事务都会被挂起。
Propagation.NEVER,有事务抛出异常。
Propagation.MANDATORY,强制在事务中执行,若无事务抛出异常。
isolation Isolation.READ_UNCOMMITTED Isolation.DEFAULT
Isolation.READ_COMMITTED
Isolation.REPEATABLE_READ
Isolation.SERIALIZABLE
Isolation.DEFAULT,使用当前数据库的隔离级别,Mysql默认是REPEATABLE_READ,Oracle和SQLServer默认是READ_COMMITTED。
timeout 过期时间 默认-1,不过期(当前数据库的事务过去时间)
readOnly 是否是只读事务 false
rollBackFor 指定哪些异常可以引起回滚 Throwable的子类
noRollBackFor 指定哪些异常,不引起回滚 Throwable的子类

上述问题,其实是在一个事务内完成的,跟事务之间的执行顺序没关系。 由于对数据库的事务,锁,隔离级别已经忘记了,为了加深理解,做如下探索:

最近遇到遇到一个需求: 在一个请求(http接口请求)中完成下面两个过程 过程1:用户的操作产生了一些数据,需要将这些数据,写入mysql数据库不同的表。 过程2:把用户的这个操作产生的数据(比如过程1产生的自增ID),从数据库中查出来,进行二次加工,用到其他地方。

需求1:过程1执行完毕,再执行过程2,如果过程1执行出错(error),则不执行过程2; 这个需求很简单,只要是按照顺序写的同步代码,问题不大。

设计:过程1产生的数据是一些数据,存储到数据库之后,过程2再从数据库取数。

问题1:过程1的事务能控制,保证用户产生的非结构化数据,全部写入数据库或者全部不写入数据库。 如果加入了过程2,在同一个事务内,能否存入数据库后,直接查到?

问题2:springboot和mysql的默认情况,对是如何处理的?

带着以上问题,我搜索并实践,最终得到如下结果:

Spring简介

2019-11-14 00:00:00 +0000

Spring简介

Spring IOC

IOC全称Inversion of Controll,控制反转。容器负责创建Bean,将功能类的bean注入到需要的Bean中。ApplicationContext就是一个容器接口,AnnotationConfigApplicationContext就是一个容器类,它接受一个配置类(被@Configuration注解的类)来实例化。

public class ContextExample {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
        UserService UserService = context.getBean(UserService.class);

        System.out.println("Hello, world!");
        context.close();
    }
}

Spring提供xml、注解、java配置、groovy配置实现Bean的创建和注入。 注解配置指的是业务Bean配置时使用的注解(@Service@Controller@Component),java配置适用于全局配置(数据库相关,MVC相关配置,主要通过@Configuration实现)。

Spring AOP

AOP全称Aspect Oriented Programming,面向切面编程。Spring支持AspectJ注解式切面编程,todo wujunpeng 使用书中1.3.3的切面实现一下需求。 比如,我们会用注解去修饰一个controller的若干个接口方法,用来做鉴权。 例子代码如下:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthAnnotation {

    /**
     * 接口类型
     * 可以有多个参数,这里只有一个value参数,且有默认值
     *
     * @return String
     */
    String value() default "select";
}
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

@Aspect
@Component
public class AuthAspect {

    private static final Logger LOGGER = LoggerFactory.getLogger(AuthAspect.class);

    /**
     * 用户权限判断.
     *
     * @param pjp ProceedingJoinPoint
     * @param annotation 注解
     * @return Object
     */
    @Around(value = "@annotation(annotation)")
    public Object process(ProceedingJoinPoint pjp, AuthAnnotation annotation) throws Throwable {
        validate(annotation.value());
        return pjp.proceed();
    }

    private void validate(String systemResourceCode) {
        String currentUser = "获取当前用户";
        LOGGER.info("当前登录用户:{}", currentUser);
        boolean canAccess = checkAuth(currentUser, systemResourceCode);
        if (!canAccess) {
            LOGGER.info("当前登录用户:{},无权限", currentUser);
            throw new AuthException(ResponseState.ERROR_STATE.getCode(), "无权限");
        }
    }
}

除了对应的@Around注解,还可以有@Pointcut@Before@After等。

建立切入点,有好几种方式,常用的有executionannotation两种

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class AuthAspect {

    private static final Logger LOGGER = LoggerFactory.getLogger(AuthAspect.class);

    @Pointcut("execution(public * com.jiler..*getGoodsList(..))")
    public void selectPoint() {

    }

    @Pointcut("execution(public * com.jiler..*test(..))")
    public void testPoint() {

    }

    @Pointcut("@annotation(AuthAnnotation)")
    public void annotationPoint() {

    }

    @Before("testPoint()")
    public void before() {
        LOGGER.info("有人查询了");
    }

    @Around("selectPoint()")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
        LOGGER.info("有人查询了1");
        joinPoint.proceed();
        LOGGER.info("有人查询了2");

    }

    @After("annotationPoint()")
    public void after(ProceedingJoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        AuthAnnotation authAnnotation = methodSignature.getMethod().getAnnotation(AuthAnnotation.class);
        String systemType = authAnnotation.value();

        LOGGER.info("有人查询了3");
    }

}

Spring中获取http请求和返回

import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
HttpServletResponse response = attributes.getResponse();

Spring Bean的Scope

  1. Singleton:一个Spring容器只有一个Bean实例,默认配置,全容器共享一个实例。
  2. Prototype:每次调用 新建一个Bean实例。每次调用的意思是:一个被@Scope("prototype")注解修饰的类,每次被用@Autowired注入到不同类,都是一个新的Bean。下有例子
  3. Request:web服务中,每个http request新建一个Bean。
  4. Session:web服务中,每个http session新建一个Bean。
  5. GlobalSession:只在 portal应用 中有用,给每个global http session新建一个Bean。

Scope的使用方式举例

@Service
@Scope("prototype")
public class UserService {

}

对于Prototyp的解释:下面两个类中的两个userService属性,他们的hashCode值不同,是两个Bean,因为限定了prototype。而没有@Scope("prototype")注解修饰的类,则默认是singleton,用@Autowired注入到不同的类中,hashCode值相同,因为是一个Bean。

@Service
public class QueryService {
    @Autowired
    private UserService userService;
}

@Service
public class InsertService {
    @Autowired
    private UserService userService;
}

@Autowired是Spring提供的注解,@Resource是JSR-250提供的注解。JSR是Java Specification Requests的缩写,意思是Java 规范提案 `

其他注解

@PostConstruct, 在构造函数执行完后执行。 @PreDestroy,在Bean销毁之前执行。

Application Event

Bean之间传递消息可以用事件,通过实现ApplicationListener接口的方式,实现监听事件。通过继承ApplicationEvent来定义事件,通过ApplicationContext的publishEvent方法来发送事件。

其他功能点

Spring Aware

Spring管理的Bean对Spring容器的存在是无感知的,如果Bean中要用到Spring容器本身的资源,就要对其有感知,Spring Aware就是用来做这个的。

Spring的多线程

Spring的多线程可以通过任务执行器TaskExecutor来实现,配置时用@EnableAsync开启对异步任务的支持,Bean中用@Async来声明这是一个异步任务。todo wujuneng 可以进一步学习线程池的设置,研究如何设置最大线程数量。

条件注解@Conditional

todo wujunpeng 除了条件注解,还可以学习自定义注解的实现,组合注解的原理等。利用书中的3.6,总结@Enable*相关注解的的原理,尤其是@Import注解来导入配置的三种类型。

Spring MVC

两个概念

  1. MVC:Model(数据模型)、View(视图)、Controller(控制器)
  2. 三层架构:Presentation tier展示层、Application tier应用层、Data tier数据访问层
    • MVC实际上对应的只是三层架构的展示层,也就是说:展示层的实现用的是MVC的思想。Model是用来和View之间做数据交互、传值的,Controller就是MVC的@Controller注解的类。目前前后端分离的纯后端接口开发,是没有view的。Model就是接口提供的json。
    • 三层架构是整个应用的架构,是由Spring框架负责管理的。项目结构中的Service层和DAO层就是三层架构中的应用层和数据访问层。

一些之前用的不太熟悉的Controller注解

@Controller // 1
@RequestMapping("/api/user")
public class UserController {
    @@ResponseBody // 2
    @RequestMapping(value = "/query/{userId}", produces = "application/xml;charset=UTF-8") // 3
    public UserVO getUserInfo(@PathVariable String userId, HttpServletRequest request) { // 4
        String str = "URL:" + request.getRequestURL() + " can access. userId:" + userId; // 5
        System.out.println(str);
        return new UserVO();
    }
}

上述代码,根据注释的位置有以下解释:

  1. 声明是一个Controller,可以接受请求
  2. 声明返回值是放在response体中,而不是返回一个页面。可以和注释1合用,直接把注释1写成@RestController
  3. produces可以定制返回数据的response媒体类型和字符集。”application/json;charset=UTF-8”返回json格式,”application/xml;charset=UTF-8”返回xml格式。还可以通过继承AbstractHttpMessageConverter的方式,自定义媒体类型。json和xml依赖的包如下:
<!-- json依赖的包 -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.3</version>
</dependency>
<!-- xml依赖的包 这个包含了json的依赖,因此如果不支持xml,可以只用上面那个;如果要支持两种,只需要这个就够了-->
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml<artifactId>
    <version>2.9.3</version>
</dependency>
  1. @PathVariable这里的用法是用来接受路径参数,和注释3中的{userId}配合使用。
  2. 这里有一点需要注意,如果请求是:http://localhost:8080/api/user/query/33.5,在Spring MVC的默认配置下,userId参数只能获取到33,无法获取到33.5;假如userId是Integer类型,则此请求错误;假如userId是Double类型,则可以正常获取33.5。要想让String类型的@PathVariable注解获取到正确的数据,则应该通过在配置中重写configurePathMatch的方式来实现;Spring boot则没有这个顾虑,不配置也能正常获取到带“英文句号”的字符串值。

Controller的全局配置

通过@ControllerAdvice这个注解,我们可以定义控制器的全局配置,比如用@ExceptionHandler异常处理;通过@InitBinder定制WebDataBinder来过滤参数;通过@ModelAttribute配置全局的键值对。

服务器端推送技术

早起的解决方案是通过Ajax向服务器轮训,但轮训的频率不好控制,增加了服务器的压力。可行的方案是客户端向服务器端发送请求,服务器端抓住这个请求不放,等有数据更新的时候再返回给客户端。客户端收到消息,再向服务器端发请求,周而复始,这样就解决了上述两个问题。还有一种双向通信技术,用WebSocket实现。

1. 基于SSE的服务器端推送

SSE(Server Send Event 服务端发送事件)技术需要浏览器的支持,目前只有新式浏览器支持,比如chrome和firefox。实现时,服务端在Controller层,对应的接口媒体类型是text/event-stream;客户端在前端界面,需要用到EventSource对象,在前端代码中实现监听来获取服务端推送的消息。

2. Servlet+异步方法

  1. 开启异步
  2. 实现一个返回DeferredResult类型结果的接口
  3. 上述接口从一个Service Bean中获取一个DeferredResult。

Spring Boot 简介

2019-11-14 00:00:00 +0000

Spring boot运行原理

Spring boot用一个总注解@SpringBootApplication开启自动配置,其核心注解是@EnableAutoConfiguration。这个注解利用了@ Import来导入配置。其基本原理是EnableAutoConfigurationImportSelector使用SpringFactoriesLoader.loadFactoryNames()这个方法扫描具有META-INFO/spring.factories文件的包。这个文件里,用名为org.springframework.boot.autoconfigure.EnableAutoConfiguration的配置项声明了包含的自动配置。

autoConfigScreanCapture

上述配置项中的任一一个AutoConfiguration文件,一般都有条件注解。比如上述截图中的AopAutoConfiguration类。todo wujunpeng 好好看看条件注解相关的代码。

todo wujunpeng 根据书中6.5.4自己编写一个自动配置的starter pom。学习maven的打包,发布到仓库。

心情整理

2019-11-06 00:00:00 +0000

现在是2019年10月20日晚上11点,从哈尔滨回来已经两周了。期间断断续续的总是有事,先是请假去枣庄参加大学寝室老大的婚礼,后来是回家。上周休息一天,还需要收拾屋子、洗衣服,真是匆忙。此刻刚从家回来,洗完澡洗完衣服,还不是特别困,整理一下之前的心情。

其实从今年五一之后,就想整理一下心情,只是一直拖着。到6月底,想了很多事儿。主要跟震源告诉我他要“从良”有关系。工作上,7月初做了一个不太明确、比较费时间的需求,又开始了另外一个老项目的重构,糟心的一直做到9月底。将近一个季度,都在做这一件事。三季度的心情,跟二季度又完全不同。十一去了哈尔滨,去了丹东,期间的回忆又是另外一件事,又与之前两种完全不同,就不知道如何整理了。那就一件一件的整理吧。先说两个季度的不同心情,再说回哈尔滨的回忆

二季度还是过得很开心的,最开心的当然是升职加薪啦,这是一种被认可。工作上的事情,零零散散的做了一些不痛不痒的事,磕磕绊绊的去找人问问题。季度总结的时候,忽然觉得什么事儿都没做,跟人扯皮浪费了很多时间。打算痛下决心,洗心革面,第三季度好好努力提高自己的技术。然而第三季度,虽然学会了组内自研框架的使用,后期大部分时间还是浪费在跟人扯皮上。心里安慰自己,踏踏实实做事儿,有问题就积极解决。期间,思考了一些问题,想通了一些之前不明白的事,将之前的一些思考有相关的地方都做了统一,就像数学上的:点动成线,线动成面,面动成体。将知识串成体系,才能综合运用到生活中去。

新年的时候定目标,好好学技术,改变自己。这眼看大半年过去了,还是碌碌无为。其实改变是个痛苦的过程,就比如当初去开部门周会,一个简单的汇报,弄得我心里比较慌乱,甚至有点压抑。别人身上看似简单无比的事,在自己实际做的时候,也会有各种困难。简单是一种举重若轻的优雅,任何事都不能奢望一蹴而就。虽然改变很痛苦,可是不改变将来更痛苦啊。

9月初,来了个新需求,就是7月初那个项目的延续,还是像7月初那样不明确。拖了一星期多点,发现没法整,还因为这个事跟同事“辩论”。我给他“下判断”:你这样问问题,我觉得你就是脱离一线开发了。他也给我“下判断”:你这样说,我总觉得你像某人附体。我一下就明白了自己刚才那句话的问题,我只说了我的判断结果,并没有说我的判断依据。由于当晚有线上问题需要排查,就没接着“吵架”。之前总听人说“要给一个人提建设性意见,不要只做判断”,现在算是明白这句话的意义了。现在刻意会注意,即使没有“建设性”意见,当我不同意对方表达的观点时,一般会首先说出来:我觉得目前这样有问题,但是我没有好的建议,祈求对方的谅解。

在推动问题解决的过程中,发现了一个道理:有些事你是推不动的,不是因为你能力有问题,而是被推的人是否能被推动,是人的问题。而之前做的一些所谓“贡献”,也是跟人有关,那些是可以被推动的人,所以显得你的角色“重要”了而已。这个认知的前提,是承认自己有些事情是办不到的。这跟第一季度时,认为凡事有了俊朋,就可以高枕无忧的想法差别太大了。我认可自己的能力有限,认可自己的平庸,也知道了自己的短板。

9月末,在重构项目上线之后,感觉提高自己技术能力的急迫程度,已经到了火烧眉毛的地步。跟领导简单沟通了几句,他也给了一些建议,不太明白,也不太认可。有一天,下去抽烟碰见祥哥,跟祥哥聊了几句志杰当前的窘境,祥哥倒是很轻松的给了建议:把关注点放到提高自己身上,那些问题自己做了该做的行动就行了,总会被解决的。回去之后翻来覆去的想这句话,最终做了一个决定,把重点放在提高自己技术水平,而非把重点放在别人身上。鉴于当时项目刚上线,还有一堆遗留问题需要跟进,也没太多时间做出行动,思路也需要理清楚。又找领导深入聊了一次,有点“不欢而散”,见解不同,那就“君子求诸几”,做自己想做的事情吧。十一假期,思路还是没空整理,但是经过假期的生活节奏修整,心境平和了很多。从假期结束到现在又快一个月了,最后一个季度就剩俩月了,静下心来慢慢提高自己吧。

很长一段时间在想,我跟力哥的差距在哪里。差距当然是从每个周末的时间利用,慢慢拉大的,毕业三年,将近一半的周末都浪费了,并且现在还时常浪费。还有一半没有浪费,做了一些有意义的事儿,允许自己不去学技术。其实,时间是自己的,利用时间做什么完全是个人选择,一个选择有得到也有损失。当初光哥刚来没多久,周会上就说过:你想要达成一个结果,可以,没问题。但你要想想,为了这个结果,你能付出什么?简单来说,就是交换。比如,用周末学习感兴趣知识的时间,交换不太感兴趣的技术知识。樊登之前解读了一本书《有限与无限的游戏》,里面有句话:相信是知道自己相信,而知道自己相信就是不相信。很喜欢这句话。学习技术知识是有限的游戏,学习自己感兴趣的知识我认为就是无限的游戏。我是既想选择无限游戏,又想在有限游戏中获取认可。其实,无限游戏对于我来说,始终是有些遥远,有些脱离生活。我之前总是觉得生活是琐碎的,想要出世的那种自由,不想要入世的那种束缚,谁不想整天“把酒拈花,细雪煎茶”。但现在我有些认可“生活”,且发现自己的长处无非就是在“入世”上稍微强一点而已,并不具备出世的能力和信念。说白了,人是一切社会关系的总和,我享受在社会关系中被人认可,享受社会关系带给我的正面反馈。倘若真的选择了出世,我不知道自己是否能耐住寂寞,潜心做自己喜欢做的事。之前,有了灵感写文章,考虑要不要发到朋友圈,晒一下自己的“作品”,这不正是活在别人的认可中吗?人生活在一个群体中,如果脱离群体,难免孤单。而我所向往的,为往圣继绝学,学成以后,不还是要用于生活吗。倘若这个世界只有我自己,这些绝学,又如何使用呢?还是我自己目前想学到的绝学,都是用于群体相处、群体感知?让我在山沟里面,衣食无忧的自由研究自己喜欢的事,我可能会走极端,路越来越窄。生死尚且无人知晓,思考成果也必然是没有什么意义的。那实际上我最后追求的,必然还是名利。哎,又回到了原点,我鄙视的名利。当然,比起名利,我更喜欢实际掌控。

我常说自己想要的不是混吃等死,想要的是理解世界、体验生活,可这个想法还是有些空虚,并不实际。没有经济基础,固然没有时间去理解世界,可以如果有一天自己真正财务自由了,去干嘛呢?我当前并没有良好的规划,说到底还是不知道自己想要什么。那么财务自由之前呢?整天苦逼的生活,等待着财务自由吗?肯定不是。最近我发现一件事:我在读书的时候,总是读不下去,因为看到书里的话,总是会想到很多事情。好多事情源于最近工作接触的人和事,这让我觉得,工作给我带来的,也是一种对世界的体验和感知,进而也就觉得即使没有实现财务自由,也能有一部分时间去做喜欢做的事。且这些事,是财务自由之后无法体验到的。也就是说,即使我选择了入世,也可以有一些出世的追求。但是必然要弥补跟力哥之间的差距,以获得更多的入世自由,换取片刻的出世宁静。

《有限与无限的游戏》书里有段话挺好的,我想直接粘贴到这里:

人们往往想保存的是公众形象,一种永远受到遮蔽的自我。永生是一种忘记了我们已经忘记的状态,即忽略了我们自愿参加有限游戏的事实。这个决定本身是游戏性质的,而非严肃的。因此,永生是有限游戏之矛盾的最高级例子,它是一种人们无法生存于其中的生活。

再回哈尔滨

2019-11-05 00:00:00 +0000

今年十一假期去哈尔滨了,早就想去了,看看罗老师,转转之前去过的地方。票是真不好买,推迟一天去的,带着书带着电脑,打算晚上有空看看书写写感受,可是期间一直没空,没有动笔。4号晚上,安静了一个小时,用纸笔写了个开头。再有空继续写的时候,发现手稿忘在公司了,那就先继续写点,之后再拼接到一起。可是题目都忘了,那就叫《再回哈尔滨》吧。等真正再找到手稿,竟然当初起名字也是《再回哈尔滨》,嗯嗯,看来这就是最合适的名字。

自从2014年毕业,已经有5年没来哈市了。再次坐在图书馆里,安安静静的想写一些心得体会,一时竟不知道如何开头。从决定来林大读书吗?好久没有写字了,字很丑,指甲也长了。当前这种长度的指甲,打字尚可,写字就有些难受,有些卡手指。当然,字写的丑,不是因为指甲。

大学想到的第一个人,必然是肖博,肖总写字那是极其漂亮。有句话是:“一个人写字的好看程度,与长相成反比”,可我和肖总就是两个反例,估计说这句话的人,肯定是那些写字丑还自恋的人说的一句托辞。肖总长相眉清目秀又帅气潇洒,写的字典雅娟秀、气势如虹。我就不多说自己了,晒几张张自己写的字吧。

myHandWritting

其实,我最终要的是电子版个人感受,明明可以用手机打字,不打字是因为当时在图书馆,周围都是学生在看书学习。减少使用手机次数,就能减少对学生们的打扰,既然来到图书馆了,也应该为学生们当一个榜样。其实也可以回住的地方,用电脑打字,可是进来图书馆一趟不容易。毕业之后,所有学生证件都不能用了,也就无法进入图书馆。这一点,北理工要比林业大学做的好,理工毕业了有校友卡,激活了就能去图书馆,还能充钱在食堂吃饭。我厚着脸皮,跟学弟借卡,好不容易混进去了,就在楼下考研自习小屋拍了一张照片,就回去吗?还是多待会儿吧,毕竟这辈子能在这里的时间不多。

高考出分数是6月23日,24日便开始报志愿,27日下午5点结束,最终定了东北林业大学作为首个志愿。其实平行志愿还有一个东北农业大学,录取分数是差不多的,为什么把林大排在第一个,也不记得原因了,姑且解释为“缘分”吧。

不知道大家是如何为大学准备行李的,我带了一些语文、物理、化学相关的高中学习资料,虽然最终也没看太多,可确实是真喜欢啊。我姐送我去的大学,好像之前说过:一下车,就被周围满嘴大碴子粥味儿的哈尔滨人包围,跟电视里的口音是一样的。到了学校接待站,跟着校车来到了图书馆附近,找到了信息学院软件工程专业。两位其他专业的学长带我去宿舍,到现在他俩的名字、声音、样貌我都记得,只是没有了联系方式。然而这非我所愿,我们是软件工程专业第一届学生,没有嫡系学长,跟他们联系少,在学校见过不超过5次。他们毕业前,我在准备考研,专门去他们寝室找过两次,见了李凤雨学长,而刘金惩学长在实习。后来我多次打电话约请他们吃饭,他俩都觉得我不用客气,也最终没吃成。再后来人人网都倒闭了,算是彻底失去联系。

放下行李,我姐带我去买生活用品,我在后面跟着走。告诉我:这里是银行,要是没现金了可以在这里取钱,挺简单的,跟着提示信息就能取到钱。我没啥心思听我姐说话,在校园里走着,看着路边草地里还有烟头,觉得很委屈,这他么就是我考的大学吗,强忍着眼泪说:要不是来上学的,我就回去了。想了想,高中复习一年会更难受,还是在大学里忍着吧。我心中的大学,应该是鸟语花香,碧水蓝天的像天安门那样干净,可这地上不仅有垃圾,还有烟头,跟我高中有什么区别?

cryPositon

入学后,发现第一个有烟的人叫曾志优,他竟然带着烟来上学!第二个叫肖博,不仅带着烟,还“公然”吸烟。然而半年后,我的烟头也出现在校园里,也不知道后来入学的学弟,是否被我这样的“渣学长”气哭。如今回学校也吸烟,但是烟头肯定是放到垃圾桶,我深爱着我的母校,维持好干净的校园,就不给学弟学妹们添堵了。

2号下午到哈尔滨,老师让我下车就去他家。我觉得去老师家里吃饭可以,但是不能住,要不然太打扰老师了,并且住的地方已经提前找好了,就之前寝室附近的专家公寓。我放下行李,走过去,到老师家快4点了。老师以为我3点能到,早就做好饭菜等着我了。然后一起边吃饭边聊天,一直吃到晚上8点。喝了点酒,老师让我随意,我的酒量本来就差,虽然控制不醉,但回去后肯定是看不了书了。路上同事给打电话,有个问题需要处理一下,我喝酒喝的手抖了,处理失误好几次,不过问题不大,回去没洗脸刷牙就睡了,这就是在哈尔滨的第一个半天。

studentMarket

3号早上,起床吃完早饭就在校园溜达。由于杯子忘在火车上了,想去超市买个热水杯子,结果没看到带有林大标志的杯子,就放弃了。进超市才发现,之前的教育超市跟学子超市打通了,成了一个超市。特意问了问兼职的学生和年龄大的售货员,他们不清楚,只知道有这一个超市,我最后也没整明白到底是谁吞并了谁,应该是学子超市吞并了教育超市。

firstLine

出来后,围着整个楼转了一圈,书店、眼睛店、仓买中心假期关门,然后沿着专家公寓跟逸夫实验楼中间的路往体育场方向走。记得大二的时候,我还报名校内兼职,工作内容是卖雪糕,工作地点就是篮球场。可是我只卖了一下午,还记错账了,就辞职不干了。

在篮球场的尽头是网球场,当初早上太极协会组织晨练,有认识的人让我也去,由于不是特别熟,为了拉近彼此关系,我就“谢邀”去参观晨练了。然而那天是他们晨练的最后一天,明天就没有了。毕竟是哈尔滨,冬天来的早且持续时间长。之后去篮球场旁边的活动场,就是轮滑社的地盘。

这个轮滑社的白漆字,还有这几排白漆桩,还是强哥在轮滑社的时候给弄的。在轮滑场的尽头,是当初军训的地方,那里的树会在9月中旬的时候有小虫子。军训时,716寝室的那几个同学嫌有虫子,就报告教官,教官问他们是喜欢树底下的虫子,还是喜欢被太阳晒着,他们回答喜欢虫子,哈哈哈哈。军训的时候,除了我大二兼职卖雪糕的冷饮车,还有好多人去批发矿泉水,冰镇后卖给军训的学生。口号是:嘎嘎凉的矿泉水,不凉不要钱。还是716的那几个同学说:那给我来瓶不凉的。

再往后门方向走,路过交通学院。当初大二选修《道路交通安全法》,最后一节课是模拟驾驶,就是操作交通学院的驾驶模型,跟游戏机似的。我们上去玩儿,跟着提示操作,我在“坡起”的时候,做的不太好,但总归没熄火。后来丁晗过来用我的“车”给我演示,那小操作6啊,给他牛逼坏了。告诉我:你这车不好用,你第一次开车,刚才操作还可以。这评价让我高兴了好长一段时间,到现在都还记得。

哈尔滨3号降温,我只穿了衬衫和薄外套,确实有些冷,想回去穿毛衣。路过校医院,再经过寝室楼回住的地方。9A,住了4年的寝室楼,如今肯定是进不去了。当时刚入学,学长帮我拿着一件行李,另外一件比较重,因为里面有语文物理化学学习资料,我不想太麻烦学长。办完手续,说住7楼,我问学长有电梯吗,学长笑了笑带我去走楼梯。走了几层,我实在走不动了,学长就帮我拿那件比较重的行李。我和我二姐空手到了7楼,学长留下电话就走了。4年,从714到309,又到616,毕业离开前,走出寝室,最后看了一眼616门口,当时就知道,这可能是最后一次见这个门口了。现在,想混进去也不容易,因为门口换了闸机,没有学生卡根本过不去。

回到住的地方,穿上毛衣,打算去林场转一圈。林大嘛,肯定是有林子的,并且还挺大的。林大是世界上最大的学校,占地2000多公顷,有两个大型实验林场:帽儿山和凉水。去过帽儿山,因为不算远,没去过凉水实验林场。而校园内,在游泳馆附近的角落有一片林子,那就是校内的林场,里面有各种树。嗯嗯,想起了校歌:小树老树那就是我。。。。。。

出专家公寓直走左转。路过经管学院,门口的小树林里有喷泉,一年开两次,一次是6月底学生毕业,一次9月初新生开学。这片小林子里有小松鼠,我是亲眼见过的,据说是家养的,不是野生的。考研的那年,10月4号路过这里,向右看了一眼,发现树叶都黄了,不是银杏树,叶子也很好看。现在是10月3号,在同样的位置,我想再拍一张照片,可是今年叶子基本上掉光了。找当时的照片,根据树杈的特征,找到了对应的位置。

compare

看了看一教(锦绣楼),假期关闭了,张贴了10月8日暖气试水打压通知。大学第一节课是海波的工科数学分析,也就是高数,就是在一教上课。原路折回来去二教(丹青楼),右侧科学会堂没变,左侧研究生院变成了奥林匹克学院。走进二教大厅,发现电梯换了新的,坐电梯到8楼,去了常去上课的几个教室,也去了当时大一早自习的教室。还记得当初教室墙上的bbs是关于武松的小黄文。不知道为啥有人说武松是山东人,可能因为水泊梁山吧。武松是河北人,确切的说是邢台人,我们家是南宫市,他们家是清河市,哦,对了,王宝强家是南和县。那时候,室友说我说话像王宝强,我就学《天下无贼》里的台词:诶诶诶,恁谁是贼呀。他们说我口音更像王宝强。再以后我给家里打电话:喂,娘,我是朋。他们学我说话:诶,娘,嗯-饿 斯朋。力哥湖南人,我只记得他家的一句话:嗯嘿嘿邓黑嗯黑一个咛。翻译成汉语普通话好像意思是:你说的(那个人)跟我说的(那个人)不是(同)一个人。

下楼去了602,当初结识尹海波的那个教室,我俩经常去那个教室去自习,地处偏僻,没别人,特别安静。下到3楼301阶梯教室附近,记得当初班级集体练习跳舞就是那个地方,《潇洒小姐》,还记得部分歌词:哦~哦哦~哦哦~哦哦,我喜欢~我喜欢你。还在那里排练过小品。再下楼去了1楼,黑咕隆咚的,还有几个学生在拿着电脑看剧。上到2楼大厅,去洗手间洗了洗手,水都是冷水,冰凉冰凉的。最后恋恋不舍的看了看周围,出门,路过图书馆,路过冬天那个滑冰场,想去林场。

studySquare

这么冷的天气,图书馆下面的学习广场竟然还有人“学习”,都是拿着手机在看,可能是在查英语单词吧。冰场那个位置,夏天是草坪,等冬天冷了,就在地面上浇水,冻结实了就是冰场。记得下雨的时候,或者化雪的时候,冰场那边的路特别泥泞,如今用木头铺了30公分高的木桥,隔离开地面。

滑冰是个特别好的运动,我非常喜欢。记得有次期末考试结束,班里的同学不约而同的来滑冰,基本上来了一多半,还是挺热闹的。强哥轮滑玩儿的好,滑冰比轮滑还简单,我们班的同学全部去抓他都抓不住。后来力哥在冰上摔了,下巴正好摔到一个铁扣子上,流血了,还去了趟校医院。

穿过冰场,就是游泳馆,左侧是体育馆,右侧就是林场。林场入口附近,有个花园,不知道有没有蔬菜,也不知道是不是试验田。去花园溜达一圈,接了个电话,老师让我中午去家里吃饭。花园对面是一栋建筑,我比较喜欢林场,就跟丁晗说:这房子多少钱?以后我有钱了想买下来。不记得丁晗怎么回复的了。我看上的房子是逸夫教学楼,现在想想真幼稚。邵逸夫先生去世的那年,我才知道大学里的逸夫楼,都是他捐赠的。我当初竟然想“买”下来,想法真是恶俗。

garden

去林场吧,走到门口,发现贴了个通知,5号前林场清理,大门关着不让进。有个老头特别想进去,我觉得就算是进不去最多就是遗憾一点,也应该遵守规定。就等着安保人员把他打发走,然后拍个照,表明到此一游。可是那个老头不走,于是我劝他:你5号的时候还能来看看,我5号早上就要离开哈尔滨了,我5年没回来,回来了却进不去,我都没说啥,你还是等等吧。结果我一说这话,安保人员心软了,放我俩进去了。

gate

好吧,我也别矫情了,进去吧。为什么我想来林场呢,因为安静,来这里整颗心都能静下来。上学的时候,我每学期都要来几次,一般是学累了,就来放松一下。赶上一次下雨,我没带伞,可我就想去走走。大三上学期,给森工做网站,跟那个实验中心的老师沟通特别费劲,心情烦闷。在图书馆实在学不进去了,那会儿刚下雪不久,还没停雪,我就踩着雪进去玩儿。后来两手冰凉,鞋里也进雪了,脚也冰凉,才回去的。

forestOne

大一上学期就发现了这么个清幽的地方,下学期夏天的时候,还跟寝室的小伙伴一起去,还带高中同学去过。时常想起那句:沉舟侧畔千帆过,病树前头万木春。如今再次来到林场,却不那么轻松惬意,我要快点逛,要不然逛不完自己想去的地方。林场在清理垃圾和枯树,怕出危险,所以不让进林区。只能从大路上走,不能走那些熟悉的小路了。不是怕被罚钱,是应该遵守规定,并且我是偷偷被放进来的,万一真有枯树枝砸到我头上,人家也不好交代。

forestTwo

林场里的小路还是特别熟悉,我知道在里面怎么走能看到最好的景致。

出林场了,还是觉得挺冷的,就往回走,路过图书馆想问问能不能进去,不让进,还建议我找学生借卡,哈哈哈。围着图书馆走了一圈,发现有校友好像是带着孩子回校,因为他们也在专家公寓住,早上一起下楼。当初刚到哈尔滨不久,一个山西的同学我俩关系不错,我俩去上自习的路上跟我说:俊朋,你不觉得咱们被发配了吗?我还真没想过这个,想想也是,但我是来求学的,无所谓吧。再后来,电视剧《甄嬛传》里提到甄嬛的父亲被发配到宁古塔,距离现在的哈尔滨不远,甄嬛说:“宁古塔苦寒无比,臣妾父母一把年纪,怎能受得了这样的苦楚。”其实我感觉没啥,刚来哈尔滨的时候,我二爷说30年前的哈尔滨确实冷,现在好多了。最近听樊登讲《宋徽宗》那本书,里面提到当初宋徽宗被抓到金国,也是距离哈尔滨不远。觉得最无语的是,金国的那些王爷们,隔三差五送宋徽宗一些鸡零狗碎的东西,就是为了得到宋徽宗写谢表的瘦金体书法。哎,如今回到这个当时感觉自己被“发配”的地方,甚是思念,苦于终要离别,后会何期啊?走回专家公寓附近,发现一家咖啡店。找了半天入口,发现咖啡店就在专家公寓的前台旁边,可以就坐的位置视野也不错,可以看到正在装修的运动场,跟楼上我住的房间视野是一样的。咖啡口味一般,不太好喝。

backLine

回去把秋裤也穿上,暖和多了,再出来逛。还有好多地方没去呢,再经过校医院去后门,左走是熟悉的小餐馆:刘岩盖好,传奇排骨米饭,喜来乐烤肉拌饭,松新美食。你看,我团的覆盖面多么广啊,都是美团外卖的牌子。唯有常相聚没了,当初毕业后没多久就换了一家店。说实话,常相聚的饭不咋好吃,只是店主人特别客气,我就真的跟同学常去那里相聚吃饭。后门向右转,走几步是学校另外一个门,附近就是奥奇网吧。我对奥奇网吧印象不太好,当初大一,那时候没有自己的电脑,好多学生都去网吧。据说奥奇不如盛捷网吧条件好,我没去过奥奇。而一个大家叫他太君的同学经常去,可是他那时候还不够18周岁,经常借身份证去上网,过年前借我的身份证去上网,我告诉他我下午坐火车回家,需要他中午给我,结果中午给他打电话他也不接,给我急的,后来再也不借给他了。

backDoor

后门右转50米再左转,就是林大出版社,当初教材都是从这里买。一般是学委统计人数,然后带着同学去买书,那次竟然还数错了,钱给了,少拿一本,我就再也不带那个学生去买书了。对面是收废品的几家店,有一学期我们攒饮料瓶,卖了好几十块钱。

netBar

后门右转直走就是刚才说的盛捷网吧,我不会打游戏,平常不去网吧,他们都觉得我是好学生。大一考试快结束的时候,实在不想复习,就跟同学去了网吧。其他同学看见我也去了网吧,都跟看见什么不得了的事一样,还说带我去的那个同学真牛逼,连吴俊朋都能给拉进网吧。那时候2块钱一小时,充100送100,而我的这200块钱,用到毕业也没用完,还给我同学去包宿几次。还有一件不想提的事,好多人都知道,但他们不知道原因,更不知道去年11月份那事几乎又翻版复现。我处理方式跟之前相同,但是出于完全不同的心境,比之前成熟多了,当然最终的结果也是一样的。

正在拍照,老师打电话来,让我去家里吃饭。本来想去哈尔滨的亲戚家,可是电话没打通,就又去了老师家里。吃饭稍晚,又喝酒了,完事让老师休息一会儿,晚上我们跟丁晗一起吃饭,期间我去了一趟亲戚家,跟老师又继续喝。喝到11点,回住的地方,又是躺下就睡,别说看书了,又是脸都没洗。

4号早上,起床吃完饭去食堂转了一圈。变化不大,只有二楼开着。溜达一圈,看了看第一次吃麻辣烫的地方。那时候没见过麻辣烫,以为是店家写错字了那饭可能叫麻辣汤,见多了才知道没写错字。麻辣烫除了有点不喜欢吃的面条状食物,就是一大碗菜,又咸又辣。那天同学让我尝尝,我还特意买了馒头,味道还不错。之后连续好长一段时间都是买馒头和麻辣烫一起吃,丁晗对我的吃法表示很无语,也理解我喜欢吃面食的想法。

canteen

出了食堂,还特别想去林大35栋附近看看,那是当初收快递的一个位置。忽然想起来,当初考研在当当买资料,货到付款,差1毛钱。快递员说先欠着吧,我想给他1块钱,他不要,并说就一毛钱,有了零钱的时候,可以来给他。毕业前,想起来欠人家钱的时候没空,有空的时候想不起来,就这样一直欠人家一毛钱。我还记得那个叔叔的样貌,只是5-6年过去了,他可能早就不送快递了。那一会儿一定过去看看他在不在吧。

路过教育超市总店,挺冷的,但是超市没有热饮。毕业那时候刚开的一个食堂,现在十一放假了,旁边有个超市叫大东琳超市,其实我们是东北林业大学,我觉得叫大东林可能更合适,虽然有点俗,或者叫东琳超市也好。其实我挺喜欢“琳”这个字,解释不清楚什么原因,觉得这才像个名字。旁边两家咖啡店,大老远的我就看见了,想去买一杯尝尝,走近了发现假期也没开门。之后去找35栋,还是老样子。想起来毕业前经常去附近打印资料,在周围转了一圈。好像还有家奶茶店,也没发现,不知道是不是倒闭了,名字倒是很“诱惑”,叫《学姐的奶茶店》。

想起大一的时候,附近有个二手书店,不记得名字了,找了一圈,找到了。对,就是这家店,叫《省省吧》,其实里面的书并不便宜,二手书按照斤买进来,按照定价打折卖出去,都是学校发的教材。进去溜达一圈,格局没变,瞎看看。竟然一眼就看到了曼昆的书《经济学原理》,据说是哈弗大学经济学专业的教材,还是很有名的。我买了上下册,还没来得及看。那么作为二手书,这本书这么牛逼,卖书的人,或者是学霸,经济学原理都学会了,觉得太简单就卖了;或者是个笨蛋,不知道这本书的价值。小店员问我找什么书,我说要新概念英语书,我知道他会告诉我没有,因为我们学校教材是视听说英语,不用新概念教材,他们是二手书店,当然没有,哈哈哈。虽然是暴利行业,但总归把书去卖给合适的人,没有浪费,也算是大功一件。

coffeeBookBar

出了书店又一家咖啡店,还挺花哨(看起来挺花俏-语出光晕Cortana),挺冷的,进去看看吧。趁着给我做咖啡的时候,看了看,风格有点朋克,每个小房间布景都不同,灯光稍暗,适合学校的小情侣来约会,不知道现在的学生有多少零花钱,有多少人能负担每天喝一两杯咖啡。也适合听歌休息,不过我肯定是没空休息了。其实我也想有自己的店,当然也就是想想而已,问了问装修,店员是林大学生兼职,她也不懂,说是老板装修的。店里没有顾客,她就在看书,是一本语言学教程,嗯嗯,这学生还不错,知道兼职的时候有空就学习。

我要咖啡肯定是打包,没空坐下来休息。我发现只要你不说不放糖,就默认给你加糖,这家店的口味跟专家公寓那边都是一样的难喝。我常在公司楼下买咖啡,都熟了,我去了不用说话,就知道我要啥,知道不给我放糖,去不熟悉的地方,就是别扭。其实,半年前我是不喜欢喝咖啡的,那时候偶尔买一两杯,后来发现另外两个同事也买咖啡,咖啡店买二赠一。所以每天一起买,就习惯了咖啡。出了咖啡店,就没去处了,都逛完了,就差图书馆,想了想不让进就算了,也不太好意思麻烦老师要学生卡,毕业5年了,认识的学弟们也都毕业了,算了吧。去看看当当的快递员来了没有,如果是那个叔叔,就去还钱吧。走过去发现没人,跟老师发个信息说要去江边,不用等吃饭,打车就去了江边。

其实我还想去江北,去看看巴洛克风格建筑,据说非常有名,去过一次,还说啥保护单位,房顶都没了。黑龙江大学附近的大书店也没空去了,夜市估计也没空去了,就中央大街溜达一圈吧。下车走几步就是防洪纪念塔,拍了照片就去江边。松花江穿过哈尔滨,据说市民饮水就是从松花江取。当初刚到哈尔滨,他们简称去“江边”,后来我才知道是松花江,而对于松花江的记忆是从“我滴家在东北~松花江上啊~那里有漫山遍野~大豆高粱~”,哈哈哈。

其实对于东北的名胜地域分布不是特别清楚,上大学的时候,有同学去祖国边境,还有去五大连池的,其实我最想去的还是长白山天池。现在地图上看了看五大连池的位置,顺着五大连池的水流发现竟然是和松花江通着的:经过石龙河到讷谟尔河,再到嫩江汇入松花江,流经哈尔滨经过佳木斯到了祖国边境,中俄边境的那条河应该就叫“黑龙江”。而长白山天池,我本来以为跟五大连池是一回事,搜索天池的时候忽然看到了二道白河这个名字。这可是《盗墓笔记》里云顶天宫附近的地名。仔细看看地图,发现了头道白河、三道白河还有四道白河。只有二道白河连着二道松花江,之后和头道松花江在吉林白山水库合并汇入松花江,再到哈尔滨。因为明天要去丹东,还跟同学发消息:今天松花江,明天鸭绿江。在地图上看了看,顺着中朝边境的鸭绿江,应该是在朝鲜境内差点就进入天池了,但是看了高德和谷歌地图,确实在地面上没有从天池下来的水能流到鸭绿江,至于地下河,那我就不得而知了。地理不太熟悉,不多扯了。

river

江边的风跟我预想的一样,清冽的让人舒爽。毕竟十一了,还是有点冷,不过这里的风,我这辈子也吹不了几次,好好享受吧。江风,江枫渔火对愁眠,特别想找个船,夜里点上油灯,带着酒菜和好朋友江上对饮,谈笑过往。然而我才30岁,哪来的那么多过往啊。对面就是太阳岛,真是看不够。其实哈尔滨市民觉得可能没啥好看的,对我来说就是稀缺,所以格外珍惜。看不够那就录像,回去慢慢看吧。

lucia

忽然想自拍,跟松花江一起拍照,跟哈尔滨的蓝天白云一起拍照。之前我还觉得喜欢自拍的人都是自恋,那就自恋一回吧,嘿嘿,真香。拍完了就去中央大街逛,看看熟悉的地方,逛一下熟悉的商店和书店。一路走下去,看见了露西亚西餐厅。其实我更喜欢华美西餐厅这个名字,是抗日神剧里的一个餐厅。露西亚西餐厅还有马迭尔西餐厅记忆比较深,当初考研结束,少爷和王超打算让我请他们吃饭,算是庆祝我闭关结束。后来一有空我就想约他们去,可是总有一个人没空,最终也没去成。今天当然要进去看看了,还是要一杯咖啡吧。我以为店员会是俄罗斯风格打扮,可好像店员就是老板,就是便装,毕竟是个中国人开的小店。咖啡不能打包,我就坐下来了,也休息一下。她给后厨说明我要的咖啡,然后就坐来听歌,非常“通俗易懂”的《殇雪》。你好歹放一个优雅的歌啊,我可是在俄罗斯风格的西餐厅。布置稍微有点品味,咖啡杯外侧有渍,不知道是没有洗干净还是洒了没擦。实在无聊就看看菜单,前面是餐厅历史介绍。后面是菜单,有俄式菜品,东西不便宜,感觉也就这样吧。陆续进来两个顾客,两人应该是合作关系,见面握手。然后其中一个广东口音的帅哥给另外一个人拍照,我也是猜的广东口音,毕竟我不知道粤语。拍照时他说:芽,易,三。我觉得就是一二三的意思,后来我问广东同事,我猜对了。这俩哥们挺逗的,和店里的布置照相,好像在留念。

sophia

出了露西亚就继续溜达,去了那家买格子衫的店,去了中央书店,别的地方去不去的都不重要了。太冷,没吃马迭尔冰棍。之后走到中央大街的尽头,往回走一点,沿着西十四道街去索菲亚教堂。之前不太清楚怎么走,临时看电子地图,现在算是熟悉了。路过一个小学,叫哈尔滨市尚志小学校,很奇怪。哈尔滨的中小学都带着个“校”字,比如某某中学,在哈尔滨是某某中学校,幸亏林大不叫东北林业大学校,多难听啊,哈哈哈哈哈。又路过一个古老的建筑,不知道是啥,也是像江北巴洛克建筑一样没了房顶。再往前有个购物商场就是哈一百,好像又叫新一百,我不知道有啥区别。路边一层对外的窗口,一堆卖零食的。我第一次吃臭豆腐就是在这里,他们告诉我好吃,非要让我尝尝,好吃你大爷,臭的不能忍,感觉他们在吃大便一样,还花钱吃。开玩笑,尊重不同的口味儿,我还喜欢吃肥肠喜欢吃香菜呢。再走就到了著名的索菲亚教堂,据说里面是铁道博物馆,有一些历史照片。我没进去过,少爷常说:这地方吧,进去后悔一时,不进去后悔一辈子。我没进去过,一点也不后悔,在外面转转就行了。旁边一家砂锅店,看着很好吃的样子,跟江北的砂锅店装修风格挺像的。虽然我还没吃饭,但是也不想吃。旁边挨着就是曼哈顿商场,挺喜欢这个名字,进去过,里面卖装修材料比较多,我去里面买过壁纸。搬寝室后,墙面看着挺脏的,就想买壁纸遮挡一下。

继续走,发现了“人和春天”,是那种地下通道的小商场,卖零零碎碎的各种东西,还有卖衣服的店。别的城市都有夜市啥的,哈尔滨也有,可能是因为时区问题,天黑得早,夜市关门也很早。再就是可能因为天气冷,像这种小商场不是露天,而是在地下。当然,好处就是不阻碍交通。当初战争年代,哈尔滨有好多防空洞,估计这些地下小商场也可能是当时的一些防空洞。但是据说19世纪20年代那时候,哈尔滨的最繁华的主城区主要是在江北,那里是富人聚集区,松花江以南的城区是后来才发展起来的。2010年刚入学那时候,小叔叔就说哈尔滨在建设地铁。后来经过好长时间还在建地铁,我就想如果毕业前能用上地铁就不错,最后在2013年年末的时候就通车了,我还坐地铁去考研的考点附近。哈尔滨有很多类似于人和春天这种地下商场,我觉得建地铁时,把这些防空洞啊、小商场啊什么的,掏干净就成了,哈哈哈哈。开个玩笑而已,实际上哪有那么简单啊,我心里对于建筑这一部分还是有很多敬畏的。

我最想说的还是江北,考研结束,跟着少爷和刘泽去江北吃好吃的,几乎逛遍了江北的城区。不仅仅是雪糕放在路边的纸盒子里卖,连带鱼啥的都是放在路边。这里有两个问题,冬天天气冷,雪糕自然不会融化,可是冬天有人吃吗?第二个问题,鱼都放在路边卖,万一没注意,被野猫叼走了怎么办?对于第一个问题,之前应该是说过,哈尔滨天气干燥,室内室外温差大,在屋里确实挺暖和的,比我家都暖和,暖暖和和的吃雪糕这是最爽不过的事了。“你在南方的艳阳里大雪纷飞,我在北方的寒夜里四季如春”,这句歌词后半句就是对于哈尔滨的真实写照,冬天室内老舒服了。第二个问题,张雪峰的考研指南大电影解读过,那猫不可能叼走,因为没有用,太冷了它咬不动,哈哈哈哈哈。估计久而久之,哈尔滨的猫会教育孩子:儿啊,别随便叼食物回来,整不好被打一顿也就算了,最后还吃不了嘴里,多难受啊,还是等着那些铲屎官们给咱们热热再吃吧。



show

再往里走就是透笼市场了,其实我一开始听错了,以为叫脱龙市场,见到这个楼的名字才知道,就像当初在成都,少陵路我听成了少林路。往前走果然看见了期待已久的透笼市场,不过记忆中这个建筑的位置还要往前走。那再往前走看看吧,哎呦卧槽,前面出现了一个秀龙市场,太他么秀了,我以为是透笼市场的偏旁部首被风吹日晒的坏掉了,其实不是,拼音也是秀龙市场。好吧,往回走去透笼市场看看,其实这就是个批发市场,各种零零碎碎的东西都有。记得当初最喜欢那个可以跟着音乐的节奏变化小灯颜色的一件短袖,但是如今真不知道买什么,当初在这里买了手机链,非常幼稚,手机链比手机都要重。看到一家卖结婚用品的店,正好吕大小姐要结婚了,给她带个礼物?不知道买啥,人家应该都准备好了,哈尔滨有啥呢,俄国风格的镜子?不行,有撒泡尿照照自己的意思。一对非常喜庆的杯子?不行,虽然有祝福大小姐一辈子幸福的意思,但是也有悲剧(杯具)的意思。大小姐的婚礼,不能有丝毫的寓意偏差。正好还没有准备红包呢,嗯嗯,那就买个红包吧,红包上写着一个亿。哈哈哈,挺好的,就这个了。其实我知道惠玲大小姐的脾气秉性,知道她会开玩笑跟我说:哎呀,礼物不重要,给我折成现金就行啦。


从透笼市场出来,就打算打车回去,去乐松广场看看。之前上学,偶尔心情不好的时候,也会自己去家乐福购物,对那边也挺熟悉的。由于到处堵车,走回中央大街的尽头看交通拥堵状况打车。司机问我去哪里,我说去林大,正好上一个乘客也是去林大,也住在专家公寓,他的房卡忘在了出租车上,问我能不能给他送回去。嗯嗯,哈尔滨人就是好,我给滴滴打电话联系上一个乘客,告诉他丢的卡我给送回前台了,感谢司机。对于哈尔滨的好感,又增加十几倍。

哎,回到住处,还是想去图书馆,怎么办呢?看了看通讯录,找张恒?那是我在学生工作网站的站长学弟,可是他只比我小一届,估计认识的人也都毕业了。哦,对了,刚毕业那年,罗老师带一个学生去北京参加竞赛,当时加了微信,找他试试吧。学弟回复的特别快,说帮忙问问。正好罗老师打电话来,让我去吃晚饭。1分钟后,回复我可以,通过qq联系上了在校学弟,李毅。跟学弟说明情况,约定8点左右去找他。本来打算去乐松,来回怎么也要1小时,可我得去吃饭啊。跟罗老师吃完饭,我又待了好久才回去,聊了很多事儿。我尊敬的罗老师,此次一别,何时再能见面啊。

从老师家出来,我就去了图书馆,联系好学弟,就偷偷混进了图书馆。其实也没啥好看的,当时每天都在负一层准备考研,偶尔去楼上找力哥聊天、找肖总抽烟。那个小屋门牌号永远记得,217,还有206的火女安妮。首先去楼下自习的小屋拍照,本来想多拍点,怕打扰学生学习,毕竟如果我在准备考试,是不希望看到这个一个怪学长到处拍照的。之后发现没有可拍的了,就回到2楼大厅,确实没意思。死皮赖脸的借卡进来了,总不能刚进来就走吧,还是趁着有空,写总结吧。随便找了个位置,用手机不太好,又去1楼学子超市买了纸笔。接近9点半,图书馆开始催促学生回去,对面的学生走了之后,拍了一张大厅的照片,旁边的小柜子真是怀念。后来学弟也打算回去了,跟学弟聊了一路,一直到9A门口,又聊到快要锁门,我就往回走了。10点多,还是想再买一杯那个朋克风格店的咖啡,心里也知道99%是关门了,随便溜达一圈吧,到了那家店果然关门了。慢慢走回专家公寓,好好洗漱,之后休息。

last

第二天,起床、吃饭、打车到哈尔滨西站,坐火车去丹东,给老师发信息说自己走了。到了西站,还有一些时间才发车。不着急,吹吹哈尔滨的风,看看哈尔滨的景,下次再来真不知道什么时候了。西站还是很漂亮的,想拍个照,当初在北京火车站的时候,经常发现有人给火车站拍照,对此不屑一顾,如今真香啊。拍了照就准备安检进站了,路上看了看书,看了看窗外的风景,睡了一会儿就到了丹东。下车后大小姐带我们去吃好吃的,下午去举办婚礼的酒店打气球,看到了鸭绿江。真的是昨天松花江,今天鸭绿江,古代的“千里江陵一日还”,如今高铁就可以做到了。

weeding

江对面的朝鲜思密达盖的小房子是黑顶白墙,像电影《山村老尸》无人居住的鬼屋。晚上聚餐,之后接力哥,又去了鸭绿江的断桥。同学说晚上风景好,白天人多更没啥看的。溜达回去,跟力哥好久不见了,叙旧到凌晨2点多,实在困得不行就睡了。第二天,早早的起床去酒店堵门,其实去了也没啥事,又跟力哥去酒店后面的鸭绿江看了看。接亲的阶段还是挺有意思,只是这次不当伴郎真是轻松,这才是参加婚礼啊,要不然多累啊。参加过很多婚礼,其实都那样,中秋节小白婚礼的时候,我们也是轻轻松松的看着别人的故事。大小姐婚礼是在室外,一看就是花了很多心思的,但觉得也没啥特别难忘的环节,直到祖宇哥哥读自己准备的婚礼致辞,还有写给惠玲大小姐的一些心里话。我感情丰富,容易被感动,但是婚礼看多了也就那样,不过听祖宇哥哥准备的话,是极其感动的。唯有真挚情感最能打动人,惠玲固然完美,可也不是极其完美(我不敢说不完美),可是祖宇是了解她的:知道她有哪些特别优秀的特点,还知道她有哪些比较优秀的点(我可不敢说有缺点)。了解一个人,然后还爱着她,这才是真的爱。觉得惠玲他俩还是很幸福的。

再后来,祖宇还为惠玲准备了一支舞。说实在的,那个舞从我的角度来看,跳的还真不咋地。之前婚礼致辞,祖宇也说了:要不就算了,自己也不太懂唱歌和跳舞,容易让人笑话,可是大家都是来参加并见证他们婚礼的,不会笑话他的。我没有笑话他,确实跳舞不咋地,但是他敢当着他父母的面,不嫌弃不在乎别人的“嘲笑”,真情实意的给自己的妻子跳一支舞,再加上之前说的那些了解惠玲、还继续爱着她的话,确实把我给感动坏了,我和力哥在台下都被感动哭了。祝福两位新人,祝福我的好朋友,平平安安,健康快乐的过一生。无论是健康还是亚健康,无论是富有还有更加富有,都希望你们永远像今天这样相亲相爱。之后便去婚宴吃饭,准备酒席的服务员说朝鲜语,不知道是不是嫁到中国的朝鲜人。其实不论政府关系如何,中朝人民友好。

再后来,就准备回北京了,到北京后打车那段的故事,在另外一篇文章里会讲的。第二天送走力哥,回到住的地方洗洗衣服,吃点饭,睡一觉,第二天就要上班了。至此,十一假期完美收官。