Java 学习日志 1

  • 在 IDEA 中调试 spring mvc,Tomcat 总是提示找不到资源。从 stackoverflow 上查到,将 JDK 从 1.8 改成 1.7,问题解决。
  • 点 Form 提交按钮,对应的接收函数没有被断住在 IDEA 里设置部署路径不是根目录,而 jsp 中跳转路径的部署目录是根目录。
  • 点 Form 提交按钮,总是返回请求非法。因为 Form 表单中某个类型与接收函数参数的类型不一致。添加 log4j 打印 spring 异常后,显示无法从 java.util.Date 自动转换成 java.sql.Date。把代码中 import java.sql.Date 都换成 import java.util.Date 后,问题解决。这是 IDEA 自动添加导入导致的问题。成

MAC 系统初体验

使用的是 macbook air 11,没有 retina 屏,少了很多乐趣,只能体验一下系统。不想花太多时间深度使用,只安装了一些常用软件,做了简单体验。

屏幕是 16:9 的,不是 retina 屏幕,完全没有优势。高度少了一大截,还不如手头正在用的 Thinkpad X200 16:10 屏幕。

输入法不习惯,虽然有 MAC 版本的 QQ 五笔,但设置跟 WIN 上完全不一样。没有分号快捷输入;默认经常是中文输入状态;无法通过 shift 选择二三字。

  • 清歌输入法支持分号模式。

Alfred 没有传说中那么神奇,大概因为没有深度发掘它的功能吧。

Docker 放在屏幕下方太占空间,拖到左边,并且设置成自动隐藏。原来在 WIN 下经常安装软件模拟 Docker,到了 MAC 下,反而不想用了。

键盘不习惯,布局跟美式 101 相差太多。键盘手感也不好。没有小红点不习惯。触控板绝对是亮点。用了一段时间,熟悉触控操作和快捷键后,主要操作没有什么问题,基本上手。

百度云盘跟 WIN 下完全不一样,同步方式比较像 WIN 下的快盘。使用倒没有什么问题。

MAC 版本的迅雷是个渣渣,同一个网络,竟然比 WIN 下版本下载慢很多。

Emacs 一如既往地好用。自带 emacs 是 22.1 版本,太老了。从 emacsformacosx.com 下载安装 25.0 版本,用 git 下载 spacemacs 配置,很快就能正常使用。字体要要调整,英文用 Manaco,中文用 STHeiti,渲染效果一般,不比 WIN 下强多少,跟 Ubuntu 比较相似。

  • 修改命令行下 emacs 默认版本:
alias emacs="/Applications/Emacs.app/Contents/MacOS/Emacs"
  • 安装 seil,设置 capslock 键为 constrol
  • 交换 option 和 command 键
(setq mac-command-modifier 'meta)
(setq mac-option-modifier 'super)
  • 设置字体
(setq fj/en-font "Monaco"
      fj/en-font-size 13
      fj/cn-font "STHeiti-15")

VPN 的安装折腾了一会,主要有两点要注意:

  • 网络配置是有优点级的,需要把 VPN 连接放到最前面。
  • MTU 大小设置成 1280.

重量和大小基本满意,再大再重就没什么意思了,最好能代替 ipad 的日常使用。这个本子如果边框窄点,屏幕大点,加上触控功能,就完美多了。CPU 正常使用没有问题,估计编译大程序会比较吃力。

设计模式一句话理解

  • 工厂方法与抽象工厂有何区别?

    工厂方法创建一个个对象,抽象工厂创建一套套对象
    
  • Visitor 模式与 Iterator 模式有何区别?

    visitor 是被动访问,一般提供遍历接口和回调函数,如 foreach 函数;iterator 模式是主动访问,可访问每个元素。
    
  • 模板方法与策略模式有何区别?

    模板方法适用于流程固定,算法区别不大的场景;策略模式适用于算法区别较大的场景。
    
  • 常用到的模式有哪些?
    • Factroy Method
    • ProtoType
    • Singleton
    • Template Method
    • Observer
    • Visitor
    • Iterator

把 c++当成脚本语言使用

工作中,经常需要批量解析文本。涉及到功能点主要包括:目录递归、文件读写、字符串解析。功能点不多,但很少有人用 C++做这方面的工作,一般认为脚本语言更适合。因为脚本语法表达更简洁,标准库更全面。C++是门严肃的语言,要写冗长的声明,标准库也不全,需要调用平台 API 完成工作,太繁琐。

这几年,C++标准频繁更新,情况不一样了。C++14 增加了 filesystem 标准库,语法也做了简化,几乎可以用来做为脚本语言。

  • 语法简化了,支持 auto 关键字,不用再写很长的 iterator 声明。
  • 目录递归功能,原来只能使用平台相关的 API,现在可以使用 filesystem 库。PS:在 Windows 平台上,MSVC 从 2015 版本开始支持。cygwin g++ 5.3 未支持。mingw g++才更新到 4.9.2 版本,也不支持。
#include <filesystem>
using namespace experimental::filesystem;

void IteratorDir(const path &p)
{
    for (const auto &iter : directory_iterator(p))
    {
        if (is_directory(iter.status()))
        {
            IteratorDir(iter.path());
        }
        else if (is_regular_file(iter.status()))
        {
            if (iter.path().extension() == ".vcproj")
            {
                // cout << iter.path().filename() << endl;
                ParseVcproj(iter.path());
            }
            else if (iter.path().extension() == ".sln")
            {
                SaveSlnContent(iter.path());
            }
        }
    }
}
  • 文件读写一直还是比较方便的
void SaveSlnContent(const path &p)
{
    ifstream file(p.string().c_str());
    ostringstream ss;
    ss << file.rdbuf();
    m_SlnContent = ss.str();
}
  • 字符串解析功能,各种语言差异不大
void ParseSln()
{
    ofstream out("R:\\a.txt");
    out << "digraph G {" << endl
        << "\trankdir = BT;" << endl
        << endl;

    size_t seg = 0;
    while ((seg = m_SlnContent.find("vcproj\", \"", seg)) != string::npos)
    {
        string curProjId = m_SlnContent.substr(seg + 10, 38);
        string curProjName = m_projectIdMap[curProjId];

        size_t seg2 = m_SlnContent.find("EndProject\n", seg);
        string tmp = m_SlnContent.substr(seg + 48, seg2 - seg - 48);
        seg = seg2;

        size_t pos = 0;
        while ((pos = tmp.find("= {", pos)) != string::npos)
        {
            string dependProjId = tmp.substr(pos + 2, 38);
            string dependProjName = m_projectIdMap[dependProjId];
            if (dependProjName.size() && curProjName.size())
                out << "\t\"" << curProjName << "\" -> \"" << dependProjName
                    << "\"" << endl;
            pos += 38;
        }
    }
    out << "}" << endl;
}
  • 编译问题。Sublime Text 3 里,自带 C++编译支持,但仅支持 g++,不支持 MSVC。添加以下配置后,可以支持 msvc 编译。写完代码后,按 C-S-b 调出编译菜单,选择 msvc Run ,直接编译运行,下方弹出窗口显示运行结果。以后再编译运行时,按 C-b 就可以了,不需要再次选择。
{
    "cmd": ["vcvars32.bat", "&", "cl", "/EHsc", "${file}", "1>&2"],
    "file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
    "working_dir": "${file_path}",
    "selector": "source.c, source.cpp, source.c++",
    // By default cl is not in your PATH, so add it to your path (preferably)
    // or uncomment "path" and check that it has correct value
    // "path": "C:\\Windows\\System32;C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin",
    // this also will set path for vcvars32.bat
    "shell": true, // Without this sublime has hard times to parse "&" in out command line

    "variants":
    [
        {
            "name": "Run",
            "cmd": ["vcvars32.bat", "&", "cl", "/EHsc", "${file}", "&", "${file_path}/${file_base_name}.exe"]
        }
    ]
}

总结,filesystem 经常用到的函数如下:

#include <filesystem>
using namespace experimental::filesystem;
path();
path.string();
for (const auto &iter : diretory_iterator(path)) {
    iter.path();
    iter.status();
}

在 spacemacs 中使用 graphviz

之前用 graphviz 画过几次流程图,感觉不错,只需要关注节点描述和节点关系, dot 程序自动搞掂图的大小和排放,很省脑。这次切换 spacemacs 后,原来的 graphviz 配置已经没有了,我也不想重新配置。

但是,spacemacs 真的很智能,你不想用都不行。我只是打算用 emacs 编辑 dot 文件,刚打开文件,spacemacs 立即提示:“我这里有现成的 graphviz layer 支持,你要不要安装?”这种好事哪能拒绝呢,当然点 YES 了。

接着,就看见窗口切换着,spacemacs 拍啦拍啦自动搞掂了一切。完事后,看看它干了什么:

  • 修改 .spacemacs 文件,加上 graphviz layer 支持。
  • 下载 graphviz layer 相关支持 package。
  • 修改 .spacemacs 文件,把 package 添加到 elpa 列表里。

我的 dot 文件瞬间语法高亮显示了。再试试 graphviz 的快捷键好用不,点两下逗号,立即生成了预览图,真不错。还有更 NB 的,输入 ,t , 打开 graphviz-live-reload 功能,每次 C-x C-s 文件存盘后,预览图自动更新。