├── .codeclimate.yml ├── .gitignore ├── .vscode └── settings.json ├── AboutJekyll.md ├── Gemfile ├── README.md ├── _config.yml ├── _data └── navigation.yml ├── _drafts ├── Android │ ├── 202301072210Doze模式源码解析.md │ ├── 202301081324Android源码解读-触摸位置显示.md │ ├── 2025-05-25-AOSP开发规范.md │ ├── Android OTA升级.md │ ├── Android Studio常用插件汇总.md │ ├── Android Studio相关目录解析.md │ ├── Android Studio移动鼠标显示悬浮提示的设置方法.md │ ├── Android平台OpenGL ES_Assimp_OpenCV_GLM集成说明.md │ ├── Android真机安装sqlite3的方法.md │ └── 解决adb push时出现的"Read-only file system"问题.md ├── C_Cpp │ ├── ACM竞赛之输入输出(以C与C++为例).md │ ├── C++从键盘输入文件结束符.md │ ├── C++编译错误cannot have cv-qualifier.md │ ├── C++语言中cin cin.getline cin.get getline gets getchar 的用法实例.md │ ├── C_C++中的abort、atexit、exit和_Exit.md │ ├── Code Blocks+gtest环境配置.md │ ├── C语言中随机数相关问题.md │ ├── const 不再迷茫.md │ ├── 屏幕输出VS文件输出.md │ ├── 由函数clock想到的.md │ └── 编程获得CPU的主频.md ├── Database │ ├── (转)SQLServer实例讲解.md │ ├── DB2常用语句.md │ ├── MYSQL常见错误及其解决方式.md │ ├── MySQL默认数据库.md │ ├── Oracle中session和processes的设置.md │ ├── Oracle导入导出常用命令.md │ ├── Oracle系统表整理+常用SQL语句收集.md │ ├── SQL Server常用语句.md │ ├── oracle表空间不足相关问题解决办法.md │ ├── oracle表空间表分区详解及oracle表分区查询使用方法(转+整理).md │ ├── 如何建立DB2分区数据库?(转).md │ ├── 忘记oracle的sys用户密码怎么修改以及Oracle 11g 默认用户名和密码.md │ └── 数据库相关总结.md ├── Java │ ├── 202110171056如何将cpdetector发布Maven依赖到中央仓库.md │ ├── 202209041204热切换Log4j级别配置.md │ ├── 202301072303Java Swing TreeTable样例指导.md │ ├── 20分钟理清Maven构建中的测试相关工具的关系.md │ ├── Calendar类中add_set_roll方法的区别.md │ ├── Eclipse+Spark搭建源码分析环境问题分析.md │ ├── Eclipse中Ant的配置与测试 转.md │ ├── Eclipse全面提速小技巧.md │ ├── Eclipse相关问题.md │ ├── Eclipse远程调试出现“JDWP Transport dt_socket failed to initialize”的解决方案.md │ ├── FindBugs详解.md │ ├── HBase介绍.md │ ├── Hibernate与autoCommit.md │ ├── JNI使用方法.md │ ├── JUnit org.junit.runner.Request.classWithoutSuiteMethod解决方法.md │ ├── JVM调优总结(转).md │ ├── Java杂项.md │ ├── Java远程调试代码不一致问题汇总.md │ ├── Peer Code Reviews Made Easy with Eclipse Plug-In.md │ ├── ServletInputStream的重复读取(多次读取)(转).md │ ├── Spring框架的反序列化远程代码执行漏洞分析(转).md │ ├── [Maven][l10n-maven-plugin]告警[WARNING] No dictionary file under folder.md │ ├── [Maven][maven-shade-plugin]告警[WARNING] maven-shade-plugin has detected that some class files are present in two or more JARs.md │ ├── [Maven][maven-site-plugin]告警[WARNING] No project URL defined - decoration links will not be relativized.md │ ├── [Maven][taglist-maven-plugin]告警[WARNING] Using legacy tag format.md │ ├── [Maven]告警[WARNING] Unable to create Maven project from repository..md │ ├── [System.currentTimeMillis]_[Calendar.getInstance().getTimeInMillis()]_[new Date().getTime()].md │ ├── eclipse插件在线发布发布和版本更新(web site) 转.md │ ├── javadoc相关问题.md │ ├── org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter与org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter.md │ ├── package-info.java文件详解.md │ ├── 一个比较全面的java随机数据生成工具包.md │ ├── 使用CXF+Spring发布WebService,启动报错.md │ ├── 利用Spring中同名Bean相互覆盖的特性,定制平台的类内容。.md │ ├── 剔除eclipse的configuration目录[转].md │ ├── 如何在大量jar包中搜索特定字符.md │ ├── 如何编写跨平台的Java代码.md │ ├── 如何编译Apache Hadoop2.2.0源代码.md │ └── 通过设置JDK解决存在多个Gradle后台进程的问题.md ├── Linux │ ├── 202317061029VSCode调试远程Linux机器上的C代码.md │ ├── 202401011357Ubuntu扩容swap文件.md │ ├── Linux下安装最新的Eclipse.md │ ├── Linux压缩与解压常用命令.md │ ├── Linux快捷键.md │ ├── Linux环境下JDK_Eclipse一键安装脚本.md │ ├── Unix_Linux操作系统中如何在sqlplus_rman中使用方向键.md │ ├── linux中无 conio.h的解决办法.md │ ├── ssh相关原理学习与常见错误总结.md │ └── 鸟哥的linux私房菜勘误表.md └── Others │ ├── 2014-11-04-EXE 文件转换成安装程序教程.md │ ├── 2015-10-25-代码风格与代码格式化工具.md │ ├── 202301072207LaTeX内容总结.md │ ├── 202302262208StableDiffusionWebui环境搭建.md │ ├── ApkToolBoxGUI Release Notes.md │ ├── Cache模拟器(CacheSim).md │ ├── Input源码解读——从"Show tabs"开始.md │ ├── Lecture Notes_ Macros.md │ ├── MIPSsim使用说明.md │ ├── OOAD与UML笔记.md │ ├── Rdseed与SAC的安装.md │ ├── SVN+Apache域用户认证配置方法_Windows(转,重新排版,部分内容更新优化).md │ ├── Use the SVN command-line tool.md │ ├── VIM常见用法总结.md │ ├── VirtualBox相关问题总结.md │ ├── Windows平台下安装Eclipse插件,开发Hadoop应用.md │ ├── Windows日志查看工具合集.md │ ├── XShell使用问题汇总.md │ ├── openmpi出现Segmentation Fault而终止运算.md │ ├── tcpdump捕捉样例.md │ ├── 一个由于网络问题导致的服务无法使用——调试过程总结.md │ ├── 一个程序员能够控制多少行代码.md │ ├── 不引入新的数组,实现数组元素交换位置函数.md │ ├── 为什么大多数编程语言中的数组都从0开始.md │ ├── 为什么我们总是完不成目标.md │ ├── 使用OpenSSL实现X25519秘钥协商功能.md │ ├── 使用PowerShell简化我的工作.md │ ├── 关于强制式(命令式)语言和声明式语言的区别.md │ ├── 关于记录日志的几个小心得.md │ ├── 分词工具比较(转).md │ ├── 判断一个数是不是2的幂.md │ ├── 制作Aspose CHM文档的过程记录.md │ ├── 华为面试题——一道关于指针方面的编程题(C_C++).md │ ├── 华为面试题——单向链表倒转(一次遍历).md │ ├── 华为面试题——约瑟夫问题的C++简单实现(循环链表).md │ ├── 在 Windows 上安装 Hadoop 教程(转).md │ ├── 在工作中遇到的问题.md │ ├── 基于对象和面向对象的区别.md │ ├── 字符乱码一锅炖.md │ ├── 对象池、线程池、数据库连接池、内存池剖析.md │ ├── 工具软件备忘.md │ ├── 清理无用的CSS样式的几个工具(转).md │ ├── 能让程序做的事情坚决不用人来做——批量修复markdownlint MD034警告.md │ └── 高可用性中的脑裂问题(split-brain problem in HA)(转).md ├── _pages ├── 404.md ├── about.md ├── category-archive.md ├── tag-archive.md └── year-archive.md ├── _posts ├── android │ ├── 2021-01-13-Repo-In-Action.md │ ├── 2021-02-14-Android-Build-System.md │ ├── 2021-02-21-Import-AOSP-To-AS.md │ └── 2025-01-05-投屏知识学习之路.md ├── linux │ ├── 2019-04-22-Linux-Memory-Analysis.md │ ├── 2020-11-21-Package-Manager-In-Ubuntu.md │ └── 2024-01-01-Grep-Sed-Awk-Example.md ├── others │ ├── 2012-01-19-how-to-learn-r-by-reading-books.md │ ├── 2016-08-23-j-lo-performance-analysissy-tools.md │ ├── 2016-08-23-j-lo-performance-analysissy-tools2.md │ ├── 2016-08-23-j-lo-performance-analysissy-tools3.md │ ├── 2018-01-07-Gradle-GradleWrappe-AndroidPluginForGradle.md │ ├── 2018-03-11-Groovy-Compiler-Analysis-01.md │ ├── 2018-03-11-Groovy-Compiler-Analysis-02.md │ ├── 2018-11-04-Publish-to-Maven-Center.md │ ├── 2018-11-23-Java-Code-Check.md │ ├── 2020-02-10-Cpp-Code-Check.md │ ├── 2023-01-07-PDF常见问题解决方案汇总.md │ ├── 2024-04-13-Password-Recovery-Tools-Analysis.md │ ├── 2024-06-22-Aloys-Build-Manual.md │ └── 2025-05-21-智能驾驶-障碍物探测.md ├── the-way-of-learning │ ├── 2015-05-19-Android学习之路.md │ ├── 2015-05-19-Basic学习之路.md │ ├── 2015-05-19-CSharp学习之路.md │ ├── 2015-05-19-C与C++学习之路.md │ ├── 2015-05-19-DB学习之路.md │ ├── 2015-05-19-Docker学习之路.md │ ├── 2015-05-19-EditorAndIDE学习之路.md │ ├── 2015-05-19-Erlang学习之路.md │ ├── 2015-05-19-Excel学习之路.md │ ├── 2015-05-19-Fortran学习之路.md │ ├── 2015-05-19-Golang学习之路.md │ ├── 2015-05-19-Groovy学习之路.md │ ├── 2015-05-19-Haskell学习之路.md │ ├── 2015-05-19-IO学习之路.md │ ├── 2015-05-19-J2EE学习之路.md │ ├── 2015-05-19-Kotlin学习之路.md │ ├── 2015-05-19-Lisp学习之路.md │ ├── 2015-05-19-Lua学习之路.md │ ├── 2015-05-19-Markdown学习之路.md │ ├── 2015-05-19-Matlab与Octave学习之路.md │ ├── 2015-05-19-Nginx学习之路.md │ ├── 2015-05-19-OCaml学习之路.md │ ├── 2015-05-19-OJ学习之路.md │ ├── 2015-05-19-OpenGL学习之路.md │ ├── 2015-05-19-PHP学习之路.md │ ├── 2015-05-19-Pascal与Delphi学习之路.md │ ├── 2015-05-19-Perl学习之路.md │ ├── 2015-05-19-Prolog学习之路.md │ ├── 2015-05-19-Python学习之路.md │ ├── 2015-05-19-Ruby学习之路.md │ ├── 2015-05-19-Rust学习之路.md │ ├── 2015-05-19-R学习之路.md │ ├── 2015-05-19-Scala学习之路.md │ ├── 2015-05-19-TCL与TK学习之路.md │ ├── 2015-05-19-TeX学习之路.md │ ├── 2015-05-19-Unix与Linux学习之路.md │ ├── 2015-05-19-Windows学习之路.md │ ├── 2015-05-19-前端学习之路.md │ ├── 2015-05-19-大数据学习之路.md │ ├── 2015-05-19-数据挖掘学习之路.md │ ├── 2015-05-19-数据结构与算法.md │ ├── 2015-05-19-数电学习之路.md │ ├── 2015-05-19-机器学习与人工智能学习之路.md │ ├── 2015-05-19-正则表达式学习之路.md │ ├── 2015-05-19-汇编学习之路.md │ ├── 2015-05-19-版本管理学习之路.md │ ├── 2015-05-19-编译原理学习之路.md │ ├── 2015-05-19-设计学习之路.md │ └── 2025-05-09-架构师学习之路.md └── vcs │ ├── 2018-11-03-How_to_merge_two_git_repo.md │ └── 2021-01-09-TortoiseSVN_TortoiseGit_BeyondCompare.md ├── assets └── images │ └── bio-photo.jpg ├── google39f08d3f2271d152.html ├── index.html └── sitemap.xml /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | --- 2 | engines: 3 | fixme: 4 | enabled: true 5 | markdownlint: 6 | enabled: true 7 | checks: 8 | MD034: 9 | enabled: true 10 | MD013: 11 | enabled: false 12 | ratings: 13 | paths: [] 14 | exclude_paths: [] -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | .settings/ 3 | *.project 4 | 5 | # jekyll related files 6 | _site 7 | .sass-cache 8 | .jekyll-metadata 9 | Gemfile.lock 10 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.exclude": { 3 | "**/.classpath": true, 4 | "**/.project": true, 5 | "**/.settings": true, 6 | "**/.factorypath": true 7 | }, 8 | "sarif-viewer.connectToGithubCodeScanning": "off" 9 | } -------------------------------------------------------------------------------- /AboutJekyll.md: -------------------------------------------------------------------------------- 1 | # Minimal Mistakes remote theme starter 2 | 3 | Click [**Use this template**](https://github.com/mmistakes/mm-github-pages-starter/generate) button above for the quickest method of getting started with the [Minimal Mistakes Jekyll theme](https://github.com/mmistakes/minimal-mistakes). 4 | 5 | Contains basic configuration to get you a site with: 6 | 7 | - Sample posts. 8 | - Sample top navigation. 9 | - Sample author sidebar with social links. 10 | - Sample footer links. 11 | - Paginated home page. 12 | - Archive pages for posts grouped by year, category, and tag. 13 | - Sample about page. 14 | - Sample 404 page. 15 | - Site wide search. 16 | 17 | Replace sample content with your own and [configure as necessary](https://mmistakes.github.io/minimal-mistakes/docs/configuration/). 18 | 19 | --- 20 | 21 | ## Troubleshooting 22 | 23 | If you have a question about using Jekyll, start a discussion on the [Jekyll Forum](https://talk.jekyllrb.com/) or [StackOverflow](https://stackoverflow.com/questions/tagged/jekyll). Other resources: 24 | 25 | - [Ruby 101](https://jekyllrb.com/docs/ruby-101/) 26 | - [Setting up a Jekyll site with GitHub Pages](https://jekyllrb.com/docs/github-pages/) 27 | - [Configuring GitHub Metadata](https://github.com/jekyll/github-metadata/blob/master/docs/configuration.md#configuration) to work properly when developing locally and avoid `No GitHub API authentication could be found. Some fields may be missing or have incorrect data.` warnings. 28 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "github-pages", group: :jekyll_plugins 4 | 5 | gem "tzinfo-data" 6 | gem "wdm", "~> 0.1.0" if Gem.win_platform? 7 | 8 | # If you have any plugins, put them here! 9 | group :jekyll_plugins do 10 | gem "jekyll-paginate" 11 | gem "jekyll-sitemap" 12 | gem "jekyll-gist" 13 | gem "jekyll-feed" 14 | gem "jemoji" 15 | gem "jekyll-include-cache" 16 | gem "jekyll-algolia" 17 | end 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cnblogs 2 | 3 | [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome) 4 | [![Maintenance](https://img.shields.io/maintenance/yes/2025.svg)](https://github.com/jiangxincode/cnblogs) 5 | [![GitHub license](https://img.shields.io/github/license/mashape/apistatus.svg)](http://mit-license.org/) 6 | 7 | 一些我在平时工作和学习中积累的编程相关的资源。每个程序员都有自己的学习之路,过程中会学习各种各样的网上知识,学习完最好记录下来,每隔一段时间看一看,会有不一样的收获。 8 | 9 | 博客地址: 10 | 11 | * [原有"学习之路系列博客"](https://jiangxincode.github.io/cnblogs/categories/#the-way-of-learning) 12 | * [Github](https://jiangxincode.github.io/cnblogs/) 13 | * [博客园](https://www.cnblogs.com/jiangxinnju) 14 | 15 | 如果大家有兴趣可以一起增加,修改。 16 | 17 | * [文章源码目录](https://github.com/jiangxincode/cnblogs/tree/master/_posts) 18 | * [文章依赖图床](https://github.com/jiangxincode/PicGo) 19 | -------------------------------------------------------------------------------- /_data/navigation.yml: -------------------------------------------------------------------------------- 1 | main: 2 | - title: "Posts" 3 | url: /posts/ 4 | - title: "Categories" 5 | url: /categories/ 6 | - title: "Tags" 7 | url: /tags/ 8 | - title: "About" 9 | url: /about/ -------------------------------------------------------------------------------- /_drafts/Android/202301072210Doze模式源码解析.md: -------------------------------------------------------------------------------- 1 | 2 | 请先阅读谷歌官网对Doze的基础性介绍: 。本文代码分析基于Android R版本。 3 | 4 | -------------------------------------------------------------------------------- /_drafts/Android/2025-05-25-AOSP开发规范.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "AOSP开发规范" 3 | categories: 4 | - Android 5 | tags: 6 | - AOSP 7 | - 开发规范 8 | - Android 9 | toc: true 10 | --- 11 | 12 | * 在AOSP原生代码函数中增加侵入式修改,需要使用begin/end函数对其进行包裹,避免影响到原生代码的可读性和可维护性。 13 | * AOSP中尽量仅包含插装代码,避免包含业务逻辑代码。业务逻辑代码应该解耦到特定目录。 14 | * 禁止在AOSP原生AIDL中添加新的接口。 15 | * 新增加接口,注意是否需要进行权限控制。 16 | * 内部接口增加@hide注解,避免被外部反射调用。 17 | * 新增内容使用特性开关进行隔离。 18 | * 核心代码修改需要在特定评审会评审通过后才能进行代码提交。 19 | -------------------------------------------------------------------------------- /_drafts/Android/Android OTA升级.md: -------------------------------------------------------------------------------- 1 | ## Android A/B System OTA分析 2 | 3 | * Android A/B System OTA分析(一)概览: 4 | * Android A/B System OTA分析(二)系统image的生成: 5 | * Android A/B System OTA分析(三)主系统和bootloader的通信: 6 | * Android A/B System OTA分析(四)系统的启动和升级: 7 | 8 | ## Android OTA升级原理和流程分析 9 | 10 | * Android OTA升级原理和流程分析(一)--update.zip包的制作: 11 | * Android OTA升级原理和流程分析(二)---update.zip差分包问题的解决: 12 | * Android OTA升级原理和流程分析(三)---Android系统的三种启动模式: 13 | * Android OTA升级原理和流程分析(四)---Android系统Recovery模式的工作原理: 14 | * Android OTA升级原理和流程分析(五)---update.zip包从上层进入Recovery服务: 15 | * Android OTA升级原理和流程分析(六)---Recovery服务流程细节: 16 | * Android OTA升级原理和流程分析(七)---Recovery服务的核心install_package函数: 17 | * Android OTA升级原理和流程分析(八)---升级程序update_binary的执行过程: 18 | * Android OTA升级原理和流程分析(九)---updater-script脚本语法简介以及执行流程: 19 | -------------------------------------------------------------------------------- /_drafts/Android/Android Studio常用插件汇总.md: -------------------------------------------------------------------------------- 1 | * Android Localizationer: 2 | * ADB Idea 方便卸载apk,删除缓存: 3 | * Android ButterKnife Zelezny ButterKnife对应的插件: 4 | * Android Code Generator 生成ViewHolder,生成initView方法: 5 | * Codota 搜索代码块: 6 | * GsonFormat jsonString自动转bean插件: 7 | * SelectorChapek for Android 帮助生成selector: 8 | * Android Drawable Importer 同一张图片生成多个自动生成多分辨率图片: 9 | * Android Layout ID Converter xml到控件的转换: 10 | * Android Postfix Completion toast和log加强: 11 | * Android Studio Prettify 帮助findViewById: 12 | * Android Parcelable code generator 生成Parcelable代码: 13 | * Gradle Dependencies Helper gradle帮助插件: 14 | * Android Toolbox Plugin 生成ViewHolder,意义不大: -------------------------------------------------------------------------------- /_drafts/Android/Android Studio相关目录解析.md: -------------------------------------------------------------------------------- 1 | ## `%USERPROFILE%\.` 2 | 3 | 其中`CONFIGURATION_FOLDER`与Android Studio版本相关,比如对于Android Studio 3.0.1来说,该目录是指`C:\Users\jiang\.AndroidStudio3.0`。这个目录中保存着用户对于Android Studio的配置修改情况,比如你修改了字体、JVM参数等,都会在该文件中体现。如果你想重置Android Studid的设置,直接删除该文件夹,并重启Android Studio即可。想了解更详细的情况可以参考:[Configure Android Studio: ] 4 | 5 | ## `%USERPROFILE%\AppData\Local\Android\Sdk` 6 | 7 | 该目录保存了下载的SDK,该目录可以修改:`Settings -> Appearance & Behavior -> System Settings -> Android SDK` 8 | 9 | ## `%USERPROFILE%\.android` 10 | 11 | 该目录中保存了你的自定义AVD的配置,这些配置会覆盖SDK目录中的相关配置。如果你想重置Android Studid的设置除了要删除`%USERPROFILE%\.`,最好把该目录也删除,然后重启Android Studio。 -------------------------------------------------------------------------------- /_drafts/Android/Android Studio移动鼠标显示悬浮提示的设置方法.md: -------------------------------------------------------------------------------- 1 | 2 | 以Windows 10 + Android Studio 3.0.1为例 3 | 4 | 默认情况下,在Android Studio中将鼠标移动到函数位置处无法显示悬浮提示,需要进行如下设置: 5 | 6 | `File -> Settings -> Editor -> General` 选中`Show quick documentation on mouse move` 点击`OK` 7 | 8 | 但是此时如果将鼠标移动到函数位置处,会显示"fetching documentation",如果你网络比较好的话,等一会后会显示文档,但是如果网络不好的话则永远不会显示。这是因为Android Studio发现你没有在本地下载对应的文档,所以去google官网进行下载,速度比较慢。将文档下载到本地的方式是: 9 | 10 | `Toos -> Android -> SDK Manager` 选择`SDK Tools`页签,勾选`Documentation for Android SDK` 点击OK,下载完成后重启Android Studio应该很快看到悬浮文档提示了。 11 | 12 | 但是如果还不行的话,可能原因是对应的Android Studio版本优先从网络获取文档,即使你在本地下载了文档也不行,此时需要参考下面的地址,将默认读取方法进行修改: -------------------------------------------------------------------------------- /_drafts/Android/Android平台OpenGL ES_Assimp_OpenCV_GLM集成说明.md: -------------------------------------------------------------------------------- 1 | # Android平台OpenGL ES/Assimp/OpenCV/GLM集成说明 2 | 3 | 本文代码见: 4 | 5 | ## 集成Assimp 6 | 7 | * 下载Assimp 5.0.1版本: 8 | * 解压后本地目录为`D:\Code\temp\assimp-5.0.1` 9 | * 将`scripts\android_crosscompile\make_android.bat`拷贝为`scripts\android_crosscompile\make_android_self_defined.bat` 10 | * 将`scripts\android_crosscompile\make_android_self_defined.bat`中的内容进行自定义配置,我的配置如下: 11 | 12 | ```shell 13 | @echo off 14 | 15 | set ASSIMP_PATH=D:\Code\temp\assimp-5.0.1 16 | set CMAKE_PATH="C:\Users\jiangxin\AppData\Local\Android\Sdk\cmake\3.6.4111459\bin\cmake.exe" 17 | set ANDROID_NDK_PATH=C:\Users\jiangxin\AppData\Local\Android\Sdk\ndk\22.0.7026061 18 | set ANDROID_CMAKE_PATH=C:\Users\jiangxin\AppData\Local\Android\Sdk\ndk\22.0.7026061\build\cmake 19 | 20 | pushd %ASSIMP_PATH% 21 | 22 | rmdir /s /q build 23 | mkdir build 24 | cd build 25 | 26 | %CMAKE_PATH% .. ^ 27 | -G"MinGW Makefiles" ^ 28 | -DCMAKE_BUILD_TYPE=Release ^ 29 | -DCMAKE_CXX_FLAGS_RELEASE="%CMAKE_CXX_FLAGS_RELEASE% -Os -Wall -s" ^ 30 | -DCMAKE_TOOLCHAIN_FILE=%ANDROID_CMAKE_PATH%\android.toolchain.cmake ^ 31 | -DCMAKE_MAKE_PROGRAM=%ANDROID_NDK_PATH%\prebuilt\windows-x86_64\bin\make.exe ^ 32 | -DANDROID_NDK=%ANDROID_NDK_PATH% ^ 33 | -DANDROID_NATIVE_API_LEVEL=android-16 ^ 34 | -DASSIMP_ANDROID_JNIIOSYSTEM=ON ^ 35 | -DANDROID_ABI=arm64-v8a ^ 36 | -DASSIMP_BUILD_ZLIB=ON ^ 37 | -DASSIMP_BUILD_TESTS=OFF ^ 38 | -DASSIMP_BUILD_ASSIMP_TOOLS=OFF ^ 39 | -DASSIMP_NO_EXPORT=ON 40 | 41 | %CMAKE_PATH% --build . 42 | 43 | popd 44 | ``` 45 | 46 | * 执行如下编译命令: 47 | 48 | ```shell 49 | cd D:\Code\temp\assimp-5.0.1\scripts\android_crosscompile 50 | .\make_android_self_defined.bat 51 | ``` 52 | 53 | * 将`assimp-4.1.0\build\codelibassimp.so`放到`app\libs\` 54 | * 将`assimp-4.1.0\include`中的目录放到`app\src\main\cpp\include` 55 | * 将`assimp-4.1.0\build\include\assimp\config.h`拷贝到`app\src\main\cpp\assimp-4.1.0\include\assimp` 56 | 57 | ## 集成OpenCV 58 | 59 | OpenCV的集成比较简单,官网提供了Android平台所需的动态库和C++头文件。 60 | 61 | * 下载OpenCV 4.5.1版本: 62 | * 解压后本地目录为`D:\Code\temp\opencv-4.5.1-android-sdk` 63 | * 将`OpenCV-android-sdk\sdk\native\libs\arm64-v8a\libopencv_java4.so`拷贝到`app\libs\` 64 | * 将`OpenCV-android-sdk\sdk\native\jni\include`中的内容拷贝到`app\src\main\cpp\include` 65 | 66 | ## 集成GLM 67 | 68 | GLM的集成就更简单了,源码都是hpp文件(即定义和实现在同一个文件中)。 69 | 70 | * 下载GLM 0.9.9.8版本: 71 | * 解压后本地目录为`D:\Code\temp\glm-0.9.9.8` 72 | * 将`glm-0.9.9.8\glm`中的内容拷贝到`app\src\main\cpp\include` 73 | 74 | ## 参考 75 | 76 | * Android: Use Assimp to load a 3D model: 77 | * AssimpAndroid: 78 | * 使用Android Studio+CMakeLists编译assimp: 79 | * TestAssimp: 80 | * Assimp编译实录: 81 | -------------------------------------------------------------------------------- /_drafts/Android/Android真机安装sqlite3的方法.md: -------------------------------------------------------------------------------- 1 | 2 | Android版本: 4.4.2 3 | 4 | ```powershell 5 | PS C:\Users\jiang> adb shell 6 | shell@hwH60:/ $ su - root 7 | 8 | # 此时输入sqlite3 发现命令无法使用 9 | root@hwH60:/ # sqlite3 10 | tmp-mksh: sqlite3: not found 11 | 12 | # find一下相关文件,确定到底需要安装哪些内容,如果已经找到则不需要安装对应文件 13 | root@hwH60:/ # find . -name "sqlite3" 14 | root@hwH60:/ # find . -name "libsqlite.so" 15 | root@hwH60:/ # find . -name "libsqlite_jni.so" 16 | 17 | root@hwH60:/ # exit 18 | shell@hwH60:/ $ exit 19 | 20 | # 从https://files.cnblogs.com/files/jiangxinnju/sqlite3.zip处下载文件并解压。 21 | 22 | # 将相关文件放到内置存储卡中,为什么不直接放到/system/xbin/和/system/lib/可以参考 23 | PS D:\> adb push sqlite3 /storage/emulated/0/ 24 | PS D:\> adb push libsqlite.so /storage/emulated/0/ 25 | PS D:\> adb push libsqlite_jni.so /storage/emulated/0/ 26 | 27 | PS D:\> adb shell 28 | shell@hwH60:/ $ su - root 29 | 30 | # 为什么需要重新挂载/system分区可以参考 31 | root@hwH60:/ # mount -o remount rw /system 32 | 33 | # 将需要的文件从内置存储卡中转移到目标目录 34 | root@hwH60:/ # cp /storage/emulated/0/sqlite3 /system/xbin/ < 35 | root@hwH60:/ # cp /storage/emulated/0/libsqlite.so /system/lib/ 36 | root@hwH60:/ # cp /storage/emulated/0/libsqlite_jni.so /system/lib/ 37 | 38 | # 修改对应文件的权限 39 | root@hwH60:/ # chmod 4755 /system/xbin/sqlite3 40 | root@hwH60:/ # chmod 0644 /system/lib/libsqlite.so 41 | root@hwH60:/ # chmod 0644 /system/lib/libsqlite_jni.so 42 | 43 | # 执行sqlite3命令,发现已经可以使用 44 | root@hwH60:/ # sqlite3 45 | SQLite version 3.7.11 2012-03-20 11:35:50 46 | Enter ".help" for instructions 47 | Enter SQL statements terminated with a ";" 48 | sqlite> .exit 49 | 50 | root@hwH60:/ # exit 51 | 52 | # 删除内置存储卡中的文件 53 | shell@hwH60:/ $ rm -rf /storage/emulated/0/sqlite3 54 | shell@hwH60:/ $ rm -rf /storage/emulated/0/libsqlite.so 55 | shell@hwH60:/ $ rm -rf /storage/emulated/0/libsqlite_jni.so 56 | 57 | ``` -------------------------------------------------------------------------------- /_drafts/Android/解决adb push时出现的"Read-only file system"问题.md: -------------------------------------------------------------------------------- 1 | 2 | 出现`Read-only file system`问题,不是因为文件或者文件夹的权限不对,而是要push的目录对应的分区是以只读方式挂载的,网上给出的解决办法是重新以读写方式挂载对应分区,以`/system`分区为例,使用命令:`mount -o remount rw /system`,当然如果你想重新挂载系统分区需要有root权限。 3 | 4 | 但是你会发现,当你在adb shell中使用该方式重新挂载分区后,退出adb shell后用adb push命令向`/system`分区推送文件时仍然报错`Read-only file system`,这是因为在adb shell中重新挂载分区只针对当前的shell有效,在退出后该挂载方式失效。所以即使你打开两个cmd/powershell窗口,一个窗口使用adb shell重新挂载分区,在另一个窗口adb push也是不行的。 5 | 6 | 我这边最终尝试可行的方法是通过手机内置存储卡(外置SD卡也可以,但是有的手机没有外置SD卡)中转下,例如我想把计算机上的SystemUI.apk文件拷贝到手机的/system/app目录下,可以按照下面方式操作: 7 | 8 | ```powershell 9 | PS C:\Users\jiang> adb push .\SystemUI.apk /sdcard 10 | .\SystemUI.apk: 1 file pushed. 3.9 MB/s (2621700 bytes in 0.648s) 11 | PS C:\Users\jiang> adb shell 12 | shell@hwH60:/ $ su - root 13 | 130|root@hwH60:/ # mount -o remount rw /system 14 | root@hwH60:/ # cp /sdcard/SystemUI.apk /system/app/ 15 | shell@hwH60:/ $ cd /system/app 16 | root@hwH60:/system/app # chmod 644 SystemUI.apk 17 | ``` -------------------------------------------------------------------------------- /_drafts/C_Cpp/C++从键盘输入文件结束符.md: -------------------------------------------------------------------------------- 1 | 当我们使用一个istream对象作为条件时,其效果是检测流的状态。如果流是有效的,即流未遇到错误,那么检测成功。当遇到文件结束符,或遇到一个无效输入时(例如需要将输入读到一个int变量中,但实际从键盘输入的是字符),istream对象的状态会变成无效。处于无效的istream对象会是条件变为假。 2 | 3 | 当从键盘向程序输入数据时,对于如何指出文件结束符,不同的操作系统有不同的实现。在Windows平台中,输入文件结束符的方法是:按Ctrl+z,然后按Enter。在Unix或Linux下是按Ctrl+d,无需Enter,当然,由于当你输入Ctrl+d后,它仍然停留在系统的输入缓冲区中,所以你还是需要使用一个Enter使其生效。下面是几个关于该用法的示例: 4 | 5 | ```CPP 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | /* 11 | 测试标准输入cin和文件结束符 12 | 测试平台:Windows 13 | */ 14 | int test_string_one(); 15 | int test_string_two(); 16 | int test_string_three(); 17 | 18 | int main() 19 | { 20 | //test_string_one(); 21 | test_string_two(); 22 | } 23 | int test_string_one() //第一个程序:输入的是整数 24 | { 25 | int num; 26 | while(cin>>num) 27 | cout << num << " "; 28 | return 0; 29 | } 30 | /* 31 | 输入:1 2 3 4 5 Ctrl+d Enter 32 | 输出:1 2 3 4 5 33 | 此处之所以循环停止,是因为遇到一个无效输入(Ctrl+d),而不是遇到了文件结束符。 34 | 因为在windows平台,结束符是Ctrl+z,然后按Enter。 35 | 例如输入:1 2 3 4 5 a Enter 36 | 输出仍是:1 2 3 4 5 37 | 当然如果该测试用例用于Linux下,那么由于系统的结束符是Ctrl+d,所以虽然输出一样, 38 | 但是之所以循环停止,是因为到达了文件结束,而不是得到了一个无效输入。 39 | */ 40 | 41 | 42 | int test_string_two() //第二个程序:输入的是字符串 43 | { 44 | string word; 45 | while(cin>>word) 46 | cout << word << " "; 47 | return 0; 48 | } 49 | /* 50 | 输入:hello world Ctrl+z 回车 51 | 输出:hello world 52 | 此处之所以循环停止,是因为遇到一个文件结束符。 53 | 因为在windows平台,结束符是Ctrl+z,然后按Enter。 54 | */ 55 | ``` -------------------------------------------------------------------------------- /_drafts/C_Cpp/C++编译错误cannot have cv-qualifier.md: -------------------------------------------------------------------------------- 1 | const关键字放在非静态成员函数声明的尾部,表示该非静态成员函数不修改对象内容。volatile关键字放到非静态函数声明的尾部,表示该非静态成员函数是线程安全的。注意他们都只能放到非静态成员函数声明的尾部,否则会产生如下报错: 2 | `error: non-member function 'xxx' cannot have cv-qualifier` 3 | 放到非成员函数声明的尾部 4 | 5 | ```CPP 6 | #include 7 | 8 | using namespace std; 9 | 10 | double getSqureArea(int a) const 11 | { 12 | return a * a; 13 | } 14 | 15 | 16 | int main(int arg, char *argv[]) 17 | { 18 | cout << getSqureArea(2) << endl; 19 | return 0; 20 | } 21 | ``` 22 | 23 | 编译上面的C++程序,报错如下: 24 | 25 | ```shell 26 | g++ -c const_volatile_test.cpp -o const_volatile_test.o 27 | const_volatile_test.cpp:12:28: error: non-member function 'double getSqureArea(int)' cannot have cv-qualifier 28 | ``` 29 | 30 | 放到静态成员函数声明的尾部 31 | 32 | ```CPP 33 | #include 34 | 35 | using namespace std; 36 | 37 | class CStatic 38 | { 39 | private: 40 | static int static_value; 41 | public: 42 | static int get_static_value() const 43 | { 44 | return static_value; 45 | } 46 | }; 47 | 48 | int CStatic::static_value = 1; 49 | int main(int argc,char *argv[]) 50 | { 51 | cout << CStatic::get_static_value()< 37 | #include 38 | 39 | void terminateTest() 40 | { 41 | cout<<"程序正在结束..."< 15 | 16 | #include 17 | 18 | #include 19 | 20 | 21 | 22 | int test_rand() 23 | 24 | { 25 | 26 | int i; 27 | 28 | /* Seed therandom-number generator with current time so that 29 | 30 | * thenumbers will be different every time we run. 31 | 32 | */ 33 | 34 | srand((unsigned)time( NULL ) ); 35 | 36 | /* Display10 numbers. */ 37 | 38 | for( i = 0;i < 10; i++ ) 39 | 40 | printf("%6d\n", rand()); 41 | 42 | return 0; 43 | 44 | } 45 | ``` 46 | 47 | C的函数库之所以没有把使用系统时钟初始化随机种子这步重要的操作直接放进rand函数的实现中,可能有如下原因: 48 | 49 | 1.可以高效产生连续的随机数,不用每次都初始化; 50 | 51 | 2.给程序员以更高的灵活性,因为可能在要求较高的场合,应该使用更好的的数据做种子,而不是系统时钟; 52 | 53 | 3.对于只是想产生大量伪随机数来尽兴某种验证或者统计,未必需要初始化,大不了程序每次运行都产生同样的一系列随机数而已——有些情况下,这是无所谓的。 54 | 55 | 4.作为伪随机序列产生器的rand()函数,必须具备的一个重要特性就是:产生的序列必须是可重现的。这不仅仅是一个算法,相当大的程度上,它关系到代码测试的准确性。如果算法中使用了和rand()的结果相关的数据,通过一个可控的可重现序列,我们就有机会再现每一次测试的过程,从而更有效的找到问题的所在。所以这里提出一个建议,代码中,如果rand()的函数结果关系到算法的结果,那么,必须保证你的rand()调用是可重现的。 56 | 57 | 另外使用rand还用几个问题: 58 | 59 | * 如何生成 0到 100之间的随机数? 60 | 61 | 用"int x = rand() % 100;"这种方法是不或取的,会使产生的随机数不在随机。产生一个0到n之间的随机数的比较好的做法是: 62 | 63 | j=(int)(n*rand()/(RAND_MAX+1.0)); 64 | 65 | * 如何产生一个范围在(a,b)之间的随机数? 66 | 67 | 先计算a与b的差值,设c=b-a;产生一个介于0和b-a的数值,设 68 | 69 | d=(int)((b-a)*rand())/(RAND_MAX+1.0) 70 | 71 | 让上面产生的值d加上a就可以了。 72 | 73 | 如果你使用C++11编程,请使用C++11自己的随机数生成方法! 74 | 75 | 虽然前面介绍了那么多,但是我还是想说C语言的随机数生成方法有很多缺陷,很容易被引入非随机性,而且功能单一,如果可以的话去,你最好避免使用它。 -------------------------------------------------------------------------------- /_drafts/C_Cpp/const 不再迷茫.md: -------------------------------------------------------------------------------- 1 | 首先说明一下const在C和C++中的主要用法,被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。它可以修饰变量、函数的参数、返回值,甚至函数的定义体。 2 | 3 | ## const修饰变量 4 | 5 | const修饰变量通常用于定义符号常量。我们过去一般使用宏定义的方式定义符号常量,比如: 6 | 7 | `#define PI3.1415926` 8 | 9 | 其实我们也可以使用const方式定义符号常量,下面的语句与上面宏定义的方式达到的效果相似。 10 | 11 | `const double PI3.1415926` 12 | 13 | 那两者有什么区别呢?在使用宏定义的方式时,首先在预处理过程中将源程序中的常量名全部替换成对应的字面常量,然后对替换过的源程序进行编译。相比较之下const方式不涉及预处理过程,它只在编译过程中起作用。因为宏定义方式定义的符号常量没有类型,所以不能进行严格的类型检查,而const则可以,并且有些调试工具可以对const常量进行调试,而不能对宏常量进行调试。但这也不是说宏常量就比const常量差,比如你能够利用const常量实现下面的宏定义功能么? 14 | 15 | ```CPP 16 | #ifndefJIANGXIN_H 17 | #defineJIANGXIN_H 18 | #endef 19 | ``` 20 | 21 | 而且由于历史原因,实际上使用宏常量的情况远远大于const常量,特别是在纯C编程环境中。不过在C++编程环境中,我还是推荐你使用const,因为这更加安全。同时时刻记住一句话,const常量作用与编译期,宏常量作用于预编译期,当你遇到一些令人迷惑的问题时想想这句话,或许能够有所收获。 22 | 23 | 现在举几个例子: 24 | 25 | const int m = 0; //其实我们通常把const符号常量叫做const常量,以便和宏常量区分 26 | 27 | typedef char * pStr; //新的类型pStr,代表一个指向char的指针类型。 28 | 29 | char string[4] = "abc"; 30 | 31 | const char *p1 = string;//p1是一个指针,指向一个const char类型 32 | 33 | p1++; //正确,p1本身不是常量,它指向一个常量 34 | 35 | const pStr p2 = string; //p2是一个常量指针,这个指针指向一个char类型变量 36 | 37 | p2++; //错误,p2是一个常量指针 38 | 39 | char *const p3 = string; //p3同p2相同,是一个常量指针 40 | 41 | char const* p4 = string; //p4同p1相同,是一个指向const char的指针,只能用于C中,在C++中只能使用const char *p4 = string; 42 | 43 | 44 | ## const修饰函数形参 45 | 46 | 函数形参主要包括传值型参数,传指针型参数,传引用型参数。 47 | 48 | 对于传指针和传引用型参数,如果我们怕在该函数中错误的改变实参的值,一般都会加上const来修饰形参。 49 | 50 | 对于传值型参数,我们一般不会使用const修饰,因为完全没有必要,你是不是用const,都不能改变实参的值,因为传值型形参是在栈中分配的,函数调用之后一定会销毁。例如:void Fun(int n)和void Fun(const int n)没有任何区别,而且还是代码更加晦涩,所以不推荐。但是有一种情况需要考虑,如果你需要传递一个比较复杂的类类型,但是你又不需要改变该类的对象,这时你可以将传值改为传指针或者引用,同时用const修饰。这样的话就避免了构造临时对象的开销。比如加入A是一个很复杂的类类型,这是使用void Fun(const A &a)要比void Fun(A a)效率更高。 51 | 52 | ## 用const修饰函数的返回值 53 | 54 | 函数的返回值与形参类似,也包括返回值类型,返回指针类型,返回引用类型。 55 | 56 | 对于返回值类型为指针或者引用的情况,如果我们不希望其被修改,可以使用const对返回值进行限定。此时该返回值const修饰的同类型const指针(返回值为指针)或者同类型的const变量(返回值为引用,且该值为基本类型或者定义了拷贝构造函数、拷贝赋值运算符的类型)。如对于: 57 | 58 | const char * Fun(void); 59 | 60 | 如下语句将出现编译错误: 61 | 62 | char *str = Fun();//cannotconvert from 'const char *' to 'char *'; 63 | 64 | 正确的用法是: 65 | 66 | const char *str= Fun(); 67 | 68 | 如果返回值类型为值类型,由于函数会把返回值复制到外部函数的存储单元中,加const修饰没有任何价值,所以不要把函数int Fun(void) 写成const int Fun(void)。但是在某些情况下将值类型改为引用类型或者指针类型可以提高效率,可用不用const就看你要不要改变它们了。 69 | 70 | ## const修饰成员函数 71 | 72 | const关键字可以放在非静态成员函数声明的尾部,表示该函数不修改对象中的成员变量的值。注意const只能修饰非静态成员函数,不能修饰普通函数,无论是C还是C++。 73 | 74 | 有些人可能会疑惑为什么纯虚函数后面为什么一般都写const,其实如前所述,函数后面的const只是提示以后维护代码的人,这个函数里面没有改变变量的值。所以,只要是没有改变变量值的函数,就在后面写个const,纯虚函数当然没有改变某个变量的值,所以习惯上就加了const,成员函数用不用const关键在于这成员函数是不是要修改对象的数据成员。而与纯虚函数没什么关系。 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /_drafts/C_Cpp/屏幕输出VS文件输出.md: -------------------------------------------------------------------------------- 1 | ## 输出到屏幕快还是输出到文件快? 2 | 3 | 我们在编写程序时经常需要数一些数据到屏幕,来查看我们的结果是否正确,虽然直接输出到屏幕,查看起来呢很方便,但当数据量很大时,需要耗费大量的时间。于是我们想到能不能通过输出到文件来减少时间呢。相同的数据是输出到屏幕更快还是输出到文件更快? 4 | 5 | 这个地方变量有很多:磁盘速度、目的文件有没有其他IO请求、文字渲染的方式、API具体的操作流程、操作系统本身的设计等等都会影响输出到文件的速度。但一般来说还是会比直接输出到屏幕快(而且通常快几个数量级)。 6 | 7 | 比如我们可以用如下代码进行测试,如果测试输出到文件的时间就在开头加入#define ToFile,如果测试输出到屏幕的时间,就注释掉。 8 | 9 | ```c 10 | //#define ToFile 11 | #include 12 | #include 13 | 14 | int main() 15 | { 16 | clock_t start_test,end_test; 17 | start_test = clock(); 18 | FILE *output_fils; 19 | output_fils = fopen("output_file.txt","w"); 20 | if(output_fils == NULL) 21 | { 22 | perror("Error to create the file\n"); 23 | } 24 | long unsigned int i; 25 | for(i=0;i<1000000;i++) 26 | { 27 | #ifdef ToFile 28 | fprintf(output_fils,"item %ld\n",i); 29 | #else 30 | printf("item %ld\n",i); 31 | #endif 32 | } 33 | fclose(output_fils); 34 | end_test = clock(); 35 | printf("The total time is: %lf",((double)(end_test-start_test)/CLOCKS_PER_SEC)); 36 | return 0; 37 | } 38 | ``` 39 | 40 | 通过编译运行,我们会发现,如果输出到文件仅需要0.015s,但是直接输出到屏幕却需要12.906s,两者差距很大。 41 | 42 | ## 怎样编程使结果全部输出到文件? 43 | 44 | 当然,你可以在每个需要输出的地方用fprintf来设置输出到文件。但是考虑到那样太麻烦了,而且我们已经系管理直接使用printf,所以我们可以用一个函数freopen来把标准输出流导出到我们设定的文件流中,这样我们以后用printf输出到东西全部到达我们设定的文件中。 45 | 46 | 但是有个问题是,那我们如何在某些特定的时候在屏幕上输出提示信息呢?考虑到标准错误流也是输出到屏幕,所以我们可以假借这个标准错误流。示例代码如下: 47 | 48 | ```c 49 | #include 50 | 51 | int main() 52 | { 53 | int num; 54 | freopen("output_file.txt","w",stdout); 55 | fprintf (stderr,"Please input your num:"); // output to the screen 56 | scanf("%d",&num); 57 | printf("The num that you input is:%d",num); // output to the file 58 | fclose (stdout); 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /_drafts/C_Cpp/由函数clock想到的.md: -------------------------------------------------------------------------------- 1 | 2 | 今天介绍一下`clock`这个函数的使用,它是C标准库的一部分,声明在头文件``中,返回处理器使用的时间值,函数声明为: 3 | `clock_t clock(void);` 4 | 5 | 这个函数看起来很简单,但是当使用时还是有不少需要注意的地方,让我们先看看`clock_t`这个类型,它表示程序所占用的处理器时间,具体的实现可以是整形或者浮点型,例如我们如果查看`CodeBlock 12.11`中的`time.h`文件,可以看到如下定义: 6 | 7 | ```c 8 | /* 9 | * A type for measuring processor time (in clock ticks). 10 | */ 11 | #ifndef _CLOCK_T_DEFINED 12 | typedef long clock_t; 13 | #define _CLOCK_T_DEFINED 14 | #endif 15 | ``` 16 | 17 | 在这里,`clock_t`被定义为long类型,`MS Visual Studio`中的time.h与此完全相同,但是,如果你将其定义修改为double也没有什么不好的,虽然它的本意是指”ticks”,也就是中文中的“滴答”。那么什么是“滴答”呢?简单的将就是系统每发生一次时钟中断就会产生一个“滴答”,如果详细介绍的话,这设计很多系统内核时钟中断的问题,不过詹荣开老师在它的一篇文章`Linux内核的时钟中断`中对这些概念有着很详细透彻的解读,虽然文章发表于2003年,但其中的骨架知识仍然适用。 18 | 19 | 介绍完`clock_t`的概念,还要介绍一下`CLOCKS_PER_SEC`这个宏定义,(也是在time.h中),从它的字面意思就可得知,它指的是每秒的时钟滴答数,通过用clock函数返回值除以该值可以得到程序运行是实际秒数。`CLOCKS_PER_SEC`的实际值也是随着操作系统和编译器的差异而不同,例如现在Windows平台上的编译器通常会将其定义为1000,也就是说每秒会产生1000个时钟滴答数。而在一些比较古老的编译器中,比如说TC2.0中,该值是18.2个(当然,在TC2.0中不叫`CLOCKS_PER_SEC`,而叫`CLK_TCK`,但它们的实质是一样的,VC6.0中为了兼容保留了`CLK_TCK`的名称,但建议使用`CLOCKS_PER_SEC`),为什么不同的编译器的默认值差异这么大,这主要是因为与当时硬件条件有关,这是个历史问题,在这里就不继续探讨了。 20 | 21 | 另外,经常看到一些文章中把`CLOCKS_PER_SEC`翻译成每秒的时钟周期数,其实这是错误的,混淆了时钟周期(clock cycle)和时钟滴答(clock tick)的概念,关于这两个词的区别詹荣开老师也做了介绍。但如果你不想深挖,可以简单的认为要经过若干时钟周期才是一个时钟滴答,具体是多少个决定于系统中对可编程间隔定时器(Programmable Interval Timer,PIT)值的初始定义。 22 | 23 | 好了,说了这么多,让我们回到clock函数,它主要的用处是衡量我们程序时间开销,例如: 24 | 25 | ```c 26 | #include 27 | #include 28 | 29 | int main(int argc,char* argv[]) 30 | { 31 | clock_t clock_time,start_time,end_time; 32 | long int count = 1000000000; 33 | start_time = clock(); 34 | while(count--); 35 | end_time = clock(); 36 | clock_time = end_time - start_time; 37 | printf("The program runs %lf clocks\n",(double)clock_time); 38 | printf("The program runs %lf s\n",(double)(clock_time/CLOCKS_PER_SEC)); 39 | return 0; 40 | } 41 | ``` 42 | 43 | 程序的运行结果为: 44 | 45 | ```shell 46 | The program runs 8430.000000 clocks 47 | The program runs 8.000000 s 48 | ``` 49 | 50 | 由于在我的机器上,`CLOCKS_PER_SEC`的值被定义为1000,所以从结果上看是没有问题的。但我们稍微修改一下程序,把初始的count值改为10000,看看结果有什么不同。 51 | 52 | ```c 53 | #include 54 | #include 55 | 56 | int main(int argc,char* argv[]) 57 | { 58 |   clock_t clock_time,start_time,end_time; 59 |   long int count = 10000; 60 |   start_time = clock(); 61 |   while(count--); 62 |   end_time = clock(); 63 |   clock_time = end_time - start_time; 64 |   printf("The program runs %lf clocks\n",(double)clock_time); 65 |   printf("The program runs %lf s\n",(double)(clock_time/CLOCKS_PER_SEC)); 66 |   return 0; 67 | } 68 | 69 | 运行结果如下: 70 | 71 | ```shell 72 | The program runs 0.000000 clocks 73 | The program runs 0.000000 s 74 | ``` 75 | 76 | 咦,为什么变成了0,结合编译器为我们指出的运行时间并联系上面的程序,可以发现程序的问题出现在由于count值很小,计算机在不到一个滴答的时间内就完成了计算,又因为clock_t的默认类型是long型,所以会截断取整,所以结果会产生错误。问题根源找到了,那有没有什么解决办法呢?欢迎大家提出自己的见解。 77 | 78 | 参考文献:`The Standart C Library P.J.Plauger` 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /_drafts/C_Cpp/编程获得CPU的主频.md: -------------------------------------------------------------------------------- 1 | CPU的主频,即CPU内核工作的时钟频率(CPU Clock Speed)。CPU的主频表示在CPU内数字脉冲信号震荡的速度。主频和实际的运算速度存在一定的关系,但目前还没有一个确定的公式能够定量两者的数值关系,因为CPU的运算速度还要看CPU的流水线的各方面的性能指标(缓存、指令集,CPU的位数等等)。由于主频并不直接代表运算速度,所以在一定情况下,很可能会出现主频较高的CPU实际运算速度较低的现象。 2 | 3 | 在windows操作系统中,可以使用右键点击“我的电脑”,查看属性来获取CPU的主频信息,然而该信息是存在于注册表之中的。也就是说可以通过修改注册表来伪造CPU主频信息。那能不能用其它方法获得该信息呢? 4 | 5 | 检测CPU的速度,一般是测试在单位时间内运算的指令条数,但用这种方法有太大的局限性,由于受到很多因素的影响,准确度比较低,因为你不知道在你的程序外别的程序占用了多少的时间片。其实在586及之后处理器中,已经有了一条专用的指令来测试主频,那就是 RDTSC指令,意思是读取时间标记计数器(Read Time-Stamp Counter),Time-stamp counter 是处理器内部的一个64位的MSR (model specific register),处理器每时钟周期递增时间标签计数器 MSR 一次,在处理器复位时将它重设为 0。RDTSC 指令把 TSC的值低32位装入EAX中,高32位装入EDX中。如果CPU的主频是200MHz,那么在一秒钟内,TSC的值增加 200,000,000 次。所以在计算的时候,把两次的TSC差值除以两次的时间差值就是CPU的主频。 6 | 7 | 从上面的资料得到了一个思路:首先使用RDTSC指令获取1个TSC的值,将其存储起来,再延时1秒,使用RDTSC指令获取1个新的TSC值,并用其减去第一次获得的TSC值,即可得到该CPU的主频。用C和汇编混合的代码如下: 8 | 9 | ```c 10 | #include 11 | #include 12 | 13 | int main(int argc,char* argv[]) 14 | { 15 | static int time[2]; 16 | int quotient = 0; //商 17 | int remainder = 0; //余数 18 | 19 | __asm{ 20 | rdtsc // read time-stamp count 21 | mov ebx,offset time //将time的偏移地址存入ebx 22 | mov [ebx+0],edx //把TSC的值的高32位存入[ebx+0]中 23 | mov [ebx+4],eax //把TSC的值的低32位存入[ebx+4]中 24 | } 25 | Sleep(1000); 26 | __asm{ 27 | rdtsc // read time-stamp count 28 | mov ecx,offset time //将time的偏移地址存入ecx 29 | sub eax,[ecx+4] //把延时1秒后的TSC值的低32位减去1秒前的TSC值的低32位 30 | sbb edx,[ecx+0] //把延时1秒后的TSC值的高32位减去1秒前的TSC值的高32位 31 | 32 | mov ecx,1000000000 //转换成GHz 33 | div ecx 34 | mov quotient,eax //将结果中的商赋值于quotiend 35 | mov remainder,edx //将结果中的余数赋值于remainder 36 | } 37 | remainder = remainder / 10000000; //余数仅保留两位 38 | printf("该机主频为:%d.%d",quotient,remainder); 39 | return 0; 40 | } 41 | ``` 42 | 43 | 注意:寄存器 CR4 中的时间标签禁用 (TSD) 标志限制 RDTSC 的使用。清除 TSD 标志时,RDTSC 指令可以在任何特权级别执行;设置此标志时,指令只能在特权级别 0 执行。在特权级别 0 执行时,时间标签计数器还可以使用 RDMSR 指令读取。 44 | 45 | 但是在多核时代,RDTSC 指令的准确度大大削弱了,原因有如下几点: 46 | 47 | 1. 不能保证同一块主板上每个核的 CPU 时钟周期数(Time Stamp Counter)是同步的; 48 | 49 | 2. CPU 的时钟频率可能变化,例如笔记本电脑的节能功能; 50 | 51 | 3. 乱序执行导致 RDTSC 测得的周期数不准。 虽然 RDTSC 废掉了,高精度计时还是有办法的,在 Windows 上用 QueryPerformanceCounter 和 QueryPerformanceFrequency,Linux 上用 POSIX 的 clock_gettime 函数,以 CLOCK_MONOTONIC 参数调用。 52 | 53 | 在接下来的几篇文章章中,我会继续介绍相关内容。 54 | 55 | 参考文章: 56 | 57 | 1、多核时代不宜再用 x86 的 RDTSC 指令测试指令周期和时间 58 | 59 | http://blog.csdn.net/solstice/article/details/5196544 60 | 61 | 2、RDTSC命令详解 62 | 63 | http://blog.csdn.net/tbwood/article/details/5536597 -------------------------------------------------------------------------------- /_drafts/Database/DB2常用语句.md: -------------------------------------------------------------------------------- 1 | 2 | ```sql 3 | CREATE TABLE STAFF_BAK LIKE STAFF; 4 | INSERT INTO STAFF_BAK SELECT * FROM STAFF; 5 | 6 | SELECT * FROM STAFF_BAK; 7 | 8 | SELECT * FROM STAFF_BAK FETCH FIRST 10 ROWS ONLY; 9 | 10 | DELETE FROM STAFF_BAK; 11 | DROP TABLE STAFF_BAK; 12 | 13 | CREATE TABLE STAFF_BAK AS (SELECT * FROM STAFF) DEFINITION ONLY; 14 | 15 | -- 创建物化表 16 | CREATE TABLE STAFF_BAK AS (SELECT * FROM STAFF) 17 | DATA INITIALLY DEFERRED REFRESH DEFERRED; 18 | REFRESH TABLE STAFF_BAK; 19 | 20 | -- 系统表说明 21 | 22 | -- SYSIBM 基本表,对于db2使用进行最优化 23 | 24 | -- 存放系统中check约束的信息,系统为每个表的每一个check约束建立一条记录 25 | SELECT * FROM SYSIBM.SYSCHECKS; 26 | 27 | -- 存放系统中所有表的数据列的描述信息,系统为db2里定义的每个表的每一列建立一条记录 28 | SELECT * FROM SYSIBM.SYSCOLUMNS; 29 | 30 | -- 为每个索引建立一条记录 31 | SELECT * FROM SYSIBM.SYSINDEXES; 32 | 33 | -- 系统为每一个表,视图和别名在该表中创建一行记录 34 | SELECT * FROM SYSIBM.SYSTABLES; 35 | 36 | -- 每个plan有一条记录 37 | SELECT * FROM SYSIBM.SYSPLAN; 38 | 39 | SELECT * FROM SYSIBM.SYSNODEGROUPDEF; 40 | 41 | -- SYSCAT 基于SYSIBM表的视图,对平常轻负荷使用进行优化 42 | 43 | -- 这两个视图显示被注册的包装器和它们特定的选项 44 | SELECT * FROM SYSCAT.WRAPPERS; 45 | SELECT * FROM SYSCAT.WRAPOPTIONS; 46 | 47 | 48 | -- 这两个视图显示被注册的远程数据源和它们的特定选项 49 | SELECT * FROM SYSCAT.SERVERS; 50 | SELECT * FROM SYSCAT.SERVEROPTIONS; 51 | 52 | 53 | -- 这个视图显示被注册的一个db2用户用于特定服务器的用户认证 54 | SELECT * FROM SYSCAT.USEROPTIONS; 55 | 56 | -- 这个视图显示分区表信息 57 | SELECT * FROM SYSCAT.DATAPARTITIONS; 58 | 59 | -- SYSSTAT 数据库分析 60 | 61 | 62 | CREATE DATABASE 'JXDB'; 63 | 64 | -- 创建分区表 65 | CREATE TABLE MUSIC(ID INTEGER,NAME VARCHAR(20),STYLE VARCHAR(20),STYLE_CODE INTEGER) 66 | PARTITION BY RANGE(STYLE_CODE) 67 | (PART P1 STARTING '1',PART P2 STARTING '2',PART P3 STARTING '3',PART P4 STARTING '4' ENDING MAXVALUE); 68 | 69 | INSERT INTO MUSIC VALUES(1,'HAVE A NICE DAY','POP',2); 70 | INSERT INTO MUSIC VALUES(2,'WE WILL ROCK YOU','ROCK',1); 71 | 72 | DESCRIBE DATA PARTITIONS FOR TABLE MUSIC SHOW DETAIL; 73 | 74 | SELECT DATAPARTITIONNAME,TABNAME,AVGROWSIZE FROM SYSCAT.DATAPARTITIONS WHERE TABNAME = 'MUSIC'; 75 | ``` -------------------------------------------------------------------------------- /_drafts/Database/MYSQL常见错误及其解决方式.md: -------------------------------------------------------------------------------- 1 | 2 | # ERROR 1130: Host 10.0.0.1 is not allowed to connect to this MySQL server 3 | 4 | 在用远程连接MySQL服务器的数据库,不管怎么弄都是连接不到,错误代码是1130,ERROR 1130: Host 10.0.0.1 is not allowed to connect to this MySQL server 5 | 猜想是无法给远程连接的用户权限问题。结果这样子操作MySQL库,即可解决。在本机登入MySQL后,更改 “mysql” 数据库里的 “user” 表里的 “host” 项,从”localhost”改称'%'。 6 | 7 | ```SQL 8 | mysql -u root -p 9 | use mysql; 10 | select `Host`, `User` from `user` where `User` = 'root'; 11 | update user set host = '%' where user ='root'; 12 | flush privileges; 13 | select `Host`, `User` from `user` where `User` = 'root'; 14 | ``` 15 | 第一句是以权限用户root登录;第二句:选择mysql库;第三句:查看mysql库中的user表的host值;第四句:修改host值(以通配符%的内容增加主机/IP地址),当然也可以直接增加IP地址;第五句:刷新MySQL的系统权限相关表;第六句:再重新查看user表时。重启mysql服务即可完成。 16 | 17 | # ERROR 1044 (42000):Access denied for user 18 | 19 | 这个问题主要是因为授权用户本身的权限不足引起的。我们以root用户为例,需要注意到地方有以下几个方面: 20 | 21 | * MySQL的user表很重要。必须保证root用户在user表里面有两条记录,也就是 22 | root localhost …….. 23 | root 127.0.0.1 ……. 24 | 25 | * 保证root用户拥有所有权限,也就是user表里面的所有字段里面对应的内容是Y 26 | * 在my.ini后者my.cnf里面有这个配置项的时候 27 | bind-address=localhost 28 | 启用这个配置项可以保证安全 29 | 30 | # Error: 1265 SQLSTATE: 01000 (WARN_DATA_TRUNCATED 31 | 32 | * 字符长度太短; 33 | * 乱码,更改统一的字符类型,比如更改字符类型为utf8; 34 | * 如果是 Enum,则可能是添加的字符不在enum类型范围内; 35 | * 另一可能是在alter table更改列设置时,影响原来存入的值,这时可将原值update为需要的类型值或删除这些原值再alter table 36 | 37 | # error while loading shared libraries: libtinfo.so.5 38 | 39 | ncurses包(ncurses-libs-5.6)已经安装,运行mysql时仍然提示: 40 | 41 | mysql: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory 42 | 43 | 此时只需要创建软连接即可,创建命令如下: 44 | 45 | ``` 46 | ln -s /usr/lib/libncurses.so.5 /lib/libtinfo.so.5 47 | ``` 48 | 49 | 其中`libncurses.so.5`到底在哪个目录,不同的OS可能有所不同(比如SUSE X64就是在`/lib64`目录下),可以尝试使用`ldd mysql`命令查看mysql依赖的其它库在哪个目录,然后在对应目录查找是否有`libncurses.so.5` 50 | 51 | # No curses/termcap library found 52 | 53 | 源码安装MySQL 5.1.30,在./configure阶段报错如下: 54 | 55 | ``` 56 | checking for tgetent in -lncurses... no 57 | checking for tgetent in -lcurses... no 58 | checking for tgetent in -ltermcap... no 59 | checking for tgetent in -ltinfo... no 60 | checking for termcap functions library... configure: error: No curses/termcap library found 61 | ``` 62 | 63 | 原因是缺少ncurses的相关库,按照下面方式安装ncurses即可: 64 | 65 | ```sh 66 | # RedHat系列 67 | yum list|grep ncurses 68 | yum -y install ncurses-devel 69 | yum install ncurses-devel 70 | 71 | # Debian系列 72 | apt-cache search ncurses 73 | apt-get install libncurses5-dev 74 | ``` -------------------------------------------------------------------------------- /_drafts/Database/MySQL默认数据库.md: -------------------------------------------------------------------------------- 1 | 2 | INFORMATION_SCHEMA:提供了访问数据库元数据的方式。 3 | 元数据是关于数据的数据,如数据库名、表名、列的数据类型或访问权限等。有些时候用于表述该信息的其他术语包括“数据词典”和“系统目录”。你可以讲INFORMATION_SCHEMA看成一个信息数据库,其中保存着关于MySQL服务器所维护的所有其他数据库的信息。在INFORMATION_SCHEMA中,有数个只读表。它们实际上是视图,而不是基本表,因此你将无法看到与之相关的任何文件。每位MySQL用户均有权访问这些表,但仅限于表中的特定行,在这类行中含有用户具有恰当访问权限的对象。 4 | 5 | PERFORMANCE_SCHEMA:主要用于收集数据库服务器性能参数。MySQL用户是不能创建存储引擎为PERFORMANCE_SCHEMA的表。performance_schema提供以下功能:提供进程等待的详细信息,包括锁、互斥变量、文件信息;保存历史的事件汇总信息,为提供MySQL服务器性能做出详细的判断;对于新增和删除监控事件点都非常容易,并可以随意改变mysql服务器的监控周期,例如(CYCLE、MICROSECOND)。通过以上得到的信息,DBA能够较明细得了解性能降低可能是由于哪些瓶颈。 6 | 7 | mysql:这个是mysql的核心数据库,类似于sql server中的master表,主要负责存储数据库的用户、权限设置、关键字等mysql自己需要使用的控制和管理信息。不可以删除,如果对mysql不是很了解,也不要轻易修改这个数据库里面的表信息。 8 | 9 | test:这个是安装时候创建的一个测试数据库,和它的名字一样,是一个完全的空数据库,没有任何表,可以删除。 -------------------------------------------------------------------------------- /_drafts/Database/Oracle中session和processes的设置.md: -------------------------------------------------------------------------------- 1 | 2 | * PROCESSES: http://docs.oracle.com/cd/B28359_01/server.111/b28320/initparams188.htm#sthref560 3 | * SESSIONS: http://docs.oracle.com/cd/B28359_01/server.111/b28320/initparams220.htm#sthref647 4 | * TRANSACTIONS: http://docs.oracle.com/cd/B28359_01/server.111/b28320/initparams248.htm 5 | 6 | * Oracle 11gR2之前:sessions=(1.1*processes) + 5 7 | * Oracle 11gR2之后:sessions=(1.5*porcesses) + 22 8 | 9 | 当Oracle需要启动新的process而又已经达到processes参数时,就会报错: 10 | 11 | ```shell 12 | 00020, 00000, "maximum number of processes (%s) exceeded" 13 | // *Cause: All process state objects are in use. 14 | // *Action: Increase the value of the PROCESSES initialization parameter. 15 | ``` 16 | 17 | 当数据库连接的并发用户已经达到sessions这个值时,又有新session连进来,就会报错 18 | 19 | ```shell 20 | 00018, 00000, "maximum number of sessions exceeded" 21 | // *Cause: All session state objects are in use. 22 | // *Action: Increase the value of the SESSIONS initialization parameter. 23 | ``` 24 | 25 | 如何使用sqlplus查看、修改processes呢?使用sys,以sysdba权限登录: 26 | 27 | ```shell 28 | show parameter processes; --显示:processes integer 150 29 | show parameter sessions; --显示:sessions integer 165 30 | select count(*) from v$process; --显示当前processes数目 31 | select count(*) from v$session; --显示当前sessions数目 32 | alter system set processes=400 scope = spfile; --显示系统已更改 33 | show parameter processes; --显示:processes integer 150 34 | create pfile from spfile; --显示:文件已创建。 35 | 36 | --重启数据库 37 | shutdown immediate; 38 | startup 39 | 40 | --重启监听 41 | lsnrctl stop/start/status 42 | 43 | show parameter processes; --显示:processes integer 400 44 | show parameter session; --显示:sessions integer 445 45 | ``` -------------------------------------------------------------------------------- /_drafts/Database/Oracle导入导出常用命令.md: -------------------------------------------------------------------------------- 1 | ```sql 2 | -- 全量导出 3 | exp system/manager@TEST file=d:\daochu.dmp full=y 4 | 5 | -- 将数据库中system用户与sys用户的表导出 6 | exp system/manager@TEST file=d:\daochu.dmp owner=(system,sys) 7 | 8 | -- 将数据库中的表table1中的字段filed1以"00"打头的数据导出 9 | exp system/manager@TEST file=d:\daochu.dmp tables=(table1) query=\" where filed1 like '00%'\" 10 | 11 | -- 将数据库中的表table1/table2导出 12 | exp system/manager@TEST file=d:\daochu.dmp tables=(table1,table2) 13 | 14 | 15 | -- 将d:\daochu.dmp中的表table1/table2导入 16 | -- 如果在Linux下导入导出,需要使用 tables="(table1,table2)",否则报错"syntax error near unexpected token(" 17 | imp system/manager@TEST file=d:\daochu.dmp tables=(table1,table2) 18 | ``` -------------------------------------------------------------------------------- /_drafts/Database/忘记oracle的sys用户密码怎么修改以及Oracle 11g 默认用户名和密码.md: -------------------------------------------------------------------------------- 1 | 2 | ## 忘记除SYS、SYSTEM用户之外的用户的登录密码 3 | 4 | CONN SYS/PASS_WORD AS SYSDBA; --用SYS (或SYSTEM)用户登录 5 | ALTER USER user_name IDENTIFIED BY "newpassword"; --修改用户的密码,密码不能是数字开头,否则会出现:ORA-00988: 口令缺失或无效 6 | 7 | ## 忘记SYS用户,或者是SYSTEM用户的密码 8 | 9 | CONN SYS/PASS_WORD AS SYSDBA; --如果是忘记SYSTEM用户的密码,可以用SYS用户登录。 10 | ALTER USER SYSTEM IDENTIFIED BY "newpassword"; 11 | 12 | CONN SYSTEM/PASS_WORD AS SYSDBA; --如果是忘记SYS用户的密码,可以用SYSTEM用户登录。 13 | ALTER USER SYS IDENTIFIED BY "newpassword"; 14 | 15 | ## SYS,SYSTEM用户的密码都忘记 16 | 17 | Oracle提供了两种验证方式,一种是OS验证,另一种密码文件验证方式,如果是第一种方式用以下方法修改密码: 18 | 19 | ```sql 20 |   sqlplus /nolog; 21 |   connect / as sysdba 22 |   alter user sys identified by newpassword; 23 |   alter user system identified by newpassword; 24 | ``` 25 | 26 | 如果是第二种方法可以使用ORAPWD.EXE 工具修改密码。打开命令提示符窗口,输入如下命令: 27 | 28 | orapwd file=D:\oracle10g\database\pwdctcsys.ora password=newpassword 29 | 30 | 这个命令重新生成了数据库的密码文件。密码文件的位置在ORACLE_HOME目录下的\database目录下。这个密码是修改sys用户的密码。除sys其他用户的密码不会改变。也可以下方法修改密码,设定完后,重新启动服务,再次登陆就可以了。 31 | 32 | orapwd file=pwdxxx.ora password=newpassword entries=10 33 | 34 | 35 | ## Oracle 11g 默认用户名和密码 36 | 37 | 安装ORACLE时,若没有为下列用户重设密码,则其默认密码如下: 38 | 39 | 用户名/密码 登录身份 说明 40 | sys/change_on_install SYSDBA 或 SYSOPER 不能以 NORMAL 登录,可作为默认的系统管理员 41 | system/manager SYSDBA 或 NORMAL 不能以 SYSOPER 登录,可作为默认的系统管理员 42 | sysman/oem_temp sysman 为 oms 的用户名 43 | scott/tiger NORMAL 普通用户 44 | aqadm/aqadm SYSDBA 或 NORMAL 高级队列管理员 45 | Dbsnmp/dbsnmp SYSDBA 或 NORMAL 复制管理员 46 | 47 | 登录身份:指登录时的Role指定,oracle11g中分SYSDBA和default两种。在安装Oracle 10g的时候,提示创建数据库,在创建的同时提示你输入口令,若此时你输入了密码,在登录数据库的时候用户名sys 对应的密码就应该是你创建数据库时候输入的口令。而非默认的change_on_install. -------------------------------------------------------------------------------- /_drafts/Database/数据库相关总结.md: -------------------------------------------------------------------------------- 1 | 2 | # 通用: 3 | 4 | * http://db-engines.com/en/ranking 5 | 6 | 7 | # MySQL 8 | 9 | * MySQL: http://www.mysql.com/ 10 | * MySQL参考:http://dev.mysql.com/doc/#manual 11 | * windows下忘记mysql超级管理员root密码的解决办法:http://superman7020.blog.163.com/blog/static/1374465920085210119253/ 12 | * 5款常用mysql slow log分析工具的比较:http://blog.chinaunix.net/uid-8504518-id-2030594.html 13 | * Autocomplete in MySQL under Windows: http://stackoverflow.com/questions/269653/autocomplete-in-mysql-under-windows 14 | 15 | 16 | # SQL Server 17 | 18 | * SQL Server: https://msdn.microsoft.com/library/bb545450.aspx 19 | * Transact-SQL 参考: https://msdn.microsoft.com/zh-cn/library/bb510741(v=sql.105).aspx 20 | * TSQLT:http://tsqlt.org/ 21 | * sqlcmd 实用工具:http://msdn.microsoft.com/zh-cn/library/ms162773.aspx 22 | * SQL SERVER 2005中的Schema(架构)概念详解:http://blog.sina.com.cn/s/blog_5b2c0dcc0100alj9.html 23 | * Sql Server 2005中的架构(Schema)、用户(User)、角色(Role)和登录(Login)(一):http://www.cnblogs.com/end/archive/2009/08/07/1541373.html 24 | * Sql Server 2005中的架构(Schema)、用户(User)、角色(Role)和登录(Login)(二):http://www.cnblogs.com/end/archive/2009/08/07/1541374.html 25 | * Sql Server 2005中的架构(Schema)、用户(User)、角色(Role)和登录(Login)(三):http://www.cnblogs.com/end/archive/2009/08/07/1541377.html 26 | * 谓词和运算符:http://www.cnblogs.com/cuiyh/archive/2010/12/18/1910090.html 27 | * Tempdb数据库详细介绍:http://www.cnblogs.com/qanholas/archive/2012/01/05/2313006.html 28 | 29 | 30 | # Oracle 31 | 32 | * Oracle Database DownLoad: http://www.oracle.com/technetwork/cn/database/enterprise-edition/downloads/index.html 33 | * Oracle SQL Developer: http://www.oracle.com/technetwork/developer-tools/sql-developer/overview/index.html 34 | * Instant Client Downloads for Microsoft Windows (32-bit): http://www.oracle.com/technetwork/topics/winsoft-085727.html 35 | 36 | * Oracle SQL Handler:http://www.heartblue.cn/ 37 | * SI Object Browser:http://www.presoft.com.cn/ob/ 38 | 39 | * Oracle Berkeley DB:http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/overview/index.html 40 | 41 | * Navicat: http://www.navicat.com.cn/ 42 | * Navicat Premium: http://www.navicat.com.cn/products/navicat-premium 43 | 44 | Navicat Premium 是一套数据库管理工具,让你以单一程序同時连接到 MySQL、MariaDB、SQL Server、SQLite、Oracle 和 PostgreSQL 数据库。 45 | 46 | * ToadWorld: http://www.toadworld.com/ 47 | 48 | * Oracle 11g安装图文攻略: http://jingyan.baidu.com/article/9f7e7ec04c14c76f29155465.html 49 | * win7_oracle11g_64位连接32位PLSQL_Developer: http://jingyan.baidu.com/article/fb48e8be4c7c206e622e1491.html 50 | * Oracle 11g 如何创建数据库:http://jingyan.baidu.com/article/cbcede07cf42ef02f40b4dc2.html 51 | * 数据库使用详解:[3]SQL Developer如何配置:http://jingyan.baidu.com/article/e4511cf33f289e2b845eafb6.html 52 | * oracle的各版本发行时间及特点: http://blog.csdn.net/dream19881003/article/details/7178357 53 | * oracle客户端软件的说明:http://blog.csdn.net/haiross/article/details/17917637 54 | * 怎么判断oracle客户端、服务器端的位数:http://blog.csdn.net/linghe301/article/details/8471945 55 | 56 | 57 | # DB2 58 | 59 | * 官网:http://www-01.ibm.com/software/data/db2/ 60 | * DB2China:http://www.db2china.net/ -------------------------------------------------------------------------------- /_drafts/Java/202110171056如何将cpdetector发布Maven依赖到中央仓库.md: -------------------------------------------------------------------------------- 1 | 参考: 2 | https://www.cnblogs.com/jiangxinnju/p/9903517.html 3 | 4 | 从官网下载最新版本的发布包 5 | https://sourceforge.net/projects/cpdetector/ 6 | 7 | 1、生成cpdetector_1.0.10_bundle.jar 8 | 9 | 解压后把几个依赖的包放到一起,为了简单把cpdetector*.jar和几个扩展依赖打包到一起,解压各个jar包 10 | jar -xvf .\cpdetector_1.0.10.jar 11 | jar -xvf .\chardet-1.0.jar 12 | jar -xvf .\antlr-2.7.4.jar 13 | jar -xvf .\jargs-1.0.jar 14 | 把jar包移除,然后 15 | jar -cvfM cpdetector-1.0.10.jar . 16 | 17 | 2、生成cpdetector-1.0.10-javadoc.jar和cpdetector-1.0.10-sources.jar 18 | 19 | jar -cvf cpdetector-1.0.10-javadoc.jar .\binary-release.txt .\MPL-1.1.txt 20 | jar -cvf cpdetector-1.0.10-sources.jar .\binary-release.txt .\MPL-1.1.txt 21 | 22 | 3、生成cpdetector-1.0.10.pom 23 | 24 | 然后创建pom.xml,填写对应信息。 25 | 26 | ```xml 27 | 30 | 4.0.0 31 | com.github.jiangxincode 32 | cpdetector 33 | 1.0.10 34 | jar 35 | cpdetector 36 | cpDetector is a proxy for codepage detection of documents. It delegates to multiple instances that try to detect the codepage by different techinques. A command line executeable is shipped that allows to sort documents by codepage. 37 | https://sourceforge.net/projects/cpdetector/ 38 | 39 | 40 | MPL-1.1 41 | https://www.mozilla.org/en-US/MPL/1.1/ 42 | 43 | 44 | 45 | git://git.code.sf.net/p/cpdetector/sourcecode cpdetector-sourcecode 46 | git://git.code.sf.net/p/cpdetector/sourcecode cpdetector-sourcecode 47 | git://git.code.sf.net/p/cpdetector/sourcecode cpdetector-sourcecode 48 | 49 | 50 | 51 | achimwestermann 52 | 53 | 54 | 55 | ``` 56 | 57 | 4、生成对应的asc签名文件 58 | 59 | gpg --gen-key创建密钥(密码12345678) 60 | 61 | pub rsa3072 2021-10-17 [SC] [expires: 2023-10-17] 62 | 6F52975E26BFE145B5A23C55A11AA01F0E9838A9 63 | uid Aloys 64 | sub rsa3072 2021-10-17 [E] [expires: 2023-10-17] 65 | 66 | 分发公钥到某个公钥服务器 67 | gpg --keyserver hkp://keyserver.ubuntu.com --send-keys 6F52975E26BFE145B5A23C55A11AA01F0E9838A9 68 | 69 | gpg -ab .\cpdetector-1.0.10.jar 70 | gpg -ab .\cpdetector-1.0.10-javadoc.jar 71 | gpg -ab .\cpdetector-1.0.10-sources.jar 72 | gpg -ab .\cpdetector-1.0.10.pom 73 | 74 | 5、打包到一起 75 | jar -cvf bundle.jar cpdetector-1.0.10* -------------------------------------------------------------------------------- /_drafts/Java/Calendar类中add_set_roll方法的区别.md: -------------------------------------------------------------------------------- 1 | 2 | Calendar类中有三个方法更改日期的某个字段:set()、add() 和 roll()。 3 | 4 | set(f, value) 将日历字段 f 更改为 value。此外,它设置了一个内部成员变量,以指示日历字段 f 已经被更改。尽管日历字段 f 是立即更改的,但是直到下次调用 get()、getTime()、getTimeInMillis()、add() 或 roll()时才会重新计算日历的时间值(以毫秒为单位)。因此,多次调用 set() 不会触发多次不必要的计算。使用 set()更改日历字段的结果是,其他日历字段也可能发生更改,这取决于日历字段、日历字段值和日历系统。此外,在重新计算日历字段之后,get(f) 没必要通过调用 set 方法返回 value 集合。具体细节是通过具体的日历类确定的。 5 | 6 | 示例:假定 GregorianCalendar 最初被设置为 1999 年 8 月 31 日。调用 set(Calendar.MONTH, Calendar.SEPTEMBER) 将该日期设置为 1999 年 9 月 31 日。如果随后调用 getTime(),那么这是解析 1999 年 10 月 1 日的一个暂时内部表示。但是,在调用 getTime() 之前调用 set(Calendar.DAY_OF_MONTH, 30) 会将该日期设置为 1999 年 9 月 30 日,因为在调用 set() 之后没有发生重新计算。 7 | 8 | add(f, delta) 将 delta 添加到 f 字段中。这等同于调用 set(f, get(f) + delta),但要带以下两个调整: 9 | 10 | * Add 规则 1。调用后 f 字段的值减去调用前 f 字段的值等于 delta,以字段 f 中发生的任何溢出为模。溢出发生在字段值超出其范围时,结果,下一个更大的字段会递增或递减,并将字段值调整回其范围内。 11 | 12 | * Add 规则 2。如果期望某一个更小的字段是不变的,但让它等于以前的值是不可能的,因为在字段 f发生更改之后,或者在出现其他约束之后,比如时区偏移量发生更改,它的最大值和最小值也在发生更改,然后它的值被调整为尽量接近于所期望的值。更小的字段表示一个更小的时间单元。HOUR 是一个比 DAY_OF_MONTH 小的字段。对于不期望是不变字段的更小字段,无需进行任何调整。日历系统会确定期望不变的那些字段。 13 | 14 | 此外,与 set() 不同,add() 强迫日历系统立即重新计算日历的毫秒数和所有字段。 15 | 16 | 示例:假定 GregorianCalendar 最初被设置为 1999 年 8 月 31 日。调用 add(Calendar.MONTH, 13) 将日历设置为 2000 年 9 月 30 日。Add 规则 1 将 MONTH 字段设置为 September,因为向 August 添加 13 个月得出的就是下一年的 September。因为在 GregorianCalendar 中,DAY_OF_MONTH 不可能是 9 月 31 日,所以 add 规则 2 将DAY_OF_MONTH 设置为 30,即最可能的值。尽管它是一个更小的字段,但不能根据规则 2 调整 DAY_OF_WEEK,因为在 GregorianCalendar 中的月份发生变化时,该值也需要发生变化。 17 | 18 | roll(f, delta) 将 delta 添加到 f 字段中,但不更改更大的字段。这等同于调用 add(f, delta),但要带以下调整: 19 | 20 | * Roll 规则。在完成调用后,更大的字段无变化。更大的字段表示一个更大的时间单元。DAY_OF_MONTH是一个比 HOUR 大的字段。 21 | 22 | 示例:请参阅 GregorianCalendar.roll(int, int)。 23 | 24 | 使用模型。为了帮助理解 add() 和 roll() 的行为,假定有一个用户界面组件,它带有用于月、日、年和底层GregorianCalendar 的递增或递减按钮。如果从界面上读取的日期为 1999 年 1 月 31 日,并且用户按下月份的递增按钮,那么应该得到什么?如果底层实现使用 set(),那么可以将该日期读为 1999 年 3 月 3 日。更好的结果是 1999 年 2 月 28 日。此外,如果用户再次按下月份的递增按钮,那么该日期应该读为 1999 年 3 月 31 日,而不是 1999 年 3 月 28 日。通过保存原始日期并使用 add() 或 roll(),根据是否会影响更大的字段,用户界面可以像大多数用户所期望的那样运行。 25 | 26 | 假设:f= 2001-1-30 27 | f.add(Calendar.MONTH, 13) = 2002.2.28 28 | f.set(Calendar.MONTH,1) = 2002.3.2 29 | f.roll(Calendar.MONTH, 13) = 2001.2.28 30 | 31 | Add:修改后如果符合实际,会调整,但不会改变调整的值,如例子中的MONTH。 32 | Set: 会改变如把2月改为3月。 33 | roll:于Add类似,不同在于不会改变更大的日期单位,如还是2001 不会为2002。 34 | 35 | 下面为代码演示: 36 | 37 | ```java 38 | Calendar c=Calendar.getInstance(); 39 | //c.setTimeInMillis(System.currentTimeMillis()); 40 | 41 | c.set(2001,0,30); 42 | c.add(Calendar.MONTH, 13); 43 | System.out.println(c.getTime().toString()); 44 | c.set(2001,0,30); 45 | c.set(Calendar.MONTH,1); 46 | System.out.println(c.getTime().toString()); 47 | c.set(2001,0,30); 48 | c.roll(Calendar.MONTH, 13); 49 | System.out.println(c.getTime().toString()); 50 | ``` 51 | 52 | 结果: 53 | 54 | ``` 55 | Thu Feb 28 10:22:37 CST 2002 56 | Fri Mar 02 10:22:37 CST 2001 57 | Wed Feb 28 10:22:37 CST 2001 58 | ``` 59 | 60 | 注意,Calendar.MONTH是从0开始的,也就是说一月用0表示 -------------------------------------------------------------------------------- /_drafts/Java/Eclipse+Spark搭建源码分析环境问题分析.md: -------------------------------------------------------------------------------- 1 | 2 | # Scala IDE complains about ‘... is cross-compiled with an incompatible version of Scala ...’ 3 | 4 | * http://scala-ide.org/docs/current-user-doc/faq/index.html 5 | 6 | 7 | # "Cannot run program "bash" ...: CreateProcess error=2" 8 | 9 | [ERROR] Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.8:run (default) on project spark-core_2.11: An Ant BuildException has occured: Execute failed: java.io.IOException: Cannot run program "bash" (in directory "D:\temp\Scala\spark\core"): CreateProcess error=2, 系统找不到指定的文件。 10 | 11 | * http://blog.csdn.net/xubo245/article/details/52073805 12 | 13 | 14 | # "Failed to execute goal org.apache.maven.plugins:maven-clean-plugin:3.0.0:clean..." 15 | 16 | [ERROR] Failed to execute goal org.apache.maven.plugins:maven-clean-plugin:3.0.0:clean (default-clean) on project spark-parent_2.10: Failed to clean project: Failed to delete /usr/spark/spark-2.1.0/target/tmp -> [Help 1] 17 | 18 | * http://www.cnblogs.com/o-din/p/6292153.html 19 | 20 | 21 | # "Could not transfer artifact ... from/to central ...: GET request of: ... from central failed: Tag mismatch!" 22 | 23 | [ERROR] Failed to execute goal on project spark-sql_2.11: Could not resolve dependencies for project org.apache.spark:spark-sql_2.11:jar:2.2.0-SNAPSHOT: Could not transfer artifact it.unimi.dsi:fastutil:jar:6.5.7 from/to central (https://repo1.maven.org/maven2): GET request of: it/unimi/dsi/fastutil/6.5.7/fastutil-6.5.7.jar from central failed: Tag mismatch! -> [Help 1] 24 | 25 | 删除fastutil-6.5.7.jar重新下载 -------------------------------------------------------------------------------- /_drafts/Java/Eclipse远程调试出现“JDWP Transport dt_socket failed to initialize”的解决方案.md: -------------------------------------------------------------------------------- 1 | 2 | 工作中经常需要使用Eclipse远程连接Tomcat,调试Web应用程序,关于如何进行远程调试,本文不再赘述,可以参考下面的文章: 3 | 4 | eclipse远程调试Tomcat方法:http://blog.csdn.net/afgasdg/article/details/9236877 5 | 6 | 但是按照上面的方法进行操作可能会有一些小问题,在远程服务器中更改Tomcat的配置文件catalina.sh之后第一次重启Tomcat时,一般是没有问题的(注意设置的DEBUG端口号不要和其它已有应用端口号冲突),但是在之后的重启过程中可能会出现下面的问题: 7 | 8 | cd tomcat/bin 9 | ./shutdown.sh ; ./startup.sh ; tailf ../logs/catalina.out 10 | 11 | ERROR: transport error 202: bind failed 12 | ERROR: JDWP Transport dt_socket failed to initialize, TRANSPORT_INIT(510) 13 | JDWP exit error AGENT_ERROR_TRANSPORT_INIT(197): No transports initialized [../../../src/share/back/debugInit.c:690] 14 | FATAL ERROR in native method: JDWP No transports initialized, jvmtiError=AGENT_ERROR_TRANSPORT_INIT(197) 15 | 16 | 之所以出现这个问题,主要是因为,我们添加的DEBUG端口在关闭Tomcat时不能正常关闭,重启时又会重新开启,所以端口被占用,我们可以在关闭Tomcat之后利用下面的命令进行验证会发现,仍然有进程在占用着DEBUG端口。 17 | 18 | lsof -i:44121(或者 netstat -na|grep 44121) 19 | 20 | 这个其实就是我们自己之前开启的。当然我们可以在每次shutdown之后手动kill掉这个进程,但是终归不是解决之道。我现在想到的比较好的方法是在catalina.sh中配置DEBUG端口时,把需要添加的那一行添加到start条件的开始处: 21 | 22 | ... 23 | elif [ "$1" = "start" ] ; then 24 | CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n" 25 | ... 26 | 27 | 并且在stop条件的开始处把DEBUG端口干掉 28 | 29 | ... 30 | elif [ "$1" = "stop" ] ; then 31 | debug_pid=`lsof -i:44121 | tail -n 1 | awk -F" " '{print $2}'` 32 | kill -9 ${debug_pid}· 33 | ... -------------------------------------------------------------------------------- /_drafts/Java/FindBugs详解.md: -------------------------------------------------------------------------------- 1 | 2 | ## Find bugs误报告警的消除方法 3 | 4 | ### 背景介绍 5 | 6 | 在java工程中,Find bugs的静态检查能够帮助我们挖掘出代码可能存在的缺陷。在我实际使用的过程中,也确实发现了两处由于“缺少else分支”导致“引入未初始化对象”的错误。与之相对应的是,通过Find bugs也发现四处对象中使用静态成员导致Find bugs告警的情况。通过仔细阅读和分析代码逻辑,可以确认代码本身没有问题,这个是属于Find bugs误报的情况。既然我们打算使用Find bugs来做代码的静态检查,那么就有必要保持一个干净的代码环境,这里面没有任何的Find bugs告警。如果确定是代码问题,毫无疑问需要马上纠正。如果确认是Find bugs误报,也应该进行消除,以便后续的检查能够基于一个干净的环境,同样的误报不需要反复确认。Find bugs告警误报的消除非常容易,只需要在两个级别(类级别和方法进行)加上Find bugs的注解就可以消除。这里建议误报消除尽量在方法级别上进行,以控制误报消除的范围,最大限度放置将真正的代码问题也作为误报给隐藏掉了。 7 | 8 | ### 方法 9 | 10 | * 在工程添加注解依赖的jar包:使用Find bugs注解需要用到两个jar包,annotations.jar和jsr305.jar。在eclipse中装完Find bugs插件后,在eclipse目录下可以找到这两个jar包文件。 11 | * 添加注解:在疑问代码所在的类或者方法前面添加注解。其中,value的值就是前面提到的find bugs告警信息中的模式,因为value是一个数组,所以可以同时添加多个模式。justification的值是一句描述信息,你可以理解为是这条注解的注释,内容可以是任意的。 12 | 13 | ```java 14 | @edu.umd.cs.findbugs.annotations 15 | SuppressWarnings(value={"NM_CONFUSING"}, justification="remove findbugs") 16 | ``` 17 | 18 | 19 | * 重新运行Find bugs进行检查:添加完注解后,接下来应该重新运行find bugs工具进行检查,以确定误报已经被消除。 20 | 21 | ## MS: Field should be package protected (MS_PKGPROTECT) 22 | 23 | A mutable static field could be changed by malicious code or by accident. The field could be made package protected to avoid this vulnerability. 24 | 25 | 我这样定义了多个数组,均使用了 public final static 修饰符: 26 | 27 | ```java 28 | public final static double[][][] Y_MIN_SCOPE= 29 | { 30 | {{-120, -25}}, 31 | {{0, 254}}, 32 | {{0, 254}}, 33 | {{0, 254}} 34 | 35 | }; 36 | public final static double[] GRID_HEIGHT = {1,1,1,1}; 37 | 38 | public final static String[][] TAG_NAMES= 39 | { 40 | {"RSRQ(dB)","RSRP(dBm)"}, 41 | {"TA(16*Ts)","UE TxPower(dBm)"}, 42 | {"TA(16*Ts)","RSRP(dBm)"}, 43 | {"TA(16*Ts)","RSRQ(dB)"} 44 | }; 45 | ``` 46 | 47 | findbugs给的修改提示是: 48 | 49 | ``` 50 | In LTE3DConstant 51 | Field LTE3DConstant.Y_MIN_SCOPE 52 | At LTE3DConstant.java:[line 53] 53 | Y_MIN_SCOPE should be package protected 54 | Bug Type: MS_PKGPROTECT 55 | Bug Category:MALICIOUS_CODE (Malicious code vulnerability) 56 | Source File: 57 | Line:53 58 | ``` 59 | 60 | 修改成这样就不报错了。 61 | 62 | ```java 63 | protected final double[][][] Y_MIN_SCOPE= 64 | { 65 | {{-120, -25}}, 66 | {{0, 254}}, 67 | {{0, 254}}, 68 | {{0, 254}} 69 | 70 | }; 71 | ``` 72 | 73 | 可能原因是因为其它地方没有使用到这个类的变量,所以最好将public改成protected,但是为什么要去掉static还是不理解。 -------------------------------------------------------------------------------- /_drafts/Java/Hibernate与autoCommit.md: -------------------------------------------------------------------------------- 1 | # JDBC 的`autoCommit`属性 2 | 3 | 对于每一个 JDBC connection,都有一个autoCommit属性,只有执行commit后,该connection中的操作(statement操作)才会在数据库中真正执行。所以若是 JDBC connection的autoCommit属性是false,且sql语句中没有显示commit,则sql语句即使被发送到数据库中,但因为没有commit,实际上也没有真正执行。若是connection的autoCommit为true,那么每一条发送到数据中的sql,会自动commit,即会自动执行。也就是说:commit才会真正的导致sql语句执行。数据库默认是自动提交的,即数据库默认的的autoCommit属性是true。 4 | 5 | # Hibernate 的`hibernate.connection.autocommit`属性 6 | 7 | Hibernate中hibernate.connection.autocommit属性用来设置获取到的 JDBC connection的autoCommit属性。hibernate.cfg.xml中默认是false。session.connection().getAutoCommit()方法可以获取session对应的connection的autoCommit属性。 8 | 9 | # Hibernate 的`session.beginTransaction()`方法 10 | 11 | session.beginTransaction()方法会将session对应的connection的autoCommit属性设为false,autoCommit=false(相当于connection 的start transaction)就是指开启jdbc的事务。所以session.beginTransaction()后一定要有:transaction.commit(),不然刷到数据库中的所有sql执行语句都没有commit,也就不会执行。 12 | 13 | # Hibernate 的`session.flush()`方法 14 | 15 | 清理session缓存;先由save()等代码中指定的操作生成对应的sql语句,可能有多条sql语句,再将session中的sql语句发送到数据库执行。若是在生成sql语句时抛错,即使生成其它sql语句时正确,也不会生成任何sql语句,也即不会有任何的sql发送到数据库中去执行。transaction.commit()和session.close()操作都已经有flush()的操作,所以commit或close后就不用flush。 16 | 17 | 18 | # 参考文章 19 | 20 | * https://forum.hibernate.org/viewtopic.php?f=1&t=944848 -------------------------------------------------------------------------------- /_drafts/Java/JUnit org.junit.runner.Request.classWithoutSuiteMethod解决方法.md: -------------------------------------------------------------------------------- 1 | 2 | ```java 3 | java.lang.NoSuchMethodError: org.junit.runner.Request.classWithoutSuiteMethod(Ljava/lang/Class;)Lorg/junit/runner/Request; 4 | at org.eclipse.jdt.internal.junit4.runner.JUnit4TestMethodReference.createRequest(JUnit4TestMethodReference.java:31) 5 | at org.eclipse.jdt.internal.junit4.runner.JUnit4TestMethodReference.(JUnit4TestMethodReference.java:25) 6 | at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:54) 7 | at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38) 8 | at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452) 9 | at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 10 | at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 11 | at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 12 | ``` 13 | 14 | 这是JUnit4早期版本存在的BUG;更新JUnit版本为4.4+即可。 -------------------------------------------------------------------------------- /_drafts/Java/JVM调优总结(转).md: -------------------------------------------------------------------------------- 1 | 2 | 3 | JVM调优总结(一)-- 一些概念: 4 | JVM调优总结(二)-一些概念: 5 | JVM调优总结(三)-基本垃圾回收算法: 6 | JVM调优总结(四)-垃圾回收面临的问题: 7 | JVM调优总结(五)-分代垃圾回收详述1: 8 | JVM调优总结(六)-分代垃圾回收详述2: 9 | JVM调优总结(七)-典型配置举例1: 10 | JVM调优总结(八)-典型配置举例2: 11 | JVM调优总结(九)-新一代的垃圾回收算法: 12 | JVM调优总结(十)-调优方法: 13 | JVM调优总结(十一)-反思: 14 | JVM调优总结(十二)-参考资料: -------------------------------------------------------------------------------- /_drafts/Java/Java远程调试代码不一致问题汇总.md: -------------------------------------------------------------------------------- 1 | 2 | Java(Eclipse IDE)远程调试Tomcat容器中的代码,经常出现两端代码不一致的情况,下面针对之前出现过的问题进行汇总,作为以后快速排查的依据。 3 | 4 | 1. 服务器中的jar包与Eclipse中的对应代码版本确实不一致。 5 | 2. Tomcat容器中可能会出现相同包路径,相同类名的情况,此种情况要注意。可以使用命令下面的命令去服务器上查看是否有相同包路径相同类名的情况:`find -type f -name "*.jar" | xargs grep "ClassName"` 6 | 3. 意外情况,比如本想望Linux服务器上替换jar包,但是由于某种情况(权限不足等)没有替换成功,或者替换错了服务器。 7 | 4. Eclipse上的jar包反编译插件有问题,或者配置错误。 8 | 5. Eclipse抽风,重启一下试试。 -------------------------------------------------------------------------------- /_drafts/Java/ServletInputStream的重复读取(多次读取)(转).md: -------------------------------------------------------------------------------- 1 | 2 | 在使用Servlet进行Web开发的时候,有时候为了增加必要的业务处理而又不想修改现有的程序,往往采用Filter。这样在各个Filter中可能都要读取ServletInputStream流的内容,而ServletInputStream却只能读一次,这时候必须备份HttpServleRequest。 3 | 4 | ```java 5 | 6 | class BufferedServletInputStream extends ServletInputStream { 7 | private ByteArrayInputStream inputStream; 8 | public BufferedServletInputStream(byte[] buffer) { 9 | this.inputStream = new ByteArrayInputStream( buffer ); 10 | } 11 | @Override 12 | public int available() throws IOException { 13 | return inputStream.available(); 14 | } 15 | @Override 16 | public int read() throws IOException { 17 | return inputStream.read(); 18 | } 19 | @Override 20 | public int read(byte[] b, int off, int len) throws IOException { 21 | return inputStream.read( b, off, len ); 22 | } 23 | } 24 | 25 | class BufferedServletRequestWrapper extends HttpServletRequestWrapper { 26 | private byte[] buffer; 27 | public BufferedServletRequestWrapper(HttpServletRequest request) throws IOException { 28 | super( request ); 29 | InputStream is = request.getInputStream(); 30 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 31 | byte buff[] = new byte[ 1024 ]; 32 | int read; 33 | while( ( read = is.read( buff ) ) > 0 ) { 34 | baos.write( buff, 0, read ); 35 | } 36 | this.buffer = baos.toByteArray(); 37 | } 38 | @Override 39 | public ServletInputStream getInputStream() throws IOException { 40 | return new BufferedServletInputStream( this.buffer ); 41 | } 42 | } 43 | 44 | ``` 45 | 46 | 在Filter的doFilter()或者Servlet的doPost()中, 47 | 48 | ```java 49 | 50 | //备份HttpServletRequest 51 | HttpServletRequest httpRequest = (HttpServletRequest)request; 52 | httpRequest = new BufferedServletRequestWrapper( httpRequest ); 53 | //使用流 54 | InputStream is = request.getInputStream(); 55 | //其他业务逻辑 56 | //将request 传到下一个Filter 57 | chain.doFilter(request, response); 58 | 59 | ``` -------------------------------------------------------------------------------- /_drafts/Java/[Maven][l10n-maven-plugin]告警[WARNING] No dictionary file under folder.md: -------------------------------------------------------------------------------- 1 | pom.xml中添加了taglist-maven-plugin配置,片段如下: 2 | 3 | ```xml 4 | 5 | com.googlecode.l10n-maven-plugin 6 | l10n-maven-plugin 7 | 1.8 8 | 9 | 10 | en 11 | zh_CN 12 | 13 | 14 | 15 | ``` 16 | 17 | 执行`mvn clean package site`时报错`[WARNING] No dictionary file under folder`,详细报错如下: 18 | 19 | ```powershell 20 | [INFO] Generating "L10n validation" report --- l10n-maven-plugin:1.8:report 21 | [INFO] Initializing l10n validators... 22 | [INFO] Looking for .dic files in: D:\temp\Java\ApkToolBoxGUI\src\main\resources 23 | [WARNING] No dictionary file under folder D:\temp\Java\ApkToolBoxGUI\src\main\resources. Skipping spellcheck validation. 24 | [INFO] Looking for .properties files in: D:\temp\Java\ApkToolBoxGUI\src\main\resources 25 | ``` 26 | 27 | 解决方案: 28 | 29 | * l10n-maven-plugin: 30 | * l10n-maven-plugin Validators: 31 | * Jazzy - Java Spell Check API: 32 | * JazzyDicts - A Free Dictionary Set: -------------------------------------------------------------------------------- /_drafts/Java/[Maven][maven-site-plugin]告警[WARNING] No project URL defined - decoration links will not be relativized.md: -------------------------------------------------------------------------------- 1 | pom.xml中添加了maven-site-plugin配置,片段如下: 2 | 3 | ```xml 4 | 5 | org.apache.maven.plugins 6 | maven-site-plugin 7 | 3.9.0 8 | 9 | en_US 10 | ${project.build.directory}/site 11 | 12 | 13 | ``` 14 | 15 | 执行`mvn clean package site`时报错`[WARNING] No project URL defined - decoration links will not be relativized!`,详细报错如下: 16 | 17 | ```powershell 18 | [INFO] --- maven-site-plugin:3.9.0:site (default-site) @ APKToolBoxGUI --- 19 | ... 20 | [INFO] Rendering site with default locale English (United States) (en_US) 21 | [WARNING] No project URL defined - decoration links will not be relativized! 22 | [INFO] Rendering content with org.apache.maven.skins:maven-default-skin:jar:1.3 skin. 23 | ``` 24 | 25 | 这个WARNING指maven-site-plugin有个功能就是帮你将生成的site信息中的绝对路径改为相对路径,比如地址是,且知道基础路径是<那么就可以帮你把地址改成相对的`findbugs.html`。默认情况下这个功能是打开的,但是你如果没有制定基础路径,插件就没有办法帮你将绝对路径改为相对路径,所以会给出一个WARNING,详细信息可以查看官网:。原因知道了,解决方案就简单了,如果你不需要改功能就直接通过配置关闭就可以了。 26 | 27 | ```xml 28 | 29 | org.apache.maven.plugins 30 | maven-site-plugin 31 | 3.9.0 32 | 33 | en_US 34 | ${project.build.directory}/site 35 | false 36 | 37 | 38 | ``` 39 | -------------------------------------------------------------------------------- /_drafts/Java/[Maven][taglist-maven-plugin]告警[WARNING] Using legacy tag format.md: -------------------------------------------------------------------------------- 1 | pom.xml中添加了taglist-maven-plugin配置,片段如下: 2 | 3 | ```xml 4 | 5 | org.codehaus.mojo 6 | taglist-maven-plugin 7 | 2.4 8 | 9 | 10 | fixme 11 | FixMe 12 | FIXME 13 | @todo 14 | todo 15 | TODO 16 | @deprecated 17 | 18 | 19 | 20 | ``` 21 | 22 | 执行`mvn clean package site`时报错`[WARNING] Using legacy tag format. This is not recommended.`,详细报错如下: 23 | 24 | ```powershell 25 | [INFO] Generating "Tag List" report --- taglist-maven-plugin:2.4:taglist 26 | [WARNING] Using legacy tag format. This is not recommended. 27 | ``` 28 | 29 | 这个WARNING指taglist-maven-plugin新版本指定tag的方式有所变更,新方式功能更强大,详细信息可以查看:。新版本的使用实例如下: 30 | 31 | ```xml 32 | 33 | org.codehaus.mojo 34 | taglist-maven-plugin 35 | 2.4 36 | 37 | 38 | 39 | 40 | Todo Work Annotation 41 | 42 | 43 | TODO 44 | ignoreCase 45 | 46 | 47 | @todo 48 | ignoreCase 49 | 50 | 51 | FIXME 52 | exact 53 | 54 | 55 | 56 | 57 | Version Annotation 58 | 59 | 60 | @deprecated 61 | ignoreCase 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | ``` 70 | -------------------------------------------------------------------------------- /_drafts/Java/[System.currentTimeMillis]_[Calendar.getInstance().getTimeInMillis()]_[new Date().getTime()].md: -------------------------------------------------------------------------------- 1 | 2 | 在Java中,生成当前的时间戳大致上有这么几种方法,分别是: 3 | 4 | * `System.currentTimeMillis()`,它属于`java.lang.System` 5 | 6 | * `Calendar.getInstance().getTimeInMillis()`,它属于`java.util.Calendar` 7 | 8 | * `new Date().getTime()`,它属于`java.util.Date`; 9 | 10 | 他们都是返回从1970/1/1返回到现在所经过的毫秒数,从实现上来看`new Date().getTime()`也是依据`System.currentTimeMillis()` 11 | 12 | ``` 13 | public Date() { 14 | this(System.currentTimeMillis()); 15 | } 16 | ``` 17 | 18 | 单从性能方面考虑,优先使用`System.currentTimeMillis()`,采用如下方式比较性能,输入结果为: 19 | 20 | System.currentTimeMillis(): 477 21 | Calendar.getInstance().getTimeInMillis(): 16415 22 | new Date().getTime(): 433 23 | 24 | ``` 25 | startTime = System.currentTimeMillis(); 26 | for (int i = 0; i < times; i++) { 27 | System.currentTimeMillis(); 28 | } 29 | endTime = System.currentTimeMillis(); 30 | System.out.println("System.currentTimeMillis(): " + (endTime - startTime)); 31 | 32 | startTime = System.currentTimeMillis(); 33 | for (int i = 0; i < times; i++) { 34 | Calendar.getInstance().getTimeInMillis(); 35 | } 36 | endTime = System.currentTimeMillis(); 37 | System.out.println("Calendar.getInstance().getTimeInMillis(): " + (endTime - startTime)); 38 | 39 | startTime = System.currentTimeMillis(); 40 | for (int i = 0; i < times; i++) { 41 | new Date().getTime(); 42 | } 43 | endTime = System.currentTimeMillis(); 44 | System.out.println("new Date().getTime(): " + (endTime - startTime)); 45 | ``` -------------------------------------------------------------------------------- /_drafts/Java/eclipse插件在线发布发布和版本更新(web site) 转.md: -------------------------------------------------------------------------------- 1 | 2 | eclipse插件在线发布发布和版本更新(web site) 3 | 4 | 在eclipse插件开发过程中免不了要发布1.0, 1.1, 1.2…….等等,随着版本的递增,假如每次都发布一个插件zip包,那使用者就想骂街了,每次都要先uninstall,然后install,中间还要两次eclipse的重启。 5 | 6 | 一般第三方插件会有2中形式共developer使用,一种是发布zip包,另一种是发布一个web site,eclipse对web site的支持相当好。Install时只需copy插件资源的URL(插件的update site)即可获取插件资源进行安装。之后有版本更新时,用户只需点击update按钮即可更新。So easy 7 | 8 | 做为 developer,下面来说说eclipse 插件 web site 的发布 9 | 10 | Web site 的发布 11 | 12 | 要发布web site,首先要为插件项目创建Feature Project 和 Update Site Project,对这个不太清楚的朋友可以看下我的上一篇文章“eclipse plugin 导出插件包”这边已经准备好了一个Update Site Project 13 | ![](http://images2015.cnblogs.com/blog/611264/201601/611264-20160102193557885-957250712.png) 14 | 15 | 16 | 17 | 18 | 既然是web,那必须创建一个web服务器,比如Apache或者Tomcat。。。 19 | 20 | 用着方便,我在本地部署了一个Apache服务器(对web服务器的使用不熟悉的可以另找机会或者来信沟通) 21 | 22 | Apache服务搭建完成之后,把Update Site Project整个工程都copy到Apache下可访问的目录中(对eclipse来说,实质是要Update Site Project下的5个File)。 23 | 24 | 发布服务完成之后的效果 25 | ![](http://images2015.cnblogs.com/blog/611264/201601/611264-20160102193618198-1845688740.png) 26 | 27 | 28 | 29 | 30 | OK,其实已经完成了,把地址copy一下,丢给人家就搞定了,不过现在演示,用的localhost,发布记得要把IP改成可访问的静态IP。 31 | 32 | 送佛送到西,演示一下安装吧。 33 | ![](http://images2015.cnblogs.com/blog/611264/201601/611264-20160102193630276-563734592.png) 34 | 35 | 36 | 37 | 38 | 一路Next,搞定。 39 | 40 | 插件安装完成之后 41 | ![](http://images2015.cnblogs.com/blog/611264/201601/611264-20160102193646495-1045213878.png) 42 | 43 | ![](http://images2015.cnblogs.com/blog/611264/201601/611264-20160102193704448-313766334.png) 44 | 45 | 46 | 47 | 48 | 49 | 50 | 很高兴的看到插件安装后的结果。仔细看下版本是1.1.0 51 | 52 | Web site 发布更新 53 | 54 | 当我们想把1.1.0的版本升级到1.2.0的时候,很简单,只需要发布一个1.2.0的web site即可,然后使用者只需要点一下上图中的Update按钮就可以做插件更新,下面具体说说。 55 | 56 | 注意:插件版本更新需要更新几个文件(还没有找到一次更新多个文件的方式) 57 | 58 | 1. 插件本身的plugin.xml文件 59 | ![](http://images2015.cnblogs.com/blog/611264/201601/611264-20160102193723854-207450760.jpg) 60 | 61 | 62 | 63 | 64 | 2. Feature Project中feature.xml文件 65 | 66 | Overview编辑器中 67 | 68 | ![](http://images2015.cnblogs.com/blog/611264/201601/611264-20160102193739073-588027991.jpg) 69 | 70 | 71 | 72 | Plug-ins编辑器中 73 | ![](http://images2015.cnblogs.com/blog/611264/201601/611264-20160102193748464-1584151231.jpg) 74 | 75 | 76 | 77 | 78 | 3. Feature Project下category.xml文件 79 | 80 | 修改前: 81 | ![](http://images2015.cnblogs.com/blog/611264/201601/611264-20160102193818464-1056678984.jpg) 82 | 83 | 84 | 85 | 86 | 修改后: 87 | ![](http://images2015.cnblogs.com/blog/611264/201601/611264-20160102193823651-997096172.jpg) 88 | 89 | 90 | 91 | 92 | 4. Update Site Project 中 site.xml 文件 93 | 94 | 在这个文件中修改完Feature后记得要再次Build,否则前功尽弃 95 | ![](http://images2015.cnblogs.com/blog/611264/201601/611264-20160102193834104-222443008.jpg) 96 | 97 | 98 | 99 | 100 | 到此为止,版本修改完成,并且Update Site Project 已经Build完成。 101 | 102 | 按照 Web Site 发布的步骤再把之前发布的几个文件替换掉 103 | 104 | 注意:URL不能改变,否则用户无法直接做Update 105 | 106 | 插件更新的演示 107 | 108 | 回到之前插件安装完成后的窗口 109 | ![](http://images2015.cnblogs.com/blog/611264/201601/611264-20160102193850698-1980311310.png) 110 | 111 | 112 | 113 | 114 | 选中需要更新的插件,点击Update按钮。 115 | ![](http://images2015.cnblogs.com/blog/611264/201601/611264-20160102193904323-1675695507.png) 116 | 117 | 118 | 119 | 120 | 看到1.2.0的新版本了吧,OK,一路Next。搞定。 121 | 122 | 通过Web Site发布eclipse插件版本,应该是现在比较流行的方式。 123 | 124 | 以上这些方式都是个人在开发过程中根据当前需要,不断尝试得到的。如有更好的或者更简便的方法,欢迎来信沟通分享。 -------------------------------------------------------------------------------- /_drafts/Java/javadoc相关问题.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | * src源代码生成html格式文档: 4 | * 自己动手制作chm格式开源文档: 5 | * Javadoc转换chm帮助文档的四种方法总结: 6 | * 如何使用eclipse生成javadoc帮助文档: 7 | * javadoc.io: 8 | 9 | 10 | ## maven下载源码和javadoc 11 | 12 | 当在IDE中使用Maven时如果想要看引用的jar包中类的源码和javadoc需要通过maven命令下载这些源码,然后再进行引入,通过mvn命令能够容易的达到这个目的: 13 | 14 | ```shell 15 | mvn dependency:sources 16 | mvn dependency:resolve -Dclassifier=javadoc 17 | ``` 18 | 19 | 命令使用方法:首先进入到相应的pom.xml目录中,然后执行以上命令。第一个命令尝试下载在pom.xml中依赖的文件的源代码。第二个命令尝试下载对应的javadocs。但是有可能一些文件没有源代码或者javadocs。也可以通过配置文件添加,打开maven配置文件 setting.xml文件(.../.m2/settings.xml) 增加如下配置: 20 | 21 | ```xml 22 | 23 | 24 | downloadSources 25 | 26 | true 27 | true 28 | 29 | 30 | 31 | 32 | 33 | downloadSources 34 | 35 | ``` 36 | 37 | 配置eclipse 38 | 39 | Window > Preferences > Maven and checking the "Download Artifact Sources" and "Download Artifact JavaDoc" options 40 | 41 | 42 | ## maven中如何生成javadoc 43 | 44 | mvn javadoc:javadoc 45 | 46 | 47 | ## javadoc注意点(原创) 48 | 49 | javadoc生成文档时总是报java.lang.IllegalArgumentException错 50 | 51 | JavamavenEXTSUNJDK . 52 | 53 | javadoc生成文档时总是报java.lang.IllegalArgumentException错误,是classpath里面字符冲突引起的。我在classpath中包含了变量引用,如:%JAVA_HOME%\lib;解决方法是重新设置classpath或者删除classpath.要注意设置完成后重启下cmd或者editplus,重启后生效! 54 | 55 | 见官方参考文档 http://maven.apache.org/plugins/maven-javadoc-plugin/faq.html 56 | 57 | 58 | ## javadoc生成时出错:编码GBK的不可映射字符 59 | 60 | 由于java源代码是用的UTF-8编码,Eclipse中默认编码是GB18030,因此,在生成javadoc的时候,需要手工指定一下编码和字符集。 61 | 62 | 解决方案是:主菜单`–>Project–>Generate javadoc–>next>next–>` 在 `Extra javadoc options`下面的文本框中填入: 63 | 64 | `-encoding UTF-8 -charset UTF-8` 65 | 66 | ## 一个例子 67 | 68 | `javadoc -d doc -subpackages edu.jiangxin -encoding utf-8 -charset utf-8 -exclude edu.jiangxin.utils:edu.jiangxin.service:edu.jiangxin.service.impl` -------------------------------------------------------------------------------- /_drafts/Java/org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter与org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter.md: -------------------------------------------------------------------------------- 1 | 2 | 使用Eclipse启动Maven+Struts项目报错,报错日志如下: 3 | 4 | ``` 5 | 2016-08-31 22:00:47 INFO ContextLoader:325 - Root WebApplicationContext: initialization completed in 2675 ms 6 | 八月 31, 2016 10:00:47 下午 org.apache.catalina.core.StandardContext filterStart 7 | 严重: Exception starting filter struts2 8 | java.lang.ClassNotFoundException: org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter 9 | at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1295) 10 | at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1147) 11 | at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:520) 12 | at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:501) 13 | at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:120) 14 | at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:258) 15 | at org.apache.catalina.core.ApplicationFilterConfig.(ApplicationFilterConfig.java:105) 16 | at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4615) 17 | at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5222) 18 | at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) 19 | at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409) 20 | at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1399) 21 | at java.util.concurrent.FutureTask.run(FutureTask.java:266) 22 | at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 23 | at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 24 | at java.lang.Thread.run(Thread.java:745) 25 | ``` 26 | 27 | 很明显是类没有找到,找到web.xml中的配置如下: 28 | 29 | ``` 30 | 31 | struts2 32 | 33 | org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter 34 | 35 | 36 | 37 | struts2 38 | /* 39 | 40 | ``` 41 | 42 | 使用`Ctrl+Shift+T`发现,存在该类,但是包路径不对,实际包路径为:`org.apache.struts2.dispatcher.filter`。于是猜测是Struts2版本升级之后包路径换了,查看pom.xml,配置如下: 43 | 44 | ```xml 45 | 46 | 47 | org.apache.struts 48 | struts2-core 49 | 2.5.1 50 | 51 | ``` 52 | 53 | 通过struts官网,可以看到从2.3到2.5部分包路径确实发生了改变。在web.xml中配置成新的包路径,重新启动,问题解决。官网说明:http://struts.apache.org/docs/version-notes-25.html。 -------------------------------------------------------------------------------- /_drafts/Java/package-info.java文件详解.md: -------------------------------------------------------------------------------- 1 | 2 | # pacakge-info.java介绍 3 | 4 | pacakge-info.java是一个Java文件,可以添加到任何的Java源码包中。pacakge-info.java的目标是提供一个包级的文档说明或者是包级的注释。 5 | 6 | pacakge-info.java文件中,唯一要求包含的内容是包的声明语句,比如: 7 | 8 | package edu.jiangxin.tools; 9 | 10 | # 包文档 11 | 12 | 在Java 5之前,包级的文档是package.html,是通过JavaDoc生成的。而在Java 5以上版本,包的描述以及相关的文档都可以写入pacakge-info.java文件,它也用于JavaDoc的生成。比如: 13 | 14 | ```java 15 | /** 16 | * 常用工具包
17 | * @author Jiangxin 18 | * @version 1.0 19 | * 20 | */ 21 | package edu.jiangxin.tools; 22 | ``` 23 | 24 | 上面的说明通过JavaDoc生成如下: 25 | 26 | ![](http://images2015.cnblogs.com/blog/611264/201601/611264-20160120220152140-1624843461.jpg) 27 | 28 | 在添加package-info.java之后,部分IDE可以在代码中进行提示,如下图: 29 | 30 | ![](http://images2015.cnblogs.com/blog/611264/201601/611264-20160120220902187-1865880427.jpg) 31 | 32 | # 包注释 33 | 34 | 注释对于程序员来说非常重要,pacakge-info.java文件包含了包级的注释。我们还可以使用ElementType来自定义注释。 35 | 36 | 包注释当然是ElementType.PACKAGE了,除此之外,还有: 37 | 38 | ```java 39 | ElementType.TYPE (class, interface, enum) 40 | ElementType.FIELD (instance variable) 41 | ElementType.METHOD ElementType.PARAMETER 42 | ElementType.CONSTRUCTOR 43 | ElementType.LOCAL_VARIABLE 44 | ElementType.ANNOTATION_TYPE 45 | ``` 46 | 47 | 比如,想让包中的所有类型过时(Deprecate),你可以注释每一个单独的类型(类、接口、枚举等),如下所示: 48 | 49 | ```java 50 | @DEPRECATED 51 | PUBLIC CLASS CONTACT { 52 | } 53 | ``` 54 | 55 | 或者是可以在package-info.java包声明文件中使用@Deprecated注释,它可以让包中的一切均过时。 56 | 57 | ```java 58 | @Deprecated 59 | package edu.jiangxin.tools; 60 | ``` 61 | 62 | # 把package-info.java添加到包中 63 | 64 | 可以手动在包目录下创建package-info.java文件,也可以通过Eclipse工具实现这一点。 65 | 66 | ![](http://images2015.cnblogs.com/blog/611264/201601/611264-20160120220302640-775137301.jpg) -------------------------------------------------------------------------------- /_drafts/Java/一个比较全面的java随机数据生成工具包.md: -------------------------------------------------------------------------------- 1 | 最近,由于一个项目的原因需要使用一些随机数据做测试,于是写了一个随机数据生成工具,ExtraRanom。可以看成是Java官方Random类的扩展,主要用于主要用于测试程序、生成密码、设计抽奖程序等情况下。目前已经实现的功能包括: 2 | 3 | 随机英文输出(自定义大小写,自定义固定长度还是随机长度); 4 | 5 | 随机数字输出(自定义固定长度还是随机长度); 6 | 7 | 随机ASCII字符,随机扩展ASCII字符,随机可打印ASCII字符输出; 8 | 9 | 随机中文输出(自定义固定长度还是随机长度); 10 | 11 | 随机Eamil地址输出; 12 | 13 | 随机手机号码输出; 14 | 15 | 随机日期输出等。 16 | 17 | 所有的生成器已经做了比较简单的单元测试,同时拥有很详细的API中文文档。但由于使用时间较短,鲁棒性尚不能保证,建议在早期版本中尽量不要用于您的工程中。 18 | 19 | 该包的使用比较简单,直接将包加入到您的工程引用类中即可。详细的使用说明可参考API文档。我开发这个工具包主要是方便大家使用,也希望抛砖引玉,希望大家提一些更好的建议,比如还有什么常用的随机数据需要加入包中。也希望志同道合的朋友与我一起开发一个应用广泛的ExtraRandom。我已经将该包的jar文件和API文档放到了SourceForge,地址为: 20 | 21 | https://sourceforge.net/projects/extra-random 22 | 23 | 想直接查看代码的请到GitHub上: 24 | 25 | https://github.com/jiangxincode/ExtraRandom -------------------------------------------------------------------------------- /_drafts/Java/利用Spring中同名Bean相互覆盖的特性,定制平台的类内容。.md: -------------------------------------------------------------------------------- 1 | 2 | 今天处理了一个问题,J2EE项目依赖了底层平台的功能,平台JAR包中配置了一个Bean,对应的实现类也在该平台JAR包中,由于Bean的配置不是懒加载的,所以在Tomcat容器启动时就会调用该Bean对应实现类中的init方法,但是该方法会对我们的业务产生副作用。现在想屏蔽这种副作用,我们肯定不能要求底层平台去修改代码,去除该Bean。所以考虑采取hack的方法解决。 3 | 4 | 我们在我们的项目目录中新建了一个`*.service.xml`文件,然后在该文件中重新配置了一下这个Bean,配置内容与平台JAR包中的配置相同,仅是把实现类修改为我们自己的类,这个类是一个空实现,也就避免了对业务产生副作用。然后在`web.xml`中的contextConfigLocation参数中,将我们自己的`*.service.xml`所在路径配置到平台JAR包中的Bean配置文件之后,也就是说我们的配置文件优先级更高。这样的话Spring容器在扫描过程中会扫描所有的配置文件,先扫描到平台JAR包中的配置文件,然后扫描到我们自定义的`*.service.xml`文件,发现同一个bean-id有两个配置,默认情况下会使用后面的覆盖前面的Bean定义,然后调用优先级更高的实现类进行初始化。 5 | 6 | 经过测试,结果和预期一致。 7 | 8 | 其实还应该有一个方法,就是不修改`web.xml`文件也不添加`*.service.xml`文件,而是在自己的项目中添加一个包路径和类名与JAR包中Bean的实现类完全相同的空实现类,然后将该项目打包到远程服务器上的时候一定要保证自己的JAR包比平台JAR包先加载到,有两个办法:如果两个JAR包在同一个目录下,要保证自己的JAR包的名称在所处的文件系统中的自动排序靠前;如果两个JAR包不在同一个目录,要保证自己的JAR包所在的目录靠前。当然这都是在没有特殊指定classpath的情况下,如果可以指定classpath,则灵活性更大。 9 | 10 | 当然虽然解决了底层平台副作用的问题,但是最好的方式是将自己的业务和平台解耦,尽量避免这种副作用问题。另外如果必须采用hack的方法解决问题,一定要在相关文件中写清注释。 -------------------------------------------------------------------------------- /_drafts/Java/剔除eclipse的configuration目录[转].md: -------------------------------------------------------------------------------- 1 | 2 | eclipse 3.4以前的版本,如果出现什么问题了,一般都会选择删除eclipse安装目录下configuration目录下除了config.ini之外的所有文件,同时在删除eclipse工作空间中的.metadata目录,这样就删除掉了eclipse的所有的配置信息,重新得到了一个类似全新安装的eclipse了,通常这种方法能够解决很多eclipse中遇到的错误。 3 | 但是,eclipse 3.4 情况就不一样了,一个全新的eclipse/configuration目录下不再是只有一个config.ini文件,另外多了三个目录: 4 | 5 | * .setting 6 | * org.eclipse.update 7 | * org.eclipse.equinox.simpleconfigurator 8 | 9 | 其实这三个目录存在的原因是p2的出现,eclipse 3.4 全新推出的更新管理器,如果我们想清空eclipse的配置信息,需要保留configuration目录下的config.ini和org.eclipse.equinox.simpleconfigurator目录,注意,只需要保留这两个目录。 10 | 如果是删除了eclipse的整个configuration目录后,eclipse无法启动,也不用怕。 11 | 由于equinox可以创建 configuration目录,但是无法自己创建config.ini文件。在启动eclipse的时候,需要用到config.ini中的配置内容。 12 | 删除了configuration后,启动eclipse会自动重建configuration目录。 13 | 然后可以自己在configuration目录下新建一个config.ini文件,增加以下五行内容到config.ini文件中。 14 | 15 | ``` 16 | osgi.splashpath = platform:/base/plugins/org.eclipse.platform 17 | osgi.bundles=org.eclipse.equinox.common@2:start, org.eclipse.update.configurator@3:start, org.eclipse.core.runtime@start 18 | eclipse.product=org.eclipse.sdk.ide 19 | osgi.instance.area.default=@user.home/workspace 20 | eof=eof 21 | ``` 22 | 23 | 保存文件后,重新启动eclipse就没有问题了。 24 | 25 | 注:3.4.1的原版为: 26 | 27 | ``` 28 | #this configuration file was written by: org.eclipse.equinox.internal.frameworkadmin.equinox.equinoxfwconfigfileparser 29 | #thu sep 11 19:36:01 edt 2008 30 | org.eclipse.update.reconcile=false 31 | osgi.launcherpath=. 32 | eclipse.p2.profile=sdkprofile 33 | osgi.instance.area.default=@user.home/workspace 34 | osgi.framework=file\:plugins/org.eclipse.osgi_3.4.2.r34x_v20080826-1230.jar 35 | eclipse.buildid=m20080911-1700 36 | osgi.bundles=reference\:file\:org.eclipse.equinox.simpleconfigurator_1.0.0.v20080604.jar@1\:start 37 | org.eclipse.equinox.simpleconfigurator.configurl=file\:org.eclipse.equinox.simpleconfigurator/bundles.info 38 | eclipse.product=org.eclipse.sdk.ide 39 | osgi.splashpath=platform\:/base/plugins/org.eclipse.platform 40 | osgi.launcherini=eclipse 41 | eclipse.p2.data.area=@config.dir/../p2 42 | osgi.bundles.defaultstartlevel=4 43 | ``` -------------------------------------------------------------------------------- /_drafts/Java/如何在大量jar包中搜索特定字符.md: -------------------------------------------------------------------------------- 1 | 2 | 工作中定位某些问题时需要在jar包中搜索某些特定的字符。如果jar包数量比较少可以直接使用JD-GUI等反编译软件导出源码,但是如果jar包数目庞大,这种方式工作量就太大了。 3 | 4 | 现在介绍一种相对简单的方法,这种方式需要三种工具: 5 | 6 | * 能够批量解压jar包的程序,比如WinRAR。 7 | * 能够批量反编译jar包或者class文件的程序,比如jad(jd不支持命令行)。 8 | * 能够批量搜索文本文件的工具,比如FileLocator。 9 | 10 | ## 具体步骤: 11 | 12 | 假如需要在D:\jar\目录中的所有jar包中搜索Calendar一词: 13 | 14 | ![](http://images2015.cnblogs.com/blog/611264/201601/611264-20160117203308710-1291877493.jpg) 15 | 16 | 首先需要利用WinRAR将所有jar包解压到独立的目录中: 17 | 18 | ![](http://images2015.cnblogs.com/blog/611264/201601/611264-20160117203336944-673584009.jpg) 19 | 20 | ![](http://images2015.cnblogs.com/blog/611264/201601/611264-20160117203354132-391911217.jpg) 21 | 22 | 打开命令行窗口,进入D:\jar\目录,输入下面命令(假设jad工具已经在path中设置): 23 | 24 | ```cmd 25 | jad -o -r -sjava -dsrc ./**/*.class 26 | ``` 27 | 28 | 会发现在该目录多了一个src目录。 29 | 注:反编译输出中经常会出现类似于The class file version is 49.0 (only 45.3, 46.0 and 47.0 are supported)的内容,说明jad只能编译49.0以下版本的class文件,虽然可以生成java文件,但是并没有正确反编译,如果大家知道其他可以在命令行执行,且不会出现类似问题的反编译工具可以告诉我。当然有一个比较折中的办法是使用我写的一个批量修改class文件版本号的小程序(通过邮件与我联系),通过修改版本号将class文件伪装成低版本的,供jad读取,但是这种方式不支持高版本的特性,比如拉姆达表达式。 30 | 31 | ![](http://images2015.cnblogs.com/blog/611264/201601/611264-20160117203446835-105419615.jpg) 32 | 33 | 然后使用FileLocator进行搜索即可。 34 | 35 | ![](http://images2015.cnblogs.com/blog/611264/201601/611264-20160117203501022-1311945266.jpg) -------------------------------------------------------------------------------- /_drafts/Java/如何编写跨平台的Java代码.md: -------------------------------------------------------------------------------- 1 | 2 | 使用Java语言编写应用程序最大的优点在于“一次编译,处处运行”,然而这并不是说所有的Java程序都具有跨平台的特性,事实上,相当一部分的Java程序是不能在别的操作系统上正确运行的,那么如何才能编写一个真正的跨平台的Java程序呢? 3 | 下面是在编写跨平台的Java程序是需要注意的一些事情: 4 | 1. 编写Java跨平台应用程序时,你可以选择JDK1.0,1.1,1.2或支持它们的GUI开发工具如:Jbuilder,Visual Age for Java 等等,但是必须注意你的Java程序只能使用Java核心API包,如果要使用第三方的类库包,则该类库包也要由Java核心包开发完成,否则在发布你的程序的时候还得将支持该Java类库包的JVM发布出去。也就是说,你的程序需要是100%纯Java的。举一个例子,Visual J++ 就不是纯Java的,由Visual J++编写的程序也就不具有平台无关性。 5 | 2. 无论你使用的是JDK或其他开发工具,在编译时都要打开所有的警告选项,这样编译器可以尽可能多的发现平台相关的语句,并给出警告。虽然不能保证没有编译时警告错误的程序一定是跨平台的,但含有警告错误的程序却很有可能是非平台无关的。 6 | 3. 在程序中使用任何一个方法的时候,要详细察看文档,确保你使用的方法不是在文档中已经申明为过时的方法(Deprecated method),也不是文档中未标明的隐含方法(Undocumented method)。 7 | 4. 退出Java程序时尽量不要使用java.lang.System的exit方法。Exit 方法可以终止JVM,从而终止程序,但如果同时运行了另一个Java程序,使用exit方法就会让该程序也关闭,这显然不是我们希望看到的情况。事实上要退出Java程序,可以使用destory()退出一个独立运行的过程。对于多线程程序,必须要关闭各个非守护线程。只有在程序非正常退出时,才使用 exit方法退出程序。 8 | 5. 避免使用本地方法和本地代码,尽可能自己编写具有相应功能的Java类,改写该方法。如果一定要使用该本地方法,可以编写一个服务器程序调用该方法,然后将现在要编写的程序作为该服务器程序的客户程序,或者考虑CORBA(公共对象请求代理)程序结构。 9 | 6. Java中有一个类似于Delphi中的winexec的方法,java.lang.runtime类的exec方法,作为该方法本身是具有平台无关性的,但是给方法所调用的命令及命令参数却是与平台相关的,因此,在编写程序时要避免使用,如果一定要调用其他的程序的话,必须要让用户自己来设置该命令及其参数。比如说,在windows中可以调用notepad.exe程序,在linux 中就要调用vi程序了。 10 | 7. 程序设计中的所有的信息都要使用ASCII码字符集,因为并不是所有的操作系统都支持Unicode字符集,这对于跨平台的Java中文软件程序不能不说是一大噩耗。 11 | 8. 在程序中不要硬性编码与平台相关的任何常量,比如行分隔符,文件分隔符,路径分隔符等等,这些常量在不同的平台上是不同的,比如文件分隔符,在UNIX和 MAC中是“/”,在windows中是“\”,如果要使用这些常量,需要使用java.io.File 类 如获得文件分隔符File.separator, 获得路径分隔符:File.pathSeparator;举例:myPath + File.separator+myFileName//跨平台、可移植性好 12 | 9. 在编写跨平台的网络程序时,不要使用java.net.InetAddress类的getHostName方法得到主机名,因为不同的平台的主机名格式是不同的,最好使用getAddress得到格式相同的IP地址,另外,程序中所有的主机名都要换成IP地址,比如www.263.net就要换成相应的 IP地址。 13 | 10. 涉及文件操作的程序需要注意:不要在程序中硬性编码文件路径,理由和8中一样,只是这一点特别重要,因此单独提出。而且,不同平台对于文件名使用的字符及最大文件名长度的要求不同,编写你的程序的时候要使用一般的ASCII码字符作为文件的名字,而且不能与平台中已存在的程序同名,否则会造成冲突。 14 | 11. 如果您写的程序是GUI程序,在使用AWT组件时不能硬性设置组件的大小和位置而应该使用Java的布局管理器(layout manager)来设置和管理可视组件的大小和位置,否则有可能造成布局混乱。 15 | 12. 由于不同的操作系统,不同的机器,系统支持的颜色和屏幕的大小和分辨率都不同,如何获得这些属性呢?使用java.awt.Systemcolor类可以获得需要的颜色,如该类的inactiveCaption 就是窗口边框中活动标题的背景颜色,menu则是菜单的背景颜色。使用java.awt.Toolkit的getScreenResolution可以以 “象素每英寸”为单位显示屏幕的分辨率。该类的getScreenSize可以得到屏幕大小(英寸),loadSystemColors可以列出所有的系统颜色。 16 | 13. 有关JDBC,JDBC有四种类型,要使用纯java的JDBC驱动,不要使用ODBC桥及其他平台相关的JDBC驱动。 17 | 18 | 参考: 19 | 实现Java程序跨平台运行十二个注意事项:http://blog.chinaunix.net/uid-20550186-id-1927257.html -------------------------------------------------------------------------------- /_drafts/Java/通过设置JDK解决存在多个Gradle后台进程的问题.md: -------------------------------------------------------------------------------- 1 | 使用Android Studio经常会在Event Log窗口遇到如下报错: 2 | ``` 3 | 21:42 Android Studio is using the following JDK location when running Gradle: 4 | C:\Program Files\Android\Android Studio\jre 5 | Using different JDK locations on different processes might cause Gradle to 6 | spawn multiple daemons, for example, by executing Gradle tasks from a terminal 7 | while using Android Studio. 8 | More info... 9 | Select a JDK from the File System 10 | Do not show this warning again 11 | ``` 12 | 可以通过如下指引了解详细信息: 13 | 14 | 15 | 16 | 简单解释下就是如果后台有一个常驻的gradle守护进程,可以提高我们构建效率。因为这样不但可以避免每次都重新启动JVM,并且可以缓存项目结构、文件、任务等信息。每次启动AS的时候,你可能会注意到如下这个提示,其实就是AS默认打开了gradle守护进程: 17 | 18 | ![](https://raw.githubusercontent.com/jiangxincode/PicGo/master/611264-20200805222550660-189587292.png) 19 | 20 | 但是如果使用守护进程特性会有一个问题,就是可能会出现多个守护进程的场景,这是因为守护进程可能在某些方面无法满足请求构建环境。比如如果守护进程运行在Java 8运行时,但是请求的环境调用Java 10,那么守护进程是不兼容的,必须启动另一个。此外,Java运行时的某些属性在JVM启动后无法更改。这也可能导致出现多个守护进程。 21 | 22 | 为了避免出现这种情况,一个最好的解决方式时我们每次使用gradle进行项目构建时,尽量使用相同的JDK配置。如果我们在命令行中使用gradle,会自动使用JAVA_HOME环境变量指向的JDK,如果在AS中使用gradle,使用的是如下指向的JDK 23 | ![](https://raw.githubusercontent.com/jiangxincode/PicGo/master/611264-20200805221541606-1552863309.png) 24 | 25 | 所以为了两者一致,我们需要将此处的JDK改为JAVA_HOME环境变量指向的JDK。修改完之后AS的告警提示信息也自然消失了。 26 | ![](https://raw.githubusercontent.com/jiangxincode/PicGo/master/611264-20200805230821788-1845237150.png) 27 | 28 | 另外注意下从Gradle 6.3版本才开始正式支持JDK 14: 29 | -------------------------------------------------------------------------------- /_drafts/Linux/202317061029VSCode调试远程Linux机器上的C代码.md: -------------------------------------------------------------------------------- 1 | # VSCode调试远程Linux机器上的C代码 2 | 3 | ## VSCode通过SSH远程连接Linux机器 4 | 5 | 保证可以正常查看代码: 6 | 7 | ![](https://raw.githubusercontent.com/jiangxincode/PicGo/master/20231706102901.png) 8 | 9 | ## 创建launch.json 10 | 11 | ![](https://raw.githubusercontent.com/jiangxincode/PicGo/master/20231706102902.png) 12 | 13 | ```json 14 | { 15 | "version": "0.2.0", 16 | "configurations": [ 17 | { 18 | "name": "(gdb) Launch", 19 | "type": "cppdbg", 20 | "request": "launch", 21 | "program": "${workspaceFolder}/main", //这里需要指定可执行文件 22 | "args": [], 23 | "stopAtEntry": false, 24 | "cwd": "${fileDirname}", 25 | "environment": [], 26 | "externalConsole": false, 27 | "MIMode": "gdb", 28 | "setupCommands": [ 29 | { 30 | "description": "Enable pretty-printing for gdb", 31 | "text": "-enable-pretty-printing", 32 | "ignoreFailures": true 33 | }, 34 | { 35 | "description": "Set Disassembly Flavor to Intel", 36 | "text": "-gdb-set disassembly-flavor intel", 37 | "ignoreFailures": true 38 | } 39 | ], 40 | "preLaunchTask": "build-debug" //这里指定一个预先执行的Task 41 | } 42 | 43 | ] 44 | } 45 | ``` 46 | 47 | ## 创建tasks.json 48 | 49 | ![](https://raw.githubusercontent.com/jiangxincode/PicGo/master/20231706102903.png) 50 | 51 | ```json 52 | { 53 | "version": "2.0.0", 54 | "tasks": [ 55 | { 56 | "label": "build-debug", 57 | "command": "make", 58 | "args": [""], 59 | "type": "shell" 60 | }, 61 | { 62 | "label": "clean", 63 | "command": "make", 64 | "args": ["clean"], 65 | "type": "shell" 66 | } 67 | ] 68 | } 69 | ``` 70 | 71 | ## 开始调试 72 | 73 | 启动调试的方式: 74 | 75 | ![](https://raw.githubusercontent.com/jiangxincode/PicGo/master/20231706102904.png) 76 | 77 | 调试界面: 78 | 79 | ![](https://raw.githubusercontent.com/jiangxincode/PicGo/master/20231706102905.png) 80 | 81 | ## 使用VSCode Makefile Tools插件 82 | 83 | 如果VSCode上安装了`Makefile Tools`插件,也可以使用该插件直接进行调试,这边不展开说明。该插件官网: 84 | 85 | 86 | 87 | ## 使用VSCode CMake Tools插件 88 | 89 | 如果VSCode上安装了`CMake Tools`插件,也可以使用该插件直接进行调试,这边不展开说明。该插件官网: 90 | 91 | 92 | 93 | ## 参考链接 94 | 95 | * Using C++ on Linux in VS Code: 96 | -------------------------------------------------------------------------------- /_drafts/Linux/202401011357Ubuntu扩容swap文件.md: -------------------------------------------------------------------------------- 1 | # Ubuntu扩容swap文件 2 | 3 | ## 查看/卸载/删除已有swap文件 4 | 5 | ```shell 6 | # 查看交换分区的大小和使用量 7 | jiangxin@ubuntu11:~$ free -m 8 | total used free shared buff/cache available 9 | 内存: 9815 297 6438 1 3080 9214 10 | 交换: 1897 510 1386 11 | 12 | # 查看swap文件的位置 13 | jiangxin@ubuntu11:~$ swapon -s 14 | Filename Type Size Used Priority 15 | /swapfile file 1942896 522948 -2 16 | 17 | # 卸载删除已有swap文件 18 | jiangxin@ubuntu11:~$ sudo swapoff /swapfile 19 | [sudo] jiangxin 的密码: 20 | jiangxin@ubuntu11:~$ sudo rm -rf /swapfile 21 | 22 | # 由于我们后面新增的swap文件和删除的swap文件时同名的,所以不再修改/etc/fstab文件 23 | jiangxin@ubuntu11:~$ cat /etc/fstab 24 | UUID=00fce965-efcd-4954-9777-14f52475b94b / ext4 errors=remount-ro 0 1 25 | /swapfile none swap sw 0 0 26 | ``` 27 | 28 | ## 创建/格式化/新的swap文件 29 | 30 | ```shell 31 | # 创建一个32G的swap文件 32 | jiangxin@ubuntu11:~$ sudo dd if=/dev/zero of=/swapfile bs=1M count=32767 33 | 记录了32767+0 的读入 34 | 记录了32767+0 的写出 35 | 34358689792字节(34 GB,32 GiB)已复制,139.379 s,247 MB/s 36 | 37 | # 格式化创建的swap文件 38 | jiangxin@ubuntu11:~$ sudo mkswap /swapfile 39 | mkswap: /swapfile: insecure permissions 0644, fix with: chmod 0600 /swapfile 40 | 正在设置交换空间版本 1,大小 = 32 GiB (34358685696 个字节) 41 | 无标签, UUID=23f37fb3-b0a6-4c71-a9e0-1b4ea50a0c68 42 | 43 | # 挂载新的swap文件,全兴提示可忽略或者按照要求整改 44 | jiangxin@ubuntu11:~$ sudo swapon /swapfile 45 | swapon: /swapfile:不安全的权限 0644,建议使用 0600。 46 | 47 | # 重新查看swap分区大小 48 | jiangxin@ubuntu11:~$ free -m 49 | total used free shared buff/cache available 50 | 内存: 9815 797 135 6 8882 8703 51 | 交换: 32766 0 32766 52 | ``` 53 | -------------------------------------------------------------------------------- /_drafts/Linux/Linux下安装最新的Eclipse.md: -------------------------------------------------------------------------------- 1 | 2 | 测试环境: 3 | 4 | * OS:Ubuntu 14.04 5 | * Eclipse:Eclipse Kepler (4.3.2) 6 | * JDK: 7 | 8 | Ubuntu软件源中提供的Eclipse版本太老了,下面介绍如何在Ubuntu 14.04下安装Eclipse Kepler (4.3.2)。其它Linux和Eclipse版本的安装也可参考本文。 9 | 10 | * 如果系统中存在OpenJDK或者其它版本的Oracle JDK,需要首先将他们删除(如果你对它们的安装目录以及对应关系非常清晰,也可以在不删除的情况下安装成功)。 11 | 12 | sudo apt-get purge openjdk* 13 | 14 | * 添加 PPA 源 15 | 16 | sudo add-apt-repository ppa:webupd8team/java 17 | 18 | * 更新源数据库 19 | 20 | sudo apt-get update 21 | 22 | * 安装 Oracle Java 7 23 | 24 | sudo apt-get install oracle-java7-installer 25 | 26 | * 下载 Eclipse 最新版 27 | 28 | 访问官方网站下载需要的 Eclipse 版本:http://www.eclipse.org/downloads/?osType=linux&release=undefined 29 | 30 | * 解压 Eclipse 31 | 32 | cd /opt/ && sudo tar -zxvf ~/Downloads/eclipse-*.tar.gz 33 | 34 | * 创建 Eclipse 快捷方式 35 | 36 | 在/usr/share/applications/下创建文件eclipse.desktop,并添加如下内容: 37 | 38 | [Desktop Entry] 39 | Name=Eclipse 4 40 | Type=Application 41 | Exec=/opt/eclipse/eclipse 42 | Terminal=false 43 | Icon=/opt/eclipse/icon.xpm 44 | Comment=Integrated Development Environment 45 | NoDisplay=false 46 | Categories=Development;IDE; 47 | Name[en]=Eclipse -------------------------------------------------------------------------------- /_drafts/Linux/Linux压缩与解压常用命令.md: -------------------------------------------------------------------------------- 1 | 2 | ```shell 3 | 4 | tar的相关参数 5 | -c: 建立压缩档案 6 | -x:解压 7 | -t:查看内容 8 | -r:向压缩归档文件末尾追加文件 9 | -u:更新原压缩包中的文件 10 | 11 | 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个。下面的参数是根据需要在压缩或解压档案时可选的。 12 | 13 | -z:有gzip属性的 14 | -j:有bz2属性的 15 | -Z:有compress属性的 16 | -v:显示所有过程 17 | -O:将文件解开到标准输出 18 | 19 | 下面的参数-f是必须的 20 | 21 | -f: 使用档案名字,切记,这个参数是最后一个参数,后面只能接档案名。 22 | 23 | tar -cf all.tar *.jpg # 这条命令是将所有.jpg的文件打成一个名为all.tar的包。-c是表示产生新的包,-f指定包的文件名。 24 | tar -rf all.tar *.gif # 这条命令是将所有.gif的文件增加到all.tar的包里面去。-r是表示增加文件的意思。 25 | tar -uf all.tar logo.gif # 这条命令是更新原来tar包all.tar中logo.gif文件,-u是表示更新文件的意思。 26 | tar -tf all.tar # 这条命令是列出all.tar包中所有文件,-t是列出文件的意思 27 | tar -xf all.tar # 这条命令是解出all.tar包中所有文件,-x是解开的意思 28 | 29 | tar –cvf jpg.tar *.jpg # 将目录里所有jpg文件打包成tar.jpg 30 | tar –czf jpg.tar.gz *.jpg # 将目录里所有jpg文件打包成jpg.tar后,并且将其用gzip压缩,生成一个gzip压缩过的包,命名为jpg.tar.gz 31 | tar -czf jpg.tgz *.jpg # 将目录里所有jpg文件打包成jpg.tar后,并且将其用gzip压缩,生成一个gzip压缩过的包,命名为jpg.tgz 32 | tar –cjf jpg.tar.bz2 *.jpg # 将目录里所有jpg文件打包成jpg.tar后,并且将其用bzip2压缩,生成一个bzip2压缩过的包,命名为jpg.tar.bz2 33 | tar –cZf jpg.tar.Z *.jpg # 将目录里所有jpg文件打包成jpg.tar后,并且将其用compress压缩,生成一个umcompress压缩过的包,命名为jpg.tar.Z 34 | 35 | tar –xvf file.tar # 解压 tar包 36 | tar -xzvf file.tar.gz # 解压tar.gz 37 | tar -xjvf file.tar.bz2 # 解压 tar.bz2 38 | tar –xZvf file.tar.Z # 解压tar.Z 39 | 40 | rar a jpg.rar *.jpg # rar格式的压缩,需要先下载rar for linux 41 | unrar e file.rar # 解压rar 42 | 43 | zip jpg.zip *.jpg # zip格式的压缩,需要先下载zip for linux 44 | unzip file.zip # 解压zip 45 | 46 | *.gz 用 gzip -d或者gunzip 解压 47 | *.bz2 用 bzip2 -d或者用bunzip2 解压 48 | *.Z 用 uncompress 解压 49 | 50 | jar -cvfM0 game.war ./ # 把当前目录下的所有文件打包成game.war 51 | jar -xvf game.war # 解压game.war到当前目录 52 | ``` -------------------------------------------------------------------------------- /_drafts/Linux/Linux快捷键.md: -------------------------------------------------------------------------------- 1 | 2 | ## Shell 快捷键 3 | 4 | ``` 5 | :删除从光标到行尾的部分 6 | :删除从光标到行首的部分 7 | :删除从光标到当前单词结尾的部分 8 | :删除从光标到当前单词开头的部分 9 | :将光标移到行首 10 | :将光标移到行尾 11 | :将光标移到当前单词头部 12 | :将光标移到当前单词尾部 13 | :插入最近删除的单词 14 | :跳到行首 15 | :左移一个字符 16 | :终止终端进程 17 | :从光标处向右删除 18 | :跳到行尾 19 | :右移一个字符 20 | :从光标处删除到行尾 21 | :清屏,类似 clear 命令 22 | :查找历史命令 23 | :Suspend/ Stop the command 、 暂停命令的执行 24 | :删除当前字符 25 | :删除最后输入的单词 26 | :重复前一个命令最后的参数。 27 | :终端上下翻页 28 | ``` 29 | 30 | ## 常用快捷键 31 | 32 | ``` 33 | :切换窗口(win) 34 | :若开3D效果了切换 35 | :相当于强制注销 36 | :调出关机菜单 37 | :锁定桌面 38 | :最小化gnome所有窗口 39 | :linux终端用户(Alt + f7返回xwindows,Alt+ <- 或-> 进行终端切换) 40 | >:切换桌面 41 | :打开主菜单 42 | :(重启x窗口:r 重启:reboot 关机:hAlt) 43 | :显示桌面 44 | :最小化当前窗口 45 | :最大化当前窗口 46 | :关闭当前窗口 47 | Print Screen截取全屏 48 | Alt + Print Screen截取窗口 49 | :切换工作区(Fedora) 50 | :调整窗口的默认大小(Fedora) 51 | ``` -------------------------------------------------------------------------------- /_drafts/Linux/Unix_Linux操作系统中如何在sqlplus_rman中使用方向键.md: -------------------------------------------------------------------------------- 1 | 默认情况下在Unix/Linux中使用Oracle的sqlplus/rman是无法使用↑↓←→几个方向键进行操作的,要想达到Windows下使用sqlplus/rman的效果需要安装rlwrap。 2 | 3 | rlwrap依赖readline,可以使用`rpm -q readline readline-devel` 查看系统中是否安装有readline和readline-devel,如果没有的话需要使用`yum install readline readline-devel`进行安装。如果系统不能使用yum方式安装软件,也可以按照 http://directory.fsf.org/project/readline/ 的说明进行下载、安装: 4 | 5 | ```shell 6 | # 根据版本差别进行对应调整 7 | su - root 8 | wget https://ftp.gnu.org/gnu/readline/readline-7.0.tar.gz 9 | tar -zxvf readline-7.0.tar.gz 10 | cd readline-7.0 11 | ./configure 12 | make 13 | make install 14 | ``` 15 | 16 | 安装成功之后在 https://github.com/hanslub42/rlwrap 下载、安装rlwrap 17 | 18 | ```shell 19 | # 根据版本差别进行对应调整 20 | su - root 21 | wget https://github.com/hanslub42/rlwrap/releases/download/v0.43/rlwrap-0.43.tar.gz 22 | tar -zxvf rlwrap-0.43.tar.gz 23 | cd rlwrap-0.43 24 | ./configure 25 | make 26 | make install 27 | ``` 28 | 29 | 安装成功之后切换到oracle用户,使用`rlwrap sqlplus user/pwd`登陆sqlplus即可在sqlplus中正常使用方向键。当然为了方便的话可以在oracle用户下的.bash_profile文件中增加如下的别名设置: 30 | 31 | ```shell 32 | alias sqlplus='rlwrap sqlplus' 33 | alias rman='rlwrap rman' 34 | ``` 35 | 然后使用`source ~/.bash_porfile`刷新配置,即可直接使用`sqlplus user/pwd`登陆sqlplus。 -------------------------------------------------------------------------------- /_drafts/Linux/linux中无 conio.h的解决办法.md: -------------------------------------------------------------------------------- 1 | conio.h不是C标准库中的头文件,在ISO和POSIX标准中均没有定义。conio是Console Input/Output(控制台输入输出)的简写,其中定义了通过控制台进行数据输入和数据输出的函数,主要是一些用户通过按键盘产生的对应操作,比如getch()函数等等。大部分DOS,Windows,Phar Lap,DOSX,OS/2等平台上的C编译器提供此文件,UNIX和Linux平台的C编译器本身通常不包含此头文件,但已经有其兼容包,可参考: 2 | http://conio.sourceforge.net/ 3 | 4 | 另外大家平时主要是利用conio.h这个头文件中的getch()函数,即读取键盘字符但是不显示出来(without echo),但是含有conio.h的程序在linux无法直接编译通过,因为linux没有这个头文件,除了利用上述的兼容包外还可以在linux采用原生的方法达到同样的效果,那就是利用linux系统的命令stty –echo,它代表不显示输入内容,源代码如下。 5 | 6 | ```cpp 7 | //in windows 8 | 9 | #include 10 | 11 | #include 12 | 13 | int main(){ 14 | 15 | char c; 16 | 17 | printf("input a char:"); 18 | 19 | c=getch(); 20 | 21 | printf("You have inputed:%c \n",c); 22 | 23 | return 0; 24 | 25 | } 26 | 27 | //in linux 28 | 29 | #include 30 | 31 | int main(){ 32 | 33 | char c; 34 | 35 | printf("Input a char:"); 36 | 37 | system("stty -echo"); 38 | 39 | c=getchar(); 40 | 41 | system("stty echo"); 42 | 43 | printf("You have inputed:%c \n",c); 44 | 45 | return 0; 46 | 47 | } 48 | ``` -------------------------------------------------------------------------------- /_drafts/Linux/ssh相关原理学习与常见错误总结.md: -------------------------------------------------------------------------------- 1 | 2 | ## SSH基本原理与运用 3 | 4 | * SSH原理与运用(一): 远程登录: http://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html 5 | * SSH原理与运用(二): 远程操作与端口转发: http://www.ruanyifeng.com/blog/2011/12/ssh_port_forwarding.html 6 | 7 | ## connect to host localhost port 22: Connection refused 8 | 9 | 参考:http://blog.csdn.net/jszhangyili/article/details/8881807 10 | 11 | ## Agent admitted failure to sign using the key 12 | 13 | ssh-keygen 产生出 id_rsa, id_rsa.pub, 已经都放到正确位置(.ssh), 但是联机时却出现下述讯息:`Agent admitted failure to sign using the key`。解决方法是在自己的机器上, 执行 ssh-add, 会出现: `Identity added: /home/user/.ssh/id_rsa (/home/user/.ssh/id_rsa)` 14 | 15 | ## 解决SSH超时断开连接问题 16 | 17 | ```sh 18 | vim /etc/ssh/sshd_config 19 | 20 | ClientAliveInterval # 指定服务器向客户端请求消息的时间间隔,默认是0表示不发送;可以改为60表示每分钟发送一次 21 | ClientAliveCountMax # 表示服务器发出请求后客户端没有响应的次数达到一定值, 就自动断开 22 | 23 | service sshd restart 24 | ``` 25 | 26 | ## sftp子系统申请已拒绝 请确保ssh连接的sftp子系统设置有效 27 | 28 | ```shell 29 | vi /etc/ssh/sshd_config 30 | 31 | # 取消下面这一行的注释 32 | Subsystem sftp /usr/libexec/openssh/sftp-server 33 | 34 | /etc/init.d/sshd reload 35 | ``` 36 | 37 | ## too many authentication failures for root 38 | 39 | 使用xshell提示此问题,但可以通过Putty登录系统。 40 | 打开文件 /etc/ssh/sshd_config 41 | 修改 MaxAuthTries 这个参数的值,不建议修改太大。 -------------------------------------------------------------------------------- /_drafts/Linux/鸟哥的linux私房菜勘误表.md: -------------------------------------------------------------------------------- 1 | 2 | 鸟哥的Linux私房菜基础学习篇(第三版)简体中文勘误表(人民邮电出版社) 3 | 简体中文版书籍资料: 4 | 出版日期:2010年7月第3版 5 | 书籍ISBN:978-7-115-22626-6 6 | 出版社:人民邮电出版社 7 | 正文P10,0.2.2 内存,表0-2 8 | “DDR DDRII800 64 400 800 6.4GB/s” 9 | 应改为:“DDR DDRII800 64 200 800 6.4GB/s” 10 | P19,0.4.1 机器程序与编译程序,图0-17下面第一行 11 | “从上面的图示我们......。鸟哥已将经程序代码(英文)写成中文,” 12 | 应改为:“从上面的图示我们......。鸟哥已经将程序代码(英文)写成中文,” 13 | P30,1.1.2 Linux之前UNIX的历史,最后一行 14 | “此外,Minux操作系统的开发者仅有谭宁邦教授” 15 | 应改为:“此外,Minix操作系统的开发者仅有谭宁邦教授” 16 | P46,1.4 重点回顾 17 | “1984年由Andrew Tannenbaum制作出Minix操作系统,” 18 | 应改为:“1984年由Andrew Tanenbaum制作出Minix操作系统,” 19 | P46,1.4 重点回顾 20 | “目前Linux内核的开发分为两种版本......;一种是开发中版本,如2.5.x版” 21 | 应改为:“目前Linux内核的开发分为两种版本......;一种是开发中版本的奇数版,如2.5.x版” 22 | P55,2.2.3 X Window的学习 23 | “Open Office(http://www.latex-project.org/)” 24 | 应改为:“Open Office(http://www.openoffice.org/)” 25 | P160,6.5 本章练习,请问下面的目录主要放置什么数据? 26 | “/etc/、/etc/initd、/boot、/usr/bin、/bin、/usr/sbin、/sbin、/dev、/var/log。” 27 | 应改为“/etc/、/etc/init.d、/boot、/usr/bin、/bin、/usr/sbin、/sbin、/dev、/var/log。”,并去掉前面的小方点 28 | P200,8.1.3 Linux的Ext2文件系统(inode),例题 29 | “所有文件容量为:50 x 10000(bytes)= 488.3KB,但此时浪费的容量为: 4046 x 10000(bytes) = 38.6MB” 30 | 应改为“所有文件容量为:50 (bytes)x 10000 = 488.3KB,但此时浪费的容量为: 4046 (bytes) x 10000 = 38.6MB” 31 | P203,8.1.3 Linux的Ext2文件系统(inode),block bitmap 32 | “同样......,此时在block bitmpap当中相对应到该block号码的标志就要修改” 33 | 应改为:“同样......,此时在block bitmap当中相对应到该block号码的标志就要修改” 34 | P243,8.6.2 磁盘空间的浪费问题,第二个灰色框 35 | “118 /etc <==单位是KB” 36 | 应改为“118 /etc <==单位是MB” 37 | 繁体中文“如果在文章內有對齊的區塊,可以使用 [ctrl]-v 進行複製/貼上/刪除的行為” 38 | P291,10.5 重点回顾,倒数第五点 39 | “可以使用[ctrl]-v进行复制/粘帖/删除的行为。” 40 | P301,11.2.2 变量的显示与设置,第三行 41 | “变量的显示就如同上面的范例,利用ehco就能够读出,” 42 | 应改为:“变量的显示就如同上面的范例,利用echo就能够读出,” 43 | P316,11.2.8 变量内容的删除、替代与替换,第一个灰色框 44 | “然后测试一下等号(-)的用法” 45 | 应改为:“然后测试一下减号(-)的用法” 46 | P338,11.6.2 排序命令,本节最后一行 47 | “就使用wc-c这个参数” 48 | 应改为:“就使用wc-m这个参数” 49 | P354,12.2.3 基础正则表达式练习,例题四 50 | “*(星号):代表重复前一个0到无穷多次的意思,为组合形态” 51 | 应改为:“*(星号):代表重复前一个字元,0到无穷多次的意思,为组合形态” 52 | P356,12.2.4 基础正则表达式字符(characters),表12-2,[n1-n2] 53 | “grep -n '[0-9]' regular_express.txt” 54 | 应改为:grep -n '[A-Z]' regular_express.txt 55 | P379,13.2.2 script的执行方式区别,图13-2 sh02.sh在父进程中运行 56 | “sh sh02.sh在此执行” 57 | 应改为:“source sh02.sh在此执行” 58 | P430,14.4.2 sudo,visudo与/etc/sudoers 59 | “有趣吧……,所以这个文件就是/etc/sudoerds” 60 | 应改为“有趣吧……,所以这个文件就是/etc/sudoers” 61 | P449,14.9 本章习题,第三个灰色框 62 | “useradd -G youcan -s -m $username” 63 | 应改为:“useradd -G youcan -s /bin/bash -m $username” 64 | P500,16.3.2 系统的配置文件:/etc/crontab,Tips 65 | “/etc/init.d/crondrestart” 66 | 应改为:“/etc/init.d/crond restart” 67 | P515,17.2.3 脱机管理问题,第二个灰色框 68 | “[root@www ~]#exit”应在灰色框中 69 | “如果你再次登录的话,再使用ps -l去查看你的进程,” 70 | 应改为:“如果你再次登录的话,再使用pstree去查看你的进程,” 71 | P560,18.2.1 默认值配置文件,表18-1,per_source 72 | “设置值:[一个数字或NULIMITED]” 73 | 应改为:“设置值:[一个数字或UNLIMITED]” 74 | P572,18.4.3 CentOS 5.x 默认启动的服务简易说明,表18-2,xfs 75 | “如果你不启动X窗口的话,那么这个服务可以启动。” 76 | 应改为:“如果你不启动X窗口的话,那么这个服务可以不启动。” 77 | P572,18.5 重点回顾,倒数第三行 78 | “而启动的方式则为/etc/init.d/xientd restart。” 79 | 应改为:“而启动的方式则为/etc/init.d/xinetd restart。” 80 | P579,19.2.1 日志文件内容的一般格式,第四行 81 | “某个demon执行过程老是不顺畅时;” 82 | 应改为:“设置值:某个daemon执行过程老是不顺畅时;” 83 | P627,20.5 重点回顾,第六点 84 | “init的配置文件为/etc/initab,” 85 | 应改为:“init的配置文件为/etc/inittab,” 86 | P652,21.3.2 驱动USB设备,第二点 87 | “至于USB2.0在Linux上都以Enahnced Host Controller Interface (EHCI)来驱动的。” 88 | 应改为:“至于USB2.0在Linux上都以Enhanced Host Controller Interface (EHCI)来驱动的。” 89 | P740,25.1.3 选择备份设备,存储设备的考虑 90 | “硬盘:/dev/hd[a-d][1-16] (IDE), /dev/sd[a-p][1-16] (SCSI/SATA)” 91 | 应改为:“硬盘:/dev/hd[a-d][1-63] (IDE), /dev/sd[a-p][1-16] (SCSI/SATA)” -------------------------------------------------------------------------------- /_drafts/Others/2014-11-04-EXE 文件转换成安装程序教程.md: -------------------------------------------------------------------------------- 1 | EXE 文件转换成安装程序(原创) 2 | 3 | 我们生成的 EXE 文件使用的时候直接打开就可以用比较方便,但现在大部分软件都带有安装程序和卸装程序,它们具有相通的界面,给用户带来了很大的方便,同时也使得软件很有专业感。我们可以使用一个制作安装程序的小软件——Install Us. 4 | 5 | ## 制作安装序 6 | 7 | 开始运行 Install-US 后,会弹出 Project 项目开始窗口,它的运行窗口显示如下图的界面,也可以从选择 File 选单下的 New 项,弹出此窗口。第一项是软盘(Disks), 第二项是光盘(CD),第三项是制作成一个自解压文件,第四项是让我们打开以前的项目文件(Open Project-File)以便修改,同时还有一个选项“Don't Show this dialog next time”,一般不选,如果选中了下次就不会出现这个对话框了,不过我们还是可以通过点击第一步 General Settings 的 Medium 按钮来选择发行介质。我是希望生成一个自解压的安装文件,所以选择 Internet-Download,这样最后会生成一个自解压安装程序文件 setup.exe(可以重命名的哈)。 8 | 9 | ![](https://raw.githubusercontent.com/jiangxincode/PicGo/master/2014110401.png) 10 | 11 | ## 设置被安装软件的主要配置 12 | 13 | 在选择了最终发行介质之后,进入制作第一步——设置被安装软件的主要配置, 此时会出现下图 的界面,在主要配置 General Settings 选项中,你可以设定被分发的软件安装后在机器上的目标目录 Directory,例如:你制作出的安装盘,运行后软件指定要安装在“C:\ Program Files\HelloWorld”文件夹下,则在Directory 输入框中输入C:\Program Files\HelloWorld;在 Configurations 配置中,指定提供给用户可以选择的安装配置方式,常用的方式有缺省、最小、定制三种。本例只提供典型 Typical 方式,所以只选择 Typecal 一 项。 14 | 15 | ![](https://raw.githubusercontent.com/jiangxincode/PicGo/master/2014110402.png) 16 | 17 | 18 | ## 选择需要安装的文件 19 | 20 | 在完成一般设置之后,单击工具条上的“Next ”钮,进入制作第二步,出现下图的界面,这一步是让用户选择将要发行的文件( EXE 的 所有文件)。左侧的文件目录窗口用来显示文件系统;右侧的窗口用来显示软件安装后的目标路径。你所作的是从左侧选择要拷贝到用户机器中的源文件, 点击“〉”按钮,将他们拷贝到右侧窗口中,也可选择“》”按钮,将当前目录下的所有文件,拷贝到右侧窗口。 21 | 22 | ![](https://raw.githubusercontent.com/jiangxincode/PicGo/master/2014110403.png) 23 | 24 | 下图为Options选项: 25 | 26 | ![](https://raw.githubusercontent.com/jiangxincode/PicGo/master/2014110404.png) 27 | 28 | 29 | 下图为User Interface选项: 30 | 31 | ![](https://raw.githubusercontent.com/jiangxincode/PicGo/master/2014110405.png) 32 | 33 | 下图为System Configuration选项: 34 | 35 | ![](https://raw.githubusercontent.com/jiangxincode/PicGo/master/2014110406.png) 36 | 37 | 38 | 最后是Building Installation选项: 39 | 40 | ![](https://raw.githubusercontent.com/jiangxincode/PicGo/master/2014110407.png) 41 | 42 | 43 | 最后是生成的安装包的安装界面: 44 | 45 | ![](https://raw.githubusercontent.com/jiangxincode/PicGo/master/2014110408.png) 46 | 47 | 这个软件还不错,还有一些其他的设置,如安装时候启动密码,安装文件,序列号等,可以查看软件自带的帮助文件。 48 | 49 | -------------------------------------------------------------------------------- /_drafts/Others/2015-10-25-代码风格与代码格式化工具.md: -------------------------------------------------------------------------------- 1 | # 代码风格与代码格式化工具 2 | 3 | * Google Style Guides: 4 | * Google 开源项目风格指南——中文版(Google Style Guide): 5 | 6 | * The tidyverse style guide: 7 | * Google’s R Style Guide: 8 | 9 | ## clang-format 10 | 11 | clang-format 位于 clang/tools/clang-format,可用于格式化 C/C++/Java/JavaScript/JSON/Objective-C/Protobuf/C# 代码。 12 | 13 | * 官网: 14 | 15 | ## astyle(Artistic Style) 16 | 17 | astyle是一个免费、快速且小巧的自动格式化工具,适用于 C、C++、C++/CLI、Objective-C、C# 和 Java 源代码。 18 | 19 | * 官网: 20 | * 文档: 21 | 22 | ### 基本命令 23 | 24 | `astyle --style=ansi main.cs` 25 | 26 | ### 格式化目录 27 | 28 | 使用ansi风格格式当前目录下的所有cpp,cs文件,注意在批处理文件时,"%f" 要改为"%%f" 29 | 30 | `for /R %f in (*.cpp;*.cs;) do astyle --style=ansi "%f"` 31 | 32 | ### 加入到VS2008,VS2005 33 | 34 | * 工具——>外部工具——>添加 35 | * 标题:astyle 36 | * 命令:AStyle.exe (填好astyle.exe的路径) 37 | * 参数:--style=allman -N $(ItemDir)$(ItemFileName)$(ItemExt) 38 | * 初始目录:$(TargetDir) 39 | * 勾上“使用初始目录” 40 | * 点击确定完成,以后就可以在工具菜单中找到“astyle“这一项了,点击它,就可以对当前文件进行格式化操作。 41 | 42 | ### 加入到VS6 43 | 44 | * Tools——>Customize——>Tools 45 | * 标题:astyle 46 | * 命令:AStyle.exe (填好astyle.exe的路径) 47 | * 参数:--style=ansi -s4 --suffix=.orig $(FileName)$(FileExt) 48 | * 初始目录:$(FileDir) 49 | * 勾上“Using Output Window” 50 | * 点击确定完成。以后就可以在工具菜单中找到“astyle“这一项了,点击它,就可以对当前文件进行格式化操作。 51 | 52 | ### 加入到UltraEdit和UltraStudio 53 | 54 | * 高级-->工具配置——>外部工具——>添加 55 | * 命令:AStyle.exe -v --style=ansi -s4 --suffix=.orig "%f"(填好astyle.exe的路径) 56 | * Optiones:选择 Windows program和Save Active File. 57 | * Output: 选择output to list box,show dos box 和no replace。 58 | * 点击确定完成。以后就可以在工具菜单中找到“astyle“这一项了,点击它,就可以对当前文件进行格式化操作。 59 | 60 | ### 加入到Source insight 61 | 62 | * Options-->Custom Command-->Add 63 | * Command:astyle 64 | * Run "D:\soft\astyle\astyle.exe" --style=ansi -f -p -P -U -v -n -N %f(填好astyle.exe的路径) 65 | * Output:不选. 66 | * Control: 选择pause when done和exit to window. 67 | * source links in output:file, then line 68 | * -->menu 69 | * add to work menu. 70 | * 点击确定完成。以后就可以在Work菜单中找到“astyle“这一项了,点击它,就可以对当前文件进行格式化操作。 71 | 72 | 另外可以参考:在source insight中集成astyle: 73 | 74 | ### 控制台目录批处理(astyle.bat) 75 | 76 | ```Bash 77 | REM 批量将本目录中的所有C++文件用Astyle进行代码美化操作 78 | REM 设置Astyle命令位置和参数 79 | @echo off 80 | set astyle="astyle.exe" 81 | REM 循环遍历目录 82 | for /r . %%a in (*.cpp;*.c) do %astyle% --style=ansi --pad=oper --unpad=paren -s4 -n "%%a" 83 | for /r . %%a in (*.hpp;*.h) do %astyle% --style=ansi --pad=oper --unpad=paren -s4 -n "%%a" 84 | REM 删除所有的astyle生成文件 85 | for /r . %%a in (*.orig) do del "%%a" 86 | pause 87 | ``` 88 | 89 | ## CoolFormat 90 | 91 | CoolFormat源代码格式化是一款C\C++\C#\CSS\HTML\Java\JavaScript\JSON\Objective-C\PHP\SQL\Verilog\XML代码格式化工具。软件可以快速多种风格格式化,并对语言进行着色。界面采用Office 2010风格,并有多种样式可以替换。并且支持代码高亮到网页上显示,方便博客文章之类的撰写阅读。 92 | 93 | * 官网: 94 | 95 | ## Adapter for Eclipse Code Formatter 96 | 97 | 允许直接从 IntelliJ 使用 Eclipse 的 Java 代码格式化工具。解决了在使用 IDEA 和 Eclipse 的团队环境中维护统一代码风格的问题。 98 | 99 | * 官网: 100 | -------------------------------------------------------------------------------- /_drafts/Others/202302262208StableDiffusionWebui环境搭建.md: -------------------------------------------------------------------------------- 1 | # stable-diffusion-webui环境搭建与使用 2 | 3 | ## 条件准备 4 | 5 | * Git(2.38.1) 6 | * Python(3.10.9) 7 | * Pillow(9.4.0) 8 | * 有科学上网工具 9 | 10 | 必须的是一台显存4g以上电脑,英伟达的显卡。最好有科学上网工具,否则最后一步的部署会经常中断,需要反复尝试。 11 | 12 | ## 安装git 13 | 14 | 下载地址https://git-scm.com/downloads 15 | 16 | 下载好,安装,一直next即可,在Select Components这一步可以把Windows Explorer integration的勾去掉,这个如果不去掉,鼠标右键菜单会加入git相关的操作。 17 | 18 | ## 安装python3.10.6 19 | 20 | 下载地址https://www.python.org/downloads/ 21 | 22 | 安装时,要打勾Add Python 3.10 to PATH,之后一直next即可。 23 | 24 | ## 部署stable-diffusion-webui 25 | 26 | 新建一个文件夹,文件名随意,用于存放stable-diffusion-webui和模型。 27 | 28 | 进入你新建的文件夹,右键页面空白处,点击在终端中打开,执行指令 git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git,下图是执行成功后的样子,成功后可关掉界面。 29 | 30 | 31 | ## 下载模型文件 32 | 33 | 模型决定了生成图片的风格和质量。新手可以下载这个默认的模型,下载地址https://huggingface.co/CompVis/stable-diffusion-v-1-4-original/tree/main,下载sd-v1-4.ckpt,点击这个右边的小箭头即可。 34 | 35 | 下载后,回到步骤4中新建的那个文件夹,把下载好的模型文件,我这里使用的是(sd-v1-4.ckpt)放到stable-diffusion-webui\models\Stable-diffusion这个文件夹下(如果是NovelAi的模型,将ckpt和pt文件都放在此文件夹下) 36 | 37 | ## 部署stable-diffusion-webui 38 | 39 | 双击webui.bat,自动开始部署,如果不使用科学上网,这个过程会很慢且容易报错。非常建议使用科学上网。 40 | 41 | 若使用科学上网,在你的上网软件里看一下代理端口(port),下图是我的。 42 | 43 | 44 | 然后在任务栏点击 45 | 46 | 47 | 搜索Windows powershell,运行这行命令:git config --global http.proxy http://127.0.0.1:7890,这里7890是我的端口,要改成你自己的。 48 | 49 | 然后再运行webui-user.bat,部署过程中,可能会出现报错,或提示更新pip,不用管,多部署几次就好,我个人3次成功。 50 | 51 | 52 | 出现这个就代表成功了。 53 | 54 | ## 开始ai作画 55 | 56 | 见上图,部署完成后会有一个链接 57 | 58 | 59 | 链接复制到浏览器中打开,会出现以下界面,这里我在左上角输入apple,点击右上角generate,生成了一张关于苹果的图片。左下角可以调整图片参数和生成图片数量。 60 | 61 | 62 | 教程结束,谢谢大家支持,欢迎在评论区交流讨论。 作者:46789FG https://www.bilibili.com/read/cv21748847 出处:bilibili -------------------------------------------------------------------------------- /_drafts/Others/Cache模拟器(CacheSim).md: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 最近写了一个Cache的模拟器,由于平时空余时间比较分散,前前后后用了一周多的时间,基本实现的Cache的模拟功能(通过读取trace文件得到相应的命中率),能够实现直接映射、全相联、组相联三种映射方式,其中全相联和组相联能够实现随机、LRU两种替换策略。目前三种映射方式均采用回写法,但已经定义了其它写策略的接口,可以很容易扩充。程序具有比较强的鲁棒性,能够接受一定范围的错误输入,并能够比较智能的提示用户输入。 5 | 6 | 我尽量缩减了不必要的代码,控制在1000行以内。但日后加上部分功能后,可能会远超这个数目,希望大家帮我优化一下代码,以提高程序的空间效率。时间效率也不是很高,至少现在来说,读取30万行的内存地址数据,如果采取全相联的话,需要耗费的时间还是很长的。我会尽量优化。 7 | 8 | 程序使用C/C++混合编程,但不是采用面向对象的方法,虽然在编写过程中想改成以类的方式实现,但是整体框架已经完成的差不多了,所以就没有改。程序中使用了一些C++11标准中的类,比如bitset,所以必须在支持C++11的编译器上进行编译,但现在主流的编译器比如gcc和VS均已支持,所以不用太担心。 9 | 10 | 我已经上传了代码和可执行程序的最新版本,下载地址是: 11 | 12 | http://download.csdn.net/detail/jiangxinnju/7404137 13 | 14 | 程序能够在Windows平台下直接运行,如果你想在Linux平台运行,请重新编译,并调整base.h中相应的编译选项,其它文件不用修改,因为我已经使用了条件编译适应不同的编译环境。如果你只是想查看最后的数据结果,不关心每条数据的具体命中情况请不要在编译的时候注释掉 15 | 16 | #define NDEBUG // For NDEBUG pattern 17 | 18 | 否则,程序需要很长的运行时间。另外如果你希望看到本程序的历史版本,或者希望在我的程序中添加新的功能,可以直接fork我的github,地址为: 19 | 20 | https://github.com/jiangxincode/CacheSim 21 | 22 | 关于本程序的版权声明,可以参考README.txt文件,在遵守相关条目的基础上,你可以任意拷贝、修改我的程序。 23 | 24 | 如果你对于程序中的内容有所疑问,比如无法在你的机器上正常编译或运行,可以直接联系我,我的Email地址为: 25 | 26 | jiangxinnju@163.com 27 | 28 | 欢迎各位朋友提出修改意见。 29 | 30 |  -------------------------------------------------------------------------------- /_drafts/Others/Rdseed与SAC的安装.md: -------------------------------------------------------------------------------- 1 | 2 | ## Rdseed的安装 3 | 4 | 1. 下载: http://www.iris.edu/pub/programs/rdseedv5.2.tar.gz 5 | 2. 解压: tar -xzvf rdseedv5.2.tar.gz 6 | 3. 编译: 7 | 8 | ```shell 9 | # 在makefile中找到这几句 10 | CC = cc 11 | # for cygwin add the -D_CYGwin flag, for users of windows pcs 12 | CFLAGS = -O -m32 -g -D_CYGwin 13 | 14 | # to compile rdseed as a 32-bit application 15 | #CFLAGS = -O -m32 -g 16 | 17 | # 将CYGwin行注释掉,取消最下面一行的注释: 18 | CC = cc 19 | # for cygwin add the -D_CYGwin flag, for users of windows pcs 20 | #CFLAGS = -O -m32 -g -D_CYGwin 21 | 22 | # to compile rdseed as a 32-bit application 23 | CFLAGS = -O -m32 -g 24 | 25 | # 然后 26 | make clean 27 | make 28 | ``` 29 | 30 | 4. 将编译好的rdseed文件拷贝靠bin目录下:sudo cp rdseed /usr/bin/ 31 | 5. 输入rdseed即可进入。 32 | 33 | 注:64位系统下可以直接使用已编译好的文件:cp -p rdseed.rh6.linux_64 /usr/local/bin/rdseed 34 | 35 | ## SAC安装 36 | 37 | 1. 软件包可以在下面给出的网站上申请,认真填写,在平台选择处选择Linux 32 位或64位(如果有兴趣也可以选择一个source code)。注意不要图省事一次把所有包都申请了,那样管理员会专门给你发邮件要你解释的。最好使用学校邮箱或者较正规的邮箱,否则有被拒的可能。若验证通过,三个工作日内即可收到邮件。申请网址:http://www.iris.edu/forms/sac_request.htm 38 | 39 | 2. 对sac 文件压缩包直接解压,会出现sac文件夹,里面包含了多个文件夹: 40 | 41 | ```shell 42 | tar xvfz netcdf-3.6.3.tar.gz 43 | for i in *.bz2;do tar jxvf $i;done 44 | ``` 45 | 46 | 3. 将整个sac 文件夹拷到某目录下(SAC 推荐安装目录为/usr/local): 47 | 48 | ```shell 49 | sudo cp -r sac /usr/local 50 | ``` 51 | 52 | 4. 编辑.bashrc 设置环境变量 53 | 54 | ```shell 55 | gedit ~/.bashrc 56 | ``` 57 | 58 | 在.bashrc 的最后添加如下语句 59 | 60 | ```shell 61 | export SACHOME=/usr/local/sac 62 | export SACAUX=$SACHOME/aux 63 | export PATH=$SACHOME/bin:$PATH 64 | ``` 65 | 66 | 5. 终端输入source ~/.bashrc 67 | 6. 终端输入sac(注意要小写),看到版本号等信息即安装成功。 -------------------------------------------------------------------------------- /_drafts/Others/Use the SVN command-line tool.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 本文转自: 4 | 排版有修改 5 | 6 | 7 | From for subversion for windows version, after installation there will be a `svn.exe` the command-line client based tool. Of course, there are also server-side program, here is not concerned about how to configure the SVN service. Setup the path to `svn.exe` joined the path environment variable, we are able to directly enter the svn command line can be used. 8 | If you do not know how to use the command svn command can query as follows: 9 | `svn help` 10 | That the sub-command, but do not know subcommands can also search for: 11 | `svn help ci` 12 | 13 | ## Developers frequently used commands 14 | Import items 15 | `svn import http://svn.chinasvn.com:82/pthread - message "Start project"` 16 | Export Project 17 | `svn checkout http://svn.chinasvn.com:82/pthread` 18 | Export to export by way of a "clean" project 19 | `svn export http://svn.chinasvn.com:82/pthread pthread` 20 | Clearance for the failure of the transaction 21 | `svn cleanup` 22 | Code changes locally, check the status changes 23 | ``` 24 | svn status-v 25 | svn diff 26 | ``` 27 | Update (update) server data to local 28 | ``` 29 | svn update directory 30 | svn update file 31 | ``` 32 | Increase (add) local data to the server 33 | ``` 34 | svn add file.c 35 | svn add dir 36 | ``` 37 | Rename the file and delete 38 | ``` 39 | svn mv bc bb.c 40 | svn rm dc 41 | ``` 42 | Submit (commit) local document to the server 43 | ``` 44 | svn commit 45 | svn ci 46 | svn ci-m "commit" 47 | ``` 48 | View Log 49 | ``` 50 | svn log directory 51 | svn log file 52 | ``` 53 | 54 | ## Some related things: 55 | 1, in the local paper, each directory has a. Svn folder (attribute is hidden), save the relevant information. 56 | 2, registered environmental variables SVN_EDITOR as `"E: \ Program Files \ Vim \ vim71 \ gvim.exe"`, results in the svn ci, when an error: 57 | ``` 58 | 'E: \ Program' is not an internal or external command, operable program or batch file. 59 | svn: Commit failed (details follow): 60 | svn: system ('E: \ Program Files \ Vim \ vim71 \ gvim.exe svn-commit.tmp') returns 1 61 | ``` 62 | The SVN_EDITOR to "gvim.exe", and add the path in the path `"E: \ Program Files \ Vim \ vim71 \"`, so that you can use vim at the time of submission of written comments. -------------------------------------------------------------------------------- /_drafts/Others/VirtualBox相关问题总结.md: -------------------------------------------------------------------------------- 1 | 2 | * VirtualBox Images: http://www.osboxes.org/virtualbox-images 3 | * VirtualBoxes – Free VirtualBox® Images: https://virtualboxes.org/images 4 | 5 | 6 | ## Virtualbox 网络 7 | 8 | * https://www.virtualbox.org/manual/ch06.html#network_nat 9 | 10 | ## VT-x features locked or unavailable in MSR 11 | 12 | * https://forums.virtualbox.org/viewtopic.php?f=6&t=43403&sid=5ccd991da007192f4c429c657b725eae 13 | 14 | 15 | ## 访问USB子系统失败 16 | 17 | 解决ubuntu下virtualbox访问usb子系统失败 18 | 19 | http://blog.coltcn.com/2012/03/13/virtualbox-error-failed-to-access-usb-subsystem/ 20 | 21 | ## ubuntu用户不在sudoers文件中问题 22 | 23 | http://blog.csdn.net/killzero/article/details/10298845 24 | 25 | ## 安装CentOS后安装增强功能 26 | 27 | 1.启动CentOS,以root身份登录,进入桌面环境。 28 | 29 | 2.执行如下命令: 30 | 31 | yum upadate 32 | yum install kernel-devel   33 | yum install gcc 34 | 35 | 3.重启系统 36 | 37 | 4.安装增强功能 38 | 39 | 5.重新启动 40 | 41 | ## Cannot register the hard disk错误解决办法 42 | 43 | virtualbox中加载已有的虚拟硬盘时出现Cannot register the hard disk错误,描述类似下面的。 44 | 45 | ERROR: Cannot register the hard disk '/mnt/ee/winxp/xp.vdi' with UUID {395ae4ae-8bf9-42e5-b82a-61af9f95fbf0} because a hard disk '/mnt/ee/winxp/xp.vdi' with UUID {395ae4ae-8bf9-42e5-b82a-61af9f95fbf0} already exists in the media registry ('/home/pzye/.VirtualBox/VirtualBox.xml') 46 | Details: code NS_ERROR_INVALID_ARG (0x80070057), component VirtualBox, interface IVirtualBox, callee nsISupports 47 | Context: "OpenHardDisk(Bstr(szFilenameAbs), AccessMode_ReadWrite, srcDisk.asOutParam())" at line 603 of file VBoxManageDisk.cpp 48 | 49 | 解决方法如下: 50 | 51 | 关闭virtualbox,重新启动它,它会检测虚拟硬盘,可能会检测出来一些虚拟硬盘,请将其删除,然后就不会出现这个问题了。 52 | 53 | 54 | ## virtualbox命令行共享CentOS目录 55 | 56 | 1. 安装virtualbox增强工具 57 | 58 | 2. 设置共享文件夹 59 | 60 | 完成后点击"设备(Devices)" -> 共享文件夹(Shared Folders)菜单,添加一个共享文件夹,选项固定和临时是指该文件夹是否是持久的。共享名可以随意取,如"yongfu",尽量使用英文名称,不要有空格。 61 | 62 | 3. 挂载共享文件夹 63 | 64 | 在命令行终端下输入: 65 | 66 | mkdir /mnt/yongfu 67 | mount -t vboxsf yongfu /mnt/yongfu 68 | 69 | 其中"yongfu"是之前创建的共享文件夹的名字。现在虚拟机和主机可以互传文件了。如不想每次都手动挂载,可以在/etc/fstab中添加一项 70 | 71 | yongfu /mnt/yongfu vboxsf rw,gid=100,uid=1000,auto 0 0 72 | 73 | 这样就能够自动挂载了。 74 | 75 | 4. 卸载的话使用下面的命令 76 | 77 | umount -f /mnt/yongfu 78 | 79 | ## Windows 8.1+VirtualBox较新版本打开虚拟机时报错 80 | 81 | 报错信息: 82 | ``` 83 | Unable to load R3 module D:\Program Files\Oracle\VirtualBox/VBoxDD.dll 84 | (VBoxDD):GetLastError=1790 85 | (VERR_UNRESOLVED_ERROR) 86 | ``` 87 | 解决办法是在Windows/system32下: 88 | 89 | * themeui.dll.old.tweakcube替换themeui.dll 90 | * uxtheme.dll.old.tweakcube替换uxtheme.dll 91 | 92 | 如果是Windows 7中遇到类似问题,参考: 93 | http://jingyan.baidu.com/article/ab69b270bb7b2a2ca6189f6d.html 94 | 95 | ## VirtualBox扩容 96 | 97 | * https://www.virtualbox.org/manual/ch08.html#vboxmanage-modifyvdi 98 | * http://www.cnblogs.com/zhcncn/articles/2948508.html 99 | * http://blog.csdn.net/ganshuyu/article/details/17954733 -------------------------------------------------------------------------------- /_drafts/Others/Windows日志查看工具合集.md: -------------------------------------------------------------------------------- 1 | 2 | 平时在Linux下查看日志,使用tail、grep、find等命令还比较方便,后来需要在Windows中处理一些问题,发现缺少类似的功能,比如tailf实时输出,于是在网上收集了一些相关的小工具,希望能够帮助到大家。 3 | 4 | 这些工具分为两类,一种是在Windows上模仿Linux的行为,使用类似的命令解决,比如: 5 | 6 | * tail for Windows: http://www.trisunsoft.com/tail-for-windows.htm 7 | * Tail for Win32: https://sourceforge.net/projects/tailforwin32/ 8 | * MinGW: http://www.mingw.org/ 9 | * Cygwin: https://www.cygwin.com/ 10 | * git自带的tail: https://git-scm.com/ 11 | 12 | 另外一种就是Windows GUI风格的工具,比如: 13 | 14 | * Hoo WinTail: http://www.hootech.com/WinTail/ 15 | * BareTail: http://www.baremetalsoft.com/baretail/index.php 16 | * Tail4win: http://www.withdata.com/tail4win/index.html 17 | * LogViewer Pro: http://www.uvviewsoft.com/logviewer/ 18 | * Java Log Viewer: https://sourceforge.net/projects/jlogviewer/ 19 | * OtrosLogViewer: https://github.com/otros-systems/otroslogviewer 20 | * LogExpert: http://www.log-expert.de/ 21 | 22 | 其中我选用的是BareTail。 23 | 24 | 另外介绍几个Java GC日志查看工具: 25 | 26 | * GCViewer: https://github.com/chewiebug/GCViewer 27 | * garbagecat: https://github.com/doctau/garbagecat 28 | * gchisto: https://java.net/projects/gchisto 29 | * GCLogViewer: https://github.com/potatofantasy/gclogviewer 30 | * HPjmeter: http://www.hp.com/go/java -------------------------------------------------------------------------------- /_drafts/Others/XShell使用问题汇总.md: -------------------------------------------------------------------------------- 1 | ## XShell使用问题汇总 2 | 3 | Xshell是一款公认的优秀SSH连接管理软件,被广泛用于管理Linux服务器或VPS。 4 | 5 | ## 解决xshell中vim显示中文乱码的问题 6 | 打开一个用utf8编码的中文文件,在vim中,执行`set encoding=utf-8 termencoding=gbk fileencoding=utf-8`后可正常显示中文。`encoding`是设置档案的当前编码。`termencoding`是用于vim屏幕的显示编码,由于xshell默认用于显示屏幕的编码是gbk,所以此处设置为gbk。同理,假设你修改了xshell的默认编码为utf-8,那么此处自然应该utf-8。`fileencoding`档案保存时的编码,此编码应和encoding保持一致,否则会弹出警告 7 | 至于xshell,打开`file->Properties`,点击`Terminal`节点,修改`Terminal Type`为linux(键盘映射模式,默认为xtrem,此种模式下对于vim小键盘输入数字会出现乱字符号),修改Encoding为uft-8(一般情况下linux系统采用此编码,可用locale命令查看自己系统的默认编码,修改为一致的就行)。 8 | 同理,也可以修改xftp的编码为utf-8以正常显示中文。 9 | 10 | ## Xshell利用登录脚本从服务器登录到另外一个服务器 11 | 通过脚本设置,可以实现从这个服务器登录到另外一个服务器。打开Xshell 4的会话属性(【文件】->【属性】),左边的类别下选择【登录脚本】,在右边底下你可以看到有个【连接会话是运行脚本】的复选框。 12 | 13 | ![](http://images2015.cnblogs.com/blog/611264/201702/611264-20170207235057041-2128114645.png) 14 | 15 | 登录脚本的格式如下: 16 | ```VBS 17 | Sub Main 18 | xsh.Screen.Send "ssh 用户名@服务器地址" 19 | xsh.Screen.Send VbCr 20 | xsh.Screen.WaitForString "password: " 21 | xsh.Screen.Send "登录密码" 22 | xsh.Screen.Send VbCr 23 | End Sub 24 | ``` 25 | 将上面内容保存成一个vbs后缀的文件(最好保存到Xshell安装文件下面),准备好脚本文件后在Xshell中打开 26 | 27 | 会话属性,勾选【连接会话是运行脚本】这个复选框,选择刚才保存的那个vbs后缀的文件就可以了。 28 | 29 | 如果想进一步了解Xshell支持的脚本API,可以查看Xshell的帮助文档: 30 | 31 | ![](http://images2015.cnblogs.com/blog/611264/201702/611264-20170207235214151-52018514.png) -------------------------------------------------------------------------------- /_drafts/Others/openmpi出现Segmentation Fault而终止运算.md: -------------------------------------------------------------------------------- 1 | 2 | ``` 3 | mpirun noticed that process rank 1 with PID 3716 on node localhost.localdomain exited on signal 11 (Segmentation fault). 4 | ``` 5 | 6 | 如果使用intel的编译器,当体系一大,刚进入主循环就会退出来,并提示上面的错误!一般是内存溢出了,原因在于编译时INTEL默认将缓存写在堆栈里,堆栈小时便会出现上述错误,可以尝试在编译VASP时,在FFLAGS里加上参数-heap-arrays 64,如果还不行的话,就换一下编译器,PGI应该会好点。 -------------------------------------------------------------------------------- /_drafts/Others/tcpdump捕捉样例.md: -------------------------------------------------------------------------------- 1 | 2 | ```shell 3 | 4 | # 下面的例子全是以抓取eth0接口为例,如果不加”-i eth0”是表示抓取所有的接口包括lo。 5 | 6 | # 抓取到目标主机example.com的http header头信息。-s 1024 抓取每个包的头1024 bytes (相对于默认的68Bytes);-l 输出模式line buffer 7 | tcpdump -i eth0 -s 1024 -l -A dst example.com 8 | 9 | GET /somepage.php HTTP/1.1 10 | Host: example.com 11 | User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.04 (lucid) Firefox/3.6.13 12 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 13 | Accept-Language: en-us,en;q=0.5 14 | Accept-Encoding: gzip,deflate 15 | Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 16 | Keep-Alive: 115 17 | Connection: keep-alive 18 | Cookie: uv=556903; __utma=74760.8756.122723.125824.126018.66; __utma=1.82217.512009.75006.095989.35; __utmz=1.0930.27.8.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=example; PHPSESSIONID=5C26; DWRSESSIONID=G9E5$Y4wdRi; __utmb=1.3.10.129; __utmc=1 19 | Cache-Control: max-age=0 20 | 21 | 22 | # 抓取http包 0x4745 为"GET"前两个字母"GE" 0x4854 为"HTTP"前两个字母"HT" 23 | tcpdump -XvvennSs 0 -i eth0 tcp[20:2]=0x4745 or tcp[20:2]=0x4854 24 | 25 | # 抓取包含10.10.10.122的数据包 26 | tcpdump -i eth0 -vnn host 10.10.10.122 27 | 28 | # 抓取包含10.10.10.0/24网段的数据包 29 | tcpdump -i eth0 -vnn net 10.10.10.0/24 30 | 31 | # 抓取包含端口22的数据包 32 | tcpdump -i eth0 -vnn port 22 33 | 34 | # 抓取udp协议的数据包 35 | tcpdump -i eth0 -vnn udp 36 | 37 | # 抓取icmp协议的数据包 38 | tcpdump -i eth0 -vnn icmp 39 | 40 | # 抓取arp协议的数据包 41 | tcpdump -i eth0 -vnn arp 42 | 43 | # 抓取ip协议的数据包 44 | tcpdump -i eth0 -vnn ip 45 | 46 | # 抓取源ip是10.10.10.122数据包。 47 | tcpdump -i eth0 -vnn src host 10.10.10.122 48 | 49 | # 抓取目的ip是10.10.10.122数据包 50 | tcpdump -i eth0 -vnn dst host 10.10.10.122 51 | 52 | # 抓取源端口是22的数据包 53 | tcpdump -i eth0 -vnn src port 22 54 | 55 | # 抓取源ip是10.10.10.253且目的ip是22的数据包 56 | tcpdump -i eth0 -vnn src host 10.10.10.253 and dst port 22 57 | 58 | # 抓取源ip是10.10.10.122或者包含端口是22的数据包 59 | tcpdump -i eth0 -vnn src host 10.10.10.122 or port 22 60 | 61 | # 抓取源ip是10.10.10.122且端口不是22的数据包 62 | tcpdump -i eth0 -vnn src host 10.10.10.122 and not port 22 63 | 64 | # 抓取源ip是10.10.10.2且目的端口是22,或源ip是10.10.10.65且目的端口是80的数据包。 65 | tcpdump -i eth0 -vnn \( src host 10.10.10.2 and dst port 22 \) or \( src host 10.10.10.65 and dst port 80 \) 66 | 67 | # 抓取源ip是10.10.10.59且目的端口是22,或源ip是10.10.10.68且目的端口是80的数据包。 68 | tcpdump -i eth0 -vnn 'src host 10.10.10.59 and dst port 22' or ' src host 10.10.10.68 and dst port 80 ' 69 | 70 | # 把抓取的数据包记录存到/tmp/fill文件中,当抓取100个数据包后就退出程序。 71 | tcpdump –i eth0 -vnn -w /tmp/fil1 -c 100 72 | 73 | # 从/tmp/fill记录中读取tcp协议的数据包 74 | tcpdump –i eth0 -vnn -r /tmp/fil1 tcp 75 | 76 | # 从/tmp/fill记录中读取包含10.10.10.58的数据包 77 | tcpdump –i eth0 -vnn -r /tmp/fil1 host 10.10.10.58 78 | 79 | ``` -------------------------------------------------------------------------------- /_drafts/Others/一个由于网络问题导致的服务无法使用——调试过程总结.md: -------------------------------------------------------------------------------- 1 | 2 | 最近测试经常让我处理一个问题,就是网站服务无法使用,通过Windows跳转机,使用Chrome浏览器访问服务首页,页面什么也没有展示,使用Chrome的F12调试窗口,发现并没有和服务端SLB的任何交互请求。查看后台门户的相关进程,均正常运行。查看后台日志,没有发现明显的错误。访问SLB的页面管理系统,发现所需服务均正常注册。定位无果后所以尝试重启,不定次数重启之后,清除浏览器缓存,继续登录,发现服务又能够正常访问。但是再次重启后,问题复现。 3 | 4 | 各个服务节点,包括双机SLB节点均是混合网卡,同时绑定大网地址(10开头)和小网地址(192开头),SLB的浮动IP地址为小网地址。考虑到可能是网络问题,但是跳转机只有一台,无法通过更换跳转机的方式,查看服务是否正常,同时因为在该组网中所有服务均使用SLB进行控制,无法通过在该跳转机中访问其他服务地址确定是否是跳转机问题。 5 | 6 | 使用ping命令,发现各个服务节点与SLB节点均能正常通信,跳转机与SLB也能正常通信,但是考虑到ping命令无法指定端口,仍无法确定跳转机与SLB之间的网络正常。于是想到了古老的telnet。首先使用ifconfig查看浮动IP绑定到哪台SLB节点上,两台均没有绑定,很奇怪,通过下面的文章了解到浮动IP无法使用ifconfig命令查出,然后按照文章中的说明使用ip addr命令找到浮动IP属于两台SLB中的A节点。 7 | 8 | 从ip addr add和ifconfig的区别看linux网卡ip地址的结构:http://blog.csdn.net/dog250/article/details/5303542/ 9 | 10 | 11 | 尝试在跳转机通过telnet命令(`telnet 192.XXX.XXX.XXX YYYY`)登陆SLB节点的A节点(为方便叙述,今后指到的SLB节点均是指其中的A节点),发现无法连接,查看SLB节点发现telnet服务未正常开启,于是根据下面的文章,开启了telnet服务。 12 | 13 | 如何启动linux的telnet服务:http://www.cnblogs.com/liuyou/archive/2011/10/17/2214498.html 14 | 15 | 之后继续尝试使用跳转机通过telnet命令登陆SLB节点,发现仍然无法连接,于是尝试使用某个服务节点用telnet去连接SLB节点,这回有提示信息,要求输入用户名,说明SLB节点的telent服务正常启动。在SLB节点尝试使用tcpdump命令进行抓包(`tcpdump -i eth1 -nn port XXXX`),也发现当使用服务节点telent登陆时发现有请求包,使用跳转机节点登陆时未发现请求包。由此确定是跳转机和SLB节点之间通信异常。 16 | 17 | 但是问题仍然没有彻底解决,仍然存在下面的问题: 18 | 19 | * 安装方式按理说能够保证各个小网见的机器的正常网路连接,为什么会出现访问异常的情况? 20 | * 如果是网路异常,为什么重启几次后可能恢复正常? 21 | * 指定端口,SLB节点和跳转机节点无法正常访问,为什么ping的时候可以正常ping通?而且可以双向ping通? 22 | 23 | 这些问题需要慢慢分析了。 24 | 25 | 注:为保护公司信息,文中的部分内容与实际情况有差异。 26 | 27 | 额外的参考链接: 28 | 29 | * Linux tcpdump命令详解: http://www.cnblogs.com/ggjucheng/archive/2012/01/14/2322659.html 30 | * 超级详细Tcpdump 的用法: http://www.cnblogs.com/maifengqiang/p/3863168.html -------------------------------------------------------------------------------- /_drafts/Others/一个程序员能够控制多少行代码.md: -------------------------------------------------------------------------------- 1 |  2 | 3 | 我觉得大家初看到这个题目时,一定会很奇怪,一个程序员能够控制多少行代码完全取决于该程序员的能力强弱,这有什么规律可循么?其实当这个想法突然冒出来时,我也都有些诧异。 4 | 5 | 首先介绍一下我遇到的情况,我当时正在编写一个小程序,是模拟cache工作原理的。这个程序中有一个函数集的实现文件(function.cpp),大概由20个左右的函数组成,由main.cpp中的main函数直接去调用它们。这个文件我是从头开始一点一点码起来的,开始时都很顺利,编写代码的速度也很平稳。但是当我的代码达到600行时,我突然发现我的编码效率出现了严重的下滑,我开始不断回顾我已经编写的代码的作用才能继续下面的内容。 6 | 7 | 不过后来我发现如果我能够将这个function.cpp文件分成两个文件function1.cpp/function2.cpp,其中function1.cpp实现一些基础函数功能,funtion2.cpp中的函数调用funciton2.cpp中的基础函数来实现一些更为复杂的功能。这时我突然发现我的编码效率又回到了正常状态,不用总是回顾之前的内容,也能够继续下去。这时我想到,在我过去的一些编码实践中经常会遇到类似的情况,只是我一直没有把它当一回事。我感觉一个程序员在它的程序的每个层次所能掌控的代码行数是近于固定的,一旦编写的代码超过这个数值,我们的代码编写效率就会急速下降。不得不将目前的代码进行划分层次,以继续完成剩下的功能。 8 | 9 | 可能你觉得上面我说的东西丝毫没有逻辑性,不知我到底要表达些什么。不过我觉得这件事情确实不太容易说清楚。为了继续说明这个问题,我先假定几个概念。一个是“控制”,一个是“代码行数”。首先说明一下这里的“代码行数”的具体所指,比如你在主函数中写出: 10 | 11 | printf(“Hello World!\n”); 12 | 13 | 这当然算一行代码,这没有什么疑问,在我们心中这行代码和:i=i+1一样的简单,虽然前者其实调用了一个库函数,而后者则没有。但是如果库函数中没有这个printf()函数,而要我们自己实现它的功能,因此编写了一个myprintf()函数,并且假设实现该功能需要10行代码,那么我们一共写了10+1=11行代码,可是一旦我们完成了这个函数功能,我们就不需要对其持续关注。因为它和我们的主函数不在一个层次上。所以我们现在虽然写了11行代码,却并不需要真正掌控11行代码就可以继续下去。但是我们有感觉,如果我们对于这个我们myprintf()函数不是很熟悉的话,每次看到这行:myprintf(“Hello World!\n”);时又要停下来想想它的作用,当我们经常使用它时,再看到这行代码,我们不会有任何思维上的停顿。所以我们假定这行代码中,我们实际需要掌控的代码行数为L1+α*L2,L1代表我们的主函数层次的代码行数。α代表我们的熟悉程度,L2代表我们实现myprintf()这个函数的所需代码(也就是说第二层次我们需要掌控代码行数)。在本文中为了简化,我们假定α=0.5,所以我们在主函数层次上真正需要掌控的代码数为1+10*0.5=6行。 14 | 15 | 现在我们谈谈什么叫做“控制”,我暂时把它定义为:如果我们所编写的代码行数在我们能控制的最大代码行数范围内,我们在编码过程中应该是舒适的。什么叫做舒适呢?就是我们能够按照我们日常的编码速度和编码质量进行编码。这里所说的编码速度和编码质量因程序员的个人能力差异而不同,但是对于一个固定的程序员来讲基本是稳定的。如果你对这种定义持有怀疑态度的话,我在用另一种形象的表述“控制”,如果你闭上眼,能够很快的回忆起你的工程中某个层次的所有代码的作用,那么你就可以说你掌控了该层次的所有代码。 16 | 17 | 好了,谈了这么多,我们探讨这个问题的目的是什么呢? 18 | 19 | 假设一个程序员通过以往的实践,发现自己所能掌控的工程中某一层次的代码数目为500行,当然开始某个新的工程时,发现他在主函数层次上已经写了将近500行代码。这是他应该警觉到:我已经快要到达我所能掌控的代码行数的极限了,如果继续在该层次上编写,势必会造成效率的严重下滑。这可能影响到总的工程进度。同时他发现这个主函数中的200行代码其实完全可以用下一个层次的一个函数来解决。于是他在下一个层次编写了一个200行的函数(比如function1),并把原来主函数中的200行代码删除。这是他实际需要掌控的代码数量为:300+0.5*200=400。这时它可以继续以一个舒适的编码状态在主函数编码。但是没过多久,他发现他在主函数层次上需要掌控的代码行数又要到达500行的极限了,这是它有发现原来主函数中的300行代码可以用一个下层次的函数解决,于是他在下一层次编写了一个300行的函数(比如function2)。这是他实际需要掌控的编码数目为:200+0.5*(200+300)=450。所以他可以继续在主函数层次编程。但这个过程不断继续,他总会到达这样一个时刻,主函数层次的代码已经足够精简,无法通过利用下一层次的函数来减少主函数层次的代码行数,但是他需要掌控的代码行数又已经达到了500行,整个工程需要的功能却还么有完全实现。这时该怎么办? 20 | 21 | 很容易想到,它可以将第二层次的函数进行精简,也就是说用第三层次的代码去实现第二层次函数的功能。这样可以进一步减少他所需要掌控的代码行数,使其一直保持在500行以内。其实这种理念和结构化程序设计理念有一些相同之处。只不过我们所说的结构化程序设计一般发生在工程的设计阶段。但是真正在实践编码过程中。我们的代码量经常会超出预期。这时我们需要不断动态的根据代码数量划分层次。 22 | 23 | 但是不是说我们可以这样一直划分层次来维持我们需要控制的代码数量低于我们最大能力呢?你也许会发现,当层次越划越细,越划越深时,我们的编码效率又开始下降了。这是什么原因呢?我们再回到之前提到的简单式子,我们在主层次需要掌控的代码数量为: 24 | 25 | L1+α2*L2+α2*α3*L3… 26 | 27 | 当层次越划越深时,我们会发现我们对于某个层次的代码的熟悉度下降了,也就是说α1,α2,α3…增大了,所以上式的数值也就增大了。但这时我们的工程任务还没有完成,有些功能还没有实现,那我们该怎么办? 28 | 29 | 其实这也是实际中一个经常遇到的问题,你会发现在某个时间段你的编码效率陡然下降,你不能再通过划分层次来加快编码效率了。这时你有几条路可以选择。 30 | 31 | 其中一条路是,你要忍耐这种编码效率下降的事实,继续在已有的层次上编写代码。这样有一个好处,就是你可能会通过训练提过你所能控制的某一层次的最大代码行数。也就是说一旦你可以从500行提高到1000行,那么你以后编程时可以在更少的层次中实现比原来更多的功能。 32 | 33 | 另外一条路是你可以查找你已经编写的代码,寻找其中可以优化的地方,以用更少的代码实现原来的功能,这样做的好处是你可以发现有许多算法可以用很少的代码实现。久而久之你可以编写出比以往更加简化的程序。但缺点是你在某一层次上所能控制的最大代码行数仍是500行。 34 | 35 | 你会发现,无论那条路都必须要求你提高自己的能力,假如说划分层次来完成工程是一种取巧的办法,那么当这种取巧的办法达到它所能达到的极限是,你就不能再取巧了。你需要提升你的硬实力,而这种硬实力是需要你不断的摸索得到的…… -------------------------------------------------------------------------------- /_drafts/Others/不引入新的数组,实现数组元素交换位置函数.md: -------------------------------------------------------------------------------- 1 | 最近遇到一道C++的面试题,要求不引入新的数组,实现数组元素交换位置函数,看似挺简单的,却还是花费了我不少时间,这里记录下来,给大家一个简单的思路。题目的详细要求是: 2 | 3 | 不引入新的数组,实现数组元素交换位置函数:void swap(int a[], int m, int n);比如,设m为3,n为4,a中的数据为:1 2 3 4 5 6 7,函数执行后,a中的数据为:4 5 6 7 1 2 3。 4 | 5 | 这里的关键是不引入新的数组,而且尽量使用较少的额外变量。我的思路是采用“倒叙追踪法”,利用一个额外变量进行两个数的swap。贴一下代码,大家有什么更好的方法可以交流一下。 6 | 7 | ```cpp 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | int judge_pos(int i,int m,int n) 14 | { 15 | if(i>=0 && i=m && i<(m+n)) 20 | { 21 | return i-m; 22 | } 23 | else 24 | { 25 | return -1; 26 | } 27 | } 28 | int main() 29 | { 30 | int num_of_data; 31 | int i_array[1024]; 32 | int m,n; 33 | 34 | cout << "How many numbers do you want to input: "; 35 | cin >> num_of_data; 36 | cout << "Input the numbers,separate with space: " << endl; 37 | for(int i=0;i> i_array[i]; 40 | } 41 | cout << "Input m and n,separate with space; " << endl; 42 | cin >> m >> n; 43 | 44 | int i = 0; 45 | while(i_array[i]>=0) 46 | { 47 | for(int j=0;j<(m+n);j++) 48 | { 49 | if(judge_pos(j,m,n)==i) 50 | { 51 | 52 | if(i_array[j]>0) 53 | { 54 | int temp = i_array[i]; 55 | i_array[i] = -i_array[j]; 56 | i_array[j] = temp; 57 | i=j; 58 | break; 59 | } 60 | else 61 | { 62 | i_array[i] *= (-1); 63 | i=j; 64 | break; 65 | } 66 | 67 | } 68 | } 69 | } 70 | for(int i=0;i 4 | * OpenSSL在使用X25519时的小坑: 5 | * 如何使用X25519派生共享秘钥: 6 | 7 | 问题在于我们使用时需要拿到X25519公钥和私钥的unsigned char*类型数据,但是OpenSSL在生成密钥对和派生共享密钥时都是用使用EVP_PKEY类型,对于一般的椭圆曲线算法,我们可以使用i2d_PublicKey/d21_PublicKey/i2d_PrivateKey/d21_PrivateKey进行两种类型的转换: 8 | 9 | * EVP_PKEY from char buffer in x509 (PKCS7): 10 | 11 | 但是结合如下链接以及查看OpenSSL源码,发现这四个方法根本不适用EVP_PKEY_X25519类型,调用时直接返回-1。 12 | 13 | * 14 | * 15 | 16 | 从以下链接中可以获取一些OpenSSL常用的转换策略,但是仍然不适用于X25519: 17 | 18 | * How does one access the raw ECDH public key, private key and params inside OpenSSL's EVP_PKEY structure? 19 | 20 | 后来发现Stack Overflow的相关提问涉及到了ecx_get_priv_key/ecx_get_pub_key两个函数,但是这两个函数都是internal的,并没有暴露给开发者,所以这条路也走不通 21 | 22 | * How to use ecx get_priv/pub_key methods from openssl? 23 | 24 | 最后翻了下OpenSSL的Github issues,发现不少人遇到了这个问题: 25 | 26 | * It's not possible to export the raw public key for X25519/Ed255919/X448/Ed448: 27 | * Add getters for raw private/public keys: 28 | 29 | 从大家的讨论中发现OpenSSL的commiter在1.1.1版本提供了EVP_PKEY_get_raw_private_key和EVP_PKEY_get_raw_public_key,经验证可以使用: 30 | 31 | * -------------------------------------------------------------------------------- /_drafts/Others/使用PowerShell简化我的工作.md: -------------------------------------------------------------------------------- 1 | 2 | 在这几年的编程学习和工作中,我积累的许多轻量级的小工具,比如Everything,BeyondCompare,BatchRename、HperSnap等等,这些软件都是绿色软件,无需安装,即使重装系统也可以很容易的迁移。但是由于工具比较多,不可能在桌面上为这些工具全部设置快捷方式,于是只能使用命令行进行调用。程序员们应该都知道,如果想要在cmd或者powershell中调用这些小工具,就要把这些工具的可执行文件的所在目录添加到系统环境变量Path之中。但是这样手工去添加太麻烦了,因为要添加的目录比较多,而且之后如果还想加入新的工具就必须继续设置环境变量,最重要的一点是每次重装系统还要重新设置一遍。作为一个程序员怎么去做这么笨的事情呢?于是我写了一个powershell配置脚本,让powershell每次启动时都去读该脚本,设置环境变量。 3 | 首先介绍一下我的工具集的结构: 4 | 5 | * Tools/ 6 | * ToolA.exe 7 | * ToolB.exe 8 | * ToolC.exe 9 | * ... 10 | * Toola/ 11 | * Toolsa.exe 12 | * Toola工具的其它文件 13 | * Toolb/ 14 | * Toolsb.exe 15 | * Toolb工具的其它文件 16 | * ... 17 | 18 | 下面是我的powershell脚本(profile.ps1): 19 | 20 | # Put this profile file into %userprofile%\[My] Documents\WindowsPowerShell for only yoursef 21 | # Put this profile file into $windir%\system32\WindowsPowerShell\v1.0 for every in your computer 22 | # Set the $BasePath to the directory which your tools are placed 23 | 24 | $BasePath = new-object System.IO.DirectoryInfo "D:\software\tools" 25 | 26 | $Env:Path = $Env:Path + ":" + $BasePath 27 | 28 | Get-ChildItem $BasePath | ForEach-Object -Process { 29 | 30 | if($_ -is [System.IO.DirectoryInfo]) { 31 | 32 | $Env:Path=$Env:Path + ";" + $BasePath.FullName + "\" + $_.Name; 33 | 34 | } 35 | } 36 | 37 | 另外这个脚本之后可能会添加一些其它功能,大家可以随时到我的github上看看:https://github.com/jiangxincode/data/blob/master/profile.ps1 -------------------------------------------------------------------------------- /_drafts/Others/关于强制式(命令式)语言和声明式语言的区别.md: -------------------------------------------------------------------------------- 1 | 在阅读Alfred V.Aho等的大作Compilers Principles,Techniques and Tools是看到如下一段话: 2 | 3 | Another classification of languages uses the term imperative for languages in which a program specifies how a computation is to be done and declarative for languages in which a program specifies what computation is to be done. Languages such as C, C++, C#, and Java are imperative languages . In imper­ative languages there is a notion of program state and statements that change the state. Functional languages such as ML and Haskell and constraint logic languages such as Prolog are often considered to be declarative languages. 4 | 5 | 讲到的是强制式语言(imperative languages,部分国内学者译为命令式语言、指令式语言)和声明式语言(declarative languages),同时还提到了函数式语言(Functional languages)和约束逻辑式语言(constraint logic languages)的概念。关于后两者如果有时间会在以后和大家进行探讨,今天暂时先说明一下前两者。 6 | 7 | 命令式编程(Imperative programming),即利用命令式语言进行编程的方式,是一种描述计算机所需作出的行为的编程范型。命令式编程语言使用变量和更复杂的语句,但仍依从相同的范型。食谱和行动清单,虽非计算机程序,但与命令式编程有相似的风格:每步都是指令,有形地控制世界情况。因为命令式编程的基础观念,不但概念上比较熟悉,而且较容易具体表现于硬件,所以大部分的编程语言都是指令式的。如上述的C, C++, C# 和 Java。大部分的命令式高级编程语言都支持四种基本的语句:运算语句、循环语句、条件分支语句、无条件分支语句。 8 | 9 | 运算语句一般来说都表现了在存储器内的数据进行运算的行为,然后将结果存入存储器中以便日后使用。高级命令式编程语言更能处理复杂的表达式,可能会产生四则运算和函数计算的结合。其中循环、条件分支和无条件分支都是控制流程。 10 | 11 | 循环语句容许一些语句反复运行数次。循环可依据一个默认的数目来决定运行这些语句的次数;或反复运行它们,直至某些条件改变。 12 | 13 | 条件分支语句容许仅当某些条件成立时才运行某个区块。否则,这个区块中的语句会略去,然后按区块后的语句继续运行。 14 | 15 | 无条件分支语句容许运行顺序转移到程序的其他部分之中。包括跳跃(在很多语言中称为Goto)、副程序和Procedure等。 16 | 17 | 早期的命令式编程语言都是计算机本身的机械语言。在这些语言中,指示非常简单,令硬件的运行更容易,却阻碍了复杂程序的设计。1954年开始开发的FORTRAN,是首个在复杂程序的设计中除掉机器码的编程语言。它是编译型的编程语言,容许命名变量、复杂的表达式、副程序和其他功能,这些功能现在在指令式语言中都非常普遍。后来的二十年中,可以看到大量的其他高级命令式编程语言出现。在1980年后,面向对象编程有迅速的发展;面向对象编程语言均有着指令式的风格,但增添了支持对象的功能。 18 | 19 | 声明式编程(Declarative programming),即利用声明式语言进行编程的方式,与命令式编程相对立。它描述目标性质,让计算机明白目标,而非流程。声明式编程不用告诉计算机问题领域,从而避免随之而来的副作用。而指令式编程则需要用算法来明确的指出每一步该怎么做。它通常被看做是形式逻辑的理论,把计算看做推导。声明式编程因大幅简化了并行计算的编写难度,自2009起备受关注。声明式语言包括数据库查询语言(SQL,XQuery),正则表达式,逻辑编程,函数式编程和组态管理系统。这种编程方式通过函数、推论规则或项重写(term-rewriting)规则,来描述变量之间的关系。它的语言运行器(编译器或解释器)采用了一个固定的算法,以从这些关系产生结果。目前,声明式编程语言通常用作解决人工智能和约束满足问题。 20 | -------------------------------------------------------------------------------- /_drafts/Others/关于记录日志的几个小心得.md: -------------------------------------------------------------------------------- 1 | 2 | 如何记录好日志其实是个很值得探讨的事情,下面两篇文章介绍了一些基本的原则: 3 | 4 | * Logging 日志记录最佳实践:http://www.oschina.net/question/12_44624 5 | * 写给开发者:记录日志的10个建议:http://blog.jobbole.com/52018/ 6 | 7 | 基于这些原则,并针对最近在工作中的实践情况,再补充一下: 8 | 9 | 1. 日志内容必须是一段能够独立成句的内容,因为日志主要的查看者很可能不是你自己,要保证任何开发人员看到你的日志都能明白其中的意思,并能够快速定位问题。 10 | 2. 工具类代码不要记录日志,要通过抛出多种异常或者通过返回值的方式告诉调用者,在内部发生了什么,产生了什么结果。 11 | 3. 业务代码要在业务逻辑进入和离开时记录日志,要知道流程在哪个模块中出现了问题,防止多方定位,互相推诿扯皮。模块内部,所有的重要分支也都要有日志记录。 12 | 4. 每一个实体要能够唯一标识,比如类的引用一定要带包名。 -------------------------------------------------------------------------------- /_drafts/Others/判断一个数是不是2的幂.md: -------------------------------------------------------------------------------- 1 |  2 | 3 | 我们经常会遇到这样一个问题,就是判断某个数据是否为2的n次方(1,2,4,8,16...)。例如如果用户输入的不是2^n,则要求用户重新输入。为了说明这种判断算法,我首先构造一个测试程序,代码如下: 4 | 5 | ```c 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | long unsigned int i; 12 | clock_t start,end; 13 | start = clock(); 14 | for(i=1;i<100000000;i++) 15 | { 16 | if(is2Power(i)) 17 | { 18 | printf("%ld\n",i); 19 | } 20 | } 21 | 22 | end =clock(); 23 | printf("The total time is: %lf",((double)(end-start))/CLOCKS_PER_SEC); 24 | return 0; 25 | } 26 | ``` 27 | 28 | 一般人很容易想到下面的算法: 29 | 30 | ```c 31 | int is2Power(long unsigned int num) 32 | { 33 | long unsigned int i; 34 | for(i=1;i<=num;i*=2) 35 | { 36 | if(i == num) 37 | { 38 | return 1; 39 | } 40 | } 41 | return 0; 42 | } 43 | ``` 44 | 45 | 该算法很容易理解,但是效率不算特别高,在我的机器上的测试结果为:The total time is: 28.566000,有人提出,其中的i*=2,可以用i<<=1来替换,效率应该会高一些,我们可以尝试一下: 46 | 47 | ```c 48 | int is2Power(long unsigned int num) 49 | { 50 | long unsigned int i; 51 | for(i=1;i<=num;i<<=1) 52 | { 53 | if(i == num) 54 | { 55 | return 1; 56 | } 57 | } 58 | return 0; 59 | } 60 | ``` 61 | 62 | 在我的机器上的测试结果为:The total time is: 27.821000,我们发现仅仅提高了不到一秒,基本可以忽略不计。又有人提出,我们可以采取另一种思路,让i从num开始每次除2来判断,如果余数不为0立即返回,这样能会快判断出那些不符合条件的值,这样便能加快判断速度。 63 | 64 | ```c 65 | int is2Power(long unsigned int num) 66 | { 67 | long unsigned int i; 68 | for(i=num;i>=1;i/=2) 69 | { 70 | if(i==1) 71 | return 1; 72 | else if(i%2 != 0) 73 | { 74 | return 0; 75 | } 76 | } 77 | return 1; 78 | } 79 | ``` 80 | 81 | 这种算法在我的机器上的测试结果为:The total time is: 3.958000,可以看出效率提高了近8倍。这时又有大神提出,由于2的n次方的数二进制表示是第1位为1,其余为0,而x-1(假如x为2的n次方)得到的数的二进制表示恰恰是第1位为0,其余为1,两者相与,得到的结果就为0,否则结果肯定不为0。于是诞生了如下算法: 82 | 83 | ```c 84 | int is2Power(long unsigned int num) 85 | { 86 | return ((num & (num-1))==0)?1:0; 87 | } 88 | ``` 89 | 90 | 简单的有点吓人,而且效率也很高,在我的机器上的测试结果为:The total time is: 1.484000,当然也有一个类似的算法,原理类似: 91 | 92 | ```c 93 | int is2Power(long unsigned int num) 94 | { 95 | return ((num & (~num+1))==num)?1:0; 96 | } 97 | ``` 98 | 99 | 这种算法在我的机器上的测试结果为:The total time is: 1.503000 100 | 101 | 很简单的问题,只要我们仔细研究一下还是有不少收获的。 102 | 103 | 注:文中的算法仅说明了相对的效率问题,鲁棒性并没有测试,如果你在实际情况中使用,需要注意一下边界值和反常输入情况。 -------------------------------------------------------------------------------- /_drafts/Others/制作Aspose CHM文档的过程记录.md: -------------------------------------------------------------------------------- 1 | 2 | 最近公司需要使用Aspose组件开发相关内容,但是网上找不到理想的参考文档,官网访问速度也慢的可以。所以打算自己做份CHM文档,做的过程中遇到很多困难,这里记录一下。 3 | 第一步是在Aspose官网上把javadoc文档爬取出来,我使用的工具是TeleportPro。爬取的网址是 4 | 5 | * http://www.aspose.com/api/java/pdf 6 | * http://www.aspose.com/api/java/cells 7 | 8 | 经过尝试爬取深度设为7最好。爬出来发现内容很多,有一个多G,而且有很多杂乱的内容,我们知道一般javadoc文档只是html和css的组合,不需要js和各种图片,所以仅保留了合适的目录下的html文档和api-reference-ui.css文件,其余文件全部删除。 9 | 10 | 但是这是发现由于删除了一些文件,导致html文件中对api-reference-ui.css引用失效,于是用notepad++对引用路径进行批量替换(../../../apireference.dynabic.com/doc/resources/css/api-reference-ui.css -> api-reference-ui.css),这时保证CSS文件能够正常引用,但是用这些文件生成的chm文档仍然很大,并且有一些无用的按钮无法点击,然后我们需要把它们干掉。于是我写了一个java程序,进行操作,需要最新的程序或者有不理解的可以联系我: 11 | 12 | ```java 13 | package edu.jiangxin.tools; 14 | 15 | import java.io.File; 16 | import java.io.FileOutputStream; 17 | import java.io.IOException; 18 | import java.io.OutputStreamWriter; 19 | import java.util.ArrayList; 20 | 21 | import org.jsoup.Jsoup; 22 | import org.jsoup.nodes.Document; 23 | import org.jsoup.nodes.Element; 24 | import org.jsoup.select.Elements; 25 | 26 | import edu.jiangxin.common.FileFilterWrapper; 27 | 28 | public class RemoveHtmlElement { 29 | 30 | static final String charsetName = "UTF-8"; 31 | static final String[] divClassNames = { "Header", "aspNetHidden", "Search", "clearAll", "Header" }; 32 | static final String[] divIds = { "Header", "leftmenu" }; 33 | 34 | public static void main(String[] args) throws IOException { 35 | ArrayList files = new FileFilterWrapper().list("C:/asposebak", "htm"); 36 | for (File file : files) { 37 | Document doc = Jsoup.parse(file, charsetName); 38 | for (int i = 0; i < divClassNames.length; i++) { 39 | Elements eles = doc.getElementsByClass(divClassNames[i]); // eles不可能为null 40 | 41 | eles.remove(); 42 | } 43 | for (int i = 0; i < divIds.length; i++) { 44 | Element ele = doc.getElementById(divIds[i]); 45 | if (ele != null) { 46 | ele.remove(); 47 | } 48 | 49 | } 50 | 51 | Elements eles = doc.getElementsByTag("script"); 52 | for (int i = 0; i < eles.size(); i++) { 53 | Element ele = eles.get(i); 54 | if (ele.attr("language").equals("javascript") && ele.attr("type").equals("text/javascript")) { 55 | ele.remove(); 56 | } 57 | } 58 | 59 | FileOutputStream fos = new FileOutputStream(file, false); 60 | OutputStreamWriter osw = new OutputStreamWriter(fos, charsetName); 61 | osw.write(doc.html()); 62 | osw.close(); 63 | System.out.println(file.getAbsolutePath()); 64 | } 65 | } 66 | 67 | } 68 | 69 | 70 | ``` 71 | 72 | 通过程序删除之后基本解很清爽了,当然还需要使用notepad++进行一些简单的文本批量替换。 73 | 最后的工作就是使用easychm生成chm文档了,我用的是试用版,感觉只不过多了广告,生成的chm文档并不影响使用。 -------------------------------------------------------------------------------- /_drafts/Others/华为面试题——一道关于指针方面的编程题(C_C++).md: -------------------------------------------------------------------------------- 1 | int A[nSize],其中隐藏着若干0,其余非0整数,写一个函数int Func(int* A, int nSize),使A把0移至后面,非0整数移至数组前面并保持有序,返回值为原数据中第一个元素为0的下标。 2 | 3 | 尽可能不使用辅助空间且考虑效率及异常问题,注释规范且给出设计思路 4 | 5 | 注:我的方法的复杂度为O(n),大家如果有其它方法希望可以交流一下。 6 | 7 | ```cpp 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | #define ARRAYSZIE 100 14 | int Func(int* A,int nSize) 15 | { 16 | int *p_zero = A; //指向最开始的零值 17 | int *p_unzero = A; //指向最后的非零值 18 | while(1) 19 | { 20 | for(int i=(p_zero-A); i d(0,1); 56 | for(int i=0; i 7 | 8 | using namespace std; 9 | struct node 10 | { 11 | char data; 12 | struct node *next; 13 | }; 14 | typedef struct node NODE; 15 | void test_exercise006() 16 | { 17 | NODE *head = new NODE; //建立附加头结点 18 | head->next = NULL; 19 | 20 | /*创建链表*/ 21 | NODE *current,*previous; 22 | previous = head; 23 | char input; 24 | cout << "Input your list table NODE data,end with '#':"; 25 | cin >> input; 26 | while(input != '#') 27 | { 28 | current = new NODE; 29 | current->data = input; 30 | current->next = NULL; 31 | previous->next = current; 32 | previous = previous->next; 33 | cout << "Input your list table NODE data,end with '#':"; 34 | cin >> input; 35 | } 36 | 37 | /*输出链表*/ 38 | current = head->next; 39 | while(current != NULL) 40 | { 41 | cout << current->data << " "; 42 | current = current->next; 43 | } 44 | cout << endl; 45 | 46 | /*倒转链表*/ 47 | current = head->next; 48 | NODE *p = current->next; 49 | NODE *q = p->next; 50 | while(q != NULL) 51 | { 52 | p->next = current; 53 | current = p; 54 | p = q; 55 | q = q->next; 56 | } 57 | p->next = current; 58 | current = p; 59 | head->next->next = NULL; 60 | head->next = current; 61 | 62 | /*输出链表*/ 63 | current = head->next; 64 | while(current != NULL) 65 | { 66 | cout << current->data << " "; 67 | current = current->next; 68 | } 69 | } 70 | ``` 71 | -------------------------------------------------------------------------------- /_drafts/Others/华为面试题——约瑟夫问题的C++简单实现(循环链表).md: -------------------------------------------------------------------------------- 1 | ```cpp 2 | /* 3 | Function:method of Josephus question 4 | */ 5 | #include 6 | 7 | using namespace std; 8 | 9 | struct node 10 | { 11 | int seq; 12 | node *next; 13 | }; 14 | typedef struct node NODE; 15 | 16 | void test_Josephus() 17 | { 18 | /*假设共有n人,从第s个人开始数数,每数到m该人出列,后面的人重新开始数,知道全部人出列*/ 19 | int n,s,m; 20 | NODE *head,*last,*current,*prev; 21 | cout << "Input the n,s,m(separate with space):"; 22 | cin >> n >> s >> m; 23 | 24 | for(int i=1;i<=n;i++) //建立循环链表 25 | { 26 | current = new NODE; 27 | current->seq = i; 28 | current->next = head; 29 | if(i == 1) 30 | { 31 | head = current; 32 | last = current; 33 | } 34 | else 35 | { 36 | last->next = current; 37 | last = last->next; 38 | } 39 | } 40 | current = head; //遍历循环链表,输出序列 41 | do 42 | { 43 | cout << current->seq << " "; 44 | current = current->next; 45 | }while(current!=head); 46 | 47 | current = head; //将current置于第s个位置 48 | for(int i=1;inext; 51 | } 52 | cout << endl; 53 | 54 | for(int i=1;i<=n;i++) //共循环n轮,得到一个整体的输出序列 55 | { 56 | for(int j=1;jnext; 60 | } 61 | cout << current->seq << " "; 62 | prev->next = current->next; 63 | delete current; 64 | current = prev->next; 65 | } 66 | } 67 | ``` -------------------------------------------------------------------------------- /_drafts/Others/在工作中遇到的问题.md: -------------------------------------------------------------------------------- 1 | 2 | 最近我经常要更改应用中的一些功能,其实要做的事情比较简单,但是也很繁琐,这里记录一下。由于只是实现一些小的功能接口,不会更改网站的显示内容,所以不能或者很难通过网页直接查看,所以我一般是按照下面的步骤进行处理。 3 | 4 | * 在Eclipse中完成基本的代码编写,比如完成所需的接口函数。 5 | * 在powershell窗口中利用maven对刚刚修改的代码内容进行打包。(不是打包整个工程,只是其中一个自工程) 6 | * 利用sftp程序(比如Xmanager中的Xftp)将打出jar包上传到服务器中的对应目录,替换掉原来的jar包。 7 | * 重启tomcat服务器。 8 | * 修改测试jsp页面。(由于符合restful,所以可以通过jsp直接出发新编写的函数) 9 | * 利用sftp程序,将上传的jsp文件上传到服务其中的对应目录。 10 | * 开启Eclipse远程Debug。 11 | * 在浏览器中登陆需要测试的网站,运行jsp文件,通过数据库进行查看,验证所实现的功能是否正确。如果不正确返回上面的某个步骤继续。 12 | 13 | 针对上面的内容再补充几点: 14 | 15 | * 由于利用jsp页面触发所实现的功能,有可能会更改数据库中的内容,在已有的Web框架下,应该能够使Web应用中的数据得到同步刷新,但是不排除意外可能。 16 | * 由于某些原因,可能需要手动修改数据库内容,也就是说不是通过页面操作,这是为了保证Web应用的数据与数据库保持一致,需要重启应用(tomcat),更新数据内容。 17 | * 在手动修改数据库时,比如利用Oracle SQL Developer和PL/SQL Developer等客户端对数据库进行操作,一定要保证本地运行的SQL脚本已经commit,否者这些客户端会持有对数据库的写锁,使Web应用无法对数据库进行写操作。 18 | * 在上述编码、测试环境中经常需要用Eclipse对远程服务器中的tomcat进行调试,所以一定要注意保持Eclipse中的源码和远程服务器中的jar包保持一致,否则会出现许多问题。 19 | * 我们一般都只对Web应用中很小的一部分进行修改,所以我们都是将某个子工程的jar包上传服务器进行替换,但是需要注意该jar包是否能和服务器中其它的内容相一致,因为很可能于此同时,其他同时已经更改了其它jar包,导致了不一致,出现难以调试的困难。为了保证一致,有两个方法:一是将本地所有的jar包上传服务器进行替换,但是我们一般不推荐这样做。另一种方法是进行减小jar包的替换范围,我们可以讲远程服务器中我们需要修改的jar包下载到本地,然后只替换其中若干个我们需要修改的class文件。 20 | * 从服务器拉出jar包 21 | * jd-jui反编译代码之后关闭jd-jui。使用反编译的代码替换eclipse中的对应代码。 22 | * mvn clean package -DskipTest 23 | * 再次从服务器拉出jar包 24 | * 用7-zip替换jar包中对应class文件 25 | * 上传到服务器 26 | * 在有些情况下可以直接使用restclient发送消息报文进行测试,不有自己编写jsp页面。 27 | * 有一次我在重启tomcat时,发现shutdown命令无法正常关闭tomcat,所以之后利用startup启动时也会出现问题,经过很长时间的排查,发现是在前一次启动tomcat时是用的root身份,所以之后在普通用户权限下无法进行关闭。解决办法比较简单,就是重新切回root身份进行关闭,然后退到普通权限重新启动。另一个关于权限的问题是在用sftp上传文件时一定注意所使用的身份,非特殊情况一般不要使用root权限上传,否则会导致文件(比如jar文件)的读写权限太严,tomcat无法正常读取。 28 | * 在Linux服务器中的文件对比工具都不是很顺手,命令行对比虽然还不错,但是文件路径都很深,每次只是输入路径就麻烦死了,我一般是将需要对比的文件、文件夹利用Xftp下载到本地,然后使用beyond compare进行对比,由于Xftp和beyond compare这两个工具都有路径历史记录,省去了每次输入路径的麻烦。 29 | * 在修改代码中经常会使用文件内容搜索功能,Eclipse的搜索限制太多,比如只能搜索java等文本文件,所以我一般都是使用filelocator进行搜索,功能更加强大,可以搜素word,pdf等二进制文件。 -------------------------------------------------------------------------------- /_drafts/Others/基于对象和面向对象的区别.md: -------------------------------------------------------------------------------- 1 | 基本上每个程序员都听过面向对象(Object-oriented)和基于对象(Object-based)这两个概念。其实这两个概念并没有很明显的界线,不过现在业界比较统一的认为只有完全具有封装、继承、多态三大特点的才能够叫做面向对象,否则即使设计中蕴含了一些对象的概念,也顶多称为基于对象。 2 | 3 | 基于对象是过程化语言自然演进而来,随着ADT【1】思想的成熟而成熟,七十年代到八十年代初曾经非常流行,但是很快被风头更盛的面向对象给遮盖了,最典型的代表是Ada83。一贯被人认为是过程化语言代表的C语言,在实际应用中基本上使用的是基于对象的思想。虽然默默无闻,但是基于对象思想下开发的软件,实际上构成了我们现在的软件工业基础。 4 | 5 | 面向对象发源于60年代的挪威,第一个面向对象语言是Simula,思想成熟于80-90年代。其标志就是继承和多态。面向对象思想的主要历史贡献是催生了面向组件思想,简化了日常编程。从严肃的软件工程意义上来讲,面向对象究竟是不是“一个历史性的进步”,还有待历史检验,但是这种思想方法现在已经成为主流,所以无论是不是进步,已经成为现实。 6 | 7 | 通常基于对象是使用对象,意味着它们有像C++的结构加函数这样的对象,然而这只是到达面向对象语言的一部分,停留在把函数捆绑在结构内部的语言是基于对象的。但是无法利用现有的对象模板产生新的对象类型,继而产生新的对象,也就是说基于对象一般没有继承的特点。没有了继承的概念也就无从谈论多态。现在的很多流行技术都是基于对象的,它们使用一些封装好的对象,调用对象的方法,设置对象的属性。但是它们无法让程序员派生新对象类型。他们只能使用现有对象的方法和属性。所以当你判断一个新的技术是否是面向对象的时候,通常可以使用后两个特性来加以判断。例如:C++是面向对象的,而VB只是基于对象的。当然,搜索现在国内大量的书籍与资料(包括大量教材)的作者都无法分清两者之间的区别,把VB称为面向对象,误人子弟。 8 | 9 | 10 | 11 | 注: 12 | 13 | 【1】ADT(Abstract Data Type)是指一个数学模型以及定义在该模型上的一组操作。ADT包括数据数据元素,数据关系以及相关的操作。即ADT 14 | 15 | { 16 | 17 | 数据对象:(数据元素集合) 18 | 19 | 数据关系:(数据关系二元组结合) 20 | 21 | 基本操作:(操作函数的罗列) 22 | 23 | } 24 | 25 | 抽象数据类型(ADT)的一个实现包括储存数据元素的存储结构以及实现基本操作的算法。在这个数据抽象思想中,数据类型的定义和它的实现是分开的,这在软件设计中是一个重要的概念。这使得只研究和使用它的结构而不用考虑它的实现细节成为可能。在面向对象编程语言中,像C++、Java都能较好的支持ADT,如类的机制。而在C语言中缺少了对相关方法的支持。抽象数据类型需要通过固有数据类型(高级编程语言中已实现的数据类型)来实现。抽象数据类型是与表示无关的数据类型,是一个数据模型及定义在该模型上的一组运算。对一个抽象数据类型进行定义时,必须给出它的名字及各运算的运算符名,即函数名,并且规定这些函数的参数性质。一旦定义了一个抽象数据类型及具体实现,程序设计中就可以像使用基本数据类型那样,十分方便地使用抽象数据类型。 26 | 27 | -------------------------------------------------------------------------------- /_drafts/Others/对象池、线程池、数据库连接池、内存池剖析.md: -------------------------------------------------------------------------------- 1 | 待完成 -------------------------------------------------------------------------------- /_drafts/Others/清理无用的CSS样式的几个工具(转).md: -------------------------------------------------------------------------------- 1 | 2 | 在我们写样式的时候,页面的CSS在经历几个版本的修改之后,可能有些样式已经用不到了,或许将某些样式更名了而原来的忘了删除,总之页面中可能存在着一些无用的样式。这些无用的浪费了一些服务器空间和带宽消耗,也会增大我们的维护成本。那么有没有一些办法来清理那些无用的样式呢?今天就让我们来了解一下几个比较有用的工具。 3 | 4 | Dust-Me selectors 5 | 6 | https://addons.mozilla.org/zh-CN/firefox/addon/dust-me-selectors/ 7 | http://www.brothercake.com/dustmeselectors/ 8 | 9 | Dust-Me是一个很有用也很好用的Firefox插件,它可以分析到你的页面中调用的所有CSS文件并分析那些在页面中没有被用到。支持本地和远程样式文件,包括使用link标签、< ?xml-stylesheet?>处理指令、@import语句等方式引入的样式文件;(但是不支持页面中的style块和内联样式),支持IE条件注释中引入的样式文件;可以检查一个页面,也可以检查整个网站;支持CSS1选择器、大部分CSS2和CSS3选择器;理解通用的CSS hack,比如 “* html #fuck-ie”将会被认为是”html #fuck-ie”;支持Firefox 3.5和Firefox 3.0,事实上得益于FF 3.5的js引擎的改进,FF 3.5中的性能比FF 3.0要高50%。 10 | 11 | Page Speed 12 | 13 | https://developers.google.com/speed/pagespeed/ 14 | 15 | Page Speed是Google提供的一个前端性能分析工具,有些类似于YSlow,但是提供了一些比较个性且很有用的工具,比如Remove unused CSS。Page Speed和YSlow一样依赖Firebug。 16 | 17 | CSS Redundancy Checker 18 | 19 | https://github.com/kmytor/css-redundancy-checker 20 | 21 | CSS Redundancy Checker 是一个免费的在线应用,可以检查所有的使用某个CSS文件的页面中无用的样式。可以同时检查某一个样式在多个页面中的使用情况。该工具的不足是虽然一次能检查多个HTML页面,但每次只能检查一个CSS文件,而且还要手动输入。 22 | 23 | IntelliJ IDEA 24 | 25 | IntelliJ IDEA 这是一个颇强大的IDE,类似于DreamWeaver,不过在国内用的不多。该软件包括一个即时代码分析工具(On-the-fly Code Analysis),可以分析CSS文件中未用到的class和id。 26 | 27 | Expression Web 28 | 29 | Expression Web作为微软的新一代网站开发工具,还是有很多人使用的,其CSS Report功能可以检查未用到需要被清除的CSS(我的确没有使用EW开发过网站,希望使用该软件的童鞋可以帮忙确认一下这一点)。 -------------------------------------------------------------------------------- /_drafts/Others/能让程序做的事情坚决不用人来做——批量修复markdownlint MD034警告.md: -------------------------------------------------------------------------------- 1 | 2 | 现在各种编程语言都有自己的lint工具来做静态检查,防止一些低级错误并维持统一的风格。Markdown这样的样式标记语言也不例外,现在大家用的比较多的是markdownlint。该项目开源在github:,当前很多实用markdown语言的项目都使用该工具。 3 | 4 | markdownlint的检查规则目前有41项,其中"MD034 - Bare URL used"是大家经常遇到的问题,如果你在Markdown文档中使用URL,但是没有在URL周围使用<>的话就会产生警告,我维护了一个类似于awesome的项目,其中报了1000多个类似的警告,如果全部手工来修改估计手都回废掉,因此写了个小程序在所有的.md文档中的所有url两遍加上了<>。 5 | 6 | 程序使用Java编写,比较简单,主要使用了正则表达式的替换,程序如下: 7 | 8 | ```java 9 | package edu.jiangxin.tools; 10 | 11 | import java.io.BufferedReader; 12 | import java.io.BufferedWriter; 13 | import java.io.File; 14 | import java.io.FileReader; 15 | import java.io.FileWriter; 16 | import java.io.IOException; 17 | import java.util.regex.Matcher; 18 | import java.util.regex.Pattern; 19 | 20 | /** 21 | * Solve the problem of MD034.

22 | * {@link https://github.com/markdownlint/markdownlint/blob/master/docs/RULES.md} 23 | * This program doesn't process any exception! 24 | * @author aloys 25 | * 26 | */ 27 | public class MD034Solver { 28 | public static final String regex = "\\b(https?|ftp|file)://[-A-Z0-9+&@#/%?=~_|$!:,.;]*[A-Z0-9+&@#/%=~_|$]"; 29 | 30 | public static final String sourceDirStr = "D:\\temp\\cnblogs"; 31 | 32 | public static final String targetDirStr = "D:\\temp\\cnblogsbak"; 33 | 34 | public static void main(String[] args) throws IOException { 35 | // Source directory must be a valid directory which contains the text files to be processed. 36 | File sourceDir = new File(sourceDirStr); 37 | 38 | // Target directory must be a valid directory which will save the proecessed files. 39 | File targetDir = new File(targetDirStr); 40 | 41 | for (File file : sourceDir.listFiles()) { 42 | 43 | // take off the .git directory and .gitignore file 44 | if (file.getName().startsWith(".")) { 45 | continue; 46 | } 47 | 48 | BufferedReader reader = new BufferedReader(new FileReader(file)); 49 | BufferedWriter writer = new BufferedWriter(new FileWriter(new File(targetDir, file.getName()))); 50 | 51 | String temp = null; 52 | while ((temp = reader.readLine()) != null) { 53 | Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE); 54 | Matcher regexMatcher = pattern.matcher(temp); 55 | StringBuffer sb = new StringBuffer(); 56 | while (regexMatcher.find()) { 57 | String group = regexMatcher.group(); 58 | int start = regexMatcher.start(); 59 | if (start >= 1 && (temp.charAt(start - 1) == '<' || temp.charAt(start - 1) == '(')) { 60 | regexMatcher.appendReplacement(sb, group); 61 | } else { 62 | regexMatcher.appendReplacement(sb, "<" + group + ">"); 63 | } 64 | 65 | } 66 | regexMatcher.appendTail(sb); 67 | writer.write(sb.toString()); 68 | writer.newLine(); 69 | } 70 | reader.close(); 71 | writer.close(); 72 | } 73 | } 74 | 75 | } 76 | 77 | ``` -------------------------------------------------------------------------------- /_drafts/Others/高可用性中的脑裂问题(split-brain problem in HA)(转).md: -------------------------------------------------------------------------------- 1 | 2 | 运行于备用主机上的Heartbeat可以通过以太网连接检测主服务器的运行状态,一旦其无法检测到主服务器的“心跳”则自动接管主服务器的资源。通常情况下,主、备服务器间的心跳连接是一个独立的物理连接,这个连接可以是串行线缆、一个由“交叉线”实现的以太网连接。Heartbeat甚至可同时通过多个物理连接检测主服务器的工作状态,而其只要能通过其中一个连接收到主服务器处于活动状态的信息,就会认为主服务器处于正常状态。从实践经验的角度来说,建议为Heartbeat配置多条独立的物理连接,以避免Heartbeat通信线路本身存在单点故障。 3 | 4 | 1、串行电缆:被认为是比以太网连接安全性稍好些的连接方式,因为hacker无法通过串行连接运行诸如telnet、ssh或rsh类的程序,从而可以降低其通过已劫持的服务器再次侵入备份服务器的几率。但串行线缆受限于可用长度,因此主、备服务器的距离必须非常短。 5 | 2、以太网连接:使用此方式可以消除串行线缆的在长度方面限制,并且可以通过此连接在主备服务器间同步文件系统,从而减少了从正常通信连接带宽的占用。 6 | 7 | 基于冗余的角度考虑,应该在主、备服务器使用两个物理连接传输heartbeat的控制信息;这样可以避免在一个网络或线缆故障时导致两个节点同时认为自已是唯一处于活动状态的服务器从而出现争用资源的情况,这种争用资源的场景即是所谓的“脑裂”(split-brain)或“partitioned cluster”。在两个节点共享同一个物理设备资源的情况下,脑裂会产生相当可怕的后果。 8 | 为了避免出现脑裂,可采用下面的预防措施: 9 | 10 | 1、如前所述,在主、备节点间建立一个冗余的、可靠的物理连接来同时传送控制信息; 11 | 2、一旦发生脑裂时,借助额外设备强制性地关闭其中一个节点; 12 | 13 | 第二种方式即是俗称的“将其它节点‘爆头’(shoot the other node in the head)”,简称为STONITH。基于能够通过软件指令关闭某节点特殊的硬件设备,Heartbeat即可实现可配置的Stonith。但当主、备服务器是基于WAN进行通信时,则很难避免“脑裂”情景的出现。因此,当构建异地“容灾”的应用时,应尽量避免主、备节点共享物理资源。 -------------------------------------------------------------------------------- /_pages/404.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Page Not Found" 3 | excerpt: "Page not found. Your pixels are in another canvas." 4 | sitemap: false 5 | permalink: /404.html 6 | --- 7 | 8 | Sorry, but the page you were trying to view does not exist. 9 | -------------------------------------------------------------------------------- /_pages/about.md: -------------------------------------------------------------------------------- 1 | --- 2 | permalink: /about/ 3 | title: "About" 4 | --- 5 | 6 | 一些我在平时工作和学习中积累的编程相关的资源。每个程序员都有自己的学习之路,过程中会学习各种各样的网上知识,学习完最好记录下来,每隔一段时间看一看,会有不一样的收获。 7 | 8 | 博客地址: 9 | 10 | * [原有"学习之路系列博客"](https://jiangxincode.github.io/cnblogs/categories/#the-way-of-learning) 11 | * [Github](https://jiangxincode.github.io/cnblogs/) 12 | * [博客园](https://www.cnblogs.com/jiangxinnju) 13 | 14 | 如果大家有兴趣可以一起增加,修改。 15 | 16 | * [文章源码目录](https://github.com/jiangxincode/cnblogs/tree/master/_posts) 17 | * [文章依赖图床](https://github.com/jiangxincode/PicGo) 18 | -------------------------------------------------------------------------------- /_pages/category-archive.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Posts by Category" 3 | layout: categories 4 | permalink: /categories/ 5 | author_profile: true 6 | --- 7 | -------------------------------------------------------------------------------- /_pages/tag-archive.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Posts by Tag" 3 | permalink: /tags/ 4 | layout: tags 5 | author_profile: true 6 | --- 7 | -------------------------------------------------------------------------------- /_pages/year-archive.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Posts by Year" 3 | permalink: /posts/ 4 | layout: posts 5 | author_profile: true 6 | --- 7 | -------------------------------------------------------------------------------- /_posts/android/2021-02-21-Import-AOSP-To-AS.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "将AOSP源码导入到Android Studio进行查看" 3 | categories: 4 | - android 5 | tags: 6 | - Android 7 | - Android Studio 8 | - AOSP 9 | toc: true 10 | --- 11 | 12 | ## 生成iml和ipr文件 13 | 14 | ```shell 15 | source build/envsetup.sh 16 | lunch aosp_x86-eng 17 | make idegen 18 | development/tools/idegen/idegen.sh 19 | ``` 20 | 21 | 说明: 22 | 23 | 1. 执行`source build/envsetup.sh`和`./build/envsetup.sh`是一样的。 24 | 2. 可以直接执行`lunch aosp_x86-eng`直接根据传入参数进行构建,也可以输入`lunch`根据提示选择对应的target。 25 | 3. 执行完`lunch`命令后直接执行`make idegen`即可,有些教程说需要先执行`make`命令,这是不需要的,我们只需要构建`idegen`模块,不需要构建所有模块。后者要花费很长时间,而且对机器性能要求很高。命令执行过程中有些提示选项,如果没有报错导致中断,可以暂时忽略。有的教程使用`mmm development/tools/idegen/`代替`make idegen`,他们的功能是类似的。 26 | 4. 执行`development/tools/idegen/idegen.sh`,可能会提示权限相关问题,如果没有中断程序可以暂时忽略,有的教程建议增加`sudo`前缀提升命令执行权限,这里不推荐,因为之前如果`source build/envsetup.sh`是以普通用户执行的,所有的构建环境都是以普通用户为前提的,提升权限可能会导致问题,比如`java: 未找到命令` 27 | 5. 以上命令成功执行后会在根目录生成`android.iml`/`android.ipr`,两个文件。 28 | 29 | ## 将代码导入到Android Studio 30 | 31 | 绝大部分人的AOSP源码是放置到远程Linux机器上的,如果本地机和远程机间网络带宽很高,可以直接通过Samba服务器在本地机中访问远程机的AOSP源码,或者通过VNC Viewer/VNC Client的方式在远程机上安装AS。网络不是很好可以选择在本地机上创建一个目录,然后把`android.iml`/`android.ipr`以及需要查看的AOSP源码目录同步到该目录中,同步方式有很多,比如FTP/rsync等。 32 | 33 | 如果使用rsync进行同步,可以参考以下命令: 34 | 35 | ```shell 36 | rsync -az --progress --delete --exclude=".git" ${USER_NAME}@${IP}:/${REMOTE_DIR} ${LOCAL_DIR} 37 | ``` 38 | 39 | 比如: 40 | 41 | ```shell 42 | rsync -az --progress --delete --exclude=".git" jiangxin@192.168.1.181:/home/jiangxin/aosp/frameworks /drives/d/aosp/ 43 | ``` 44 | 45 | 如果想保留git记录,可以使用 46 | 47 | ```shell 48 | rsync -azL --progress --delete jiangxin@192.168.1.181:/home/jiangxin/aosp/frameworks /drives/d/aosp/ 49 | ``` 50 | 51 | 如果使用FTP命令,由于文件数目较多,直接下载或者上传目录耗时比较长,可以考虑使用`tar`将需要的文件和目录打包,然后再进行同步。 52 | 53 | 我选择的是把`android.iml`/`android.ipr`以及`frameworks`目录同步到本地。打开Android Studio,`Open an Existed Project`,选择`android.ipr`,导入时间根据机器性能以及源码规模相关,可能比较长。 54 | 55 | * `android.iml`文件中有目录的配置,如果打开整个工程非常慢,可以把里面无关的目录删除或者改到excludeFolder中。 56 | * 如果代码跳转到jar包的反编译文件中而不是导入的源码中,可以`File->Project Structure->Project Settings->Moudules->Dependencies`,把`Module source`调整到最顶端(Alt+Up)。 57 | * Android Studio默认只能打开10个代码文件,且文件打开多了以后显示不开的文件还会被隐藏,需要点击最右边的箭头才能查看。而最致命的是,如果不小心修改了某个文件,在标签页上,不会有任何的提示。`File->Settings->Editor->General->Editor Tabs`根据自己的习惯进行配置。 58 | * Android Studio只支持Java代码,C++代码只有最基础的着色功能。 59 | * 如果想要支持断点调试,按照如下步骤操作: 60 | * `File->Project Structure->Project Settings->Project->Project SDK`,选择`Android API .. Platform` 61 | * `Run->Edit Configurations->Add New Configuration->Android App`,然后直接保存。 62 | * 此时可以使用Attach To Process进行调试。调试要注意源码和手机版本匹配。service相关代码需要attach到system_process进程。 63 | 64 | ## 另一种利用Android Studio查看AOSP源码的方式 65 | 66 | 还有另一种不需要`android.iml`/`android.ipr`就可以查看AOSP源码的方式: 67 | 68 | 1. 使用Android Studio创建一个简单的demo工程,确保编译通过。 69 | 2. 在`app/build.gradle`文件的`android`节点下增加如下配置,其中路径是自己想查看的AOSP源码路径,可以是本地路径也可以是远程路径: 70 | 71 | ```gradle 72 | sourceSets { 73 | main.java.srcDirs += 'D:\\Code\\sync\\android-11.0.0_r27\\frameworks\\base\\services\\core\\java' 74 | main.resources.srcDirs += 'D:\\Code\\sync\\android-11.0.0_r27\\frameworks\\base\\core\\res\\res' 75 | } 76 | ``` 77 | 78 | 当然这种方式如果在自己想要查看的路径比较多时,自己手工配置路径会比较麻烦。 79 | 80 | ## 参考资料 81 | 82 | * Android Studio导入整个Android系统源码: 83 | * 使用Android Studio导入Android系统源码: 84 | * AndroidStudio工程导入部分Android源码: 85 | -------------------------------------------------------------------------------- /_posts/android/2025-01-05-投屏知识学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "投屏知识学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - 投屏 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了投屏知识学习的相关资源,包括投屏的基本概念、投屏协议、投屏应用等内容,适合投屏开发者参考。 12 | 13 | ## 投屏模式 14 | 15 | 首先了解投屏的模式。 16 | 17 | ### 推送模式 18 | 19 | 主要用于投屏视频和音乐,投屏之后手机可以关闭或聊微信,电视不会停止播放。玩手机看电视两不误。最常见是视频软件里的tv按钮。 20 | 21 | 投屏推送的原理:原理就是,让手机与电视连接同一个wifi后,通过投屏协议传输数据。(就好像蓝牙一样的一个专门通道)。点击投屏按钮,手机就开始搜索wifi内有没有投屏广播服务。 22 | 23 | 手机搜索到电视之后,手机会发送一个视频地址给电视,电视收到地址后,开始播放。投屏后,手机可以控制电视的进度,暂停,下一集,音量之类的指令。 24 | 25 | ### 镜像模式 26 | 27 | 就是投屏手机屏幕或者投屏电脑屏幕;就是同屏显示。主要用于投屏手机PPT、手机桌面、吃鸡王者荣耀等手游;投屏淘宝、微信、抖音等暂时投屏功能的APP。苹果手机的屏幕镜像,安卓手机的多屏互动,都属于镜像模式。 28 | 29 | 原理:一样依靠局域网wifi通道,手机搜索到电视之后,开始镜像后,手机会不断截屏就是录屏。手机一边录屏,一般发送给电视。速度超快每秒60帧以上,电视收到之后再展现出来,就成了同屏功能了。 30 | 31 | ### 拓展模式 32 | 33 | 拓展模式是指将电脑屏幕投射到电视上,同时电脑屏幕也可以显示。这种模式一般用于工作场景,比如在电视上展示PPT,而在电脑上操作PPT。 34 | 35 | ## 投屏协议/应用对比 36 | 37 | |投屏协议/应用|源平台|目标平台|无线/有线|推送/镜像|厂商|备注| 38 | |-|-|-|-|-|-|-| 39 | |[Miracast](https://www.wi-fi.org/discover-wi-fi/miracast)|支持协议的源设备|支持协议的显示设备|无线/有线|推送/镜像|Wi-Fi联盟|NA| 40 | |[AirPlay](https://www.apple.com/airplay/)|iOS/iPadOS/Mac|AirPlay‑enabled smart TV|无线/有线|推送/镜像|Apple|NA| 41 | |[DLNA](https://www.dlna.org/)|支持协议的源设备|支持协议的显示设备|无线/有线|推送|由索尼、英特尔、微软等企业共同发起|大部分视频软件投屏使用该协议| 42 | |[Cast+](https://developer.huawei.com/consumer/cn/codelab/CastPlusKit)|华为/荣耀手机|Android大屏设备|无线/有线|镜像|华为|NA| 43 | |[Chromecast](https://support.google.com/chromecast)|Android/iOS设备|插入Chromecast的显示设备|无线/有线|镜像|谷歌|NA| 44 | |[WiDi](https://www.intel.cn/content/www/cn/zh/support/articles/000014926/emerging-technologies.html)|Windows设备|支持协议的显示设备|无线/有线|镜像/拓展|Intel|[已停止支持](https://www.intel.cn/content/www/cn/zh/support/articles/000021693/emerging-technologies.html)| 45 | |[Windows手机连接](https://support.microsoft.com/zh-cn/topic/%E6%89%8B%E6%9C%BA%E8%BF%9E%E6%8E%A5%E8%A6%81%E6%B1%82%E5%92%8C%E8%AE%BE%E7%BD%AE-cd2a1ee7-75a7-66a6-9d4e-bf22e735f9e3)|Android/iOS|Windows|无线|推送|微软|NA| 46 | |[scrcpy](https://github.com/Genymobile/scrcpy)|Android|Windows|有线+无线|镜像|开源|NA| 47 | |[AnLink](https://anl.ink/)|Android|Linux/Windows/macOS|有线+无线|镜像|AnLink|NA| 48 | |[Vysor](https://www.vysor.io/#)|Android/iOS|Linux/Windows/macOS|有线+无线|镜像|vysor|NA| 49 | 50 | ## 其它链接 51 | -------------------------------------------------------------------------------- /_posts/linux/2019-04-22-Linux-Memory-Analysis.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Linux内存工具解析之RSS/VSS/USS/PSS区别于联系" 3 | categories: 4 | - linux 5 | tags: 6 | - Linux Memory Analysis 7 | --- 8 | 9 | 对于Linux系统程序开发人员,经常需要和进程所使用的内存情况打交道,比如,分析程序的内存泄漏问题。这时候我们可能使用ps、top、procrank、dumpsys(后两个命令为Android系统)来跟踪、调试进程内存的使用情况。上述几个工具进程涉及到的几个比较的重要的概念:VSS、RSS、PSS、USS,对于这几个概念,大家总是存在一种似曾相识,却又不甚了解的感觉,这对于真正的把握进程内存使用情况是十分有害的。所以,本文旨在彻底分析这个四个概念,弄清各个量之间的联系和区别,提供有助于解释各种工具的内存报告的信息,以便确定Linux进程和系统的实际内存使用量,为以后分析内存问题提供坚实的理论基础。 10 | 11 | ## 基本概念 12 | 13 | * VSS:Virtual Set Size 虚拟耗用的内存(包含与其他进程共享占用的虚拟内存) 14 | * RSS:Resident Set Size 实际使用的物理内存(包含与其他进程共享占用的内存) 15 | * PSS:Proportional Set Size 实际使用的物理内存(按比例包含与其他进程共享占用的内存) 16 | * USS:Unique Set Size 进程独自占用的物理内存(不包含与其他进程共享占用的内存) 17 | 18 | 对于单个进程,一般来说内存占用大小排序如下:`VSS >= RSS >= PSS >= USS` 19 | 20 | ## 概念解析 21 | 22 | Android有一个名为`procrank`(`/system/xbin/procrank`)的工具,它列出了Linux进程的内存使用量,并按使用量的高低排序。每个进程报告的内存使用情况分为VSS、RSS、PSS和USS。 23 | 24 | 为了简单起见,在这个描述中,内存将用页面而不是字节来表示。像我们这样的Linux系统在最低级别上以4096字节的页面管理内存。 25 | 26 | 下面分别具体解释一下各个概念的含义: 27 | 28 | * VSS(ps工具中表示为VSZ)表示进程总的可访问地址空间。这个大小还包括可能不驻留在RAM中的内存,比如使用malloc分配内存后,尚未写入数据的内存。VSS对于确定进程的实际内存使用量几乎没有什么用处。 29 | * RSS表示一个进程在RAM中实际拥有的总内存。RSS可能具有误导性,因为它包括了该进程与其他进程共享的实际物理内存使用量,例如,对于共享库,其往往只加载到内存中一次,而不管有多少进程使用它。RSS不能准确地表示单个进程的内存使用情况。 30 | * PSS与RSS不同之处是,对于进程间共享的内存,其按比例报告其所使用的共享物理内存大小。比如有n进程同时在使用一个共享库,那对于单个进程其占用的该共享库的内存为1/n。如果三个进程都使用一个有30页的共享库,那么这个库将只向每个进程报告的PSS贡献10页。PSS是一个非常有用的数字,因为当系统中所有进程的PSS加在一起时,就可以很好地表示系统中总的内存使用量。当一个进程被终止时,贡献给它的PSS的共享库将按比例分配给仍然使用该库的其他进程的PSS总数。这样,PSS可能有点误导人,因为当进程被终止时,PSS不能准确地表示返回到整个系统的内存。 31 | * USS表示进程占用的总的物理内存大小,也就是说这部分内存是该进程完全独占的。 USS是一个非常有用的数字,因为它表示运行特定进程的实际增量成本。当进程被终止时,USS是实际返回给系统的总内存。当最初怀疑某个进程存在内存泄漏时,USS是最好的监视数字。 32 | 33 | 对于使用Python的系统,还有一个很好的工具叫做`ledsmem`,它可以报告内存统计信息,包括所有这些类别。 34 | 35 | NOTE:这里有几个问题需要注意: 36 | 37 | * 两个进程共享的部分,远远不是只有共享库,比如我们在Linux里面开2个bash进程,那么这2个bash,实际是共享1个代码段;其他的mmap()的时候shared的映射当然也是两个进程共享的内存。 38 | * 共享库里面的内存,也不是都共享,只是代码段等不会做CoW(写时拷贝)的内存才会跨进程共享。 39 | * USS去掉的是所有跨进程共享的内存,不是只去掉了共享库。 40 | 41 | ## 实例解析 42 | 43 | 下面通过一个实例,具体解析各个量之间的关系。假设Linux下有两个bash进程、一个cat进程,进程ID分别为1044、1045、1054,下面通过公式分别计算VSS、RSS、PSS、USS: 44 | 45 | ![](https://raw.githubusercontent.com/jiangxincode/PicGo/master/20190422144031323.png) 46 | 47 | * VSS = 1 + 2 + 3 48 | * RSS = 4 + 5 + 6 49 | * PSS = 4/3 + 5/2 + 6 50 | * USS = 6 51 | 52 | 上图中的4这片内存,是libc的代码段在内存驻留的部分,被3个进程共享;5这段内存,是bash的代码段,被2个进程(1044和1045)指向。在计算PSS的时候,这些都需要被比例化。 53 | 54 | ## 监测工具 55 | 56 | 对于Linux系统,一般都会提供ps、top两个命令,Android系统还会提供procrank、dumpsys这两个命令。对于ps、top其只能查到VSS、RSS这两个值;procrank、dumpsys可以提供PSS、USS信息,dumpsys meminfo 可以查出native和dalvik分别占用多少内存。另外,dumpsys可以查询到很多有用的系统信息,比如meminfo、cpuinfo、activity、window、wifi、account等信息。 57 | 58 | ## 参考信息 59 | 60 | * 性能优化工具(十)- Android内存分析命令: 61 | * 内存耗用:VSS/RSS/PSS/USS: -------------------------------------------------------------------------------- /_posts/others/2020-02-10-Cpp-Code-Check.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Cpp代码质量度量工具大阅兵" 3 | categories: 4 | - others 5 | tags: 6 | - Cpp 7 | - Code Check 8 | toc: true 9 | --- 10 | 11 | 姊妹篇:Java代码质量度量工具大阅兵: 12 | 13 | ## cppcheck 14 | 15 | * cppcheck: 16 | * 各种IDE和编辑器插件: <> 17 | * 检查项: 18 | 19 | ## CCCC 20 | 21 | * C and C++ Code Counter(CCCC): 22 | 23 | ## PC-lint 24 | 25 | * ~~PC-lint for C/C++: ~~ 26 | * PC-lint Plus: 27 | 28 | ## cpplint 29 | 30 | * cpplint: 31 | 32 | ## Splint 33 | 34 | Splint is a tool for statically checking C programs for security vulnerabilities and coding mistakes. With minimal effort, Splint can be used as a better lint. If additional effort is invested adding annotations to programs, Splint can perform stronger checking than can be done by any standard lint. 35 | 36 | * Splint: 37 | 38 | ## Frama-C 39 | 40 | Frama-C is a suite of tools dedicated to the analysis of the source code of software written in C. 41 | 42 | * Frama-C: 43 | 44 | ## Goanna Studio 45 | 46 | * Goanna Studio(Static Analysis for C/C++): 47 | 48 | ## Visual Leak Detector 49 | 50 | * Visual Leak Detector for Visual C++ : 51 | 52 | ## MemLeak 53 | 54 | MemLeak -- a module to debug memory leaks in C code and other problems with malloc()--free() invocations. Written in ANSI C. Distributed under GPL. 55 | 56 | * MemLeak: 57 | 58 | ## Valgrind 59 | 60 | Valgrind is an instrumentation framework for building dynamic analysis tools. There are Valgrind tools that can automatically detect many memory management and threading bugs, and profile your programs in detail. You can also use Valgrind to build new tools. 61 | 62 | * Valgrind: 63 | 64 | ## 额外阅读 65 | 66 | * C/C++内存泄漏及检测: 67 | * 浅谈C/C++内存泄露及其检测工具: -------------------------------------------------------------------------------- /_posts/others/2023-01-07-PDF常见问题解决方案汇总.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "PDF常见问题解决方案汇总" 3 | categories: 4 | - others 5 | tags: 6 | - PDF 7 | - Adobe Acrobat 8 | toc: true 9 | --- 10 | 11 | 本文针对PDF文件的常见问题及其解决方案进行汇总,主要是Adobe Acrobat的使用问题。 12 | 13 | ## Adobe Acrobat 14 | 15 | ### Adobe Acrobat修改PDF文档,保存的时候报错“读取本文档时出现问题(135)” 16 | 17 | * 导出图片,然后再合并成PDF了。这种方法是可行的,但是缺点是书签就都没了,文字也因为变成图片格式而无法复制为文本了。 18 | * 直接导出PDF,但是试验了一下,此方法不可行。说缺少文件:`The file "PreflightLib.dll" is missing or corrupt` 19 | * 另存为其他——优化的PDF——标准设置,对新的文档进行之前的修改即可。 20 | * 先随便找一个PDF文件(1.PDF)(可以先用一张图片转换成PDF,或者Word直接打印为PDF)。然后把需要保存的PDF文件和那个1.pdf一起选中,右键“在Acrobat中合并支持的文件...”。 然后保存为组合1.pdf。这个组合1已经能编辑自如了。把刚才的1.PDF的多余页面删除即可。此方法的优点是:保留了书签,而且保留了文本形式PDF上的文本的可复制性。 21 | 22 | ### Adobe Acrobat修改PDF文档,保存的时候报错:“读取本文档时出现问题(110)” 23 | 24 | 1. 另存为其他——优化的PDF——标准设置,对新的文档进行之前的修改即可。 25 | 2. 下载PDF-Viewer,然后用这个软件把问题文件打开,再把问题文件另存为自己随便取个名字的pdf文件。保存好后用之前的文件阅读器打开看看,基本上问题就解决了。最后记得把转存好的文件名字改回需要的名字。把原来的问题文件删除就OK了。 26 | 27 | ### 用Adobe Acrobat去除PDF文件的数字签名 28 | 29 | 今天遇到一个PDF,不但加了口令,还用了数字签名。口令很多工具都能对付,但是目前还真没什么工具能去除数字签名。我先把口令去了,现在可以复制内容,可以打印。但是由于数字签名还在,仍然无法进行修改、注释等操作。我尝试把这份文档再打印成PDF,这下数字签名倒是没有了,可原文件的书签也没了。又在网上看到有人说用“提取页面”也可以达到同样效果,但是也无法连书签一起提取。最后在网上找到一个解决方案: 30 | 31 | 1. 创建一个只有一页的PDF,用Adobe Acrobat打开。 32 | 2. 使用“文档->插入页面”,把有数字签名的文档插入到那一页后面。 33 | 3. 使用“文档->删除页面”,删除第一页,然后保存文档。 34 | 35 | ### 用Adobe Acrobat批量删除PDF文件中各类水印、背景、文本等 36 | 37 | 下载的 PDF 文件经常被加入许多广告性质的水印等,影响阅读。其删除办法如下: 38 | 39 | 1. `工具`-`页面`-`页眉和页脚`-`删除` 40 | 2. `工具`-`页面`-`背景`-`删除` 41 | 3. `工具`-`页面`-`水印`-`删除` 42 | 4. `工具`-`页面`-`Bates 编号`-`删除` 43 | 5. `工具`-`表单`-`清除表单` 44 | 6. `工具`-`保护`-`删除隐藏信息` 45 | 7. `工具`-`内容`-`编辑对象:删除选中对象`,或者有些对象在正文下层,需要先移开正文对象再删除 46 | 8. 对于用以上方法仍删除的文本,用以下方法: 47 | 48 | 1. `工具`-`保护`-`搜索并删除文本`-`将选定结果标记密文` 49 | 2. `工具`-`保护`-`应用密文` 50 | 3. `工具`-`保护`-`删除隐藏信息` 51 | 4. `工具`-`保护`-`整理文档` 52 | 53 | 注:标记密文前,最好设置密文属性为无填充、100%透明:`工具`-`保护`-`密文属性` 54 | 55 | ### 用Adobe Acrobat解决pdf页面大小不一致问题 56 | 57 | `视图`-`工具`-`印刷制作`-`设置页面框`。在弹出的“设置页面框”视图里设置`固定大小:页面大小A4`(注:此处请按需设置)、`页面范围:所有页面`。然后点击“确定”。 58 | 59 | ### 使用Adobe Acrobat将PDF所有书签批量修改为“适合宽度”显示 60 | 61 | 注意:本文所述方法不能自动创建书签,仅仅是修改点击书签后的显示模式。 62 | 63 | 1. 使用Adobe Acrobat打开PDF文件,点击左侧书签栏,让书签栏获得焦点,按组合键Shift+*展开所有书签。 64 | 2. 按组合键Ctrl+A选中所有书签,在任一书签上点击右键,选择“属性”菜单项,在弹出的“书签属性”对话框中,展开“选择动作”下拉框,选中“执行菜单项”。点击“添加…”按钮,在弹出的“菜单项”列表中选择“视图>缩放>适合宽度”,然后点击“确定”按钮返回“书签属性”对话框,再次点击“确定”按钮返回主界面。 65 | 3. 按组合键Shift+/折叠所有书签。注意:组合键中的‘/’必须是数字小键盘上的除号,这意味着:如果您使用的笔记本没有数字小键盘,您需要外接一个带数字小键盘的完整键盘。 66 | 4. 最后保存PDF文件的修改即可。 67 | 68 | ### Adobe Acrobat防盗版弹框 69 | 70 | `Adobe Acrobat Pro`打开PDF后,过一会就会弹出盗版保护窗口,提示:`This unlicensed Adobe app has been disabled`。解决方式如下: 71 | 72 | * `C:\Program Files\Adobe\Acrobat DC\Acrobat\AcroCEF\AcroCEF.exe`改名为`AcroCEF.exe.bak` 73 | * `C:\Program Files\Adobe\Acrobat DC\Acrobat\acrocef_1\AcroCEF.exe`改名为`AcroCEF.exe.bak` 74 | 75 | 然后重新打开`Adobe Acrobat Pro`,就不会弹出盗版保护窗口了。 76 | 77 | ## 其它问题 78 | 79 | * PDF to Word Converter: 80 | -------------------------------------------------------------------------------- /_posts/others/2025-05-21-智能驾驶-障碍物探测.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "智能驾驶-障碍物探测" 3 | categories: 4 | - 智能驾驶 5 | tags: 6 | - 障碍物探测 7 | - 智能驾驶 8 | toc: true 9 | --- 10 | 11 | 本文主要汇总了智能驾驶领域的一些技术和方案。 12 | 13 | * 自动驾驶的眼睛:激光、毫米波雷达&摄像头三种技术产品之比较: 14 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-Basic学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Basic学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - Basic 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 Basic 语言学习的相关资源,包括 Visual Basic、FreeBASIC 等语言的学习路径和参考资料,适合对 Basic 感兴趣的开发者参考。 12 | 13 | * BASIC: 14 | 15 | ## Visual Basic/Visual Basic .NET 16 | 17 | * Developing Automated Tests Using NUnit and VB.NET: 18 | * Comparison of Visual Basic and Visual Basic .NET: 19 | 20 | ## FreeBASIC 21 | 22 | * FreeBASIC: 23 | * freeBASIC: 24 | * ~~FBIde - editor for FreeBASIC: ~~ 25 | * ~~FbEdit FreeBASIC code editor: ~~ 26 | * FBWiki: 27 | 28 | ## ~~QuickBASIC/QBasic~~ 29 | 30 | * ~~QuickBASIC: ~~ 31 | * ~~QBasic: ~~ 32 | * ~~QBasic讨论区: ~~ 33 | * ~~Features of QuickBasic: ~~ 34 | * ~~文章分类 - Quick Basic: ~~ 35 | * ~~Quick Basic 常用的语句: ~~ 36 | * ~~All about QBasic and QuickBasic: ~~ 37 | 38 | ## Other 39 | 40 | * QB64: 41 | * KBasic(Basic For Qt): 42 | * BASIC-256: 43 | * PowerBASIC: 44 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-CSharp学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "C#学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - C# 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 C# 学习的相关资源,包括语言基础、.NET 框架、WPF、ASP.NET 等技术的学习路径和参考资料,适合 C# 开发者参考。 12 | 13 | * Mono: 14 | * MonoDevelop: 15 | * ~~SharpDevelop: ~~ 16 | * Emonic: 17 | 18 | ## .NET 19 | 20 | * NuGet: 21 | 22 | ## 其它 23 | 24 | * Windows Forms: 25 | * WPF: 26 | * WCF: 27 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-Docker学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Docker学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - Docker 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 Docker 学习的相关资源,包括 Docker 的基本概念、安装配置、镜像管理、容器操作等内容,适合容器化技术的初学者参考。 12 | 13 | * 14 | * 15 | * About images, containers, and storage drivers: 16 | 17 | * Kubernetes: 18 | * Kubernetes指南: 19 | 20 | * Docker —— 从入门到实践: 21 | * docker中文: 22 | * DOCKER windows安装: 23 | * boot2docker: 24 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-Erlang学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Erlang学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - Erlang 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 Erlang 学习的相关资源,包括 Erlang 的基本概念、安装配置、编程语言特性等内容,适合 Erlang 开发者参考。 12 | 13 | * 14 | * 15 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-Excel学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Excel学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - Excel 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 Excel 学习的相关资源,包括 Excel 的基本概念、函数、VBA 编程等内容,适合 Excel 开发者参考。 12 | 13 | ## 书籍 14 | 15 | * Excel 2019 Bible[EXCEL2019宝典(第10版)]: Michael Alexander,Dick Kusleika,Previously by John Walkenbach: 主力学习 16 | * Excel 2016 Power Programming with VBA[Excel 2016高级VBA编程宝典(第8版)]: Michael Alexander,Dick Kusleika: 主力学习 17 | * Excel 2016应用大全: 主力学习 18 | * Excel 2007 VBA办公范例应用: 内容老旧,阅读人数少,不适合学习 19 | * Excel 2010实用技巧集锦: 内容老旧,阅读人数少,不适合学习 20 | * Excel VBA实战技巧精粹: 评价不错 21 | * Excel VBA程序开发自学宝典(第3版): 已经有了,但是后者找不到对应的电子版。前者评价还不错 22 | * 疑难千寻千解丛书 23 | * Excel 2010 VBA编程与实践/Excel 2013 VBA编程与实践,评价还不错,后者找不到对应的电子版。 24 | 25 | ## 函数 26 | 27 | • All functions (alphabetical): 28 | • IFS function: 29 | • SWITCH function: 30 | 31 | ## 小知识点 32 | 33 | ### 改变日期格式 34 | 35 | ```shell 36 | # 'Fri Mar 18 22:49:05 2022 +0800'->'20220318 22:49:05' 37 | # =MID(C1, 21,4)&TEXT(MONTH(MID(C1,5,3)&"-1"), "00")&MID(C1,9,2)&" "&MID(C1,12,8) 38 | # 如果有点时间格式不稳定,如'Fri Mar 8 22:49:05 2022 +0800',则先分列再处理 39 | ``` 40 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-Fortran学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Fortran学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - Fortran 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 Fortran 学习的相关资源,包括 Fortran 的基本概念、编程语言特性、编译器等内容,适合 Fortran 开发者参考。 12 | 13 | * 14 | * GNU Fortran: 15 | * LFortran: 16 | * Fortran中文网: 17 | * Fortran77和90/95编程入门: 18 | * Approximatrix: 19 | * Fortran Coder: 20 | 21 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-Golang学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Golang学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - Golang 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 Golang 学习的相关资源,包括 Golang 的基本概念、安装配置、编程语言特性等内容,适合 Golang 开发者参考。 12 | 13 | * Go: 14 | * Go Documentation: 15 | * Go (programming language): 16 | * Go语言圣经(中文版): 17 | * Go 学习笔记: 18 | * the-way-to-go_ZH_CN: 19 | * 深入解析Go: 20 | * The-Golang-Standard-Library-by-Example: 21 | * Go 标准库 中文参考: 22 | * ~~GoClipse: ~~ 23 | * liteide: 24 | 25 | * Go Search: 26 | * Go Walker: 27 | * GoDoc: 28 | * Golang中国: 29 | * Go语言入门: 30 | * Go语言中文网: 31 | * GOROOT 和 GOPATH: 32 | * 搭建Go开发及调试环境(LiteIDE + GoClipse) -- Windows篇: 33 | * Go语言内存模型: 34 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-Groovy学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Groovy学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - Groovy 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 Groovy 学习的相关资源,包括 Groovy 的基本概念、编程语言特性、Groovy 语法等内容,适合 Groovy 开发者参考。 12 | 13 | * Groovy: 14 | * source: 15 | * Grape: 16 | * 实战 Groovy: 在 Java 应用程序中加一些 Groovy 进来: 17 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-Haskell学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Haskell学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - Haskell 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 Haskell 学习的相关资源,包括 Haskell 的基本概念、编程语言特性、编译器等内容,适合 Haskell 开发者参考。 12 | 13 | * 14 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-IO学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "IO学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - IO 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 IO 学习的相关资源,包括 IO 的基本概念、编程语言特性、编译器等内容,适合 IO 开发者参考。 12 | 13 | * 14 | * 15 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-Kotlin学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Kotlin学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - Kotlin 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 Kotlin 学习的相关资源,包括 Kotlin 的基本概念、编程语言特性、编译器等内容,适合 Kotlin 开发者参考。 12 | 13 | * 14 | * 15 | * 16 | * 17 | * 中文站: 18 | * 《Kotlin for android developers》中文版翻译: 19 | * Kotlin-Tutorials: 20 | * 21 | 22 | * Android Testing with Kotlin: 23 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-Lua学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Lua学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - Lua 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 Lua 学习的相关资源,包括 Lua 的基本概念、编程语言特性、编译器等内容,适合 Lua 开发者参考。 12 | 13 | * 14 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-Markdown学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Markdown学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - Markdown 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 Markdown 学习的相关资源,包括 Markdown 的基本概念、语法、编辑器等内容,适合 Markdown 开发者参考。 12 | 13 | * Markdown 语法说明 (简体中文版): 14 | 15 | * Typora: 16 | * MarkdownPad: 17 | * Online Markdown Editor, DILLINGER: 18 | * Cmd Markdown: 19 | * 马克飞象: 20 | * 10款流行的Markdown编辑器,总有一款适合你: 21 | * 求关于 Markdown 或类似标记语言的任何吐槽、建议、个人使用风格说明: 22 | * Markdeep: 23 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-Matlab与Octave学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Matlab & Octave学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - Matlab 8 | - Octave 9 | toc: true 10 | --- 11 | 12 | 本篇文章汇总了 Matlab 和 Octave 学习的相关资源,包括 Matlab 和 Octave 的基本概念、安装配置、编程语言特性等内容,适合 Matlab 和 Octave 开发者参考。 13 | 14 | ## Matlab 15 | 16 | * Matlab: 17 | 18 | * Matrix: HB/west0479: 19 | * ilovematlab.cn: 20 | 21 | * matlab GUI程序转换成exe可执行文件: 22 | * 基于MATLAB2008B与VS 2003生成独立可执行的程序: 23 | * 我与matlab的三年: 24 | * 网络MATLAB高手谈MATLAB学习: 25 | * RTW-real-time workshop: 26 | * matlab中怎样实现程序换行: 27 | 28 | ## Octave 29 | 30 | * GNU Octave: 31 | * GNU Octave Manual: 32 | * Octclipse项目地址: 33 | 34 | ## Maple 35 | 36 | * Maple: 37 | * User Manual: 38 | 39 | ## Mathematica 40 | 41 | * Mathematica: 42 | 43 | ## Mathcad 44 | 45 | * Mathcad: 46 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-Nginx学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Nginx学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - Nginx 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 Nginx 学习的相关资源,包括 Nginx 的基本概念、安装配置、编程语言特性等内容,适合 Nginx 开发者参考。 12 | 13 | * 14 | * Pre-Built Packages for Stable version: 15 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-OCaml学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "OCaml学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - OCaml 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 OCaml 学习的相关资源,包括 OCaml 的基本概念、安装配置、编程语言特性等内容,适合 OCaml 开发者参考。 12 | 13 | * OCaml: 14 | * opam(OCaml Package Manager): -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-OJ学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "OJ学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - OJ 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了Online Judge的相关资源,包含主要的OJ平台。 12 | 13 | * ACM竞赛之输入输出: 14 | * awesome-algorithm: 15 | 16 | * LeetCode Online Judge: 17 | * HackerRanker: 18 | * 洛谷: 19 | * Vijos: 20 | * Virtual Judge: 21 | * 牛客: 22 | * hihocoder: 23 | * cometoj: 24 | * LibreOJ: 25 | * Universal Online Judge: 26 | * 青藤OJ: 27 | * SPOJ (Sphere Online Judge): 28 | * OpenJudge: 29 | * codechef: 30 | * UVa Online Judge: 31 | * codeforces: 32 | * AtCoder: 33 | * 小米OJ: 34 | 35 | ## 高校OJ 36 | 37 | * PKU JudgeOnline: 38 | * ZOJ: 39 | * HDU Online Judge System: 40 | * ~~topcoder: ~~ 41 | * ~~codevs: ~~ 42 | * ~~猿圈: ~~ 43 | * ~~九度OJ: ~~ 44 | * ~~九度OJ永久关闭声明: ~~ 45 | * ~~ACdream Online Judge: ~~ 46 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-PHP学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "PHP学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - PHP 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 PHP 学习的相关资源,包括 PHP 的基本概念、安装配置、编程语言特性等内容,适合 PHP 开发者参考。 12 | 13 | * PHP: 14 | * PHP Manual: 15 | * ~~PHP 5 Manual: ~~ 16 | 17 | * Apache HTTP Server: 18 | 19 | * phpMyAdmin: 20 | * phpStudy: 21 | * WAMPSERVER: 22 | * WATMServer服务管理器: 23 | * LNMP一键安装包: 24 | * AppServ : Apache + PHP + MySQL: 25 | * XAMPP Apache + MariaDB + PHP + Perl: 26 | 27 | * Zend Optimizer,Zend Guard Loader 和 Zend Opcache 三者之间的区别: 28 | 29 | * PHPUnit: 30 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-Pascal与Delphi学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Pascal&Delphi学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - Pascal 8 | - Delphi 9 | toc: true 10 | --- 11 | 12 | 本篇文章汇总了 Pascal&Delphi 学习的相关资源,包括 Pascal&Delphi 的基本概念、安装配置、编程语言特性等内容,适合 Pascal&Delphi 开发者参考。 13 | 14 | * free pascal: 15 | * free pascal docs: 16 | * Lazarus: 17 | * Delphi: 18 | * Pascal (programming language): 19 | * Delphi (programming language): -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-Perl学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Perl学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - Perl 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 Perl 学习的相关资源,包括 Perl 的基本概念、安装配置、编程语言特性等内容,适合 Perl 开发者参考。 12 | 13 | * The Perl Programming Language: 14 | * Perl FAQ: 15 | * Perl programming documentation: 16 | * The Comprehensive Perl Archive Network (CPAN): 17 | * 18 | * 19 | 20 | * Strawberry Perl: 21 | * DWIM Perl: 22 | * ActivePerl: 23 | * Perl Express: 24 | * BioPerl: 25 | * Perl Mongers: 26 | 27 | * 功能丰富的 Perl: 一行程序 101: 28 | 29 | ## EPIC 30 | 31 | * 项目地址: 32 | * 安装说明: 33 | 34 | ## PerlUnit 35 | 36 | * 37 | 38 | ## Open Perl IDE 39 | 40 | * -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-Prolog学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Prolog学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - Prolog 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 Prolog 学习的相关资源,包括 Prolog 的基本概念、安装配置、编程语言特性等内容,适合 Prolog 开发者参考。 12 | 13 | * Visual Prolog: 14 | * SWI-Prolog: 15 | * Amzi! Prolog + Logic Server™: 16 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-Ruby学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Ruby学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - Ruby 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 Ruby 学习的相关资源,包括 Ruby 的基本概念、安装配置、编程语言特性等内容,适合 Ruby 开发者参考。 12 | 13 | * Ruby: 14 | * Help and documentation for the Ruby programming language: 15 | * RubyGems: 16 | * Ruby on Rails 指南: 17 | * Programming Ruby The Pragmatic Programmer's Guide: 18 | 19 | * 写给 Ruby 新人的公开信: 20 | 21 | * irb 與 ruby 指令: 22 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-Rust学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Rust学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - Rust 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 Rust 学习的相关资源,包括 Rust 的基本概念、安装配置、编程语言特性等内容,适合 Rust 开发者参考。 12 | 13 | * Rust: 14 | 15 | * Rust Documentation: 16 | * Rust 官方文档中文教程: 17 | 18 | * The Rust Programming Language: 19 | * Rust 程序设计语言: 20 | * Rust编程语言入门教程: 21 | 22 | * Rust语言圣经(Rust Course): 23 | 24 | * awesome-rust: 25 | 26 | * The Cargo Book: 27 | * crates.io: 28 | 29 | * 欢迎来到 Comprehensive Rust: 30 | * Android Rust 简介: 31 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-R学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "R学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - R 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 R 学习的相关资源,包括 R 语言的基本概念、安装配置、编程语言特性等内容,适合 R 开发者参考。 12 | 13 | * R: 14 | * The Comprehensive R Archive Network: 15 | 16 | * Rtools: 17 | 18 | ## RStudio 19 | 20 | * RStudio: 21 | * RStudio User Guide: 22 | * Using RStudio Projects: 23 | 24 | ## R Packages 25 | 26 | * R语言中,你最常用的软件包有哪些,请简述功能及特点? 27 | * R语言书籍的学习路线图: 28 | 29 | * Bioconductor: 30 | * Shiny(Easy web apps for data science without the compromises): 31 | * colourpicker(A colour picker tool for Shiny and for selecting colours in plots): 32 | * R Markdown: 33 | * quantmod(Quantitative Financial Modelling & Trading Framework for R): 34 | * Tidyverse: 35 | * ggplot2: 36 | * gganimate: 37 | * Plotly R Open Source Graphing Library: 38 | * plyr(The split-apply-combine strategy for R): 39 | * reshape2(长宽数据转换): 40 | * PerformanceAnalytics(Econometric tools for performance and risk analysis): 41 | * lavaan(latent variable analysis, 隐变量分析): 42 | * brew(用于动态生成文本和代码,类似于模板引擎): 43 | * rstatscn(R Interface for China National Data): 44 | * Hmisc(数据分析、数据操作、数据可视化以及生成描述性统计信息): 45 | 46 | * xlsx: 47 | 48 | * ggplot2 Version of Figures in “Lattice: Multivariate Data Visualization with R”: 49 | * The R Graph Gallery: 50 | * R Charts: 51 | 52 | ## R Books 53 | 54 | * Econometrics in R: 55 | * Applied Econometrics with R: 56 | * Statistics Using R with Biological Examples: 57 | 58 | * Statorials – 您的统计素养指南! -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-Scala学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Scala学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - Scala 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 Scala 学习的相关资源,包括 Scala 的基本概念、安装配置、编程语言特性等内容,适合 Scala 开发者参考。 12 | 13 | * 14 | * documentation: 15 | * wikipedia: (programming_language) 16 | * scalachina: 17 | 18 | * ScalaTest: 19 | * SBT: 20 | * ScalaIDE: 21 | 22 | * Scala入门之高级类型:this.type: -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-TCL与TK学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "TCL与TK学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - TCL与TK 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 TCL 与 TK 学习的相关资源,包括 TCL 与 TK 的基本概念、安装配置、编程语言特性等内容,适合 TCL 与 TK 开发者参考。 12 | 13 | * Tloona Tcl/Tk IDE: 14 | * tclsqueak: 15 | * CrowTDE: 16 | * MyTcl: 17 | 18 | * ACTIVETCL: 19 | * Getting started with ActiveTc: 20 | 21 | * Tcler's Wiki: 22 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-TeX学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "TeX学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - TeX 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 TeX 学习的相关资源,包括 TeX 的基本概念、安装配置等内容,适合 TeX 开发者参考。 12 | 13 | * TeX Live: 14 | 15 | * LaTeX-Workshop: 16 | * WinEdt: 17 | * Texmaker: 18 | * TeXworks: 19 | * TeXstudio: 20 | * TeXmacs: 21 | * The easy to use, online, collaborative LaTeX editor: 22 | * ~~TeXpen: ~~ 23 | * ~~SciTE LaTeX IDE: ~~ 24 | * ~~Kile LaTeX Editor: >~~ 25 | * ~~Gummi: The simple LaTeX editor: ~~ 26 | * ~~LEd, is an environment for rapid TeX and LaTeX document development: ~~ 27 | * ~~jaxedit: ~~ 28 | 29 | * Typst: 30 | * LyX: 31 | * ~~Word-to-LaTeX Converter: ~~ 32 | * MathType: 33 | 34 | * The Comprehensive TEX Archive Network(CTAN): 35 | * LaTeX – A document preparation system: 36 | * All about TeXnique: 37 | * Chinese TeX(CTEX): 38 | * LaTeX Stack Exchange: 39 | * LaTeX工作室: 40 | 41 | ## TeX Live自带文档 42 | 43 | * CTEX FAQ (常见问题集): texlive\${VERSION}\texmf-dist\doc\latex\ctex-faq\ctex-faq.pdf 44 | * 一份(不太)简短的LATEX2e 介绍: texlive\${VERSION}\texmf-dist\doc\latex\lshort-chinese\lshort-zh-cn.pdf 45 | * The Comprehensive LATEX Symbol List: texlive\${VERSION}\texmf-dist\doc\latex\comprehensive\symbols-a4.pdf 46 | * moderncv: texlive\${VERSION}\texmf-dist\doc\latex\moderncv\manual\moderncv_userguide.pdf 47 | 48 | ## 其它文档 49 | 50 | * An overview of TEX, its children and their friends: 51 | * 使用VSCode编写LaTeX: 52 | * LaTeX内容总结: 53 | * TeX/LaTeX 常用宏包简介: 54 | * Linux下Texlive的ctex包中文字体问题: 55 | * Latex相关资源汇总: 56 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-Windows学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Windows学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - Windows 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 Windows 学习的相关资源,包括 Windows 的基本概念、命令行工具、PowerShell 等内容,适合 Windows 开发者参考。 12 | 13 | ## Dos 14 | 15 | * FreeDOS: 16 | * DOSBox: 17 | * 中国DOS联盟: 18 | * MaxDOS: 19 | 20 | ## CMD 21 | 22 | * 浅谈批处理中的%cd%与%~dp0: 23 | 24 | ## PowerShell 25 | 26 | * PowerShell: 27 | * PowerShell Studio 2023: 28 | * Powershell 错误记录:详细错误: 29 | * pstips.net: 30 | * 如何改变PowerShell启动的默认目录: 31 | 32 | * 同时打开多个powershell窗口:Win+R+powershell 多次即可 33 | * 查看powershell命令帮助 help [cmd]:help Remove-Item 34 | * 删除文件夹:Remove-Item path –Recurse –Forse 35 | * 查看历史记录:Get-Content (Get-PSReadLineOption).HistorySavePath 36 | 37 | ## Others 38 | 39 | * chocolatey(The Package Manager for Windows): 40 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-数据挖掘学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "数据挖掘学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - 数据挖掘 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了数据挖掘学习的相关资源,包括数据挖掘的基本概念、算法、工具等内容,适合数据挖掘开发者参考。 12 | 13 | ## 开源数据集 14 | 15 | * Dataset Search: 16 | * Data in Brief: 17 | * data.world: 18 | * Mendeley Data: 19 | * figshare: 20 | * Zenodo: 21 | * UC Irvine Machine Learning Repository: 22 | * Harvard Dataverse: 23 | * DRYAD: 24 | * Socrata: 25 | * kaggle: 26 | * Microsoft Research Open Data: 27 | * 各领域公开数据集下载: 28 | 29 | ## SPSS 30 | 31 | * 32 | * SPSSAU: 33 | * SPSSPRO: 34 | 35 | ## SAS 36 | 37 | * SAS: 38 | 39 | ## SYSTAT 40 | 41 | * SYSTAT: 42 | 43 | ## RapidMiner 44 | 45 | * RapidMiner: 46 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-数据结构与算法.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "数据结构与算法学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - 数据结构与算法 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了数据结构与算法学习的相关资源,包括数据结构与算法的基本概念等内容。 12 | 13 | * 排序算法: 14 | * 算法可视化: 15 | * 十大经典排序算法动画,看我就够了! 16 | 17 | ## 算法大牛和讲师们 18 | 19 | * Robert Sedgewick: 20 | * Mark Allen Weiss: 21 | * Sartaj Sahni: 22 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-数电学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "数电学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - 数电 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了数电学习的相关资源,适合数电开发者参考。 12 | 13 | * 中国电子顶级开发网论坛(EETOP) 国内最顶级的电子论坛,最活跃的电子工程师交流社区: 14 | * Altera: -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-正则表达式学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "正则表达式学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - 正则表达式 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了正则表达式学习的相关资源,适合正则表达式开发者参考。 12 | 13 | * 我爱正则表达式: 14 | * Regular Expression Library: 15 | * RegexBuddy/RegexMagic/PowerGREP: 16 | * learn-regex: 17 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-汇编学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "汇编学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - 汇编 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了 汇编 学习的相关资源,包括 汇编 的基本概念、编程语言特性、编译器等内容,适合 汇编 开发者参考。 12 | 13 | * MASM: 14 | * ~~TASM: ~~ 15 | * flat assembler: 16 | * Yasm: 17 | * NASM: 18 | 19 | * winasm: 20 | * The MASM32 SDK: 21 | * RadASM: 22 | * The Go tools for Windows + Assembler: 23 | * Masm for windows 集成实验环境: 24 | * ~~asmplugin:~~ 25 | * ~~Win-Masm v2.2 汇编集成编译器: ~~ 26 | 27 | * dosbox: 28 | * EMU8086 - THE MICROPROCESSOR EMULATOR: 29 | * OllyDbg: 30 | * IDA Pro: 31 | * WinHex: 32 | 33 | * 汇编网: 34 | * 看雪学院: 35 | * 看雪安全论坛: 36 | * 鱼C工作室: 37 | * Linux 汇编语言开发指南: 38 | * AT&T(GAS)汇编指令小集: 39 | * 汇编指令 int 21 h 调用: 40 | * 汇编编写DOS下的内存驻留程序: <汇编编写DOS下的内存驻留程序.docx> 41 | * 汇编语言常见的错误提示代码及含义: 42 | * X86汇编快速入门: 43 | * BIOS中断大全: 44 | * 中断向量地址一览表: 45 | 46 | ## MiPS汇编 47 | 48 | * 常见模拟器列表: 49 | * MARS (MIPS Assembler and Runtime Simulator): 50 | * SPIM(QtSpim): 51 | * mipster20(MIPSter is a text editor written specifically for the MIPS assembly language, SPIM included): 52 | * WinMIPS64: 53 | * MIPSsim使用说明(含下载): 54 | * 建立基于linux的MIPS交叉编译环境: 55 | * MIPS的演化:See MIPS Run: Appendix D Evolving MIPS 56 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-编译原理学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "编译原理学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - 编译原理 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了编译原理学习的相关资源,包括编译原理的基本概念、编译器的实现、编译器优化等内容,适合编译原理开发者参考。 12 | 13 | * Win flex-bison: 14 | * Compilers: Principles, Techniques, and Tools: 15 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2015-05-19-设计学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "设计学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - 设计 8 | toc: true 9 | --- 10 | 11 | 本篇文章汇总了设计学习的相关资源,适合设计开发者参考。 12 | 13 | ## 图像处理 14 | 15 | * Photoshop: 16 | * GIMP: 17 | * SAI: 18 | * Krita: 19 | * 可牛影像: 20 | * 美图秀秀: 21 | * 光影魔术手: 22 | 23 | ## 矢量图形设计 24 | 25 | * Illustrator: 26 | * CorelDRAW Graphics Suite: 27 | 28 | ## 视频编辑 29 | 30 | * EDIUS(非线性编辑软件专为广播和后期制作环境而设计): 31 | * Adobe Premiere: 32 | * VideoStudio(会声会影): 33 | * Adobe After Effects(影视后期处理): 34 | * Adobe Premiere: 35 | * VideoStudio(会声会影): 36 | * Adobe After Effects(影视后期处理): 37 | 38 | ## 音频编辑 39 | 40 | * Adobe Audition: 41 | * RX: 42 | * fabfilter: 43 | 44 | ## PDF处理 45 | 46 | * Adobe Acrobat: 47 | * Adobe Acrobat: 48 | * PitStop Pro: 49 | * PitStop Pro Manuals: 50 | 51 | ## 三维建模与动画 52 | 53 | * blender(3D CG): 54 | * CINEMA 4D(三维动画、建模、模拟、渲染软件): 55 | * Autodesk 3ds Max(三维建模、渲染和动画软件): 56 | * Autodesk Maya(三维动画和视觉特效软件): 57 | * blender(3D CG): 58 | * CINEMA 4D(三维动画、建模、模拟、渲染软件): 59 | * 【C4D教程】零基础快速入门教程合集: 60 | * Autodesk 3ds Max(三维建模、渲染和动画软件): 61 | * Autodesk Maya(三维动画和视觉特效软件): 62 | 63 | ## AutoCAD 64 | 65 | * Autodesk AutoCAD(二维和三维 CAD 工具,助力提升创造力): 66 | * Autodesk Viewer: 67 | 68 | * 浩辰CAD: 69 | * 中望CAD: 70 | * 天正建筑软件: 71 | * ~~Acme CAD Converter: ~~ 72 | * CAD迷你看图: 73 | 74 | ## 其它 75 | 76 | * Adobe Dreamweaver: 77 | * Adobe InDesign: 78 | -------------------------------------------------------------------------------- /_posts/the-way-of-learning/2025-05-09-架构师学习之路.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "架构师学习之路" 3 | categories: 4 | - the-way-of-learning 5 | tags: 6 | - 学习之路 7 | - 架构师 8 | - 架构 9 | toc: true 10 | --- 11 | 12 | 本篇文章汇总了架构师学习的相关资源,包括架构师的基本概念、架构设计、架构模式等内容,适合架构师开发者参考。 13 | -------------------------------------------------------------------------------- /_posts/vcs/2021-01-09-TortoiseSVN_TortoiseGit_BeyondCompare.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "在TortoiseSVN/TortoiseGit中使用BeyondCompare进行差异对比" 3 | categories: 4 | - vcs 5 | tags: 6 | - TortoiseSVN 7 | - TortoiseGit 8 | - BeyondCompare 9 | toc: true 10 | --- 11 | 12 | BeyondCompare支持不同的版本控制系统相关工具,官网说明: 。本文仅针对比较常用的TortoiseSVN/TortoiseGit进行说明 13 | 14 | ## TortoiseSVN 15 | 16 | 在资源管理器右键菜单中:`TortoiseSVN-Settings` 17 | 18 | * 设置比较不同版本文件的程序,选择`External(外部)`,在下面文本框中填入如下内容,其中前半部分是`BComp.exe`所在目录: 19 | 20 | `"C:\Program Files\Beyond Compare 4\BComp.exe" %base %mine /title1=%bname /title2=%yname /leftreadonly` 21 | 22 | * 设置读取`GNU patch files`的程序,选择`External(外部)`,在下面文本框中填入`BCompare.exe`所在目录: 23 | 24 | `C:\Program Files\Beyond Compare 4\BCompare.exe` 25 | 26 | ![](https://raw.githubusercontent.com/jiangxincode/PicGo/master/611264-20210109113438890-50940543.png) 27 | 28 | * 设置解决文件冲突的程序,选择`External(外部)`,在下面文本框中填入如下内容,其中前半部分是`BComp.exe`所在目录: 29 | 30 | `"C:\Program Files\Beyond Compare 4\BComp.exe" %mine %theirs %base %merged /title1=%yname /title2=%tname /title3=%bname /title4=%mname` 31 | 32 | ![](https://raw.githubusercontent.com/jiangxincode/PicGo/master/611264-20210109113449706-495206858.png) 33 | 34 | 操作完成后点击确定结束。 35 | 36 | ## TortoiseGit 37 | 38 | 在资源管理器右键菜单中:`TortoiseGit-Settings`,后续操作步骤和`TortoiseSVN`相同: 39 | ![](https://raw.githubusercontent.com/jiangxincode/PicGo/master/611264-20210109113503069-903682193.png) 40 | 41 | ![](https://raw.githubusercontent.com/jiangxincode/PicGo/master/611264-20210109113508634-1811462627.png) 42 | -------------------------------------------------------------------------------- /assets/images/bio-photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiangxincode/cnblogs/0ac4eb7545e7c3a9872f16bf21a91287b988a722/assets/images/bio-photo.jpg -------------------------------------------------------------------------------- /google39f08d3f2271d152.html: -------------------------------------------------------------------------------- 1 | google-site-verification: google39f08d3f2271d152.html -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | --- 2 | # You don't need to edit this file, it's empty on purpose. 3 | # Edit theme's home layout instead if you wanna make some changes 4 | # See: https://jekyllrb.com/docs/themes/#overriding-theme-defaults 5 | layout: home 6 | author_profile: true 7 | --- 8 | --------------------------------------------------------------------------------