Hegel2011的博客

读书 - 工作 - 生活 - 笔记

装机i5-6500

许久没有装机了,入了如下的配置:

  • intel i5-6500 1150元,
  • 散热器采融B48 99元,
  • 技嘉 B150M-D3H 599元,
  • 芝奇 DDR4 2400 395元,
    合计2243元

1.货物来源

某宝买散片和散热器,某东买入主板和内存。原因在于散片确实比盒装的便宜很多,差价在300的样子,而京东等电商基本不做散片的生意。主板的价格相对统一的多,内存差价也不大,所以就还是京东买了。

2.cpu插座保护盖及安装注意事项

自己diy还是有一定的风险。而且自己装cpu还是第一次,一开始搞主板的cpu保护插座还费了点事情。好在有惊无险。这个保护盖一定不要先揭走,而是要等到安装完cpu后自己会弹出来。主要是保护插座上的针脚。iU现在本身只有垫片了,针脚全在主板上,所以主板容易弄坏。

3.散热器的安装,包括硅胶涂在cpu上

cpu安装好,压好架子后就可以涂硅胶装散热器了。硅胶可以用九点法后直接压上去,也可以涂在中间,然后用散热器磨开来。我用的是后面这个法子。一般都应该行得通,反正只是为了保证散热器和cpu的接触面积。 分散和散热器采融48采用的是搭扣,其实就是靠线扣的弹力自己箍上去的。

4.UEFI与GPT和win10

技嘉这个新板子默认就是UEFI的界面,比bios启动快一些吧。win10装好,10秒内可以启动成功。2年前买的ssd终于找到了相得益彰的平台。

5.网卡驱动,win10默认也没有

即使装了win10,网卡驱动也要另外装的,默认并不提供。

6.vpn拨号

如果拨号成功还不行,可以尝试一下禁用IPv6.

附最近12年的配过的自己的机器,应该还漏了一台

2004年4月买的,花了38xx

AMD barton 2500+
KST 512M ddr400
日立硬盘 7k250 120g/2m
华硕 a7v600-x 主板
迪兰横进 9600pro 显卡

2011年买入,花了2615元

AMD Athlon II X4 640 699元,
4GB KST DDR1333,300元
技嘉 MA770T-UD3P 主板,
华硕EAH5750显卡,
安钛克BP430plus电源 300元,
机箱,
无硬盘

老婆的:

2010年11月购入,合计花了4249.00元

Intel 英特尔 奔腾双核 E6500 (2.93GHz/LGA775/2M/1066MHz/45纳米)盒装 519元,
威刚 DDR3 1333 2G 内存 178元,
华硕 P5P54TD主板 569元,
华硕 ENGT40/512M 显卡 539元,
希捷 1TB硬盘 408元,
酷冷至尊 破坏者塔式机箱 229元,
ACBEL 康舒 IP-430台式机电源(额定功率380w/ATX2.3版) 电源 229元,
Samsung 三星 2494LW 23.6英寸宽屏液晶显示器 1285元,
微软多媒体键盘 79元

Spring Boot in Action

  • Auto-Config
  • 用starter处理依赖
  • CLI 命令行处理启动等
  • Actuator 监控组件 , 通过web或者shell
1
2
3
spring version 
spring --version
spring shell # windows下打开可以自动补全的功能

工程初始化

1
2
spring init -dweb,jpa,security --build gradle -p jar -x //-x表示生成到当前目录
spring init -dweb,jpa,security --build gradle -p war myapp //表示生成工程到myapp目录
1
2
3
4
5
6
7
@SpringBootApplication
public class DemoddfApplication {

public static void main(String[] args) {
SpringApplication.run(DemoddfApplication.class, args);
}
}

@SpringBootApplication 起到了过去3个标注的作用,打开了自动配置和自动扫描。如果有新的配置要求,@Configuration用在其他配置类中进行配置的扩充。而主class可以不必修改

用starter定义可实现更高度的抽象,也不必给出每个组件的版本号。通过mvn dependency:tree可查看实际的包依赖关系. starter就是普通的maven或gradle依赖,所以可以exclude也可以指定更直接的版本。

自动配置定制化的举例

安全是最好的需要自己自行设置的例子,not one–size-fits-all。 这是yml方式

1
2
3
4
5
6
server:
port: 8443
ssl:
key-store: file:///path/to/mykeys.jks
key-store-password: letmein
key-password: letmein

配置数据源

1
2
3
4
5
6
spring:
datasource:
url: jdbc:mysql://localhost/readinglist
username: dbuser
password: dbpass
driver-class-name: com.mysql.jdbc.Driver

属性信息的几种来源

  1. Command-line arguments
  2. JNDI attributes from java:comp/env
  3. JVM system properties
  4. Operating system environment variables
  5. Randomly generated values for properties prefixed with random.* (referenced when setting other properties, such as `${random.long})
  6. An application.properties or application.yml file outside of the application
  7. An application.properties or application.yml file packaged inside of the application
  8. Property sources specified by @PropertySource
  9. Default properties

在application.properties中指定spring.profiles.active的值后,boot就会读取application-{active}.properties的值

自动化测试

@WebIntegrationTest Test class有这个标注就会让spring启动一个测试的tomcat或jetty进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(
classes=ReadingListApplication.class)
@WebIntegrationTest

public class SimpleWebTest {
@Test(expected=HttpClientErrorException.class)
public void pageNotFound() {
try {
RestTemplate rest = new RestTemplate();
rest.getForObject(
"http://localhost:8080/bogusPage", String.class);
fail("Should result in HTTP 404");
} catch (HttpClientErrorException e) {
assertEquals(HttpStatus.NOT_FOUND, e.getStatusCode());
throw e;
}
}
}

代入参数 @WebIntegrationTest(value={"server.port=0"})@WebIntegrationTest("server.port=0")

selenium的用ie模拟访问自己的服务很有意思,值得制作一个。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
            FirefoxDriver browser = new FirefoxDriver();
browser.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
String baseUrl = "http://www.baidu.com/";
browser.get(baseUrl);
String currentUrl = browser.getCurrentUrl();
assertEquals(baseUrl +"/readingList", currentUrl);

assertEquals("You have no books in your book list",
             browser.findElementByTagName("div").getText());

browser.findElementByName("title").sendKeys("BOOK TITLE");
browser.findElementByName("author").sendKeys("BOOK AUTHOR");
browser.findElementByName("isbn").sendKeys("1234567890");
browser.findElementByName("description").sendKeys("DESCRIPTION");
browser.findElementByTagName("form").submit();

WebElement dl =
    browser.findElementByCssSelector("dt.bookHeadline");
assertEquals("BOOK TITLE by BOOK AUTHOR (ISBN: 1234567890)",
             dl.getText());
WebElement dt =
    browser.findElementByCssSelector("dd.bookDescription");
assertEquals("DESCRIPTION", dt.getText());

《Selenium WebDriver in Practice》但还没完成,可能要到2016年10月份才能出版

/beans 列出创建的全部bean
/autoconfig 列出自动配置生效和未生效的内容
/env 列出设置的环境
/configprops 列出所有的参数
/metrics 列出访问的指标
/trace 给出近100个http请求的处理信息
/dump 给出所有线程的情况
/health 表明是否UP
/info 列出属性文件中info.开头的信息,但似乎有乱码

actuator的remote shell 默认启动一个端口在2000,每次启动时会生成一个密码,可以用ssh访问

1
2
3
ssh user@localhost -p 2000
Password authentication
Password:

自己定义metrics:

actuator有CounterService服务,可以用于增加值。

1
2
3
4
5
public interface CounterService {
void increment(String metricName);
void decrement(String metricName);
void reset(String metricName);
}

GaugeService是记录值

1
2
3
public interface GaugeService {
void submit(String metricName, double value);
}

自定义Health

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Component
public class AmazonHealth implements HealthIndicator {
@Override
public Health health() {
try {
RestTemplate rest = new RestTemplate();
rest.getForObject("http://www.amazon.com", String.class);
return Health.up().build();
} catch (Exception e) {
return Health.down().build();
}
}
}

//还可以加入更多的细节内容,使用withDetail

return Health.down().withDetail("reason", e.getMessage()).build();

上述endPoint的保护需采用所有spring暴露的链接一致的方式

management.context-path=/mgmt,其中的management.context-path可以给spring actuator定义全部的前缀

这样可便于统一控制 .antMatchers("/mgmt/**").access("hasRole('ADMIN')")

部署时调整production环境变量

@Profile("production")

export SPRING_PROFILES_ACTIVE=production

最简单的是export active的环境变量为production

spring的db migrate,不算很实用吧

Spring Boot includes auto-configuration support for two popular database migration libraries:
■ Flyway (http://flywaydb.org) — 直接采用SQL编写ddl
■ Liquibase (www.liquibase.org) — 使用yaml json等

附录

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>

开发工具具备自动重启的功能,但下面这些静态资源默认是exclude的: /META-INF/resources, /resources, /static, / public, /templates.

关于冠道

本田的冠道近日宣传的比较多,虽然价格还没最后公布,但车还是造成了足够的话题。 因为这车既是本田目前的旗舰suv,也是首次使用了2.0T发动机的中国产本田车型。

其实这个车挺像昂科威的,只是更高级也更大些。CRV相对这类车,最大的优势还是在于尺寸、操控,尤其是尺寸相对冠道的优势更大。毕竟CRV这种4米6以下的长度,1米8左右的宽度,在城市开还是挺舒服的,再搭配一个装载能力很大的尾箱,是各方面都很均衡的车型。 而冠道,对拥挤的中国城市来讲,它的尺寸还是大了些。而尺寸大的车,操控必然是要打折扣的。 而从空间看,尾箱部分因为溜背造型,并不如crv的尾箱实惠。 油耗、可靠性方面可能也是crv更有优势些。 当然,同昂科威一样,冠道内饰的高级感、拥有税金更省的涡轮、拥有at变速箱、静音等方面都是对crv碾压了。

不过问我会不会买冠道?只要这个车不是比crv便宜,那肯定还是crv,毕竟crv开着更舒服。

Nginx 通过Lua输出response Body

Nginx默认是不只支持$request_body 而不支持response的body输出的。这个设定是合理的,因为大量的html响应或者静态文件的内容输出将使得整个日志毫无意义。 然而,response body输出对api的请求来讲,则很多时候、尤其是在调试的时候是很有必要的。取代了抓包的作用,且简单直观许多。 搜寻之下,发现使用lua的话,可以达到此目的。

  1. 下载并安装lua语言的安装包
1
2
3
4
 wget http://luajit.org/download/LuaJIT-2.0.3.tar.gz
tar -zxvf LuaJIT-2.0.3.tar.gz
cd LuaJIT-2.0.3.tar.gz
make && make install

注意,可能你的服务器的wget会实际下载一个html到本地导致tar解压失败,此时可以用浏览器下载完毕后再次上传到服务器上。

  1. 下载并解压ngx_devel_kit套件
1
2
wget https://github.com/simpl/ngx_devel_kit/archive/v0.2.19.tar.gz
tar v0.2.19
  1. 下载并解压lua-nginx-module模块
1
2
wget https://github.com/chaoslawful/lua-nginx-module/archive/v0.9.6.tar.gz
tar v0.9.6
  1. 下载并解压nginx后,使用下面的命令重新编译nginx
1
2
3
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_flv_module --with-http_gzip_static_module --with-pcre --sbin-path=/usr/sbin/nginx --add-module=/root/lua-nginx-module-0.9.6 --add-module=/root/ngx_devel_kit-0.2.19 
make && make install
cp /usr/sbin/nginx /usr/local/nginx/sbin/

最后,在nginx的conf文件中的server{}上下文里加入下面代码

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
log_format  main_with_response  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"'
                      'request: "$request_body"' 'response: $resp_body';

server {

...
   lua_need_request_body on;
    set $resp_body "";
    body_filter_by_lua '
        local resp_body = string.sub(ngx.arg[1], 1, 1000)
        ngx.ctx.buffered = (ngx.ctx.buffered or "") .. resp_body
        if ngx.arg[2] then
             ngx.var.resp_body = ngx.ctx.buffered
        end
    ';

       location /xxxx {
            root   html;
            access_log  logs/access.log  main_with_response;
            proxy_pass http://192.168.203.198:8080;
        }

}

为避免response溢出整个日志,可选择在特定的location中使用输出response body。

车险

时间很快,CRV买了快要一年了,又到了车险续保的日子。过去的11个月还算基本顺利,车子没遇到大的损害, 只有一些小的刮蹭。本来想用划痕险统一处理一下,但又担心来年保费政策大变化,所以还是没用。

因为没有出险,所以商业险给打了七折,下面是对比

  • 车损:现2109.58,原3514.15
  • 三责:现1176, 原1689.48
  • 盗抢:现取消, 原977.02
  • 划痕:现339.5, 原486.35
  • 各项不计免赔:现543.77,原1049.04

总体折扣尤其是车损的折扣比7折还是要低不少的。那么问题来了,明明是7折,怎么反而会更低呢?难道政府控制的 保险公司是活雷锋?

非也。差的多的主要是车损,而对比两份保单,可以发现原先的保额是249441元,然而新的是224475元,这就 差了近10%。经过一番搜索,发现其实保额的计算是这么来的:车厂的出厂原价+10%的购置税。所以从天籁到crv, 甚至是跑在中国马路上的其他私家车,金额都会稍大。CRV今年比去年车损保额降了10%,应该是总理新政的功劳。

与去年不同,盗抢险这次取消掉了,毕竟生活在上海,发生车辆被盗又不被找回的概率是很低很低的,还是不买了吧。

StringHttpMessageConverter的头属性

使用Spring MVC中的@ResponseBody或者@RestController产生的json消息格式会产生一个很大的响应头。 其主要内容就是Accept-Charset会罗列几乎所有的charset变量,从utf到gbk再到iso等等。而这很大程度上是无谓的开销。

要解决可以在xml的配置中设置

1
2
3
4
5
6
7
8
9
  <mvc:annotation-driven>
    <mvc:message-converters register-defaults="true">
      <!-- 将StringHttpMessageConverter的默认编码设为UTF-8 -->
      <bean class="org.springframework.http.converter.StringHttpMessageConverter">
        <constructor-arg value="UTF-8" />
        <property name="writeAcceptCharset" value="false" />
      </bean>
    </mvc:message-converters>
  </mvc:annotation-driven>

注意给StringHttpMessageConverter的属性writeAcceptCharset设置成false

—- update on 2016.10.17

RestTemplate作为客户端发送请求时也有类似的问题,会带出一串过长的Charset。解决办法如下:

1
2
3
4
5
6
7
8
9
static RestTemplate restTemplate = new RestTemplate();
  static {
    List<HttpMessageConverter<?>> converts = restTemplate.getMessageConverters();
    for (HttpMessageConverter<?> convert : converts) {
      if (convert.getClass() == StringHttpMessageConverter.class) {
        ((StringHttpMessageConverter) convert).setWriteAcceptCharset(false);
      }
    }
  }

获得converts,然后对String的Convert进行设置

换证流程

地点: 杨高中路1500号, 浦东交警支队
时间: 2016年5月10日下午3点半

三点多从公司出发,20分钟左右抵达。到门口发现说停车场不对外接待,其实也不是不对外,只是确实很容易就满了然后就不放了。 建议停蓝天路等社会停车场。于是转到蓝天路,停车费10块。收费的师傅还问我来的挺晚啊,不过这个点到人应该少了。 看来附近也是肥缺。

3点半到大厅,看上去人也不是很多。

  1. 先问左手边的老爷苏领了表格,他看了看我的身份证和驾照,确定是在90天之内后, 表格给我并告诉我拍照、复印、体检都在左面一排。

  2. 复印件已经有了,只要正面就可以,最后在窗口工作人员会剪下正面并贴在申报的材料上。

  3. 牌照25元,需要提供身份证和驾照,付完钱当场拍,还是会让你尽量衣服整理好并摆好姿势。

  4. 等照片的过程中,可以去体检的地方填表,提交要交60元。填完个人信息后,一般照片也就打印好了, 体检工作人员会帮忙剪下来并贴到刚填的体检表上。今天碰到的医生挺认真负责,视力检查每个眼睛要看3个标识, 色盲色弱也要看很多图形,而且她那个色盲检查本还是挺混淆的,属于比较吃力的一类。而前面其他两个人则被她要求重测和找眼镜废了 不少时间。至于握力、蹲下等动作倒是没有测试。最后给的发票是杨思医院出具的,看来也是合作医院。

  5. 弄好之后,拿上照片、体检表、登记表就可以再找老爷叔去了,会给一个排队的号,到手的时候提示前面还有9人。 当天有4个换证窗口开放,所以等待的时间并不多。

  6. 在窗口递上材料,然后就是等工作人员干活,就没我什么事情了。她输入各种信息结束后,给一张牌子,告知在旁边的窗口凭牌子领证。 问了下大概要多少时间,直接答复一刻钟左右。

  7. 实际上很快,去趟厕所的时间然后再等了1分钟,就叫到号了。付10元,给你驾照的正页、副页、封皮。

整个过程还是很快的,40分钟左右基本就办完了。

查了下现行的规定,如果在过去的6年内有过一年满12分的记录,那这次的有效期 就只有6年而不是10年了。我的新证件的有效期是10年,正页上开始和结束结束的月、日和过去的一样,副页上会写上从当天开始生效。 所以对记分周期没有任何影响。

总体而言,还是挺愉快的一次和政府打交道的体验。

Iptables 的一些解释

物理机部署的年代里,组网通常是分层而建。例如所有的服务器都接到二层交换机组成内网,随后交换机上联三层交换机及防火墙。彼时,防火墙通常由专用 的设备承担。所有的路由规则、端口开放等也均在网络设备上进行配置。对于服务器而言,通常最简单的做法就是关闭iptables,在内部实现完全互通,而把防护任务交给专用设备。

然而转到云部署的年代,专用的网络设备大都收归云所有,此时虽然还有内网的概念,但已经模糊,从而要求把防火墙建在主机上。做到几个域的隔离。

iptables的配法有命令行和配置文件,此处以配置文件/etc/sysconfig/iptables为例,说明一些概念。

对于安全类的防护,集中在*filter上,nat 等是管映射和路由的

1
2
3
4
*filter
:INPUT ACCEPT [1194191:146127015]
:FORWARD ACCEPT [159938:8304428]
:OUTPUT ACCEPT [1044829:126818322]

上面这段代码表示对三种包的处理状态及已处理的包和字节数量。 INPUT就是输入的包,ACCEPT表示默认都可以进入,如果设置成DROP就是都废弃输入包了。如果主要以开白名单的方式,INPUT后可以接DROP。中括号里面的数字,冒号前是包数量统计,冒号后是字节数统计。
FORWARD表示转发,OUTPUT表示输出访问,通常这两个可以设置成ACCEPT即表示允许。
这3个表示的是基础的规则,类似默认路由,优先级是最低的。

1
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

随后就是很重要的这一段。这段的含义表示对连接状态是ESTABLISHED, RELATED的链接全部放行。iptables中的链接共有4种,established表示链接已建立,related的含义是由已建立的链接产生的链接,此外还有newinvalid两种链接状态, 其实这段话的含义也可以理解成invalid链接放弃,new状态之外的连接则允许通过。 这个指示关键的原因在于,比如本机设置了禁止外网访问本机的各个端口,同时本机作为客户端访问了另一个外网服务,那么外网服务的响应信息允许被接收。否则,就会面临只有一个单工链路的情况。

1
2
3
4
5
6
7
8
9
10
-A INPUT -d 192.168.1.202 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -d 192.168.1.202 -p tcp -m tcp --dport 8080 -j ACCEPT
-A INPUT -d 192.168.1.202 -p tcp -m tcp --dport 8081 -j ACCEPT
-A INPUT -d 192.168.1.202 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -d 192.168.1.202 -p tcp -m tcp --dport 21 -j ACCEPT
-A INPUT -d 192.168.1.202 -p tcp -m tcp --dport 20 -j ACCEPT
-A INPUT -d 192.168.1.202 -s 10.3.1.0/24 -j ACCEPT
-A INPUT -d 192.168.1.202 -j DROP

-A INPUT -d 10.10.10.222 -j DROP

这个机器有两块网卡,分别有两个地址192.168.1.20210.10.10.222,对于后者,只允许从这个口子发出包以及收入已建立连接的包(通过上面的 -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT)。
而对于前一个地址,则打开了http相关的80 8080 8081端口,开放了ssh和ftp端口,并对来自10.3.1.0网段的全部IP开放访问权限。

对于包的动作有ACCEPT DROP 和REJECT,后两个都表示拒绝,只是REJECT是明确拒绝,DROP只是沉默不答。

对于iptables,简单的用用,安全防护做到这样也就够了。

两次苏州游

阳春三月,正是江南好风景,3月初和4月中旬分别去了苏州的阳澄湖和金鸡湖。出行的方式选择了自驾。 两次自驾类似的地方很多,都是从家里出发,经内环走武宁路到G2京沪高速,高速上开50KM左右后从苏州工业园区出口下去,再开10公里左右即可抵达目的地。车程基本在一个半小时到两小时之间。

比较让人费解的是,明明都是度假区,但整个新区的正式名字却叫苏州工业园区,可能早年间这个区就叫这个名字,产业也以传统工业为主, 近来度假旅游经济兴起,才搞出了度假村,建了很多四五星级的酒店吧。

4月金鸡湖

入驻的是苏州凯宾斯基酒店,一路很顺,只开了1小时40分钟不到就到了酒店。车直接停在酒店大堂门口。 由于是周日12点之前到的,正直退房高峰且房间都在打扫中,check in需要等待,于是带孩子去后面的后花园转了一下。

花园在酒店的南面,所对的湖面是独墅湖。 image image

花园转了一圈后去酒店的中餐厅吃饭,吃完后继续去办理check in,这回终于有房了。 前台等待期间拿了一粒糖给小家伙吃。最近懂事很多,反问我这个不用付(钱)就能吃啦? 我只能简单地告诉他这个东西是免费的,可以拿了就吃。

入住房间对应的就是金鸡湖了。其实整个凯宾斯基就是位于南北两个湖中间。 从房间正中望出去可以看见金鸡湖大致的样子。 image

摩天轮在右面,左面则是苏州的新地标东方之门,俗称秋裤。

从酒店出发,开七八公里就可以到这个摩天轮公园。 image

要去需要趁早,5点就不让客人进去了。整个新区的停车倒还很友好,大部分停车场是不要钱的。 商场下面的停车场也有3小时免费的政策。整个新区开车的节奏很慢,红绿灯起步比上海还要慢一倍。

夜景也还不错,关键是这个地方的人口密度确实比上海低很多了,后来百科一下,整个新区其实只有100万人,其中本地户籍的40万,还有60万外来人口。所以感觉密度低是正常的。 image

这个金融中心还有诚品书店,不过似乎都是光看不买的,很可能会步百思买的后尘。 而比较后悔的是没去逛逛附近的Flexa专卖。 image image

然后在苏浙汇吃完饭就开车回酒店了。正好赶上当地人在酒店办婚礼,二楼大堂门前的车位客满, 只能停到一楼的车库里面去了。

第二天酒店用完早餐,和小家伙在后面的草坪打了会儿童羽毛球,随后就出发去拙政园了。

原本也没打算去苏州市中心,老婆提了一下我又研究了一下路线,发现其实新区离市中心很近, 所以决定开过去了还是。顺道去看了看东方之门。 image 其实对比名字,倒也不算刮三。 iamge 整个广场其实还行。秋裤其实也还在建设中,并未完工。可惜湖面的喷泉没开。

拙政园倒是不错的去处,尤其是这个游览时间特别好。门票也是够贵的了,现在是旺季,单人就要90元了。淡季稍便宜20。

拙政园的南北其实都有较大的停车场,但南面的路不好走,最后我还是停到北面去了。两三个小时下来最后付了12块停车费。这也是此次苏州之行唯一付停车费的地方。 从北停车场过去有450米的距离,走走其实也还可以。

对园林的欣赏一方面是因为年纪渐长,另一方面也是因为如今的园林确实修补的比小时候要号许多。 image image image image image

逛完拙政园,在旁边马路的朱鸿兴吃完中饭,就开车返程了。一路还算顺利,就上内环高架堵了一下,最后用了 2个小时回到家中。

3月阳澄湖

阳澄湖去的是苏州阳澄湖澜廷度假酒店,在阳澄湖半岛上,半岛上还有一个重元寺。

image 酒店是泰式风格的,没有金鸡湖的酒店大,整个半岛其实还在大规模地建设中。 工地比较多。但封闭性好,更适合在岛上骑自行车游玩。

停车场的充电桩很多。 image 苏州度假区的酒店此类东西其实都不少。不过最喜欢的还是直接走坡道上去停在大堂门口。 image image

第二天就去了重元寺。跟灵隐寺的布局有很多类似的地方,但依水而建是其一大特色,环境非常不错,寺庙也很整洁。 image image

在庙里吃完一碗素面之后,就开车回家了。

三四月确实是出行的好时节,这个季节去周边玩玩还是挺心旷神怡的。

Maven的Dependency和打包

使用Maven一大便捷之处就是管理依赖变得方便了,另一个好处就是打包更加灵活。

以前全部用jar包加入到工程里面,如果实际部署的时候需要剔除个别包,就需要自己手工在war包里删除。 而实际上需要这么干的情况还是有一些的,比如一些公共的包像ojdbc.jar,都已经放到容器里面了,如果war包里再有,则容易引发冲突。 删除公共的包,另一个好处就是可以给war包瘦身,这样在传递、部署时都会更加便捷。

6种范围依赖:

  • compile: 默认的选项,会在export的时候加入全部依赖
  • provided: 由其他环境提供,如容器或jdk,但在编译和测试的时候还是会导入,对于容器公共的包,可以使用这个选项
  • runtime
  • test
  • system: 和provided很类似,但需要自己指名jar所处的位置,类似于以前直接把jar包加到工程里面的做法
  • import

个人用的比较多的还是compile和provided两种。

Included file 'twitter_sharing.html' not found in _includes directory