From 5b2f7279ea925fdedab8aac6ac57fedb86251b9f Mon Sep 17 00:00:00 2001 From: lniwn Date: Fri, 26 Jul 2019 14:50:20 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A6=96=E6=AC=A1=E4=B8=8A=E4=BC=A0=EF=BC=8C?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E4=B8=BB=E9=A2=98https://github.com/Track3/h?= =?UTF-8?q?ermit.git?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitmodules | 3 + archetypes/default.md | 6 + config.toml | 89 +++ content/about.md | 17 + content/posts/CMake学习笔记.md | 142 +++++ .../posts/CMake项目添加预编译头.md | 77 +++ content/posts/Cef-Bug-Fix-List.md | 42 ++ .../posts/Python模块timezone学习笔记.md | 67 ++ content/posts/SQLAlchemy学习笔记.md | 79 +++ content/posts/Vim快捷键备忘录.md | 135 +++++ content/posts/Win32汇编学习.md | 572 ++++++++++++++++++ content/posts/office2016激活步骤.md | 169 ++++++ content/posts/一句话Windows.md | 67 ++ ...Hexo博客Next主题添加Schnack评论.md | 43 ++ ...客Next主题添加Wildfire评论系统.md | 101 ++++ content/posts/为Ubuntu启用Swap分区.md | 190 ++++++ .../posts/加快Visual-Studio编译速度.md | 58 ++ ...取当前模块的HMODULE-HINSTANCE值.md | 93 +++ content/posts/在vps上搭建hexo.md | 46 ++ content/posts/注释大全.md | 362 +++++++++++ content/posts/流畅的Python学习笔记.md | 478 +++++++++++++++ content/posts/解决chromium警告C4819.md | 36 ++ ...s_3d041b08546090308b2e5d3a88088713.content | 2 + ...e.js_3d041b08546090308b2e5d3a88088713.json | 1 + ...s_d11fe7b62c27961c87ecd0f2490357b9.content | 9 + ...n.js_d11fe7b62c27961c87ecd0f2490357b9.json | 1 + ...s_39fa5fe97be74115670eace810202c56.content | 1 + ...scss_39fa5fe97be74115670eace810202c56.json | 1 + ...s_c16d144eee185fbddd582cd5e25a4fae.content | 5 + ...scss_c16d144eee185fbddd582cd5e25a4fae.json | 1 + static/android-chrome-192x192.png | Bin 0 -> 40542 bytes static/android-chrome-384x384.png | Bin 0 -> 5397 bytes static/android-chrome-512x512.png | Bin 0 -> 233822 bytes static/apple-touch-icon.png | Bin 0 -> 36180 bytes static/browserconfig.xml | 9 + static/favicon-16x16.png | Bin 0 -> 1496 bytes static/favicon-32x32.png | Bin 0 -> 2558 bytes static/favicon.ico | Bin 0 -> 15086 bytes static/mstile-150x150.png | Bin 0 -> 21693 bytes static/safari-pinned-tab.svg | 1 + static/site.webmanifest | 19 + themes/hermit | 1 + 42 files changed, 2923 insertions(+) create mode 100644 .gitmodules create mode 100644 archetypes/default.md create mode 100644 config.toml create mode 100644 content/about.md create mode 100644 content/posts/CMake学习笔记.md create mode 100644 content/posts/CMake项目添加预编译头.md create mode 100644 content/posts/Cef-Bug-Fix-List.md create mode 100644 content/posts/Python模块timezone学习笔记.md create mode 100644 content/posts/SQLAlchemy学习笔记.md create mode 100644 content/posts/Vim快捷键备忘录.md create mode 100644 content/posts/Win32汇编学习.md create mode 100644 content/posts/office2016激活步骤.md create mode 100644 content/posts/一句话Windows.md create mode 100644 content/posts/为Hexo博客Next主题添加Schnack评论.md create mode 100644 content/posts/为Hexo博客Next主题添加Wildfire评论系统.md create mode 100644 content/posts/为Ubuntu启用Swap分区.md create mode 100644 content/posts/加快Visual-Studio编译速度.md create mode 100644 content/posts/动态获取当前模块的HMODULE-HINSTANCE值.md create mode 100644 content/posts/在vps上搭建hexo.md create mode 100644 content/posts/注释大全.md create mode 100644 content/posts/流畅的Python学习笔记.md create mode 100644 content/posts/解决chromium警告C4819.md create mode 100644 resources/_gen/assets/js/bundle.js_3d041b08546090308b2e5d3a88088713.content create mode 100644 resources/_gen/assets/js/bundle.js_3d041b08546090308b2e5d3a88088713.json create mode 100644 resources/_gen/assets/js/js/main.js_d11fe7b62c27961c87ecd0f2490357b9.content create mode 100644 resources/_gen/assets/js/js/main.js_d11fe7b62c27961c87ecd0f2490357b9.json create mode 100644 resources/_gen/assets/scss/scss/main.scss_39fa5fe97be74115670eace810202c56.content create mode 100644 resources/_gen/assets/scss/scss/main.scss_39fa5fe97be74115670eace810202c56.json create mode 100644 resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.content create mode 100644 resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.json create mode 100644 static/android-chrome-192x192.png create mode 100644 static/android-chrome-384x384.png create mode 100644 static/android-chrome-512x512.png create mode 100644 static/apple-touch-icon.png create mode 100644 static/browserconfig.xml create mode 100644 static/favicon-16x16.png create mode 100644 static/favicon-32x32.png create mode 100644 static/favicon.ico create mode 100644 static/mstile-150x150.png create mode 100644 static/safari-pinned-tab.svg create mode 100644 static/site.webmanifest create mode 160000 themes/hermit diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..ff46467 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "themes/hermit"] + path = themes/hermit + url = https://github.com/Track3/hermit.git diff --git a/archetypes/default.md b/archetypes/default.md new file mode 100644 index 0000000..00e77bd --- /dev/null +++ b/archetypes/default.md @@ -0,0 +1,6 @@ +--- +title: "{{ replace .Name "-" " " | title }}" +date: {{ .Date }} +draft: true +--- + diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..2c9eb9a --- /dev/null +++ b/config.toml @@ -0,0 +1,89 @@ +baseURL = "https://oaoa.me" +languageCode = "en-us" +defaultContentLanguage = "en" +title = "个人博客" +theme = "hermit" +# enableGitInfo = true +pygmentsCodefences = true +pygmentsUseClasses = true +hasCJKLanguage = true # If Chinese/Japanese/Korean is your main content language, enable this to make wordCount works right. +rssLimit = 10 # Maximum number of items in the RSS feed. +copyright = "This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License." # This message is only used by the RSS template. +enableEmoji = true # Shorthand emojis in content files - https://gohugo.io/functions/emojify/ +# googleAnalytics = "UA-123-45" +# disqusShortname = "yourdiscussshortname" + +[author] + name = "lniwn" + +[blackfriday] + # hrefTargetBlank = true + # noreferrerLinks = true + # nofollowLinks = true + +[taxonomies] + tag = "tags" + category = "categories" + # Categories are disabled by default. + +[params] + dateform = "Jan 2, 2006" + dateformShort = "Jan 2" + dateformNum = "2006-01-02" + dateformNumTime = "2006-01-02 15:04 -0700" + + # Metadata mostly used in document's head + # description = "" + # images = [""] + themeColor = "#494f5c" + + homeSubtitle = "记录读书笔记和心得体会" + footerCopyright = ' · CC BY-NC 4.0' + # bgImg = "" # Homepage background-image URL + + # Prefix of link to the git commit detail page. GitInfo must be enabled. + # gitUrl = "https://github.com/username/repository/commit/" + + # Toggling this option needs to rebuild SCSS, requires Hugo extended version + justifyContent = false # Set "text-align: justify" to `.content`. + + relatedPosts = false # Add a related content section to all single posts page + + # Add custom css + # customCSS = ["css/foo.css", "css/bar.css"] + + # Social Icons + # Check https://github.com/Track3/hermit#social-icons for more info. + [[params.social]] + name = "twitter" + url = "https://twitter.com/sglshdo" + + [[params.social]] + name = "telegram" + url = "https://t.me/lniwn" + + [[params.social]] + name = "github" + url = "https://github.com/lniwn" + +[menu] + + [[menu.main]] + name = "Posts" + url = "posts/" + weight = 1 + + [[menu.main]] + name = "Categories" + url = "categories/" + weight = 2 + + [[menu.main]] + name = "Tags" + url = "tags/" + weight = 3 + + [[menu.main]] + name = "About" + url = "about/" + weight = 4 diff --git a/content/about.md b/content/about.md new file mode 100644 index 0000000..b188b2a --- /dev/null +++ b/content/about.md @@ -0,0 +1,17 @@ ++++ +title = "About Hugo" +date = "2014-04-09" ++++ + +Hugo is the **world’s fastest framework for building websites**. It is written in Go. + +It makes use of a variety of open source projects including: + +* https://github.com/russross/blackfriday +* https://github.com/alecthomas/chroma +* https://github.com/muesli/smartcrop +* https://github.com/spf13/cobra +* https://github.com/spf13/viper + +Learn more and contribute on [GitHub](https://github.com/gohugoio). + diff --git a/content/posts/CMake学习笔记.md b/content/posts/CMake学习笔记.md new file mode 100644 index 0000000..acb6e4d --- /dev/null +++ b/content/posts/CMake学习笔记.md @@ -0,0 +1,142 @@ +--- +title: CMake学习笔记 +date: 2017-12-27 13:54:05 +tags: [cmake, visual studio] +categories: cmake +--- + +本文主要记录CMake学习过程的一些笔记。 + + + +## 基本文件结构 +编写CMakeLists.txt + +``` +# CMake 最低版本号要求 +cmake_minimum_required (VERSION 2.8) +# 项目信息 +project (Demo1) +# 指定生成目标 +add_executable(Demo main.cc) +``` + +## 常用命令 + +### 项目类型命令 +- `add_executable`可执行文件 +- `add_library` 静态库 + +### 文件依赖命令 +- `aux_source_directory( )` + 查找指定目录下的所有源文件,然后将结果保存进指定的变量名。 +``` +# CMake 最低版本号要求 +cmake_minimum_required (VERSION 2.8) +# 项目信息 +project (Demo2) +# 查找当前目录下的所有源文件 +# 并将名称保存到 DIR_SRCS 变量 +aux_source_directory(. DIR_SRCS) +# 指定生成目标 +add_executable(Demo ${DIR_SRCS}) +``` +这样,CMake 会将当前目录所有源文件的文件名赋值给变量`DIR_SRCS`,再指示变量`DIR_SRCS` 中的源文件需要编译成一个名称为 Demo 的可执行文件。 + +- `add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])` + 添加子文件夹到构建系统中。 + `source_dir`子文件夹路径 + `binary_dir` 输出路径 + `EXCLUDE_FROM_ALL` 从Build All项目中排除 + +### 编译选项命令 +- Visual Studio to CMake Mapping + {% asset_img VS-to-CMake-Mapping.png VS-to-CMake-Mapping %} + {% asset_img CMake-Projects.png CMake-Projects %} +> ZERO_CHECK will rerun cmake. You can/should execute this after changing something on your CMake files. +> ALL_BUILD is simply a target which builds all and everything project in the active solution, I guess one can compare it to "make all". +> 可以通过`set(CMAKE_SUPPRESS_REGENERATION true)`不生成`ZERO_CHECK`工程。 + +### 链接命令 +- `target_link_libraries`指明链接库 + `target_link_libraries( [lib1 [lib2 [...]]] [[debug|optimized|general] ] ...)` + `general`可选字段,表示所有模式都链接的库 + `debug`表示debug模式才链接的库 + `optimized`表示非debug模式才链接的库 + +```cmake +target_link_libraries(${PROJECT_NAME} + delayimp.lib libcef.lib + debug cef_module_d.lib + debug libcef_dll_wrapper_d.lib + optimized cef_module.lib + optimized libcef_dll_wrapper.lib) +``` + +## 项目实例 + +### 自定义编译选项 + +顶层CMakeLists.txt文件 +``` +# CMake 最低版本号要求 +cmake_minimum_required (VERSION 2.8) +# 项目信息 +project (Demo4) +# 加入一个配置头文件,用于处理 CMake 对源码的设置 +configure_file ( + "${PROJECT_SOURCE_DIR}/config.h.in" + "${PROJECT_BINARY_DIR}/config.h" + ) +# 是否使用自己的 MathFunctions 库 +option (USE_MYMATH + "Use provided math implementation" ON) +# 是否加入 MathFunctions 库 +if (USE_MYMATH) + include_directories ("${PROJECT_SOURCE_DIR}/math") + add_subdirectory (math) + set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions) +endif (USE_MYMATH) +# 查找当前目录下的所有源文件 +# 并将名称保存到 DIR_SRCS 变量 +aux_source_directory(. DIR_SRCS) +# 指定生成目标 +add_executable(Demo ${DIR_SRCS}) +target_link_libraries (Demo ${EXTRA_LIBS}) +``` +编写`config.h.in`文件 `#cmakedefine USE_MYMATH` + +### 设置编译模式 + +``` +set(CMAKE_BUILD_TYPE "Debug") +set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb") +set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall") +``` + +### 环境检查 + +首先在顶层 CMakeLists 文件中添加 CheckFunctionExists.cmake 宏,并调用 `check_function_exists` 命令测试链接器是否能够在链接阶段找到 pow 函数。 +``` +# 检查系统是否支持 pow 函数 +include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake) +check_function_exists (pow HAVE_POW) +``` + +### 设置libcurl运行时环境 + +```cmake +if(USE_ALLMT_) + target_compile_definitions(libcurl PRIVATE -DRTLIBCFG=static) + set_property(TARGET libcurl APPEND_STRING PROPERTY COMPILE_OPTIONS $,/MTd,/MT>) +else() + target_compile_definitions(libcurl PRIVATE -DRTLIBCFG=shared) + set_property(TARGET libcurl APPEND_STRING PROPERTY COMPILE_OPTIONS $,/MDd,/MD>) +endif() +``` + +## 参考链接 +- [cmake-and-visual-studio](https://cognitivewaves.wordpress.com/cmake-and-visual-studio/) +- [CMake手册](https://www.zybuluo.com/khan-lau/note/254724) +- [CMakeLists.txt](http://wiki.ros.org/catkin/CMakeLists.txt) + diff --git a/content/posts/CMake项目添加预编译头.md b/content/posts/CMake项目添加预编译头.md new file mode 100644 index 0000000..db37971 --- /dev/null +++ b/content/posts/CMake项目添加预编译头.md @@ -0,0 +1,77 @@ +--- +title: CMake项目添加预编译头 +date: 2017-12-28 11:46:13 +08:00 +tags: [cmake, visual studio] +images: ["apple-touch-icon.png"] +categories: cmake +--- + +本文主要记录为CMake项目添加预编译头支持,以及过程中遇到的坑,比如`set_target_properties`连续调用两次失效的问题。 + + + +各个编译器支持预编译头指令不同,这里仅以Visual Studio为例进行说明。 + +## 操作步骤 + +- 创建cmake宏文件`PrecompiledHeader.cmake` + +```cmake PrecompiledHeader.cmake +#------------------------------------------------------- +# Support macro to use a precompiled header +# Usage: +# use_precompiled_header(TARGET HEADER_FILE SRC_FILE) +#------------------------------------------------------- + +macro(use_precompiled_header TARGET HEADER_FILE SRC_FILE) + get_filename_component(HEADER ${HEADER_FILE} NAME) + + # Use MSVC_IDE to exclude NMake from using PCHs + if (MSVC AND NOT NMAKE AND NOT OGRE_UNITY_BUILD) + + set_property(TARGET ${TARGET} APPEND_STRING PROPERTY + COMPILE_FLAGS " /Yu\"${HEADER}\"") + set_property(TARGET ${TARGET} APPEND_STRING PROPERTY + COMPILE_FLAGS " /FI\"${HEADER}\"") + set_source_files_properties(${SRC_FILE} + PPROPERTIES COMPILE_FLAGS /Yc"${HEADER}") + elseif (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGXX) + endif () +endmacro(use_precompiled_header) +``` + +- 在主工程的`CMakeLists.txt`中添加依赖 + +```cmake +list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/Tools/CMake) +include(PrecompiledHeader) +``` + +- 在需要使用预编译头的项目中调用`use_precompiled_header`宏函数 + +```cmake +use_precompiled_header(${PROJECT_NAME} + "${CMAKE_CURRENT_SOURCE_DIR}/stdafx.h" + "${CMAKE_CURRENT_SOURCE_DIR}/stdafx.cpp") +``` + +## 踩坑记录 + +- set_target_properties连续调用两次,导致前一次调用无效 + +在`PrecompiledHeader.cmake`文件中,最开始使用了如下的代码 + +{% note danger %} + +{% codeblock lang:cmake %} +if (MSVC AND NOT NMAKE AND NOT OGRE_UNITY_BUILD) + set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS /Yu"${HEADER}") + set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS /FI"${HEADER}") + set_source_files_properties(${SRC_FILE} + PPROPERTIES COMPILE_FLAGS /Yc"${HEADER}" + ) +{% endcodeblock %} + +{% endnote %} + +可是发现永远只有/FI生效,后来查找了大量资料,替换为了`set_property APPEND`的形式,才最终解决。 \ No newline at end of file diff --git a/content/posts/Cef-Bug-Fix-List.md b/content/posts/Cef-Bug-Fix-List.md new file mode 100644 index 0000000..722ed5b --- /dev/null +++ b/content/posts/Cef-Bug-Fix-List.md @@ -0,0 +1,42 @@ +--- +title: Cef Bug Fix List +date: 2017-12-20 16:59:50 +tags: [cef, cplusplus] +categories: cplusplus +--- + +本文主要记录在cef开发过程中发现的bug及解决方法。 + + + +## 解决CEF中html页面不显示鼠标tips的bug + +在预编译头文件`stdafx.h`最下方加入: + +```c +#ifdef _UNICODE +#if defined _M_IX86 +#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") +#elif defined _M_IA64 +#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"") +#elif defined _M_X64 +#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") +#else +#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") +#endif +#endif +``` + +> VS2015自动生成的manifest如下,去掉了ia64选项: + +```c +#ifdef _UNICODE +#if defined _M_IX86 +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") +#elif defined _M_X64 +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") +#else +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") +#endif +#endif +``` \ No newline at end of file diff --git a/content/posts/Python模块timezone学习笔记.md b/content/posts/Python模块timezone学习笔记.md new file mode 100644 index 0000000..8ff7832 --- /dev/null +++ b/content/posts/Python模块timezone学习笔记.md @@ -0,0 +1,67 @@ +--- +title: Python模块timezone学习笔记 +date: 2018-08-06 18:19:30 +tags: [python] +categories: python +--- +本文基于python3,记录了datetime包中的timezone用法。 + + +使用第三方扩展包pytz,构造指定时区。 + +> **astimezone** + +`datetime.datetime.astimezone`是将原始输入解释为本地时区,然后再转换为目标时区,而pytz包的`localize`方法,是将原始输入直接解释为目标时区,例如: + +```python +tz = pytz.timezone('Asia/Shanghai') +target_dt = datetime.datetime(2018, 8, 5, 0, 0, 0, 0) +print(repr(target_dt.astimezone(tz))) +print(repr(tz.localize(target_dt))) + +# Output +# > datetime.datetime(2018, 8, 5, 8, 0, tzinfo=) +# > datetime.datetime(2018, 8, 5, 0, 0, tzinfo=) +``` + +> **timetuple** + +由于`datetime.datetime.timetuple`方法不存储时区,所以如果需要构造不同时区的timestamp,需要使用`datetime.datetime.utctimetuple`方法。 + +```python +target_dt = datetime.datetime(2018, 8, 5, 0, 0, 0, 0) +print(repr(target_dt.utctimetuple())) +print(repr(target_dt.timetuple())) + +# Output +# > time.struct_time(tm_year=2018, tm_mon=8, tm_mday=5, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=6, tm_yday=217, tm_isdst=0) +# > time.struct_time(tm_year=2018, tm_mon=8, tm_mday=5, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=6, tm_yday=217, tm_isdst=-1) +``` + +> `datetime.``timetuple`()[¶](https://docs.python.org/3/library/datetime.html#datetime.datetime.timetuple) +> +> Return a [`time.struct_time`](https://docs.python.org/3/library/time.html#time.struct_time) such as returned by [`time.localtime()`](https://docs.python.org/3/library/time.html#time.localtime). `d.timetuple()` is equivalent to `time.struct_time((d.year, d.month, d.day, d.hour, d.minute, d.second, d.weekday(), yday, dst))`, where `yday = d.toordinal() - date(d.year, 1, 1).toordinal() + 1` is the day number within the current year starting with `1` for January 1st. The `tm_isdst` flag of the result is set according to the [`dst()`](https://docs.python.org/3/library/datetime.html#datetime.datetime.dst) method: [`tzinfo`](https://docs.python.org/3/library/datetime.html#datetime.datetime.tzinfo) is `None` or [`dst()`](https://docs.python.org/3/library/datetime.html#datetime.datetime.dst) returns `None`, `tm_isdst` is set to `-1`; else if [`dst()`](https://docs.python.org/3/library/datetime.html#datetime.datetime.dst) returns a non-zero value, `tm_isdst`is set to `1`; else `tm_isdst` is set to `0`. + +> `datetime.``utctimetuple`()[¶](https://docs.python.org/3/library/datetime.html#datetime.datetime.utctimetuple) +> +> If [`datetime`](https://docs.python.org/3/library/datetime.html#datetime.datetime) instance *d* is naive, this is the same as `d.timetuple()` except that `tm_isdst` is forced to 0 regardless of what `d.dst()` returns. DST is never in effect for a UTC time. +> +> If *d* is aware, *d* is normalized to UTC time, by subtracting `d.utcoffset()`, and a [`time.struct_time`](https://docs.python.org/3/library/time.html#time.struct_time) for the normalized time is returned. `tm_isdst` is forced to 0. Note that an [`OverflowError`](https://docs.python.org/3/library/exceptions.html#OverflowError) may be raised if *d*.year was`MINYEAR` or `MAXYEAR` and UTC adjustment spills over a year boundary. + +目标需求,将东8区(+8)的`2018-08-05 00:00:00`转换为unix timestamp: + +```python +tz = pytz.timezone('Asia/Shanghai') +target_dt = datetime.datetime(2018, 8, 5, 0, 0, 0, 0) +target_dt = tz.localize(target_dt) +print(time.mktime(target_dt.utctimetuple())) +print(target_dt.timestamp()) + +# Output +# > 1533398400.0 +# > 1533398400.0 +``` + +参考文档: + +https://kkc.github.io/2015/07/08/dealing-with-datetime-and-timezone-in-python/ \ No newline at end of file diff --git a/content/posts/SQLAlchemy学习笔记.md b/content/posts/SQLAlchemy学习笔记.md new file mode 100644 index 0000000..6dc8b22 --- /dev/null +++ b/content/posts/SQLAlchemy学习笔记.md @@ -0,0 +1,79 @@ +--- +title: SQLAlchemy学习笔记 +date: 2018-08-02 16:28:45 +tags: [sql, python] +categories: python +--- + +本文记录SQLAlchemy学习及使用笔记。 + + + +- **如何替换一个已有主键的记录?** + + 使用`session.merge()`方法替换`session.add()`,其实就是`SELECT + UPDATE`。 + +- **插入大量数据** + + - ORM方式 + + ```python + s = Session() + objects = [ + User(name="u1"), + User(name="u2"), + User(name="u3") + ] + s.bulk_save_objects(objects) + ``` + + 如果插入字典形式的数据,可以使用 [`Session.bulk_insert_mappings()`](http://docs.sqlalchemy.org/en/rel_1_0/orm/session_api.html#sqlalchemy.orm.session.Session.bulk_insert_mappings), 和 [`Session.bulk_update_mappings()`](http://docs.sqlalchemy.org/en/rel_1_0/orm/session_api.html#sqlalchemy.orm.session.Session.bulk_update_mappings) + + ```python + s.bulk_insert_mappings(User, + [dict(name="u1"), dict(name="u2"), dict(name="u3")] + ) + ``` + + - 非ORM方式 + + ```python + session.execute( + User.__table__.insert(), + [{'name': `randint(1, 100)`,'age': randint(1, 100)} for i in xrange(10000)] + ) + session.commit() + ``` + +- **获取大量数据** + + - 使用stream方式 + + ```python + def test_core_fetchmany_w_streaming(n): + """Load Core result rows using fetchmany/streaming.""" + + with engine.connect() as conn: + result = conn.execution_options(stream_results=True).\ + execute(Customer.__table__.select().limit(n)) + while True: + chunk = result.fetchmany(10000) + if not chunk: + break + for row in chunk: + data = row['id'], row['name'], row['description'] + ``` + + - 使用yield_per方式 + + ```python + def test_orm_full_objects_chunks(n): + """Load fully tracked ORM objects a chunk at a time using yield_per().""" + + sess = Session(engine) + for obj in sess.query(Customer).yield_per(1000).enable_eagerloads(False).limit(n): + pass + ``` + + + diff --git a/content/posts/Vim快捷键备忘录.md b/content/posts/Vim快捷键备忘录.md new file mode 100644 index 0000000..1d7effb --- /dev/null +++ b/content/posts/Vim快捷键备忘录.md @@ -0,0 +1,135 @@ +--- +title: Vim快捷键备忘录 +date: 2018-10-17 10:17:49 +tags: [vim] +categories: daily +--- +Vim快捷键查询。 + + +## 光标移动 + +| 命令 | 作用 | +| ----------------- | ------------------------------------------ | +| h,j,k,l | h表示往左,j表示往下,k表示往上,l表示往右 | +| ctrl+f | 上一页 | +| ctrl+b | 下一页 | +| w,e,W,E | 跳到单词的后面,小写包括标点 | +| b,B | 跳到单词的前面,小写包括标点 | +| 0 | 跳到本行的头部 | +| ^ | 跳到一行的开始 | +| $ | 跳到一行的结尾 | +| gg | 文档的第一行 | +| [N]G | 文档的第N行(G是最后一行),如:27G | +| f`space`,F`space` | 移动到右边的空格,大写移动到左边的空格 | + + + +## 插入 + +| 命令 | 作用 | +| ---- | -------------------------- | +| i | 插入到光标前面 | +| I | 插入到行的开始位置 | +| a | 插入到光标的后面 | +| A | 插入到行的最后位置 | +| o | 在当前光标的下方插入新一行 | +| O | 在当前光标的上方插入新一行 | +| Esc | 关闭插入模式 | +| | | +| | | +| | | +| | | + + + +## 编辑 + +| 命令 | 作用 | +| ------ | -------------------------------------- | +| r | 替换光标所在的一个字符 | +| J | 合并下一行到当前行 | +| s | 删除光标所在的一个字符,光标还在当前行 | +| S | 删除光标所在行的内容,光标还在当前行 | +| u | 撤销上一步操作 | +| U | 撤销当前行的更改 | +| ctrl+r | 恢复上一步操作 | +| . | 重复最后一个命令 | +| ~ | 变换为大写 | +| [N]>> | 一行或N行往右移动一个tab | +| [N]<< | 一行或N行往左移动一个tab | +| | | + + + +## 退出 + +| 命令 | 作用 | +| ------ | ---------------- | +| :w | 保存 | +| :wq,:x | 保存并关闭 | +| :q | 关闭(已保存) | +| :q! | 强制关闭,不保存 | +| | | + + + +## 查找和搜索 + +| 命令 | 作用 | +| -------------------- | ------------------------------------------------------------ | +| /pattern | 搜索(非插入模式),支持正则 | +| ?pattern | 往后搜索 | +| n | 当前搜索结果的下一个目标 | +| N | 当前搜索结果的上一个目标 | +| rp | 将光标之后的字符替换为字母p | +| :s/word/replace | 光标所在行的第一个word替换为replace | +| :%s/word/replace | 全文查找word并替换为replace | +| :1,50s/word/replace | 在第1行和第50行之间(含)进行搜索和替换 | +| :45s/word/replace/ | 表示仅仅在第45行进行搜索和替换。而 1,$ 行号范围和 % 是等价的 | +| :%s/^/要插入的字符串 | 每行开头插入字符串 | +| :%s/$/要插入的字符串 | 每行结尾插入字符串 | + + + +## 剪切、复制和粘贴 + +| 命令 | 作用 | +| ----- | ------------------------------------------------------------ | +| dd | 删除一行,同时被删除内容存于剪贴板上 | +| de | 删除光标后的单词内容,同时被删除内容存于剪贴板上 | +| dG | 删除当前位置到文件结尾内容 | +| dw | 删除光标后的单词内容以及之后的空格,同时被删除内容存于剪贴板上 | +| [N]dd | 删除以当前行开始的n行 | +| x | 删除后一个字符 | +| X | 删除前一个字符 | +| D | 删除当前位置到行末的内容 | +| [N]yy | 复制一行或者N行 | +| yw | 复制一个单词 | +| p | 粘贴 | + + + +## 窗口操作 + +| 命令 | 作用 | +| ------- | ------------------------------------------------------------ | +| :split | 水平方向分割出一个窗口 | +| :vsplit | 垂直方向分割出一个窗口 | +| :close | 关闭窗口 | +| ctrl+w | 切换窗口, h到左边窗口,j到下方窗口,k到上方窗口,l到右边窗口 | + +## 常用操作 + +| 命令 | 作用 | +| ------- | --------------------------------- | +| gg + dG | 清空文件内容 | +| viw,vaw | 选中光标所在单词(vaw包括前后空格) | +| | | + + + +## 在线文档 +- [VIM QUICK REFERENCE CARD](http://tnerual.eriogerg.free.fr/vimqrc.pdf) +- {% asset_img morden1.png 增强版 %} +- {% asset_img text1.png 文字版 %} diff --git a/content/posts/Win32汇编学习.md b/content/posts/Win32汇编学习.md new file mode 100644 index 0000000..6496cf5 --- /dev/null +++ b/content/posts/Win32汇编学习.md @@ -0,0 +1,572 @@ +--- +title: Win32汇编学习 +date: 2018-02-12 17:48:00 +tags: [win32, 汇编] +categories: windows +--- + +本文记录了C函数调用过程,以及常用的汇编函数指令集。 + + + +## 函数调用过程 + +栈帧,即stack frame,其本质就是一种栈,只是这种栈专门用于保存函数调用过程中的各种信息,栈帧有栈顶(TOS)和栈底之分,其中栈顶的地址最低,栈底的地址最高,增长方向为高地址向低地址方向。在x86-32bit中,用esp(extended stack pointer)一直指向栈顶,ebp(extended base pointer)指向栈底。 + +{% asset_img stackframe.png 栈帧方向 %} + +一般来说,ebp和esp之间的区域叫做栈帧,每调用一个函数,就会生成一个新的栈帧。在函数调用过程中,我们将调用函数称为“调用者(caller)”,将被调用的函数称为“被调用者(callee)”。 + +函数调用过程如下: + +```asm +push ebp ; 保存ebp的值 +mov ebp,esp ; 将esp的值赋给ebp,使新的ebp指向栈顶 +sub esp,0d8h ; 分配额外的空间给局部变量,对于大内存,使用call __alloca_probe (010FD4EAh) 的方式来分配 +``` + +windows平台,返回值保存在eax中。 + +## x86汇编指令 + +### 寄存器 + +{% asset_img x86-registers.png x86寄存器 %} + +X86处理器中有8个32位的通用寄存器。由于历史的原因,EAX通常用于计算,ECX通常用于循环变量计数。ESP和EBP有专门用途,ESP指示栈指针(用于指示栈顶位置),而EBP则是基址指针(用于指示子程序或函数调用的基址指针)。如图中所示,EAX、EBX、ECX和EDX的前两个高位字节和后两个低位字节可以独立使用,其中两位低字节又被独立分为H和L部分,这样做的原因主要是考虑兼容16位的程序,具体兼容匹配细节请查阅相关文献。 + +应用寄存器时,其名称大小写是不敏感的,如EAX和eax没有区别。 + +### 内存和寻址模式 + +#### 声明静态数据区 + +可以在X86汇编语言中用汇编指令.DATA声明静态数据区(类似于全局变量),数据以单字节、双字节、或双字(4字节)的方式存放,分别用DB,DW, DD指令表示声明内存的长度。在汇编语言中,相邻定义的标签在内存中是连续存放的。 + +| .DATA | | | +| ----- | -------- | ------------------------------------- | +| var | DB 64 | ;声明一个字节,并将数值64放入此字节中 | +| var2 | DB ? | ; 声明一个未初始化的字节. | +| | DB 10 | ; 声明一个没有label的字节,其值为10. | +| X | DW ? | ; 声明一个双字节,未初始化. | +| Y | DD 30000 | ; 声明一个4字节,其值为30000. | + +还可以声明连续的数据和数组,声明数组时使用DUP关键字。 + +| .DATA | | | +| ----- | ------------- | ------------------------------------------------------------ | +| Z | DD 1, 2, 3 | ; Declare three 4-byte values, initialized to 1, 2, and 3. The value of location Z + 8 will be 3. | +| bytes | DB 10 DUP(?) | ; Declare 10 uninitialized bytes starting at location *bytes*. | +| arr | DD 100 DUP(0) | ; Declare 100 4-byte words starting at location arr, all initialized to 0 | +| str | DB 'hello',0 | ; Declare 6 bytes starting at the address str, initialized to the ASCII character values for hello and the null (0) byte. | + +#### 寻址模式 + +现代X86处理器具有232字节的寻址空间。在上面的例子中,我们用标签(label)表示内存区域,这些标签在实际汇编时,均被32位的实际地址代替。除了支持这种直接的内存区域描述,X86还提供了一种灵活的内存寻址方式,即利用最多两个32位的寄存器和一个32位的有符号常数相加计算一个内存地址,其中一个寄存器可以左移1、2或3位以表述更大的空间。下面例子是汇编程序中常见的方式。 + +| 指令 | 说明 | +| -------------------- | ----------------------------------------------- | +| mov eax, [ebx] | ; 将ebx值指示的内存地址中的4个字节传送到eax中 | +| mov [var], ebx | ; 将ebx的内容传送到var的值指示的内存地址中. | +| mov eax, [esi-4] | ; 将esi-4值指示的内存地址中的4个字节传送到eax中 | +| mov [esi+eax], cl | ; 将cl的值传送到esi+eax的值指示的内存地址中 | +| mov edx, [esi+4*ebx] | ; 将esi+4*ebx值指示的内存中的4个字节传送到edx | + +#### 长度规定 + +在声明内存大小时,在汇编语言中,一般用DB,DW,DD均可声明的内存空间大小,这种现实声明能够很好地指导汇编器分配内存空间,但是,对于`mov [ebx], 2`,如果没有特殊的标识,则不确定常数2是单字节、双字节,还是双字。对于这种情况,X86提供了三个指示规则标记,分别为`BYTE PTR`, `WORD PTR`, and `DWORD PTR`,如上面例子写成:`mov BYTE PTR [ebx], 2`, `mov WORD PTR [ebx], 2`, `mov DWORD PTR [ebx], 2`,则意思非常清晰。 + +### 汇编指令 + +汇编指令通常可以分为数据传送指令、逻辑计算指令和控制流指令。本节将讲述其中最重要的指令,以下标记分别表示寄存器、内存和常数。 + +| 标识 | 描述 | +| ------- | --------------------------------------------------------- | +| | 32位寄存器 (EAX, EBX, ECX, EDX, ESI, EDI, ESP, or EBP) | +| | 16位寄存器 (AX, BX, CX, or DX) | +| | 8位寄存器(AH, BH, CH, DH, AL, BL, CL, or DL) | +| | 任何寄存器 | +| | 内存地址 (e.g., [eax], [var + 4], or dword ptr [eax+ebx]) | +| | 32为常数 | +| | 16位常数 | +| | 8位常数 | +| | 任何8位、16位或32位常数 | + +#### 数据传送指令 + +- **mov** — Move (Opcodes: 88, 89, 8A, 8B, 8C, 8E, ...) + +mov指令将第二个操作数(可以是寄存器的内容、内存中的内容或值)复制到第一个操作数(寄存器或内存)。mov不能用于直接从内存复制到内存,其语法如下所示: + +``` asm +mov , +mov , +mov , +mov , +mov , +``` + +*Examples* +`mov eax, ebx — 将ebx的值拷贝到eax` +`mov byte ptr [var], 5 — 将5保存找var指示内存中的一个字节中` + +- **push**— Push stack (Opcodes: FF, 89, 8A, 8B, 8C, 8E, ...) + +push指令将操作数压入内存的栈中,栈是程序设计中一种非常重要的数据结构,其主要用于函数调用过程中,其中ESP只是栈顶。在压栈前,首先将ESP值减4(X86栈增长方向与内存地址编号增长方向相反),然后将操作数内容压入ESP指示的位置。其语法如下所示: + +```asm +push +push +push +``` + +*Examples* +`push eax — 将eax内容压栈` +`push [var] — 将var指示的4直接内容压栈` + +- **pop**— Pop stack + +pop指令与push指令相反,它执行的是出栈的工作。它首先将ESP指示的地址中的内容出栈,然后将ESP值加4. 其语法如下所示: + +```asm +pop +pop +``` + +*Examples* +`pop edi — pop the top element of the stack into EDI.` +`pop [ebx] — pop the top element of the stack into memory at the four bytes starting at location EBX.` + +- **lea**— Load effective address + + lea实际上是一个载入有效地址指令,将第二个操作数表示的地址载入到第一个操作数(寄存器)中。其语法如下所示: + +*Syntax* +`lea ,` + +*Examples* +`lea eax, [var] — var指示的地址载入eax中.` +`lea edi, [ebx+4*esi] — ebx+4*esi表示的地址载入到edi中,这实际是上面所说的寻址模式的一种表示方式.` + +#### 算术和逻辑指令 + +- **add**— Integer Addition + +add指令将两个操作数相加,且将相加后的结果保存到第一个操作数中。其语法如下所示: + +```asm +add , +add , +add , +add , +add , +``` + +*Examples* +`add eax, 10 — EAX ← EAX + 10` +`add BYTE PTR [var], 10 — 10与var指示的内存中的一个byte的值相加,并将结果保存在var指示的内存中` + +- **sub**— Integer Subtraction + +sub指令指示第一个操作数减去第二个操作数,并将相减后的值保存在第一个操作数,其语法如下所示: + +```asm +sub , +sub , +sub , +sub , +sub , +``` + +*Examples* +`sub al, ah — AL ← AL - AH` +`sub eax, 216 — eax中的值减26,并将计算值保存在eax中` + +- **inc, dec**— Increment, Decrement + +inc,dec分别表示将操作数自加1,自减1,其语法如下所示: + +```asm +inc +inc +dec +dec +``` + +*Examples* +`dec eax — eax中的值自减1.` +`inc DWORD PTR [var] — *var指示内存中的一个4-byte值自加1`* + +- **imul**— Integer Multiplication + +整数相乘指令,它有两种指令格式,一种为两个操作数,将两个操作数的值相乘,并将结果保存在第一个操作数中,第一个操作数必须为寄存器;第二种格式为三个操作数,其语义为:将第二个和第三个操作数相乘,并将结果保存在第一个操作数中,第一个操作数必须为寄存器。其语法如下所示: + +```asm +imul , +imul , +imul ,, +imul ,, +``` + +*Examples* + +`imul eax, [var] — eax→ eax * [var]` + +`imul esi, edi, 25 — ESI → EDI * 25` + +- **idiv**— Integer Division + +idiv指令完成整数除法操作,idiv只有一个操作数,此操作数为除数,而被除数则为EDX:EAX中的内容(一个64位的整数),操作的结果有两部分:商和余数,其中商放在eax寄存器中,而余数则放在edx寄存器中。其语法如下所示: + +*Syntax* +`idiv ` +`idiv ` + +*Examples* + +`idiv ebx` + +`idiv DWORD PTR [var]` + +- **and, or, xor**— Bitwise logical and, or and exclusive or + +逻辑与、逻辑或、逻辑异或操作指令,用于操作数的位操作,操作结果放在第一个操作数中。其语法如下所示: + +```asm +and , +and , +and , +and , +and , +or , +or , +or , +or , +or , +xor , +xor , +xor , +xor , +xor , +``` + +*Examples* +`and eax, 0fH — 将eax中的钱28位全部置为0,最后4位保持不变.` +`xor edx, edx — 设置edx中的内容为0.` + +- **not**— Bitwise Logical Not + +位翻转指令,将操作数中的每一位翻转,即0->1, 1->0。其语法如下所示: + +`not ` +`not ` + +*Example* +`not BYTE PTR [var] — *将var指示的一个字节中的所有位翻转*.` + +- **neg**— Negate + +取负指令。语法为: + +`neg ` +`neg ` + +*Example* +`neg eax — EAX → - EAX` + +- **shl, shr**— Shift Left, Shift Right + +位移指令,有两个操作数,第一个操作数表示被操作数,第二个操作数指示位移的数量。其语法如下所示: + +```asm +shl , +shl , +shl , +shl , +shr , +shr , +shr , +shr , + +``` + +*Examples* + +`shl eax, 1 — Multiply the value of EAX by 2 (if the most significant bit is 0),左移1位,相当于乘以2` + +`shr ebx, cl — Store in EBX the floor of result of dividing the value of EBX by 2*n* where *n* is the value in CL.` + +#### 控制转移指令 + +X86处理器维持着一个指示当前执行指令的指令指针(IP),当一条指令执行后,此指针自动指向下一条指令。IP寄存器不能直接操作,但是可以用控制流指令更新。 + +> ``` +> mov esi, [ebp+8] +> begin: xor ecx, ecx +> mov eax, [esi] +> +> ``` + +如第二条指令用begin指示,这种标签的方法在某种程度上简化了汇编程序设计,控制流指令通过标签实现程序指令跳转。 + +- **jmp** — Jump + +控制转移到label所指示的地址,(从label中取出执行执行),如下所示: + +`jmp